1
0

Merge pull request #1015 from mc-server/Stats

Statistics
This commit is contained in:
xdot 2014-05-21 11:14:44 +03:00
commit 671c73c639
7 changed files with 130 additions and 15 deletions

View File

@ -46,8 +46,30 @@ public:
bool IsWither(void) const { return m_IsWither; }
void Reset(void) { m_IsWither = false; }
} CallbackA, CallbackB;
class cPlayerCallback : public cPlayerListCallback
{
Vector3f m_Pos;
virtual bool Item(cPlayer * a_Player)
{
// TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one
double Dist = (a_Player->GetPosition() - m_Pos).Length();
if (Dist < 50.0)
{
// If player is close, award achievement
a_Player->AwardAchievement(achSpawnWither);
}
return false;
}
public:
cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
} PlayerCallback(Vector3f(a_BlockX, a_BlockY, a_BlockZ));
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
if (!CallbackA.IsWither())
@ -86,6 +108,9 @@ public:
// Spawn the wither:
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement
a_World->ForEachPlayer(PlayerCallback);
return true;
}
@ -113,6 +138,9 @@ public:
// Spawn the wither:
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement
a_World->ForEachPlayer(PlayerCallback);
return true;
}

View File

@ -456,8 +456,18 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
else
{
float Dist = (float)(m_LastGroundHeight - floor(GetPosY()));
if (Dist >= 2.0) // At least two blocks - TODO: Use m_LastJumpHeight instead of m_LastGroundHeight above
{
// Increment statistic
m_Stats.AddValue(statDistFallen, (StatValue)floor(Dist * 100 + 0.5));
}
int Damage = (int)(Dist - 3.f);
if (m_LastJumpHeight > m_LastGroundHeight) Damage++;
if (m_LastJumpHeight > m_LastGroundHeight)
{
Damage++;
}
m_LastJumpHeight = (float)GetPosY();
if (Damage > 0)
@ -1951,31 +1961,64 @@ void cPlayer::HandleFloater()
bool cPlayer::IsClimbing(void) const
{
int PosX = POSX_TOINT;
int PosY = POSY_TOINT;
int PosZ = POSZ_TOINT;
if ((PosY < 0) || (PosY >= cChunkDef::Height))
{
return false;
}
BLOCKTYPE Block = m_World->GetBlock(PosX, PosY, PosZ);
switch (Block)
{
case E_BLOCK_LADDER:
case E_BLOCK_VINES:
{
return true;
}
default: return false;
}
}
void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos)
{
StatValue Value = (StatValue)floor(a_DeltaPos.Length() * 100 + 0.5);
if (m_AttachedTo == NULL)
{
int PosX = POSX_TOINT;
int PosY = POSY_TOINT;
int PosZ = POSZ_TOINT;
BLOCKTYPE Block;
NIBBLETYPE Meta;
if (!m_World->GetBlockTypeMeta(PosX, PosY, PosZ, Block, Meta))
if (IsClimbing())
{
return;
if (a_DeltaPos.y > 0.0) // Going up
{
m_Stats.AddValue(statDistClimbed, (StatValue)floor(a_DeltaPos.y * 100 + 0.5));
}
}
if ((Block == E_BLOCK_LADDER) && (a_DeltaPos.y > 0.0)) // Going up
else if (IsSubmerged())
{
m_Stats.AddValue(statDistClimbed, (StatValue)floor(a_DeltaPos.y * 100 + 0.5));
m_Stats.AddValue(statDistDove, Value);
}
else if (IsSwimming())
{
m_Stats.AddValue(statDistSwum, Value);
}
else if (IsOnGround())
{
m_Stats.AddValue(statDistWalked, Value);
}
else
{
// TODO 2014-05-12 xdot: Other types
m_Stats.AddValue(statDistWalked, Value);
if (Value >= 25) // Ignore small/slow movement
{
m_Stats.AddValue(statDistFlown, Value);
}
}
}
else

View File

@ -127,6 +127,9 @@ public:
inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export
/** Returns whether the player is climbing (ladders, vines e.t.c). */
bool IsClimbing(void) const;
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) override;
// tolua_begin

View File

@ -142,6 +142,8 @@ public:
break;
}
}
a_Player->GetStatManager().AddValue(statTreasureFished, 1);
}
else if (ItemCategory <= 14) // Junk 10%
{
@ -190,6 +192,8 @@ public:
{
Drops.Add(cItem(E_BLOCK_TRIPWIRE_HOOK));
}
a_Player->GetStatManager().AddValue(statJunkFished, 1);
}
else // Fish
{
@ -210,6 +214,8 @@ public:
{
Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_FISH));
}
a_Player->GetStatManager().AddValue(statFishCaught, 1);
}
if (cRoot::Get()->GetPluginManager()->CallHookPlayerFishing(*a_Player, Drops))

View File

@ -2,7 +2,9 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Wither.h"
#include "../World.h"
#include "../Entities/Player.h"
@ -100,3 +102,35 @@ void cWither::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cWither::KilledBy(cEntity * a_Killer)
{
super::KilledBy(a_Killer);
class cPlayerCallback : public cPlayerListCallback
{
Vector3f m_Pos;
virtual bool Item(cPlayer * a_Player)
{
// TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one
double Dist = (a_Player->GetPosition() - m_Pos).Length();
if (Dist < 50.0)
{
// If player is close, award achievement
a_Player->AwardAchievement(achKillWither);
}
return false;
}
public:
cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
} PlayerCallback(GetPosition());
m_World->ForEachPlayer(PlayerCallback);
}

View File

@ -29,6 +29,7 @@ public:
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
virtual void KilledBy(cEntity * a_Killer) override;
private:

View File

@ -52,7 +52,7 @@ cStatInfo cStatInfo::ms_Info[statCount] = {
/* Type | Name */
cStatInfo(statGamesQuit, "stat.leaveGame"),
cStatInfo(statMinutesPlayed, "stat.playOneMinute"),
cStatInfo(statDistWalked, "stat.walkOnCm"),
cStatInfo(statDistWalked, "stat.walkOneCm"),
cStatInfo(statDistSwum, "stat.swimOneCm"),
cStatInfo(statDistFallen, "stat.fallOneCm"),
cStatInfo(statDistClimbed, "stat.climbOneCm"),