summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/BlockEntities/BeaconEntity.cpp2
-rw-r--r--src/BlockEntities/BrewingstandEntity.cpp2
-rw-r--r--src/BlockEntities/ChestEntity.cpp9
-rw-r--r--src/BlockEntities/DropSpenserEntity.cpp9
-rw-r--r--src/BlockEntities/EnderChestEntity.cpp3
-rw-r--r--src/BlockEntities/FlowerPotEntity.cpp2
-rw-r--r--src/BlockEntities/FurnaceEntity.cpp2
-rw-r--r--src/BlockEntities/HopperEntity.cpp2
-rw-r--r--src/BlockEntities/JukeboxEntity.cpp2
-rw-r--r--src/BlockEntities/NoteEntity.cpp3
-rw-r--r--src/Blocks/BlockBed.cpp1
-rw-r--r--src/Blocks/BlockCake.h1
-rw-r--r--src/Blocks/BlockCauldron.h2
-rw-r--r--src/Blocks/BlockWorkbench.h2
-rw-r--r--src/ClientHandle.cpp1
-rw-r--r--src/Entities/Player.cpp35
-rw-r--r--src/Mobs/PassiveMonster.cpp12
-rw-r--r--src/Mobs/PassiveMonster.h4
18 files changed, 88 insertions, 6 deletions
diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp
index 9923be749..f9ceb6f34 100644
--- a/src/BlockEntities/BeaconEntity.cpp
+++ b/src/BlockEntities/BeaconEntity.cpp
@@ -303,6 +303,8 @@ bool cBeaconEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
bool cBeaconEntity::UsedBy(cPlayer * a_Player)
{
+ a_Player->GetStatManager().AddValue(Statistic::InteractWithBeacon);
+
cWindow * Window = GetWindow();
if (Window == nullptr)
{
diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp
index 3f437d4cb..27dabf177 100644
--- a/src/BlockEntities/BrewingstandEntity.cpp
+++ b/src/BlockEntities/BrewingstandEntity.cpp
@@ -156,6 +156,8 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
{
+ a_Player->GetStatManager().AddValue(Statistic::InteractWithBrewingstand);
+
cWindow * Window = GetWindow();
if (Window == nullptr)
{
diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp
index 0f005fb53..8c8e75b25 100644
--- a/src/BlockEntities/ChestEntity.cpp
+++ b/src/BlockEntities/ChestEntity.cpp
@@ -105,6 +105,15 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
}
}
+ if (m_BlockType == E_BLOCK_CHEST)
+ {
+ a_Player->GetStatManager().AddValue(Statistic::OpenChest);
+ }
+ else // E_BLOCK_TRAPPED_CHEST
+ {
+ a_Player->GetStatManager().AddValue(Statistic::TriggerTrappedChest);
+ }
+
// If the window is not created, open it anew:
cWindow * Window = PrimaryChest->GetWindow();
if (Window == nullptr)
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index 2b048bce2..97a67ff60 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -153,6 +153,15 @@ void cDropSpenserEntity::SendTo(cClientHandle & a_Client)
bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
{
+ if (m_BlockType == E_BLOCK_DISPENSER)
+ {
+ a_Player->GetStatManager().AddValue(Statistic::InspectDispenser);
+ }
+ else // E_BLOCK_DROPPER
+ {
+ a_Player->GetStatManager().AddValue(Statistic::InspectDropper);
+ }
+
cWindow * Window = GetWindow();
if (Window == nullptr)
{
diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp
index 74e6a7d23..44bfaf7d4 100644
--- a/src/BlockEntities/EnderChestEntity.cpp
+++ b/src/BlockEntities/EnderChestEntity.cpp
@@ -61,6 +61,9 @@ bool cEnderChestEntity::UsedBy(cPlayer * a_Player)
// Obstruction, don't open
return false;
}
+
+ a_Player->GetStatManager().AddValue(Statistic::OpenEnderchest);
+
// If the window is not created, open it anew:
cWindow * Window = GetWindow();
if (Window == nullptr)
diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp
index 5446ee5bd..60b2db4f5 100644
--- a/src/BlockEntities/FlowerPotEntity.cpp
+++ b/src/BlockEntities/FlowerPotEntity.cpp
@@ -59,6 +59,8 @@ bool cFlowerPotEntity::UsedBy(cPlayer * a_Player)
return false;
}
+ a_Player->GetStatManager().AddValue(Statistic::PotFlower);
+
cItem SelectedItem = a_Player->GetInventory().GetEquippedItem();
if (IsFlower(SelectedItem.m_ItemType, SelectedItem.m_ItemDamage))
{
diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp
index f521bf666..e8e981065 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -139,6 +139,8 @@ bool cFurnaceEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
{
+ a_Player->GetStatManager().AddValue(Statistic::InteractWithFurnace);
+
cWindow * Window = GetWindow();
if (Window == nullptr)
{
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index f7cb13b7d..9665b9f25 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -106,6 +106,8 @@ void cHopperEntity::SendTo(cClientHandle & a_Client)
bool cHopperEntity::UsedBy(cPlayer * a_Player)
{
+ a_Player->GetStatManager().AddValue(Statistic::InspectHopper);
+
// If the window is not created, open it anew:
cWindow * Window = GetWindow();
if (Window == nullptr)
diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp
index c8d08f327..6f25c4a36 100644
--- a/src/BlockEntities/JukeboxEntity.cpp
+++ b/src/BlockEntities/JukeboxEntity.cpp
@@ -70,6 +70,8 @@ bool cJukeboxEntity::UsedBy(cPlayer * a_Player)
const cItem & HeldItem = a_Player->GetEquippedItem();
if (PlayRecord(HeldItem.m_ItemType) && !a_Player->IsGameModeCreative())
{
+ a_Player->GetStatManager().AddValue(Statistic::PlayRecord);
+
a_Player->GetInventory().RemoveOneEquippedItem();
return true;
}
diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp
index d56f45548..3e9958892 100644
--- a/src/BlockEntities/NoteEntity.cpp
+++ b/src/BlockEntities/NoteEntity.cpp
@@ -4,6 +4,7 @@
#include "NoteEntity.h"
#include "../World.h"
#include "json/value.h"
+#include "../Entities/Player.h"
@@ -33,7 +34,7 @@ void cNoteEntity::CopyFrom(const cBlockEntity & a_Src)
bool cNoteEntity::UsedBy(cPlayer * a_Player)
{
- UNUSED(a_Player);
+ a_Player->GetStatManager().AddValue(Statistic::TuneNoteblock);
IncrementNote();
MakeSound();
return true;
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp
index e333c0700..79e4a0019 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -128,6 +128,7 @@ bool cBlockBedHandler::OnUse(
SetBedPos(a_Player, a_BlockPos);
SetBedOccupationState(a_ChunkInterface, a_Player.GetLastBedPos(), true);
a_Player.SetIsInBed(true);
+ a_Player.GetStatManager().AddValue(Statistic::SleepInBed);
// Fast-forward the time if all players in the world are in their beds:
auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer)
diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h
index dbcce5f17..b7506f2e7 100644
--- a/src/Blocks/BlockCake.h
+++ b/src/Blocks/BlockCake.h
@@ -36,6 +36,7 @@ public:
return false;
}
+ a_Player.GetStatManager().AddValue(Statistic::EatCakeSlice);
if (Meta >= 5)
{
a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockPos);
diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h
index da7c43860..263f539a7 100644
--- a/src/Blocks/BlockCauldron.h
+++ b/src/Blocks/BlockCauldron.h
@@ -54,6 +54,7 @@ public:
if (!a_Player.IsGameModeCreative())
{
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_WATER_BUCKET));
+ a_Player.GetStatManager().AddValue(Statistic::UseCauldron);
}
}
break;
@@ -68,6 +69,7 @@ public:
{
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET));
}
+ a_Player.GetStatManager().AddValue(Statistic::FillCauldron);
}
break;
}
diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h
index 19bf551dd..329a1ddeb 100644
--- a/src/Blocks/BlockWorkbench.h
+++ b/src/Blocks/BlockWorkbench.h
@@ -34,6 +34,8 @@ public:
const Vector3i a_CursorPos
) override
{
+ a_Player.GetStatManager().AddValue(Statistic::InteractWithCraftingTable);
+
cWindow * Window = new cCraftingWindow();
a_Player.OpenWindow(*Window);
return true;
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 040c3a306..86e90aa8b 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -2109,6 +2109,7 @@ void cClientHandle::Tick(float a_Dt)
LOGD("Client %s @ %s (%p) has been queued for destruction, destroying now.",
m_Username.c_str(), m_IPString.c_str(), static_cast<void *>(this)
);
+ GetPlayer()->GetStatManager().AddValue(Statistic::LeaveGame);
Destroy();
return;
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 841b70b01..d9353f67f 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -334,7 +334,12 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
- m_Stats.AddValue(Statistic::PlayOneMinute, 1);
+ m_Stats.AddValue(Statistic::PlayOneMinute);
+ m_Stats.AddValue(Statistic::TimeSinceDeath);
+ if (IsCrouched())
+ {
+ m_Stats.AddValue(Statistic::SneakTime);
+ }
// Handle the player detach, when the player is in spectator mode
if (
@@ -1235,6 +1240,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
}
m_Stats.AddValue(Statistic::Deaths);
+ m_Stats.SetValue(Statistic::TimeSinceDeath, 0);
m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1);
}
@@ -2675,14 +2681,33 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs
}
else if (IsInWater())
{
- // TODO: implement differentiation between diving and swimming
- m_Stats.AddValue(Statistic::WalkUnderWaterOneCm, Value);
+ if (m_IsHeadInWater)
+ {
+ m_Stats.AddValue(Statistic::WalkUnderWaterOneCm, Value);
+ }
+ else
+ {
+ m_Stats.AddValue(Statistic::WalkOnWaterOneCm, Value);
+ }
AddFoodExhaustion(0.00015 * static_cast<double>(Value));
}
else if (IsOnGround())
{
- m_Stats.AddValue(Statistic::WalkOneCm, Value);
- AddFoodExhaustion((IsSprinting() ? 0.001 : 0.0001) * static_cast<double>(Value));
+ if (IsCrouched())
+ {
+ m_Stats.AddValue(Statistic::CrouchOneCm, Value);
+ AddFoodExhaustion(0.0001 * static_cast<double>(Value));
+ }
+ if (IsSprinting())
+ {
+ m_Stats.AddValue(Statistic::SprintOneCm, Value);
+ AddFoodExhaustion(0.001 * static_cast<double>(Value));
+ }
+ else
+ {
+ m_Stats.AddValue(Statistic::WalkOneCm, Value);
+ AddFoodExhaustion(0.0001 * static_cast<double>(Value));
+ }
}
else
{
diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp
index f9d5e4ba4..1a8aaa3bf 100644
--- a/src/Mobs/PassiveMonster.cpp
+++ b/src/Mobs/PassiveMonster.cpp
@@ -57,6 +57,7 @@ void cPassiveMonster::ResetLoveMode()
m_LoveTimer = 0;
m_MatingTimer = 0;
m_LoveCooldown = 20 * 60 * 5; // 5 minutes
+ m_Feeder = cUUID();
// when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata
m_World->BroadcastEntityMetadata(*this);
@@ -125,6 +126,15 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
m_World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, GetRandomProvider().RandInt(1, 6));
+ m_World->DoWithPlayerByUUID(m_Feeder, [&] (cPlayer & a_Player)
+ {
+ a_Player.GetStatManager().AddValue(Statistic::AnimalsBred);
+ if (GetMobType() == eMonsterType::mtCow)
+ {
+ a_Player.AwardAchievement(Statistic::AchBreedCow);
+ }
+ return true;
+ });
m_LovePartner->ResetLoveMode();
ResetLoveMode();
}
@@ -241,6 +251,8 @@ void cPassiveMonster::OnRightClicked(cPlayer & a_Player)
}
}
}
+ // Stores feeder UUID for statistic tracking
+ m_Feeder = a_Player.GetUUID();
}
diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h
index fbe381955..67d7399d8 100644
--- a/src/Mobs/PassiveMonster.h
+++ b/src/Mobs/PassiveMonster.h
@@ -2,6 +2,7 @@
#pragma once
#include "Monster.h"
+#include "../UUID.h"
@@ -60,6 +61,9 @@ protected:
/** The monster's breeding partner. */
cPassiveMonster * m_LovePartner;
+ /** Remembers the player is was last fed by for statistics tracking */
+ cUUID m_Feeder;
+
/** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */
int m_LoveTimer;