summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMake/GenerateBindings.cmake1
-rw-r--r--Server/Plugins/APIDump/APIDesc.lua415
-rw-r--r--Server/Plugins/APIDump/main_APIDump.lua12
-rw-r--r--src/Bindings/AllToLua.pkg2
-rw-r--r--src/Bindings/LuaState.cpp15
-rw-r--r--src/Bindings/LuaState.h2
-rw-r--r--src/Bindings/ManualBindings.cpp69
-rw-r--r--src/BlockEntities/BeaconEntity.cpp4
-rw-r--r--src/BlockEntities/BrewingstandEntity.cpp2
-rw-r--r--src/BlockEntities/ChestEntity.cpp4
-rw-r--r--src/BlockEntities/DropSpenserEntity.cpp4
-rw-r--r--src/BlockEntities/EnderChestEntity.cpp2
-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.cpp3
-rw-r--r--src/BlockEntities/NoteEntity.cpp2
-rw-r--r--src/Blocks/BlockBed.cpp2
-rw-r--r--src/Blocks/BlockCake.h2
-rw-r--r--src/Blocks/BlockCauldron.h4
-rw-r--r--src/Blocks/BlockWorkbench.h2
-rw-r--r--src/ClientHandle.cpp4
-rw-r--r--src/ClientHandle.h6
-rw-r--r--src/Entities/Entity.cpp2
-rw-r--r--src/Entities/Pickup.cpp8
-rw-r--r--src/Entities/Player.cpp68
-rw-r--r--src/Entities/Player.h10
-rw-r--r--src/Items/ItemFishingRod.h6
-rw-r--r--src/Items/ItemMobHead.h2
-rw-r--r--src/Mobs/Monster.cpp4
-rw-r--r--src/Mobs/Wither.cpp2
-rw-r--r--src/Protocol/Palettes/Palette_1_13.cpp106
-rw-r--r--src/Protocol/Palettes/Palette_1_13.h2
-rw-r--r--src/Protocol/Palettes/Palette_1_13_1.cpp118
-rw-r--r--src/Protocol/Palettes/Palette_1_13_1.h2
-rw-r--r--src/Protocol/Palettes/Palette_1_14.cpp140
-rw-r--r--src/Protocol/Palettes/Palette_1_14.h2
-rw-r--r--src/Protocol/Palettes/Palette_1_15.cpp144
-rw-r--r--src/Protocol/Palettes/Palette_1_15.h2
-rw-r--r--src/Protocol/Palettes/Palette_1_16.cpp150
-rw-r--r--src/Protocol/Palettes/Palette_1_16.h2
-rw-r--r--src/Protocol/Protocol.h5
-rw-r--r--src/Protocol/Protocol_1_13.cpp47
-rw-r--r--src/Protocol/Protocol_1_13.h6
-rw-r--r--src/Protocol/Protocol_1_14.cpp2
-rw-r--r--src/Protocol/Protocol_1_14.h2
-rw-r--r--src/Protocol/Protocol_1_8.cpp199
-rw-r--r--src/Protocol/Protocol_1_8.h4
-rw-r--r--src/Registries/Statistics.h8
-rw-r--r--src/Statistics.cpp92
-rw-r--r--src/Statistics.h26
-rw-r--r--src/UI/SlotArea.cpp26
-rw-r--r--src/WorldStorage/NamespaceSerializer.cpp442
-rw-r--r--src/WorldStorage/NamespaceSerializer.h4
-rw-r--r--src/WorldStorage/StatSerializer.cpp201
-rw-r--r--src/WorldStorage/StatSerializer.h7
56 files changed, 1405 insertions, 999 deletions
diff --git a/CMake/GenerateBindings.cmake b/CMake/GenerateBindings.cmake
index 6d702a778..924202f21 100644
--- a/CMake/GenerateBindings.cmake
+++ b/CMake/GenerateBindings.cmake
@@ -79,6 +79,7 @@ function(enable_bindings_generation)
Mobs/MonsterTypes.h
OSSupport/File.h
Protocol/MojangAPI.h
+ Registries/Statistics.h
Root.h
Scoreboard.h
Server.h
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua
index 888ce9aef..0e616a35c 100644
--- a/Server/Plugins/APIDump/APIDesc.lua
+++ b/Server/Plugins/APIDump/APIDesc.lua
@@ -10245,27 +10245,17 @@ a_Player:OpenWindow(Window);
},
Notes = "Returns the full color code to be used for this player's messages (based on their rank). Prefix player messages with this code.",
},
- GetDraggingItem =
- {
- Returns =
- {
- {
- Type = "cItem",
- },
- },
- Notes = "Returns the item the player is dragging in a UI window."
- },
- GetPrefix =
+ GetCurrentXp =
{
Returns =
{
{
- Type = "string",
+ Type = "number",
},
},
- Notes = "Returns the prefix to player names for messages (based on their rank), may contain @ format codes.",
+ Notes = "Returns the current amount of XP",
},
- GetSuffix =
+ GetCustomName =
{
Returns =
{
@@ -10273,27 +10263,17 @@ a_Player:OpenWindow(Window);
Type = "string",
},
},
- Notes = "Returns the suffix to player names for messages (based on their rank), may contain @ format codes.",
- },
- GetCurrentXp =
- {
- Returns =
- {
- {
- Type = "number",
- },
- },
- Notes = "Returns the current amount of XP",
+ Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string.",
},
- GetCustomName =
+ GetDraggingItem =
{
Returns =
{
{
- Type = "string",
+ Type = "cItem",
},
},
- Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string.",
+ Notes = "Returns the item the player is dragging in a UI window."
},
GetEffectiveGameMode =
{
@@ -10489,6 +10469,16 @@ a_Player:OpenWindow(Window);
},
Notes = "Returns the name that is used in the playerlist.",
},
+ GetPrefix =
+ {
+ Returns =
+ {
+ {
+ Type = "string",
+ },
+ },
+ Notes = "Returns the prefix to player names for messages (based on their rank), may contain @ format codes.",
+ },
GetRestrictions =
{
Returns =
@@ -10519,6 +10509,26 @@ a_Player:OpenWindow(Window);
},
Notes = "Returns the player's current set of skin part flags. This is a bitwise OR of various {{Globals#eSkinPart|eSkinPart}} constants. Note that HasSkinPart may be easier to use in most situations.",
},
+ GetStatistics =
+ {
+ Returns =
+ {
+ {
+ Type = "StatisticsManager",
+ },
+ },
+ Notes = "Returns the player's statistics manager."
+ },
+ GetSuffix =
+ {
+ Returns =
+ {
+ {
+ Type = "string",
+ },
+ },
+ Notes = "Returns the suffix to player names for messages (based on their rank), may contain @ format codes.",
+ },
GetTeam =
{
Returns =
@@ -13219,7 +13229,41 @@ end
Include = { "wt.*" },
}
}, -- ConstantGroups
- }, -- cWindow
+ },
+ StatisticsManager =
+ {
+ Desc = [[
+ This class provides a store for various types of player statistics. The store will be read and sent to the client when the Statistics button is pressed.
+ ]],
+ Variables =
+ {
+ Custom =
+ {
+ Type = "Map of {{CustomStatistic}} to number",
+ Notes = "Gets or sets the value of a custom statistic.",
+ },
+ },
+ AdditionalInfo =
+ {
+ {
+ Header = "Example usage",
+ Contents = [[
+ Each store is a table, keyed by the statistic that the entry tracks, with value typically representing the number of times the event happened:
+<pre class="prettyprint lang-lua">
+function ModifyPlayerFurnaceInteractions(Player)
+ local Statistics = Player:GetStatistics()
+
+ if (Statistics.Custom[CustomStatistic.WalkOneCm] > 10) then
+ Statistics.Custom[CustomStatistic.InteractWithFurnace] = 1337
+ end
+
+ -- Next time the player presses Statistics they will see the updated value for furnace interactions.
+end
+</pre>
+ ]],
+ },
+ },
+ },
BannerPattern =
{
@@ -13700,6 +13744,319 @@ end
},
}
},
+ CustomStatistic =
+ {
+ Desc = [[
+ An enumeration of statistics of the custom type to be used with the {{StatisticsManager#Custom|Custom}} statistics store.
+ ]],
+ Constants =
+ {
+ AnimalsBred =
+ {
+ Notes = "",
+ },
+ AviateOneCm =
+ {
+ Notes = "",
+ },
+ BellRing =
+ {
+ Notes = "",
+ },
+ BoatOneCm =
+ {
+ Notes = "",
+ },
+ CleanArmor =
+ {
+ Notes = "",
+ },
+ CleanBanner =
+ {
+ Notes = "",
+ },
+ CleanShulkerBox =
+ {
+ Notes = "",
+ },
+ ClimbOneCm =
+ {
+ Notes = "",
+ },
+ CrouchOneCm =
+ {
+ Notes = "",
+ },
+ DamageAbsorbed =
+ {
+ Notes = "",
+ },
+ DamageBlockedByShield =
+ {
+ Notes = "",
+ },
+ DamageDealt =
+ {
+ Notes = "",
+ },
+ DamageDealtAbsorbed =
+ {
+ Notes = "",
+ },
+ DamageDealtResisted =
+ {
+ Notes = "",
+ },
+ DamageResisted =
+ {
+ Notes = "",
+ },
+ DamageTaken =
+ {
+ Notes = "",
+ },
+ Deaths =
+ {
+ Notes = "",
+ },
+ Drop =
+ {
+ Notes = "",
+ },
+ EatCakeSlice =
+ {
+ Notes = "",
+ },
+ EnchantItem =
+ {
+ Notes = "",
+ },
+ FallOneCm =
+ {
+ Notes = "",
+ },
+ FillCauldron =
+ {
+ Notes = "",
+ },
+ FishCaught =
+ {
+ Notes = "",
+ },
+ FlyOneCm =
+ {
+ Notes = "",
+ },
+ HorseOneCm =
+ {
+ Notes = "",
+ },
+ InspectDispenser =
+ {
+ Notes = "",
+ },
+ InspectDropper =
+ {
+ Notes = "",
+ },
+ InspectHopper =
+ {
+ Notes = "",
+ },
+ InteractWithAnvil =
+ {
+ Notes = "",
+ },
+ InteractWithBeacon =
+ {
+ Notes = "",
+ },
+ InteractWithBlastFurnace =
+ {
+ Notes = "",
+ },
+ InteractWithBrewingstand =
+ {
+ Notes = "",
+ },
+ InteractWithCampfire =
+ {
+ Notes = "",
+ },
+ InteractWithCartographyTable =
+ {
+ Notes = "",
+ },
+ InteractWithCraftingTable =
+ {
+ Notes = "",
+ },
+ InteractWithFurnace =
+ {
+ Notes = "",
+ },
+ InteractWithGrindstone =
+ {
+ Notes = "",
+ },
+ InteractWithLectern =
+ {
+ Notes = "",
+ },
+ InteractWithLoom =
+ {
+ Notes = "",
+ },
+ InteractWithSmithingTable =
+ {
+ Notes = "",
+ },
+ InteractWithSmoker =
+ {
+ Notes = "",
+ },
+ InteractWithStonecutter =
+ {
+ Notes = "",
+ },
+ JunkFished =
+ {
+ Notes = "",
+ },
+ Jump =
+ {
+ Notes = "",
+ },
+ LeaveGame =
+ {
+ Notes = "",
+ },
+ MinecartOneCm =
+ {
+ Notes = "",
+ },
+ MobKills =
+ {
+ Notes = "",
+ },
+ OpenBarrel =
+ {
+ Notes = "",
+ },
+ OpenChest =
+ {
+ Notes = "",
+ },
+ OpenEnderchest =
+ {
+ Notes = "",
+ },
+ OpenShulkerBox =
+ {
+ Notes = "",
+ },
+ PigOneCm =
+ {
+ Notes = "",
+ },
+ PlayNoteblock =
+ {
+ Notes = "",
+ },
+ PlayOneMinute =
+ {
+ Notes = "",
+ },
+ PlayRecord =
+ {
+ Notes = "",
+ },
+ PlayerKills =
+ {
+ Notes = "",
+ },
+ PotFlower =
+ {
+ Notes = "",
+ },
+ RaidTrigger =
+ {
+ Notes = "",
+ },
+ RaidWin =
+ {
+ Notes = "",
+ },
+ SleepInBed =
+ {
+ Notes = "",
+ },
+ SneakTime =
+ {
+ Notes = "",
+ },
+ SprintOneCm =
+ {
+ Notes = "",
+ },
+ StriderOneCm =
+ {
+ Notes = "",
+ },
+ SwimOneCm =
+ {
+ Notes = "",
+ },
+ TalkedToVillager =
+ {
+ Notes = "",
+ },
+ TargetHit =
+ {
+ Notes = "",
+ },
+ TimeSinceDeath =
+ {
+ Notes = "",
+ },
+ TimeSinceRest =
+ {
+ Notes = "",
+ },
+ TradedWithVillager =
+ {
+ Notes = "",
+ },
+ TreasureFished =
+ {
+ Notes = "",
+ },
+ TriggerTrappedChest =
+ {
+ Notes = "",
+ },
+ TuneNoteblock =
+ {
+ Notes = "",
+ },
+ UseCauldron =
+ {
+ Notes = "",
+ },
+ WalkOnWaterOneCm =
+ {
+ Notes = "",
+ },
+ WalkOneCm =
+ {
+ Notes = "",
+ },
+ WalkUnderWaterOneCm =
+ {
+ Notes = "",
+ },
+ },
+ },
Globals =
{
Desc = [[
diff --git a/Server/Plugins/APIDump/main_APIDump.lua b/Server/Plugins/APIDump/main_APIDump.lua
index f92abb932..61dd1e66c 100644
--- a/Server/Plugins/APIDump/main_APIDump.lua
+++ b/Server/Plugins/APIDump/main_APIDump.lua
@@ -52,7 +52,6 @@ end
-
--- Returns the API currently detected from the global environment
local function CreateAPITables()
--[[
@@ -121,14 +120,15 @@ local function CreateAPITables()
end
-- Member variables:
+ local GetField = a_ClassObj[".get"];
local SetField = a_ClassObj[".set"] or {};
- if ((a_ClassObj[".get"] ~= nil) and (type(a_ClassObj[".get"]) == "table")) then
- for k in pairs(a_ClassObj[".get"]) do
- if (SetField[k] == nil) then
- -- It is a read-only variable, add it as a constant:
+ if ((GetField ~= nil) and (type(GetField) == "table")) then
+ for k, v in pairs(GetField) do
+ if ((SetField[k] == nil) and ((type(v) ~= "table") or (v["__newindex"] == nil))) then
+ -- It is a read-only variable or array, add it as a constant:
table.insert(res.Constants, {Name = k, Value = ""});
else
- -- It is a read-write variable, add it as a variable:
+ -- It is a read-write variable or array, add it as a variable:
table.insert(res.Variables, { Name = k });
end
end
diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg
index dc25ca379..e6787b70d 100644
--- a/src/Bindings/AllToLua.pkg
+++ b/src/Bindings/AllToLua.pkg
@@ -123,6 +123,8 @@ $cfile "../BlockEntities/MobHeadEntity.h"
$cfile "../BlockEntities/MobSpawnerEntity.h"
$cfile "../BlockEntities/FlowerPotEntity.h"
+// Registries:
+$cfile "../Registries/Statistics.h"
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 8c47ab322..ccd7244fa 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -1378,6 +1378,21 @@ bool cLuaState::GetStackValue(int a_StackPos, ContiguousByteBuffer & a_Data)
+bool cLuaState::GetStackValue(int a_StackPos, CustomStatistic & a_Value)
+{
+ if (lua_isnumber(m_LuaState, a_StackPos))
+ {
+ a_Value = static_cast<CustomStatistic>(static_cast<std::underlying_type_t<CustomStatistic>>(lua_tonumber(m_LuaState, a_StackPos)));
+ return true;
+ }
+
+ return true;
+}
+
+
+
+
+
bool cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal)
{
if (lua_isnumber(m_LuaState, a_StackPos))
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index 0493804e5..f615ef0a6 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -37,6 +37,7 @@ extern "C"
#include "../Defines.h"
#include "../FunctionRef.h"
+#include "../Registries/Statistics.h"
#include "PluginManager.h"
#include "LuaState_Typedefs.inc"
@@ -657,6 +658,7 @@ public:
bool GetStackValue(int a_StackPos, cTrackedRefPtr & a_Ref);
bool GetStackValue(int a_StackPos, cTrackedRefSharedPtr & a_Ref);
bool GetStackValue(int a_StackPos, ContiguousByteBuffer & a_Data);
+ bool GetStackValue(int a_StackPos, CustomStatistic & a_Value);
bool GetStackValue(int a_StackPos, double & a_Value);
bool GetStackValue(int a_StackPos, eBlockFace & a_Value);
bool GetStackValue(int a_StackPos, eWeather & a_Value);
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index cd5e69b22..f06f4da37 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -4348,6 +4348,69 @@ static int tolua_cEntity_GetSpeed(lua_State * tolua_S)
+static int tolua_get_StatisticsManager_Custom(lua_State * tolua_S)
+{
+ // Check the params:
+ cLuaState L(tolua_S);
+ if (!L.CheckParamNumber(2))
+ {
+ return 0;
+ }
+
+ // Get the params:
+ lua_pushstring(tolua_S, ".self");
+ lua_rawget(tolua_S, 1);
+ StatisticsManager * Self = static_cast<StatisticsManager *>(lua_touserdata(tolua_S, -1));
+ CustomStatistic Statistic;
+ if (!L.GetStackValue(2, Statistic))
+ {
+ return L.ApiParamError("Expected a valid custom statistic ID");
+ }
+
+ // Push result if statistic exists:
+ if (const auto Result = Self->Custom.find(Statistic); Result != Self->Custom.end())
+ {
+ L.Push(Result->second);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+
+
+static int tolua_set_StatisticsManager_Custom(lua_State * tolua_S)
+{
+ // Check the params:
+ cLuaState L(tolua_S);
+ if (!L.CheckParamNumber(2))
+ {
+ return 0;
+ }
+
+ // Get the params:
+ lua_pushstring(tolua_S, ".self");
+ lua_rawget(tolua_S, 1);
+ StatisticsManager * Self = static_cast<StatisticsManager *>(lua_touserdata(tolua_S, -1));
+ CustomStatistic Statistic;
+ StatisticsManager::StatValue Value;
+ if (!L.GetStackValues(2, Statistic, Value))
+ {
+ return L.ApiParamError("Expected a valid custom statistic ID and value");
+ }
+
+ // Set the value:
+ Self->Custom[Statistic] = Value;
+
+ return 0;
+}
+
+
+
+
+
void cManualBindings::Bind(lua_State * tolua_S)
{
tolua_beginmodule(tolua_S, nullptr);
@@ -4357,10 +4420,12 @@ void cManualBindings::Bind(lua_State * tolua_S)
tolua_usertype(tolua_S, "cLineBlockTracer");
tolua_usertype(tolua_S, "cStringCompression");
tolua_usertype(tolua_S, "cUrlParser");
+ // StatisticsManager was already created by cPlayer::GetStatistics' autogenerated bindings.
tolua_cclass(tolua_S, "cCryptoHash", "cCryptoHash", "", nullptr);
tolua_cclass(tolua_S, "cLineBlockTracer", "cLineBlockTracer", "", nullptr);
tolua_cclass(tolua_S, "cStringCompression", "cStringCompression", "", nullptr);
tolua_cclass(tolua_S, "cUrlParser", "cUrlParser", "", nullptr);
+ tolua_cclass(tolua_S, "StatisticsManager", "StatisticsManager", "", nullptr);
// Globals:
tolua_function(tolua_S, "Clamp", tolua_Clamp);
@@ -4592,6 +4657,10 @@ void cManualBindings::Bind(lua_State * tolua_S)
tolua_variable(tolua_S, "PostParams", tolua_get_HTTPRequest_PostParams, nullptr);
tolua_endmodule(tolua_S);
+ tolua_beginmodule(tolua_S, "StatisticsManager");
+ tolua_array(tolua_S, "Custom", tolua_get_StatisticsManager_Custom, tolua_set_StatisticsManager_Custom);
+ tolua_endmodule(tolua_S);
+
BindNetwork(tolua_S);
BindRankManager(tolua_S);
BindWorld(tolua_S);
diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp
index 6a7916dd1..87d25e57a 100644
--- a/src/BlockEntities/BeaconEntity.cpp
+++ b/src/BlockEntities/BeaconEntity.cpp
@@ -206,7 +206,7 @@ void cBeaconEntity::UpdateBeacon(void)
(std::abs(Distance.z) <= 20)
)
{
- a_Player.AwardAchievement(Statistic::AchFullBeacon);
+ a_Player.AwardAchievement(CustomStatistic::AchFullBeacon);
}
return false;
}
@@ -313,7 +313,7 @@ bool cBeaconEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
bool cBeaconEntity::UsedBy(cPlayer * a_Player)
{
- a_Player->GetStatManager().AddValue(Statistic::InteractWithBeacon);
+ a_Player->GetStatistics().Custom[CustomStatistic::InteractWithBeacon]++;
cWindow * Window = GetWindow();
if (Window == nullptr)
diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp
index bdac1b327..ff7b49821 100644
--- a/src/BlockEntities/BrewingstandEntity.cpp
+++ b/src/BlockEntities/BrewingstandEntity.cpp
@@ -145,7 +145,7 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
{
- a_Player->GetStatManager().AddValue(Statistic::InteractWithBrewingstand);
+ a_Player->GetStatistics().Custom[CustomStatistic::InteractWithBrewingstand]++;
cWindow * Window = GetWindow();
if (Window == nullptr)
diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp
index c2c31b30a..11146bf46 100644
--- a/src/BlockEntities/ChestEntity.cpp
+++ b/src/BlockEntities/ChestEntity.cpp
@@ -204,11 +204,11 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
if (m_BlockType == E_BLOCK_CHEST)
{
- a_Player->GetStatManager().AddValue(Statistic::OpenChest);
+ a_Player->GetStatistics().Custom[CustomStatistic::OpenChest]++;
}
else // E_BLOCK_TRAPPED_CHEST
{
- a_Player->GetStatManager().AddValue(Statistic::TriggerTrappedChest);
+ a_Player->GetStatistics().Custom[CustomStatistic::TriggerTrappedChest]++;
}
auto & PrimaryChest = GetPrimaryChest();
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index 814b0c147..b067e1081 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -163,11 +163,11 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
{
if (m_BlockType == E_BLOCK_DISPENSER)
{
- a_Player->GetStatManager().AddValue(Statistic::InspectDispenser);
+ a_Player->GetStatistics().Custom[CustomStatistic::InspectDispenser]++;
}
else // E_BLOCK_DROPPER
{
- a_Player->GetStatManager().AddValue(Statistic::InspectDropper);
+ a_Player->GetStatistics().Custom[CustomStatistic::InspectDropper]++;
}
cWindow * Window = GetWindow();
diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp
index efc5dce4f..ba9ca5609 100644
--- a/src/BlockEntities/EnderChestEntity.cpp
+++ b/src/BlockEntities/EnderChestEntity.cpp
@@ -62,7 +62,7 @@ bool cEnderChestEntity::UsedBy(cPlayer * a_Player)
return false;
}
- a_Player->GetStatManager().AddValue(Statistic::OpenEnderchest);
+ a_Player->GetStatistics().Custom[CustomStatistic::OpenEnderchest]++;
// If the window is not created, open it anew:
cWindow * Window = GetWindow();
diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp
index bc936c246..df14acc8e 100644
--- a/src/BlockEntities/FlowerPotEntity.cpp
+++ b/src/BlockEntities/FlowerPotEntity.cpp
@@ -50,7 +50,7 @@ bool cFlowerPotEntity::UsedBy(cPlayer * a_Player)
return false;
}
- a_Player->GetStatManager().AddValue(Statistic::PotFlower);
+ a_Player->GetStatistics().Custom[CustomStatistic::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 d36b19791..8ca539170 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -127,7 +127,7 @@ bool cFurnaceEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
{
- a_Player->GetStatManager().AddValue(Statistic::InteractWithFurnace);
+ a_Player->GetStatistics().Custom[CustomStatistic::InteractWithFurnace]++;
cWindow * Window = GetWindow();
if (Window == nullptr)
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index 82e07f6a0..1e5c59c94 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -113,7 +113,7 @@ void cHopperEntity::SendTo(cClientHandle & a_Client)
bool cHopperEntity::UsedBy(cPlayer * a_Player)
{
- a_Player->GetStatManager().AddValue(Statistic::InspectHopper);
+ a_Player->GetStatistics().Custom[CustomStatistic::InspectHopper]++;
// If the window is not created, open it anew:
cWindow * Window = GetWindow();
diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp
index b99d9d39c..065f9cb46 100644
--- a/src/BlockEntities/JukeboxEntity.cpp
+++ b/src/BlockEntities/JukeboxEntity.cpp
@@ -65,7 +65,8 @@ bool cJukeboxEntity::UsedBy(cPlayer * a_Player)
const cItem & HeldItem = a_Player->GetEquippedItem();
if (PlayRecord(HeldItem.m_ItemType))
{
- a_Player->GetStatManager().AddValue(Statistic::PlayRecord);
+ a_Player->GetStatistics().Custom[CustomStatistic::PlayRecord]++;
+
if (!a_Player->IsGameModeCreative())
{
a_Player->GetInventory().RemoveOneEquippedItem();
diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp
index 419d084b2..b4696f7b1 100644
--- a/src/BlockEntities/NoteEntity.cpp
+++ b/src/BlockEntities/NoteEntity.cpp
@@ -34,7 +34,7 @@ void cNoteEntity::CopyFrom(const cBlockEntity & a_Src)
bool cNoteEntity::UsedBy(cPlayer * a_Player)
{
- a_Player->GetStatManager().AddValue(Statistic::TuneNoteblock);
+ a_Player->GetStatistics().Custom[CustomStatistic::TuneNoteblock]++;
IncrementNote();
MakeSound();
return true;
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp
index ef4359416..37c57b6b3 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -134,7 +134,7 @@ bool cBlockBedHandler::OnUse(
// Occupy the bed, where 0x4 = occupied bit:
a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta | 0x04);
- a_Player.GetStatManager().AddValue(Statistic::SleepInBed);
+ a_Player.GetStatistics().Custom[CustomStatistic::SleepInBed]++;
// When sleeping, the player's bounding box moves to approximately where his head is.
// Set the player's position to somewhere close to the edge of the pillow block:
diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h
index ae8cd0228..4b238fa48 100644
--- a/src/Blocks/BlockCake.h
+++ b/src/Blocks/BlockCake.h
@@ -33,7 +33,7 @@ private:
return false;
}
- a_Player.GetStatManager().AddValue(Statistic::EatCakeSlice);
+ a_Player.GetStatistics().Custom[CustomStatistic::EatCakeSlice]++;
if (Meta >= 5)
{
a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockPos, &a_Player);
diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h
index 37e638d72..80f95164f 100644
--- a/src/Blocks/BlockCauldron.h
+++ b/src/Blocks/BlockCauldron.h
@@ -65,7 +65,7 @@ private:
{
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET));
}
- a_Player.GetStatManager().AddValue(Statistic::FillCauldron);
+ a_Player.GetStatistics().Custom[CustomStatistic::FillCauldron]++;
}
break;
}
@@ -79,7 +79,7 @@ private:
{
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_POTION));
}
- a_Player.GetStatManager().AddValue(Statistic::UseCauldron);
+ a_Player.GetStatistics().Custom[CustomStatistic::UseCauldron]++;
}
break;
}
diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h
index e654a6b84..a0ec3df4a 100644
--- a/src/Blocks/BlockWorkbench.h
+++ b/src/Blocks/BlockWorkbench.h
@@ -29,7 +29,7 @@ private:
const Vector3i a_CursorPos
) const override
{
- a_Player.GetStatManager().AddValue(Statistic::InteractWithCraftingTable);
+ a_Player.GetStatistics().Custom[CustomStatistic::InteractWithCraftingTable]++;
cWindow * Window = new cCraftingWindow();
a_Player.OpenWindow(*Window);
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 2a1ae2357..4ee5a1c65 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -369,7 +369,7 @@ void cClientHandle::FinishAuthenticate(const AString & a_Name, const cUUID & a_U
cRoot::Get()->SendPlayerLists(m_Player); // Add everyone else to ourself
// Send statistics:
- SendStatistics(m_Player->GetStatManager());
+ SendStatistics(m_Player->GetStatistics());
// Delay the first ping until the client "settles down"
// This should fix #889, "BadCast exception, cannot convert bit to fm" error in client
@@ -2970,7 +2970,7 @@ void cClientHandle::SendSpawnMob(const cMonster & a_Mob)
-void cClientHandle::SendStatistics(const cStatManager & a_Manager)
+void cClientHandle::SendStatistics(const StatisticsManager & a_Manager)
{
m_Protocol->SendStatistics(a_Manager);
}
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 00d5051d2..17dbefbeb 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -35,9 +35,11 @@ class cProtocol;
class cWindow;
class cFallingBlock;
class cCompositeChat;
-class cStatManager;
class cMap;
class cClientHandle;
+
+struct StatisticsManager;
+
typedef std::shared_ptr<cClientHandle> cClientHandlePtr;
@@ -211,7 +213,7 @@ public: // tolua_export
void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data);
void SendSpawnEntity (const cEntity & a_Entity);
void SendSpawnMob (const cMonster & a_Mob);
- void SendStatistics (const cStatManager & a_Manager);
+ void SendStatistics (const StatisticsManager & a_Manager);
void SendTabCompletionResults (const AStringVector & a_Results);
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks); // tolua_export
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 1d95ec56e..5c79e58d1 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -528,7 +528,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
}
}
- Player->GetStatManager().AddValue(Statistic::DamageDealt, FloorC<cStatManager::StatValue>(a_TDI.FinalDamage * 10 + 0.5));
+ Player->GetStatistics().Custom[CustomStatistic::DamageDealt] += FloorC<StatisticsManager::StatValue>(a_TDI.FinalDamage * 10 + 0.5);
}
m_Health -= a_TDI.FinalDamage;
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index 39fff913d..fd2cc3a4b 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -242,10 +242,10 @@ bool cPickup::CollectedBy(cPlayer & a_Dest)
// Check achievements
switch (m_Item.m_ItemType)
{
- case E_BLOCK_LOG: a_Dest.AwardAchievement(Statistic::AchMineWood); break;
- case E_ITEM_LEATHER: a_Dest.AwardAchievement(Statistic::AchKillCow); break;
- case E_ITEM_DIAMOND: a_Dest.AwardAchievement(Statistic::AchDiamonds); break;
- case E_ITEM_BLAZE_ROD: a_Dest.AwardAchievement(Statistic::AchBlazeRod); break;
+ case E_BLOCK_LOG: a_Dest.AwardAchievement(CustomStatistic::AchMineWood); break;
+ case E_ITEM_LEATHER: a_Dest.AwardAchievement(CustomStatistic::AchKillCow); break;
+ case E_ITEM_DIAMOND: a_Dest.AwardAchievement(CustomStatistic::AchDiamonds); break;
+ case E_ITEM_BLAZE_ROD: a_Dest.AwardAchievement(CustomStatistic::AchBlazeRod); break;
default: break;
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 233c0a8c3..1e7c8df98 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -167,7 +167,7 @@ cPlayer::~cPlayer(void)
LOGD("Deleting cPlayer \"%s\" at %p, ID %d", GetName().c_str(), static_cast<void *>(this), GetUniqueID());
// "Times ragequit":
- m_Stats.AddValue(Statistic::LeaveGame);
+ m_Stats.Custom[CustomStatistic::LeaveGame]++;
SaveToDisk();
@@ -482,7 +482,7 @@ void cPlayer::TossItems(const cItems & a_Items)
return;
}
- m_Stats.AddValue(Statistic::Drop, static_cast<cStatManager::StatValue>(a_Items.Size()));
+ m_Stats.Custom[CustomStatistic::Drop] += static_cast<StatisticsManager::StatValue>(a_Items.Size());
const auto Speed = (GetLookVector() + Vector3d(0, 0.2, 0)) * 6; // A dash of height and a dollop of speed
const auto Position = GetEyePosition() - Vector3d(0, 0.2, 0); // Correct for eye-height weirdness
@@ -859,7 +859,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
{
Pickups.Add(cItem(E_ITEM_RED_APPLE));
}
- m_Stats.AddValue(Statistic::Drop, static_cast<cStatManager::StatValue>(Pickups.Size()));
+ m_Stats.Custom[CustomStatistic::Drop] += static_cast<StatisticsManager::StatValue>(Pickups.Size());
m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10);
SaveToDisk(); // Save it, yeah the world is a tough place !
@@ -923,8 +923,8 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
}
}
- m_Stats.AddValue(Statistic::Deaths);
- m_Stats.SetValue(Statistic::TimeSinceDeath, 0);
+ m_Stats.Custom[CustomStatistic::Deaths]++;
+ m_Stats.Custom[CustomStatistic::TimeSinceDeath] = 0;
m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1);
}
@@ -939,7 +939,7 @@ void cPlayer::Killed(cEntity * a_Victim)
if (a_Victim->IsPlayer())
{
- m_Stats.AddValue(Statistic::PlayerKills);
+ m_Stats.Custom[CustomStatistic::PlayerKills]++;
ScoreBoard.AddPlayerScore(GetName(), cObjective::otPlayerKillCount, 1);
}
@@ -947,10 +947,10 @@ void cPlayer::Killed(cEntity * a_Victim)
{
if (static_cast<cMonster *>(a_Victim)->GetMobFamily() == cMonster::mfHostile)
{
- AwardAchievement(Statistic::AchKillEnemy);
+ AwardAchievement(CustomStatistic::AchKillEnemy);
}
- m_Stats.AddValue(Statistic::MobKills);
+ m_Stats.Custom[CustomStatistic::MobKills]++;
}
ScoreBoard.AddPlayerScore(GetName(), cObjective::otTotalKillCount, 1);
@@ -1373,7 +1373,7 @@ void cPlayer::UpdateCapabilities()
-void cPlayer::AwardAchievement(const Statistic a_Ach)
+void cPlayer::AwardAchievement(const CustomStatistic a_Ach)
{
// Check if the prerequisites are met:
if (!m_Stats.SatisfiesPrerequisite(a_Ach))
@@ -1382,7 +1382,7 @@ void cPlayer::AwardAchievement(const Statistic a_Ach)
}
// Increment the statistic and check if we already have it:
- if (m_Stats.AddValue(a_Ach) != 1)
+ if (m_Stats.Custom[a_Ach]++ != 1)
{
return;
}
@@ -2262,12 +2262,12 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs
return;
}
- const auto Value = FloorC<cStatManager::StatValue>(a_DeltaPos.Length() * 100 + 0.5);
+ const auto Value = FloorC<StatisticsManager::StatValue>(a_DeltaPos.Length() * 100 + 0.5);
if (m_AttachedTo == nullptr)
{
if (IsFlying())
{
- m_Stats.AddValue(Statistic::FlyOneCm, Value);
+ m_Stats.Custom[CustomStatistic::FlyOneCm] += Value;
// May be flying and doing any of the following:
}
@@ -2275,18 +2275,18 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs
{
if (a_DeltaPos.y > 0.0) // Going up
{
- m_Stats.AddValue(Statistic::ClimbOneCm, FloorC<cStatManager::StatValue>(a_DeltaPos.y * 100 + 0.5));
+ m_Stats.Custom[CustomStatistic::ClimbOneCm] += FloorC<StatisticsManager::StatValue>(a_DeltaPos.y * 100 + 0.5);
}
}
else if (IsInWater())
{
if (m_IsHeadInWater)
{
- m_Stats.AddValue(Statistic::WalkUnderWaterOneCm, Value);
+ m_Stats.Custom[CustomStatistic::WalkUnderWaterOneCm] += Value;
}
else
{
- m_Stats.AddValue(Statistic::WalkOnWaterOneCm, Value);
+ m_Stats.Custom[CustomStatistic::WalkOnWaterOneCm] += Value;
}
AddFoodExhaustion(0.00015 * static_cast<double>(Value));
}
@@ -2294,17 +2294,17 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs
{
if (IsCrouched())
{
- m_Stats.AddValue(Statistic::CrouchOneCm, Value);
+ m_Stats.Custom[CustomStatistic::CrouchOneCm] += Value;
AddFoodExhaustion(0.0001 * static_cast<double>(Value));
}
if (IsSprinting())
{
- m_Stats.AddValue(Statistic::SprintOneCm, Value);
+ m_Stats.Custom[CustomStatistic::SprintOneCm] += Value;
AddFoodExhaustion(0.001 * static_cast<double>(Value));
}
else
{
- m_Stats.AddValue(Statistic::WalkOneCm, Value);
+ m_Stats.Custom[CustomStatistic::WalkOneCm] += Value;
AddFoodExhaustion(0.0001 * static_cast<double>(Value));
}
}
@@ -2313,13 +2313,13 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs
// If a jump just started, process food exhaustion:
if ((a_DeltaPos.y > 0.0) && a_PreviousIsOnGround)
{
- m_Stats.AddValue(Statistic::Jump, 1);
+ m_Stats.Custom[CustomStatistic::Jump]++;
AddFoodExhaustion((IsSprinting() ? 0.008 : 0.002) * static_cast<double>(Value));
}
else if (a_DeltaPos.y < 0.0)
{
// Increment statistic
- m_Stats.AddValue(Statistic::FallOneCm, static_cast<cStatManager::StatValue>(std::abs(a_DeltaPos.y) * 100 + 0.5));
+ m_Stats.Custom[CustomStatistic::FallOneCm] += static_cast<StatisticsManager::StatValue>(-a_DeltaPos.y * 100 + 0.5);
}
// TODO: good opportunity to detect illegal flight (check for falling tho)
}
@@ -2328,15 +2328,15 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs
{
switch (m_AttachedTo->GetEntityType())
{
- case cEntity::etMinecart: m_Stats.AddValue(Statistic::MinecartOneCm, Value); break;
- case cEntity::etBoat: m_Stats.AddValue(Statistic::BoatOneCm, Value); break;
+ case cEntity::etMinecart: m_Stats.Custom[CustomStatistic::MinecartOneCm] += Value; break;
+ case cEntity::etBoat: m_Stats.Custom[CustomStatistic::BoatOneCm] += Value; break;
case cEntity::etMonster:
{
cMonster * Monster = static_cast<cMonster *>(m_AttachedTo);
switch (Monster->GetMobType())
{
- case mtPig: m_Stats.AddValue(Statistic::PigOneCm, Value); break;
- case mtHorse: m_Stats.AddValue(Statistic::HorseOneCm, Value); break;
+ case mtPig: m_Stats.Custom[CustomStatistic::PigOneCm] += Value; break;
+ case mtHorse: m_Stats.Custom[CustomStatistic::HorseOneCm] += Value; break;
default: break;
}
break;
@@ -3004,7 +3004,7 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
NotifyNearbyWolves(static_cast<cPawn*>(a_TDI.Attacker), true);
}
}
- m_Stats.AddValue(Statistic::DamageTaken, FloorC<cStatManager::StatValue>(a_TDI.FinalDamage * 10 + 0.5));
+ m_Stats.Custom[CustomStatistic::DamageTaken] += FloorC<StatisticsManager::StatValue>(a_TDI.FinalDamage * 10 + 0.5);
return true;
}
return false;
@@ -3154,11 +3154,11 @@ void cPlayer::OnRemoveFromWorld(cWorld & a_World)
// Award relevant achievements:
if (DestinationDimension == dimEnd)
{
- AwardAchievement(Statistic::AchTheEnd);
+ AwardAchievement(CustomStatistic::AchTheEnd);
}
else if (DestinationDimension == dimNether)
{
- AwardAchievement(Statistic::AchPortal);
+ AwardAchievement(CustomStatistic::AchPortal);
}
// Set capabilities based on new world:
@@ -3218,12 +3218,16 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
return;
}
- m_Stats.AddValue(Statistic::PlayOneMinute);
- m_Stats.AddValue(Statistic::TimeSinceDeath);
-
- if (IsCrouched())
{
- m_Stats.AddValue(Statistic::SneakTime);
+ const auto TicksElapsed = static_cast<StatisticsManager::StatValue>(std::chrono::duration_cast<cTickTime>(a_Dt).count());
+
+ m_Stats.Custom[CustomStatistic::PlayOneMinute] += TicksElapsed;
+ m_Stats.Custom[CustomStatistic::TimeSinceDeath] += TicksElapsed;
+
+ if (IsCrouched())
+ {
+ m_Stats.Custom[CustomStatistic::SneakTime] += TicksElapsed;
+ }
}
// Handle the player detach, when the player is in spectator mode
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index df84d25e0..e7b18f3b6 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -230,6 +230,9 @@ public:
AString GetIP(void) const; // tolua_export
+ /** Return the associated statistic and achievement manager. */
+ StatisticsManager & GetStatistics() { return m_Stats; }
+
/** Returns the associated team, nullptr if none */
cTeam * GetTeam(void) { return m_Team; } // tolua_export
@@ -244,13 +247,10 @@ public:
/** Forces the player to query the scoreboard for his team */
cTeam * UpdateTeam(void);
- /** Return the associated statistic and achievement manager. */
- cStatManager & GetStatManager() { return m_Stats; }
-
/** Awards the player an achievement.
If all prerequisites are met, this method will award the achievement and will broadcast a chat message.
If the achievement has been already awarded to the player, this method will just increment the stat counter. */
- void AwardAchievement(Statistic a_Ach);
+ void AwardAchievement(CustomStatistic a_Ach);
/** Forces the player to move in the given direction.
@deprecated Use SetSpeed instead. */
@@ -735,7 +735,7 @@ private:
cTeam * m_Team;
- cStatManager m_Stats;
+ StatisticsManager m_Stats;
/** How long till the player's inventory will be saved
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h
index ec59763ed..183c9756c 100644
--- a/src/Items/ItemFishingRod.h
+++ b/src/Items/ItemFishingRod.h
@@ -210,7 +210,7 @@ public:
}
}
- a_Player.GetStatManager().AddValue(Statistic::TreasureFished, 1);
+ a_Player.GetStatistics().Custom[CustomStatistic::TreasureFished]++;
}
else if (ItemCategory < JunkChances[LotSLevel])
{
@@ -262,7 +262,7 @@ public:
Drops.Add(cItem(E_BLOCK_TRIPWIRE_HOOK));
}
- a_Player.GetStatManager().AddValue(Statistic::JunkFished, 1);
+ a_Player.GetStatistics().Custom[CustomStatistic::JunkFished]++;
}
else
{
@@ -284,7 +284,7 @@ public:
Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_FISH));
}
- a_Player.GetStatManager().AddValue(Statistic::FishCaught, 1);
+ a_Player.GetStatistics().Custom[CustomStatistic::FishCaught]++;
}
// Check with plugins if this loot is acceptable:
diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h
index 07c628ceb..90d67b02b 100644
--- a/src/Items/ItemMobHead.h
+++ b/src/Items/ItemMobHead.h
@@ -285,7 +285,7 @@ public:
double Dist = (a_Player.GetPosition() - Pos).Length();
if (Dist < 50.0)
{
- a_Player.AwardAchievement(Statistic::AchSpawnWither);
+ a_Player.AwardAchievement(CustomStatistic::AchSpawnWither);
}
return false;
}
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index c1a244a9f..ae186d2bb 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -1361,10 +1361,10 @@ void cMonster::LoveTick(void)
m_World->DoWithPlayerByUUID(m_Feeder, [&] (cPlayer & a_Player)
{
- a_Player.GetStatManager().AddValue(Statistic::AnimalsBred);
+ a_Player.GetStatistics().Custom[CustomStatistic::AnimalsBred]++;
if (GetMobType() == eMonsterType::mtCow)
{
- a_Player.AwardAchievement(Statistic::AchBreedCow);
+ a_Player.AwardAchievement(CustomStatistic::AchBreedCow);
}
return true;
});
diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp
index 77a31a0bd..87f5e170d 100644
--- a/src/Mobs/Wither.cpp
+++ b/src/Mobs/Wither.cpp
@@ -84,7 +84,7 @@ void cWither::KilledBy(TakeDamageInfo & a_TDI)
if (Dist < 50.0)
{
// If player is close, award achievement
- a_Player.AwardAchievement(Statistic::AchKillWither);
+ a_Player.AwardAchievement(CustomStatistic::AchKillWither);
}
return false;
}
diff --git a/src/Protocol/Palettes/Palette_1_13.cpp b/src/Protocol/Palettes/Palette_1_13.cpp
index 513763b2a..d60c7a516 100644
--- a/src/Protocol/Palettes/Palette_1_13.cpp
+++ b/src/Protocol/Palettes/Palette_1_13.cpp
@@ -7859,62 +7859,62 @@ namespace Palette_1_13
}
}
- UInt32 From(const Statistic ID)
+ UInt32 From(const CustomStatistic ID)
{
switch (ID)
{
- case Statistic::AnimalsBred: return 25;
- case Statistic::AviateOneCm: return 17;
- case Statistic::BoatOneCm: return 14;
- case Statistic::CleanArmor: return 33;
- case Statistic::CleanBanner: return 34;
- case Statistic::ClimbOneCm: return 10;
- case Statistic::CrouchOneCm: return 6;
- case Statistic::DamageDealt: return 21;
- case Statistic::DamageTaken: return 22;
- case Statistic::Deaths: return 23;
- case Statistic::Drop: return 20;
- case Statistic::EatCakeSlice: return 30;
- case Statistic::EnchantItem: return 45;
- case Statistic::FallOneCm: return 9;
- case Statistic::FillCauldron: return 31;
- case Statistic::FishCaught: return 27;
- case Statistic::FlyOneCm: return 11;
- case Statistic::HorseOneCm: return 16;
- case Statistic::InspectDispenser: return 39;
- case Statistic::InspectDropper: return 37;
- case Statistic::InspectHopper: return 38;
- case Statistic::InteractWithBeacon: return 36;
- case Statistic::InteractWithBrewingstand: return 35;
- case Statistic::InteractWithCraftingTable: return 48;
- case Statistic::InteractWithFurnace: return 47;
- case Statistic::Jump: return 19;
- case Statistic::LeaveGame: return 0;
- case Statistic::MinecartOneCm: return 13;
- case Statistic::MobKills: return 24;
- case Statistic::OpenChest: return 49;
- case Statistic::OpenEnderchest: return 44;
- case Statistic::OpenShulkerBox: return 51;
- case Statistic::PigOneCm: return 15;
- case Statistic::PlayerKills: return 26;
- case Statistic::PlayNoteblock: return 40;
- case Statistic::PlayOneMinute: return 1;
- case Statistic::PlayRecord: return 46;
- case Statistic::PotFlower: return 42;
- case Statistic::SleepInBed: return 50;
- case Statistic::SneakTime: return 4;
- case Statistic::SprintOneCm: return 7;
- case Statistic::SwimOneCm: return 8;
- case Statistic::TalkedToVillager: return 28;
- case Statistic::TimeSinceDeath: return 2;
- case Statistic::TimeSinceRest: return 3;
- case Statistic::TradedWithVillager: return 29;
- case Statistic::TriggerTrappedChest: return 43;
- case Statistic::TuneNoteblock: return 41;
- case Statistic::UseCauldron: return 32;
- case Statistic::WalkOneCm: return 5;
- case Statistic::WalkOnWaterOneCm: return 18;
- case Statistic::WalkUnderWaterOneCm: return 12;
+ case CustomStatistic::AnimalsBred: return 25;
+ case CustomStatistic::AviateOneCm: return 17;
+ case CustomStatistic::BoatOneCm: return 14;
+ case CustomStatistic::CleanArmor: return 33;
+ case CustomStatistic::CleanBanner: return 34;
+ case CustomStatistic::ClimbOneCm: return 10;
+ case CustomStatistic::CrouchOneCm: return 6;
+ case CustomStatistic::DamageDealt: return 21;
+ case CustomStatistic::DamageTaken: return 22;
+ case CustomStatistic::Deaths: return 23;
+ case CustomStatistic::Drop: return 20;
+ case CustomStatistic::EatCakeSlice: return 30;
+ case CustomStatistic::EnchantItem: return 45;
+ case CustomStatistic::FallOneCm: return 9;
+ case CustomStatistic::FillCauldron: return 31;
+ case CustomStatistic::FishCaught: return 27;
+ case CustomStatistic::FlyOneCm: return 11;
+ case CustomStatistic::HorseOneCm: return 16;
+ case CustomStatistic::InspectDispenser: return 39;
+ case CustomStatistic::InspectDropper: return 37;
+ case CustomStatistic::InspectHopper: return 38;
+ case CustomStatistic::InteractWithBeacon: return 36;
+ case CustomStatistic::InteractWithBrewingstand: return 35;
+ case CustomStatistic::InteractWithCraftingTable: return 48;
+ case CustomStatistic::InteractWithFurnace: return 47;
+ case CustomStatistic::Jump: return 19;
+ case CustomStatistic::LeaveGame: return 0;
+ case CustomStatistic::MinecartOneCm: return 13;
+ case CustomStatistic::MobKills: return 24;
+ case CustomStatistic::OpenChest: return 49;
+ case CustomStatistic::OpenEnderchest: return 44;
+ case CustomStatistic::OpenShulkerBox: return 51;
+ case CustomStatistic::PigOneCm: return 15;
+ case CustomStatistic::PlayerKills: return 26;
+ case CustomStatistic::PlayNoteblock: return 40;
+ case CustomStatistic::PlayOneMinute: return 1;
+ case CustomStatistic::PlayRecord: return 46;
+ case CustomStatistic::PotFlower: return 42;
+ case CustomStatistic::SleepInBed: return 50;
+ case CustomStatistic::SneakTime: return 4;
+ case CustomStatistic::SprintOneCm: return 7;
+ case CustomStatistic::SwimOneCm: return 8;
+ case CustomStatistic::TalkedToVillager: return 28;
+ case CustomStatistic::TimeSinceDeath: return 2;
+ case CustomStatistic::TimeSinceRest: return 3;
+ case CustomStatistic::TradedWithVillager: return 29;
+ case CustomStatistic::TriggerTrappedChest: return 43;
+ case CustomStatistic::TuneNoteblock: return 41;
+ case CustomStatistic::UseCauldron: return 32;
+ case CustomStatistic::WalkOneCm: return 5;
+ case CustomStatistic::WalkOnWaterOneCm: return 18;
+ case CustomStatistic::WalkUnderWaterOneCm: return 12;
default: return UInt32(-1);
}
}
diff --git a/src/Protocol/Palettes/Palette_1_13.h b/src/Protocol/Palettes/Palette_1_13.h
index 6f8ceec2e..5b2a5ccb5 100644
--- a/src/Protocol/Palettes/Palette_1_13.h
+++ b/src/Protocol/Palettes/Palette_1_13.h
@@ -8,6 +8,6 @@ namespace Palette_1_13
{
UInt32 From(BlockState Block);
UInt32 From(Item ID);
- UInt32 From(Statistic ID);
+ UInt32 From(CustomStatistic ID);
Item ToItem(UInt32 ID);
}
diff --git a/src/Protocol/Palettes/Palette_1_13_1.cpp b/src/Protocol/Palettes/Palette_1_13_1.cpp
index cfc4ed5f4..1dba4caf8 100644
--- a/src/Protocol/Palettes/Palette_1_13_1.cpp
+++ b/src/Protocol/Palettes/Palette_1_13_1.cpp
@@ -7870,68 +7870,68 @@ namespace Palette_1_13_1
}
}
- UInt32 From(const Statistic ID)
+ UInt32 From(const CustomStatistic ID)
{
switch (ID)
{
- case Statistic::AnimalsBred: return 30;
- case Statistic::AviateOneCm: return 17;
- case Statistic::BoatOneCm: return 14;
- case Statistic::CleanArmor: return 38;
- case Statistic::CleanBanner: return 39;
- case Statistic::CleanShulkerBox: return 40;
- case Statistic::ClimbOneCm: return 10;
- case Statistic::CrouchOneCm: return 6;
- case Statistic::DamageAbsorbed: return 26;
- case Statistic::DamageBlockedByShield: return 25;
- case Statistic::DamageDealt: return 21;
- case Statistic::DamageDealtAbsorbed: return 22;
- case Statistic::DamageDealtResisted: return 23;
- case Statistic::DamageResisted: return 27;
- case Statistic::DamageTaken: return 24;
- case Statistic::Deaths: return 28;
- case Statistic::Drop: return 20;
- case Statistic::EatCakeSlice: return 35;
- case Statistic::EnchantItem: return 51;
- case Statistic::FallOneCm: return 9;
- case Statistic::FillCauldron: return 36;
- case Statistic::FishCaught: return 32;
- case Statistic::FlyOneCm: return 11;
- case Statistic::HorseOneCm: return 16;
- case Statistic::InspectDispenser: return 45;
- case Statistic::InspectDropper: return 43;
- case Statistic::InspectHopper: return 44;
- case Statistic::InteractWithBeacon: return 42;
- case Statistic::InteractWithBrewingstand: return 41;
- case Statistic::InteractWithCraftingTable: return 54;
- case Statistic::InteractWithFurnace: return 53;
- case Statistic::Jump: return 19;
- case Statistic::LeaveGame: return 0;
- case Statistic::MinecartOneCm: return 13;
- case Statistic::MobKills: return 29;
- case Statistic::OpenChest: return 55;
- case Statistic::OpenEnderchest: return 50;
- case Statistic::OpenShulkerBox: return 57;
- case Statistic::PigOneCm: return 15;
- case Statistic::PlayerKills: return 31;
- case Statistic::PlayNoteblock: return 46;
- case Statistic::PlayOneMinute: return 1;
- case Statistic::PlayRecord: return 52;
- case Statistic::PotFlower: return 48;
- case Statistic::SleepInBed: return 56;
- case Statistic::SneakTime: return 4;
- case Statistic::SprintOneCm: return 7;
- case Statistic::SwimOneCm: return 8;
- case Statistic::TalkedToVillager: return 33;
- case Statistic::TimeSinceDeath: return 2;
- case Statistic::TimeSinceRest: return 3;
- case Statistic::TradedWithVillager: return 34;
- case Statistic::TriggerTrappedChest: return 49;
- case Statistic::TuneNoteblock: return 47;
- case Statistic::UseCauldron: return 37;
- case Statistic::WalkOneCm: return 5;
- case Statistic::WalkOnWaterOneCm: return 18;
- case Statistic::WalkUnderWaterOneCm: return 12;
+ case CustomStatistic::AnimalsBred: return 30;
+ case CustomStatistic::AviateOneCm: return 17;
+ case CustomStatistic::BoatOneCm: return 14;
+ case CustomStatistic::CleanArmor: return 38;
+ case CustomStatistic::CleanBanner: return 39;
+ case CustomStatistic::CleanShulkerBox: return 40;
+ case CustomStatistic::ClimbOneCm: return 10;
+ case CustomStatistic::CrouchOneCm: return 6;
+ case CustomStatistic::DamageAbsorbed: return 26;
+ case CustomStatistic::DamageBlockedByShield: return 25;
+ case CustomStatistic::DamageDealt: return 21;
+ case CustomStatistic::DamageDealtAbsorbed: return 22;
+ case CustomStatistic::DamageDealtResisted: return 23;
+ case CustomStatistic::DamageResisted: return 27;
+ case CustomStatistic::DamageTaken: return 24;
+ case CustomStatistic::Deaths: return 28;
+ case CustomStatistic::Drop: return 20;
+ case CustomStatistic::EatCakeSlice: return 35;
+ case CustomStatistic::EnchantItem: return 51;
+ case CustomStatistic::FallOneCm: return 9;
+ case CustomStatistic::FillCauldron: return 36;
+ case CustomStatistic::FishCaught: return 32;
+ case CustomStatistic::FlyOneCm: return 11;
+ case CustomStatistic::HorseOneCm: return 16;
+ case CustomStatistic::InspectDispenser: return 45;
+ case CustomStatistic::InspectDropper: return 43;
+ case CustomStatistic::InspectHopper: return 44;
+ case CustomStatistic::InteractWithBeacon: return 42;
+ case CustomStatistic::InteractWithBrewingstand: return 41;
+ case CustomStatistic::InteractWithCraftingTable: return 54;
+ case CustomStatistic::InteractWithFurnace: return 53;
+ case CustomStatistic::Jump: return 19;
+ case CustomStatistic::LeaveGame: return 0;
+ case CustomStatistic::MinecartOneCm: return 13;
+ case CustomStatistic::MobKills: return 29;
+ case CustomStatistic::OpenChest: return 55;
+ case CustomStatistic::OpenEnderchest: return 50;
+ case CustomStatistic::OpenShulkerBox: return 57;
+ case CustomStatistic::PigOneCm: return 15;
+ case CustomStatistic::PlayerKills: return 31;
+ case CustomStatistic::PlayNoteblock: return 46;
+ case CustomStatistic::PlayOneMinute: return 1;
+ case CustomStatistic::PlayRecord: return 52;
+ case CustomStatistic::PotFlower: return 48;
+ case CustomStatistic::SleepInBed: return 56;
+ case CustomStatistic::SneakTime: return 4;
+ case CustomStatistic::SprintOneCm: return 7;
+ case CustomStatistic::SwimOneCm: return 8;
+ case CustomStatistic::TalkedToVillager: return 33;
+ case CustomStatistic::TimeSinceDeath: return 2;
+ case CustomStatistic::TimeSinceRest: return 3;
+ case CustomStatistic::TradedWithVillager: return 34;
+ case CustomStatistic::TriggerTrappedChest: return 49;
+ case CustomStatistic::TuneNoteblock: return 47;
+ case CustomStatistic::UseCauldron: return 37;
+ case CustomStatistic::WalkOneCm: return 5;
+ case CustomStatistic::WalkOnWaterOneCm: return 18;
+ case CustomStatistic::WalkUnderWaterOneCm: return 12;
default: return UInt32(-1);
}
}
diff --git a/src/Protocol/Palettes/Palette_1_13_1.h b/src/Protocol/Palettes/Palette_1_13_1.h
index 02085aa2b..fda47e5c4 100644
--- a/src/Protocol/Palettes/Palette_1_13_1.h
+++ b/src/Protocol/Palettes/Palette_1_13_1.h
@@ -8,6 +8,6 @@ namespace Palette_1_13_1
{
UInt32 From(BlockState Block);
UInt32 From(Item ID);
- UInt32 From(Statistic ID);
+ UInt32 From(CustomStatistic ID);
Item ToItem(UInt32 ID);
}
diff --git a/src/Protocol/Palettes/Palette_1_14.cpp b/src/Protocol/Palettes/Palette_1_14.cpp
index 02c871331..0dca7c142 100644
--- a/src/Protocol/Palettes/Palette_1_14.cpp
+++ b/src/Protocol/Palettes/Palette_1_14.cpp
@@ -9505,79 +9505,79 @@ namespace Palette_1_14
}
}
- UInt32 From(const Statistic ID)
+ UInt32 From(const CustomStatistic ID)
{
switch (ID)
{
- case Statistic::AnimalsBred: return 30;
- case Statistic::AviateOneCm: return 17;
- case Statistic::BellRing: return 66;
- case Statistic::BoatOneCm: return 14;
- case Statistic::CleanArmor: return 38;
- case Statistic::CleanBanner: return 39;
- case Statistic::CleanShulkerBox: return 40;
- case Statistic::ClimbOneCm: return 10;
- case Statistic::CrouchOneCm: return 6;
- case Statistic::DamageAbsorbed: return 26;
- case Statistic::DamageBlockedByShield: return 25;
- case Statistic::DamageDealt: return 21;
- case Statistic::DamageDealtAbsorbed: return 22;
- case Statistic::DamageDealtResisted: return 23;
- case Statistic::DamageResisted: return 27;
- case Statistic::DamageTaken: return 24;
- case Statistic::Deaths: return 28;
- case Statistic::Drop: return 20;
- case Statistic::EatCakeSlice: return 35;
- case Statistic::EnchantItem: return 51;
- case Statistic::FallOneCm: return 9;
- case Statistic::FillCauldron: return 36;
- case Statistic::FishCaught: return 32;
- case Statistic::FlyOneCm: return 11;
- case Statistic::HorseOneCm: return 16;
- case Statistic::InspectDispenser: return 45;
- case Statistic::InspectDropper: return 43;
- case Statistic::InspectHopper: return 44;
- case Statistic::InteractWithBeacon: return 42;
- case Statistic::InteractWithBlastFurnace: return 59;
- case Statistic::InteractWithBrewingstand: return 41;
- case Statistic::InteractWithCampfire: return 62;
- case Statistic::InteractWithCartographyTable: return 63;
- case Statistic::InteractWithCraftingTable: return 54;
- case Statistic::InteractWithFurnace: return 53;
- case Statistic::InteractWithLectern: return 61;
- case Statistic::InteractWithLoom: return 64;
- case Statistic::InteractWithSmoker: return 60;
- case Statistic::InteractWithStonecutter: return 65;
- case Statistic::Jump: return 19;
- case Statistic::LeaveGame: return 0;
- case Statistic::MinecartOneCm: return 13;
- case Statistic::MobKills: return 29;
- case Statistic::OpenBarrel: return 58;
- case Statistic::OpenChest: return 55;
- case Statistic::OpenEnderchest: return 50;
- case Statistic::OpenShulkerBox: return 57;
- case Statistic::PigOneCm: return 15;
- case Statistic::PlayerKills: return 31;
- case Statistic::PlayNoteblock: return 46;
- case Statistic::PlayOneMinute: return 1;
- case Statistic::PlayRecord: return 52;
- case Statistic::PotFlower: return 48;
- case Statistic::RaidTrigger: return 67;
- case Statistic::RaidWin: return 68;
- case Statistic::SleepInBed: return 56;
- case Statistic::SneakTime: return 4;
- case Statistic::SprintOneCm: return 7;
- case Statistic::SwimOneCm: return 18;
- case Statistic::TalkedToVillager: return 33;
- case Statistic::TimeSinceDeath: return 2;
- case Statistic::TimeSinceRest: return 3;
- case Statistic::TradedWithVillager: return 34;
- case Statistic::TriggerTrappedChest: return 49;
- case Statistic::TuneNoteblock: return 47;
- case Statistic::UseCauldron: return 37;
- case Statistic::WalkOneCm: return 5;
- case Statistic::WalkOnWaterOneCm: return 8;
- case Statistic::WalkUnderWaterOneCm: return 12;
+ case CustomStatistic::AnimalsBred: return 30;
+ case CustomStatistic::AviateOneCm: return 17;
+ case CustomStatistic::BellRing: return 66;
+ case CustomStatistic::BoatOneCm: return 14;
+ case CustomStatistic::CleanArmor: return 38;
+ case CustomStatistic::CleanBanner: return 39;
+ case CustomStatistic::CleanShulkerBox: return 40;
+ case CustomStatistic::ClimbOneCm: return 10;
+ case CustomStatistic::CrouchOneCm: return 6;
+ case CustomStatistic::DamageAbsorbed: return 26;
+ case CustomStatistic::DamageBlockedByShield: return 25;
+ case CustomStatistic::DamageDealt: return 21;
+ case CustomStatistic::DamageDealtAbsorbed: return 22;
+ case CustomStatistic::DamageDealtResisted: return 23;
+ case CustomStatistic::DamageResisted: return 27;
+ case CustomStatistic::DamageTaken: return 24;
+ case CustomStatistic::Deaths: return 28;
+ case CustomStatistic::Drop: return 20;
+ case CustomStatistic::EatCakeSlice: return 35;
+ case CustomStatistic::EnchantItem: return 51;
+ case CustomStatistic::FallOneCm: return 9;
+ case CustomStatistic::FillCauldron: return 36;
+ case CustomStatistic::FishCaught: return 32;
+ case CustomStatistic::FlyOneCm: return 11;
+ case CustomStatistic::HorseOneCm: return 16;
+ case CustomStatistic::InspectDispenser: return 45;
+ case CustomStatistic::InspectDropper: return 43;
+ case CustomStatistic::InspectHopper: return 44;
+ case CustomStatistic::InteractWithBeacon: return 42;
+ case CustomStatistic::InteractWithBlastFurnace: return 59;
+ case CustomStatistic::InteractWithBrewingstand: return 41;
+ case CustomStatistic::InteractWithCampfire: return 62;
+ case CustomStatistic::InteractWithCartographyTable: return 63;
+ case CustomStatistic::InteractWithCraftingTable: return 54;
+ case CustomStatistic::InteractWithFurnace: return 53;
+ case CustomStatistic::InteractWithLectern: return 61;
+ case CustomStatistic::InteractWithLoom: return 64;
+ case CustomStatistic::InteractWithSmoker: return 60;
+ case CustomStatistic::InteractWithStonecutter: return 65;
+ case CustomStatistic::Jump: return 19;
+ case CustomStatistic::LeaveGame: return 0;
+ case CustomStatistic::MinecartOneCm: return 13;
+ case CustomStatistic::MobKills: return 29;
+ case CustomStatistic::OpenBarrel: return 58;
+ case CustomStatistic::OpenChest: return 55;
+ case CustomStatistic::OpenEnderchest: return 50;
+ case CustomStatistic::OpenShulkerBox: return 57;
+ case CustomStatistic::PigOneCm: return 15;
+ case CustomStatistic::PlayerKills: return 31;
+ case CustomStatistic::PlayNoteblock: return 46;
+ case CustomStatistic::PlayOneMinute: return 1;
+ case CustomStatistic::PlayRecord: return 52;
+ case CustomStatistic::PotFlower: return 48;
+ case CustomStatistic::RaidTrigger: return 67;
+ case CustomStatistic::RaidWin: return 68;
+ case CustomStatistic::SleepInBed: return 56;
+ case CustomStatistic::SneakTime: return 4;
+ case CustomStatistic::SprintOneCm: return 7;
+ case CustomStatistic::SwimOneCm: return 18;
+ case CustomStatistic::TalkedToVillager: return 33;
+ case CustomStatistic::TimeSinceDeath: return 2;
+ case CustomStatistic::TimeSinceRest: return 3;
+ case CustomStatistic::TradedWithVillager: return 34;
+ case CustomStatistic::TriggerTrappedChest: return 49;
+ case CustomStatistic::TuneNoteblock: return 47;
+ case CustomStatistic::UseCauldron: return 37;
+ case CustomStatistic::WalkOneCm: return 5;
+ case CustomStatistic::WalkOnWaterOneCm: return 8;
+ case CustomStatistic::WalkUnderWaterOneCm: return 12;
default: return static_cast<UInt32>(-1);
}
}
diff --git a/src/Protocol/Palettes/Palette_1_14.h b/src/Protocol/Palettes/Palette_1_14.h
index 037d9b4c1..c92a19eba 100644
--- a/src/Protocol/Palettes/Palette_1_14.h
+++ b/src/Protocol/Palettes/Palette_1_14.h
@@ -8,6 +8,6 @@ namespace Palette_1_14
{
UInt32 From(BlockState Block);
UInt32 From(Item ID);
- UInt32 From(Statistic ID);
+ UInt32 From(CustomStatistic ID);
Item ToItem(UInt32 ID);
}
diff --git a/src/Protocol/Palettes/Palette_1_15.cpp b/src/Protocol/Palettes/Palette_1_15.cpp
index 4070a3715..29467d6d7 100644
--- a/src/Protocol/Palettes/Palette_1_15.cpp
+++ b/src/Protocol/Palettes/Palette_1_15.cpp
@@ -9578,81 +9578,81 @@ namespace Palette_1_15
}
}
- UInt32 From(const Statistic ID)
+ UInt32 From(const CustomStatistic ID)
{
switch (ID)
{
- case Statistic::AnimalsBred: return 30;
- case Statistic::AviateOneCm: return 17;
- case Statistic::BellRing: return 66;
- case Statistic::BoatOneCm: return 14;
- case Statistic::CleanArmor: return 38;
- case Statistic::CleanBanner: return 39;
- case Statistic::CleanShulkerBox: return 40;
- case Statistic::ClimbOneCm: return 10;
- case Statistic::CrouchOneCm: return 6;
- case Statistic::DamageAbsorbed: return 26;
- case Statistic::DamageBlockedByShield: return 25;
- case Statistic::DamageDealt: return 21;
- case Statistic::DamageDealtAbsorbed: return 22;
- case Statistic::DamageDealtResisted: return 23;
- case Statistic::DamageResisted: return 27;
- case Statistic::DamageTaken: return 24;
- case Statistic::Deaths: return 28;
- case Statistic::Drop: return 20;
- case Statistic::EatCakeSlice: return 35;
- case Statistic::EnchantItem: return 51;
- case Statistic::FallOneCm: return 9;
- case Statistic::FillCauldron: return 36;
- case Statistic::FishCaught: return 32;
- case Statistic::FlyOneCm: return 11;
- case Statistic::HorseOneCm: return 16;
- case Statistic::InspectDispenser: return 45;
- case Statistic::InspectDropper: return 43;
- case Statistic::InspectHopper: return 44;
- case Statistic::InteractWithAnvil: return 69;
- case Statistic::InteractWithBeacon: return 42;
- case Statistic::InteractWithBlastFurnace: return 59;
- case Statistic::InteractWithBrewingstand: return 41;
- case Statistic::InteractWithCampfire: return 62;
- case Statistic::InteractWithCartographyTable: return 63;
- case Statistic::InteractWithCraftingTable: return 54;
- case Statistic::InteractWithFurnace: return 53;
- case Statistic::InteractWithGrindstone: return 70;
- case Statistic::InteractWithLectern: return 61;
- case Statistic::InteractWithLoom: return 64;
- case Statistic::InteractWithSmoker: return 60;
- case Statistic::InteractWithStonecutter: return 65;
- case Statistic::Jump: return 19;
- case Statistic::LeaveGame: return -0;
- case Statistic::MinecartOneCm: return 13;
- case Statistic::MobKills: return 29;
- case Statistic::OpenBarrel: return 58;
- case Statistic::OpenChest: return 55;
- case Statistic::OpenEnderchest: return 50;
- case Statistic::OpenShulkerBox: return 57;
- case Statistic::PigOneCm: return 15;
- case Statistic::PlayNoteblock: return 46;
- case Statistic::PlayOneMinute: return 1;
- case Statistic::PlayRecord: return 52;
- case Statistic::PlayerKills: return 31;
- case Statistic::PotFlower: return 48;
- case Statistic::RaidTrigger: return 67;
- case Statistic::RaidWin: return 68;
- case Statistic::SleepInBed: return 56;
- case Statistic::SneakTime: return 4;
- case Statistic::SprintOneCm: return 7;
- case Statistic::SwimOneCm: return 18;
- case Statistic::TalkedToVillager: return 33;
- case Statistic::TimeSinceDeath: return 2;
- case Statistic::TimeSinceRest: return 3;
- case Statistic::TradedWithVillager: return 34;
- case Statistic::TriggerTrappedChest: return 49;
- case Statistic::TuneNoteblock: return 47;
- case Statistic::UseCauldron: return 37;
- case Statistic::WalkOnWaterOneCm: return 8;
- case Statistic::WalkOneCm: return 5;
- case Statistic::WalkUnderWaterOneCm: return 12;
+ case CustomStatistic::AnimalsBred: return 30;
+ case CustomStatistic::AviateOneCm: return 17;
+ case CustomStatistic::BellRing: return 66;
+ case CustomStatistic::BoatOneCm: return 14;
+ case CustomStatistic::CleanArmor: return 38;
+ case CustomStatistic::CleanBanner: return 39;
+ case CustomStatistic::CleanShulkerBox: return 40;
+ case CustomStatistic::ClimbOneCm: return 10;
+ case CustomStatistic::CrouchOneCm: return 6;
+ case CustomStatistic::DamageAbsorbed: return 26;
+ case CustomStatistic::DamageBlockedByShield: return 25;
+ case CustomStatistic::DamageDealt: return 21;
+ case CustomStatistic::DamageDealtAbsorbed: return 22;
+ case CustomStatistic::DamageDealtResisted: return 23;
+ case CustomStatistic::DamageResisted: return 27;
+ case CustomStatistic::DamageTaken: return 24;
+ case CustomStatistic::Deaths: return 28;
+ case CustomStatistic::Drop: return 20;
+ case CustomStatistic::EatCakeSlice: return 35;
+ case CustomStatistic::EnchantItem: return 51;
+ case CustomStatistic::FallOneCm: return 9;
+ case CustomStatistic::FillCauldron: return 36;
+ case CustomStatistic::FishCaught: return 32;
+ case CustomStatistic::FlyOneCm: return 11;
+ case CustomStatistic::HorseOneCm: return 16;
+ case CustomStatistic::InspectDispenser: return 45;
+ case CustomStatistic::InspectDropper: return 43;
+ case CustomStatistic::InspectHopper: return 44;
+ case CustomStatistic::InteractWithAnvil: return 69;
+ case CustomStatistic::InteractWithBeacon: return 42;
+ case CustomStatistic::InteractWithBlastFurnace: return 59;
+ case CustomStatistic::InteractWithBrewingstand: return 41;
+ case CustomStatistic::InteractWithCampfire: return 62;
+ case CustomStatistic::InteractWithCartographyTable: return 63;
+ case CustomStatistic::InteractWithCraftingTable: return 54;
+ case CustomStatistic::InteractWithFurnace: return 53;
+ case CustomStatistic::InteractWithGrindstone: return 70;
+ case CustomStatistic::InteractWithLectern: return 61;
+ case CustomStatistic::InteractWithLoom: return 64;
+ case CustomStatistic::InteractWithSmoker: return 60;
+ case CustomStatistic::InteractWithStonecutter: return 65;
+ case CustomStatistic::Jump: return 19;
+ case CustomStatistic::LeaveGame: return -0;
+ case CustomStatistic::MinecartOneCm: return 13;
+ case CustomStatistic::MobKills: return 29;
+ case CustomStatistic::OpenBarrel: return 58;
+ case CustomStatistic::OpenChest: return 55;
+ case CustomStatistic::OpenEnderchest: return 50;
+ case CustomStatistic::OpenShulkerBox: return 57;
+ case CustomStatistic::PigOneCm: return 15;
+ case CustomStatistic::PlayNoteblock: return 46;
+ case CustomStatistic::PlayOneMinute: return 1;
+ case CustomStatistic::PlayRecord: return 52;
+ case CustomStatistic::PlayerKills: return 31;
+ case CustomStatistic::PotFlower: return 48;
+ case CustomStatistic::RaidTrigger: return 67;
+ case CustomStatistic::RaidWin: return 68;
+ case CustomStatistic::SleepInBed: return 56;
+ case CustomStatistic::SneakTime: return 4;
+ case CustomStatistic::SprintOneCm: return 7;
+ case CustomStatistic::SwimOneCm: return 18;
+ case CustomStatistic::TalkedToVillager: return 33;
+ case CustomStatistic::TimeSinceDeath: return 2;
+ case CustomStatistic::TimeSinceRest: return 3;
+ case CustomStatistic::TradedWithVillager: return 34;
+ case CustomStatistic::TriggerTrappedChest: return 49;
+ case CustomStatistic::TuneNoteblock: return 47;
+ case CustomStatistic::UseCauldron: return 37;
+ case CustomStatistic::WalkOnWaterOneCm: return 8;
+ case CustomStatistic::WalkOneCm: return 5;
+ case CustomStatistic::WalkUnderWaterOneCm: return 12;
default: return UInt32(-1);
}
}
diff --git a/src/Protocol/Palettes/Palette_1_15.h b/src/Protocol/Palettes/Palette_1_15.h
index 7fcac7e72..22c993de7 100644
--- a/src/Protocol/Palettes/Palette_1_15.h
+++ b/src/Protocol/Palettes/Palette_1_15.h
@@ -8,6 +8,6 @@ namespace Palette_1_15
{
UInt32 From(BlockState Block);
UInt32 From(Item ID);
- UInt32 From(Statistic ID);
+ UInt32 From(CustomStatistic ID);
Item ToItem(UInt32 ID);
}
diff --git a/src/Protocol/Palettes/Palette_1_16.cpp b/src/Protocol/Palettes/Palette_1_16.cpp
index fae43766d..86b684cb8 100644
--- a/src/Protocol/Palettes/Palette_1_16.cpp
+++ b/src/Protocol/Palettes/Palette_1_16.cpp
@@ -12762,84 +12762,84 @@ namespace Palette_1_16
UNREACHABLE("Invalid item");
}
- UInt32 From(const Statistic ID)
+ UInt32 From(const CustomStatistic ID)
{
switch (ID)
{
- case Statistic::AnimalsBred: return 31;
- case Statistic::AviateOneCm: return 17;
- case Statistic::BellRing: return 67;
- case Statistic::BoatOneCm: return 14;
- case Statistic::CleanArmor: return 39;
- case Statistic::CleanBanner: return 40;
- case Statistic::CleanShulkerBox: return 41;
- case Statistic::ClimbOneCm: return 10;
- case Statistic::CrouchOneCm: return 6;
- case Statistic::DamageAbsorbed: return 27;
- case Statistic::DamageBlockedByShield: return 26;
- case Statistic::DamageDealt: return 22;
- case Statistic::DamageDealtAbsorbed: return 23;
- case Statistic::DamageDealtResisted: return 24;
- case Statistic::DamageResisted: return 28;
- case Statistic::DamageTaken: return 25;
- case Statistic::Deaths: return 29;
- case Statistic::Drop: return 21;
- case Statistic::EatCakeSlice: return 36;
- case Statistic::EnchantItem: return 52;
- case Statistic::FallOneCm: return 9;
- case Statistic::FillCauldron: return 37;
- case Statistic::FishCaught: return 33;
- case Statistic::FlyOneCm: return 11;
- case Statistic::HorseOneCm: return 16;
- case Statistic::InspectDispenser: return 46;
- case Statistic::InspectDropper: return 44;
- case Statistic::InspectHopper: return 45;
- case Statistic::InteractWithAnvil: return 70;
- case Statistic::InteractWithBeacon: return 43;
- case Statistic::InteractWithBlastFurnace: return 60;
- case Statistic::InteractWithBrewingstand: return 42;
- case Statistic::InteractWithCampfire: return 63;
- case Statistic::InteractWithCartographyTable: return 64;
- case Statistic::InteractWithCraftingTable: return 55;
- case Statistic::InteractWithFurnace: return 54;
- case Statistic::InteractWithGrindstone: return 71;
- case Statistic::InteractWithLectern: return 62;
- case Statistic::InteractWithLoom: return 65;
- case Statistic::InteractWithSmithingTable: return 73;
- case Statistic::InteractWithSmoker: return 61;
- case Statistic::InteractWithStonecutter: return 66;
- case Statistic::Jump: return 20;
- case Statistic::LeaveGame: return -0;
- case Statistic::MinecartOneCm: return 13;
- case Statistic::MobKills: return 30;
- case Statistic::OpenBarrel: return 59;
- case Statistic::OpenChest: return 56;
- case Statistic::OpenEnderchest: return 51;
- case Statistic::OpenShulkerBox: return 58;
- case Statistic::PigOneCm: return 15;
- case Statistic::PlayNoteblock: return 47;
- case Statistic::PlayOneMinute: return 1;
- case Statistic::PlayRecord: return 53;
- case Statistic::PlayerKills: return 32;
- case Statistic::PotFlower: return 49;
- case Statistic::RaidTrigger: return 68;
- case Statistic::RaidWin: return 69;
- case Statistic::SleepInBed: return 57;
- case Statistic::SneakTime: return 4;
- case Statistic::SprintOneCm: return 7;
- case Statistic::StriderOneCm: return 19;
- case Statistic::SwimOneCm: return 18;
- case Statistic::TalkedToVillager: return 34;
- case Statistic::TargetHit: return 72;
- case Statistic::TimeSinceDeath: return 2;
- case Statistic::TimeSinceRest: return 3;
- case Statistic::TradedWithVillager: return 35;
- case Statistic::TriggerTrappedChest: return 50;
- case Statistic::TuneNoteblock: return 48;
- case Statistic::UseCauldron: return 38;
- case Statistic::WalkOnWaterOneCm: return 8;
- case Statistic::WalkOneCm: return 5;
- case Statistic::WalkUnderWaterOneCm: return 12;
+ case CustomStatistic::AnimalsBred: return 31;
+ case CustomStatistic::AviateOneCm: return 17;
+ case CustomStatistic::BellRing: return 67;
+ case CustomStatistic::BoatOneCm: return 14;
+ case CustomStatistic::CleanArmor: return 39;
+ case CustomStatistic::CleanBanner: return 40;
+ case CustomStatistic::CleanShulkerBox: return 41;
+ case CustomStatistic::ClimbOneCm: return 10;
+ case CustomStatistic::CrouchOneCm: return 6;
+ case CustomStatistic::DamageAbsorbed: return 27;
+ case CustomStatistic::DamageBlockedByShield: return 26;
+ case CustomStatistic::DamageDealt: return 22;
+ case CustomStatistic::DamageDealtAbsorbed: return 23;
+ case CustomStatistic::DamageDealtResisted: return 24;
+ case CustomStatistic::DamageResisted: return 28;
+ case CustomStatistic::DamageTaken: return 25;
+ case CustomStatistic::Deaths: return 29;
+ case CustomStatistic::Drop: return 21;
+ case CustomStatistic::EatCakeSlice: return 36;
+ case CustomStatistic::EnchantItem: return 52;
+ case CustomStatistic::FallOneCm: return 9;
+ case CustomStatistic::FillCauldron: return 37;
+ case CustomStatistic::FishCaught: return 33;
+ case CustomStatistic::FlyOneCm: return 11;
+ case CustomStatistic::HorseOneCm: return 16;
+ case CustomStatistic::InspectDispenser: return 46;
+ case CustomStatistic::InspectDropper: return 44;
+ case CustomStatistic::InspectHopper: return 45;
+ case CustomStatistic::InteractWithAnvil: return 70;
+ case CustomStatistic::InteractWithBeacon: return 43;
+ case CustomStatistic::InteractWithBlastFurnace: return 60;
+ case CustomStatistic::InteractWithBrewingstand: return 42;
+ case CustomStatistic::InteractWithCampfire: return 63;
+ case CustomStatistic::InteractWithCartographyTable: return 64;
+ case CustomStatistic::InteractWithCraftingTable: return 55;
+ case CustomStatistic::InteractWithFurnace: return 54;
+ case CustomStatistic::InteractWithGrindstone: return 71;
+ case CustomStatistic::InteractWithLectern: return 62;
+ case CustomStatistic::InteractWithLoom: return 65;
+ case CustomStatistic::InteractWithSmithingTable: return 73;
+ case CustomStatistic::InteractWithSmoker: return 61;
+ case CustomStatistic::InteractWithStonecutter: return 66;
+ case CustomStatistic::Jump: return 20;
+ case CustomStatistic::LeaveGame: return -0;
+ case CustomStatistic::MinecartOneCm: return 13;
+ case CustomStatistic::MobKills: return 30;
+ case CustomStatistic::OpenBarrel: return 59;
+ case CustomStatistic::OpenChest: return 56;
+ case CustomStatistic::OpenEnderchest: return 51;
+ case CustomStatistic::OpenShulkerBox: return 58;
+ case CustomStatistic::PigOneCm: return 15;
+ case CustomStatistic::PlayNoteblock: return 47;
+ case CustomStatistic::PlayOneMinute: return 1;
+ case CustomStatistic::PlayRecord: return 53;
+ case CustomStatistic::PlayerKills: return 32;
+ case CustomStatistic::PotFlower: return 49;
+ case CustomStatistic::RaidTrigger: return 68;
+ case CustomStatistic::RaidWin: return 69;
+ case CustomStatistic::SleepInBed: return 57;
+ case CustomStatistic::SneakTime: return 4;
+ case CustomStatistic::SprintOneCm: return 7;
+ case CustomStatistic::StriderOneCm: return 19;
+ case CustomStatistic::SwimOneCm: return 18;
+ case CustomStatistic::TalkedToVillager: return 34;
+ case CustomStatistic::TargetHit: return 72;
+ case CustomStatistic::TimeSinceDeath: return 2;
+ case CustomStatistic::TimeSinceRest: return 3;
+ case CustomStatistic::TradedWithVillager: return 35;
+ case CustomStatistic::TriggerTrappedChest: return 50;
+ case CustomStatistic::TuneNoteblock: return 48;
+ case CustomStatistic::UseCauldron: return 38;
+ case CustomStatistic::WalkOnWaterOneCm: return 8;
+ case CustomStatistic::WalkOneCm: return 5;
+ case CustomStatistic::WalkUnderWaterOneCm: return 12;
default: return UInt32(-1);
}
}
diff --git a/src/Protocol/Palettes/Palette_1_16.h b/src/Protocol/Palettes/Palette_1_16.h
index 6e6e632ce..ae6cf9484 100644
--- a/src/Protocol/Palettes/Palette_1_16.h
+++ b/src/Protocol/Palettes/Palette_1_16.h
@@ -8,6 +8,6 @@ namespace Palette_1_16
{
UInt32 From(BlockState Block);
UInt32 From(Item ID);
- UInt32 From(Statistic ID);
+ UInt32 From(CustomStatistic ID);
Item ToItem(UInt32 ID);
}
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index c87ab4a7d..334d8d56b 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -29,9 +29,10 @@ class cPainting;
class cWorld;
class cMonster;
class cCompositeChat;
-class cStatManager;
class cPacketizer;
+struct StatisticsManager;
+
@@ -422,7 +423,7 @@ public:
virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0;
virtual void SendSpawnEntity (const cEntity & a_Entity) = 0;
virtual void SendSpawnMob (const cMonster & a_Mob) = 0;
- virtual void SendStatistics (const cStatManager & a_Manager) = 0;
+ virtual void SendStatistics (const StatisticsManager & a_Manager) = 0;
virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0;
diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp
index 44a011c76..336f3c339 100644
--- a/src/Protocol/Protocol_1_13.cpp
+++ b/src/Protocol/Protocol_1_13.cpp
@@ -142,24 +142,22 @@ void cProtocol_1_13::SendScoreboardObjective(const AString & a_Name, const AStri
-void cProtocol_1_13::SendStatistics(const cStatManager & a_Manager)
+void cProtocol_1_13::SendStatistics(const StatisticsManager & a_Manager)
{
ASSERT(m_State == 3); // In game mode?
UInt32 Size = 0;
- a_Manager.ForEachStatisticType([this, &Size](const auto & Store)
+
+ for (const auto & [Statistic, Value] : a_Manager.Custom)
{
- for (const auto & Item : Store)
- {
- // Client balks at out-of-range values so there is no good default value
- // We're forced to not send the statistics this protocol version doesn't support
+ // Client balks at out-of-range values so there is no good default value.
+ // We're forced to not send the statistics this protocol version doesn't support.
- if (GetProtocolStatisticType(Item.first) != static_cast<UInt32>(-1))
- {
- Size++;
- }
+ if (GetProtocolStatisticType(Statistic) != static_cast<UInt32>(-1))
+ {
+ Size++;
}
- });
+ }
// No need to check Size != 0
// Assume that the vast majority of the time there's at least one statistic to send
@@ -167,22 +165,19 @@ void cProtocol_1_13::SendStatistics(const cStatManager & a_Manager)
cPacketizer Pkt(*this, pktStatistics);
Pkt.WriteVarInt32(Size);
- a_Manager.ForEachStatisticType([this, &Pkt](const cStatManager::CustomStore & Store)
+ for (const auto & [Statistic, Value] : a_Manager.Custom)
{
- for (const auto & Item : Store)
+ const auto ID = GetProtocolStatisticType(Statistic);
+ if (ID == static_cast<UInt32>(-1))
{
- const auto ID = GetProtocolStatisticType(Item.first);
- if (ID == static_cast<UInt32>(-1))
- {
- // Unsupported, don't send:
- continue;
- }
-
- Pkt.WriteVarInt32(8); // "Custom" category
- Pkt.WriteVarInt32(ID);
- Pkt.WriteVarInt32(static_cast<UInt32>(Item.second));
+ // Unsupported, don't send:
+ continue;
}
- });
+
+ Pkt.WriteVarInt32(8); // "Custom" category.
+ Pkt.WriteVarInt32(ID);
+ Pkt.WriteVarInt32(static_cast<UInt32>(Value));
+ }
}
@@ -588,7 +583,7 @@ UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType) const
-UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic) const
+UInt32 cProtocol_1_13::GetProtocolStatisticType(const CustomStatistic a_Statistic) const
{
return Palette_1_13::From(a_Statistic);
}
@@ -1480,7 +1475,7 @@ UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
-UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic) const
+UInt32 cProtocol_1_13_1::GetProtocolStatisticType(const CustomStatistic a_Statistic) const
{
return Palette_1_13_1::From(a_Statistic);
}
diff --git a/src/Protocol/Protocol_1_13.h b/src/Protocol/Protocol_1_13.h
index b478fe5ed..53e7cdc91 100644
--- a/src/Protocol/Protocol_1_13.h
+++ b/src/Protocol/Protocol_1_13.h
@@ -42,7 +42,7 @@ protected:
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
- virtual void SendStatistics (const cStatManager & a_Manager) override;
+ virtual void SendStatistics (const StatisticsManager & a_Manager) override;
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override;
virtual UInt8 GetEntityMetadataID(EntityMetadata a_Metadata) const;
@@ -53,7 +53,7 @@ protected:
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const;
virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override;
- virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const;
+ virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const;
virtual Version GetProtocolVersion() const override;
virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
@@ -88,7 +88,7 @@ protected:
virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) const override;
virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override;
virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override;
- virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const override;
+ virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const override;
virtual Version GetProtocolVersion() const override;
};
diff --git a/src/Protocol/Protocol_1_14.cpp b/src/Protocol/Protocol_1_14.cpp
index f2bbdd955..161bf2f4d 100644
--- a/src/Protocol/Protocol_1_14.cpp
+++ b/src/Protocol/Protocol_1_14.cpp
@@ -238,7 +238,7 @@ UInt32 cProtocol_1_14::GetProtocolItemType(short a_ItemID, short a_ItemDamage) c
-UInt32 cProtocol_1_14::GetProtocolStatisticType(Statistic a_Statistic) const
+UInt32 cProtocol_1_14::GetProtocolStatisticType(const CustomStatistic a_Statistic) const
{
return Palette_1_14::From(a_Statistic);
}
diff --git a/src/Protocol/Protocol_1_14.h b/src/Protocol/Protocol_1_14.h
index 32ae6640e..f4907a7d0 100644
--- a/src/Protocol/Protocol_1_14.h
+++ b/src/Protocol/Protocol_1_14.h
@@ -45,7 +45,7 @@ protected:
virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override;
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override;
- virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const override;
+ virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const override;
virtual Version GetProtocolVersion() const override;
virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp
index 78483a45d..980348887 100644
--- a/src/Protocol/Protocol_1_8.cpp
+++ b/src/Protocol/Protocol_1_8.cpp
@@ -1458,30 +1458,21 @@ void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob)
-void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager)
+void cProtocol_1_8_0::SendStatistics(const StatisticsManager & a_Manager)
{
ASSERT(m_State == 3); // In game mode?
- UInt32 Size = 0;
- a_Manager.ForEachStatisticType([&Size](const auto & Store)
- {
- Size += static_cast<UInt32>(Store.size());
- });
-
- // No need to check Size != 0
- // Assume that the vast majority of the time there's at least one statistic to send
-
cPacketizer Pkt(*this, pktStatistics);
- Pkt.WriteVarInt32(Size);
- a_Manager.ForEachStatisticType([&Pkt](const cStatManager::CustomStore & Store)
+ // No need to check Size != 0.
+ // Assume that the vast majority of the time there's at least one statistic to send:
+ Pkt.WriteVarInt32(static_cast<UInt32>(a_Manager.Custom.size()));
+
+ for (const auto & [Statistic, Value] : a_Manager.Custom)
{
- for (const auto & Item : Store)
- {
- Pkt.WriteString(GetProtocolStatisticName(Item.first));
- Pkt.WriteVarInt32(static_cast<UInt32>(Item.second));
- }
- });
+ Pkt.WriteString(GetProtocolStatisticName(Statistic));
+ Pkt.WriteVarInt32(static_cast<UInt32>(Value));
+ }
}
@@ -2401,15 +2392,13 @@ void cProtocol_1_8_0::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
case 1:
{
// Request stats
- const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager();
- SendStatistics(Manager);
-
+ SendStatistics(m_Client->GetPlayer()->GetStatistics());
break;
}
case 2:
{
// Open Inventory achievement
- m_Client->GetPlayer()->AwardAchievement(Statistic::AchOpenInventory);
+ m_Client->GetPlayer()->AwardAchievement(CustomStatistic::AchOpenInventory);
break;
}
}
@@ -4042,99 +4031,99 @@ int cProtocol_1_8_0::GetProtocolParticleID(const AString & a_ParticleName)
-const char * cProtocol_1_8_0::GetProtocolStatisticName(Statistic a_Statistic)
+const char * cProtocol_1_8_0::GetProtocolStatisticName(const CustomStatistic a_Statistic)
{
switch (a_Statistic)
{
// V1.8 Achievements
- case Statistic::AchOpenInventory: return "achievement.openInventory";
- case Statistic::AchMineWood: return "achievement.mineWood";
- case Statistic::AchBuildWorkBench: return "achievement.buildWorkBench";
- case Statistic::AchBuildPickaxe: return "achievement.buildPickaxe";
- case Statistic::AchBuildFurnace: return "achievement.buildFurnace";
- case Statistic::AchAcquireIron: return "achievement.acquireIron";
- case Statistic::AchBuildHoe: return "achievement.buildHoe";
- case Statistic::AchMakeBread: return "achievement.makeBread";
- case Statistic::AchBakeCake: return "achievement.bakeCake";
- case Statistic::AchBuildBetterPickaxe: return "achievement.buildBetterPickaxe";
- case Statistic::AchCookFish: return "achievement.cookFish";
- case Statistic::AchOnARail: return "achievement.onARail";
- case Statistic::AchBuildSword: return "achievement.buildSword";
- case Statistic::AchKillEnemy: return "achievement.killEnemy";
- case Statistic::AchKillCow: return "achievement.killCow";
- case Statistic::AchFlyPig: return "achievement.flyPig";
- case Statistic::AchSnipeSkeleton: return "achievement.snipeSkeleton";
- case Statistic::AchDiamonds: return "achievement.diamonds";
- case Statistic::AchPortal: return "achievement.portal";
- case Statistic::AchGhast: return "achievement.ghast";
- case Statistic::AchBlazeRod: return "achievement.blazeRod";
- case Statistic::AchPotion: return "achievement.potion";
- case Statistic::AchTheEnd: return "achievement.theEnd";
- case Statistic::AchTheEnd2: return "achievement.theEnd2";
- case Statistic::AchEnchantments: return "achievement.enchantments";
- case Statistic::AchOverkill: return "achievement.overkill";
- case Statistic::AchBookcase: return "achievement.bookcase";
- case Statistic::AchExploreAllBiomes: return "achievement.exploreAllBiomes";
- case Statistic::AchSpawnWither: return "achievement.spawnWither";
- case Statistic::AchKillWither: return "achievement.killWither";
- case Statistic::AchFullBeacon: return "achievement.fullBeacon";
- case Statistic::AchBreedCow: return "achievement.breedCow";
- case Statistic::AchDiamondsToYou: return "achievement.diamondsToYou";
+ case CustomStatistic::AchOpenInventory: return "achievement.openInventory";
+ case CustomStatistic::AchMineWood: return "achievement.mineWood";
+ case CustomStatistic::AchBuildWorkBench: return "achievement.buildWorkBench";
+ case CustomStatistic::AchBuildPickaxe: return "achievement.buildPickaxe";
+ case CustomStatistic::AchBuildFurnace: return "achievement.buildFurnace";
+ case CustomStatistic::AchAcquireIron: return "achievement.acquireIron";
+ case CustomStatistic::AchBuildHoe: return "achievement.buildHoe";
+ case CustomStatistic::AchMakeBread: return "achievement.makeBread";
+ case CustomStatistic::AchBakeCake: return "achievement.bakeCake";
+ case CustomStatistic::AchBuildBetterPickaxe: return "achievement.buildBetterPickaxe";
+ case CustomStatistic::AchCookFish: return "achievement.cookFish";
+ case CustomStatistic::AchOnARail: return "achievement.onARail";
+ case CustomStatistic::AchBuildSword: return "achievement.buildSword";
+ case CustomStatistic::AchKillEnemy: return "achievement.killEnemy";
+ case CustomStatistic::AchKillCow: return "achievement.killCow";
+ case CustomStatistic::AchFlyPig: return "achievement.flyPig";
+ case CustomStatistic::AchSnipeSkeleton: return "achievement.snipeSkeleton";
+ case CustomStatistic::AchDiamonds: return "achievement.diamonds";
+ case CustomStatistic::AchPortal: return "achievement.portal";
+ case CustomStatistic::AchGhast: return "achievement.ghast";
+ case CustomStatistic::AchBlazeRod: return "achievement.blazeRod";
+ case CustomStatistic::AchPotion: return "achievement.potion";
+ case CustomStatistic::AchTheEnd: return "achievement.theEnd";
+ case CustomStatistic::AchTheEnd2: return "achievement.theEnd2";
+ case CustomStatistic::AchEnchantments: return "achievement.enchantments";
+ case CustomStatistic::AchOverkill: return "achievement.overkill";
+ case CustomStatistic::AchBookcase: return "achievement.bookcase";
+ case CustomStatistic::AchExploreAllBiomes: return "achievement.exploreAllBiomes";
+ case CustomStatistic::AchSpawnWither: return "achievement.spawnWither";
+ case CustomStatistic::AchKillWither: return "achievement.killWither";
+ case CustomStatistic::AchFullBeacon: return "achievement.fullBeacon";
+ case CustomStatistic::AchBreedCow: return "achievement.breedCow";
+ case CustomStatistic::AchDiamondsToYou: return "achievement.diamondsToYou";
// V1.8 stats
- case Statistic::AnimalsBred: return "stat.animalsBred";
- case Statistic::BoatOneCm: return "stat.boatOneCm";
- case Statistic::ClimbOneCm: return "stat.climbOneCm";
- case Statistic::CrouchOneCm: return "stat.crouchOneCm";
- case Statistic::DamageDealt: return "stat.damageDealt";
- case Statistic::DamageTaken: return "stat.damageTaken";
- case Statistic::Deaths: return "stat.deaths";
- case Statistic::Drop: return "stat.drop";
- case Statistic::FallOneCm: return "stat.fallOneCm";
- case Statistic::FishCaught: return "stat.fishCaught";
- case Statistic::FlyOneCm: return "stat.flyOneCm";
- case Statistic::HorseOneCm: return "stat.horseOneCm";
- case Statistic::Jump: return "stat.jump";
- case Statistic::LeaveGame: return "stat.leaveGame";
- case Statistic::MinecartOneCm: return "stat.minecartOneCm";
- case Statistic::MobKills: return "stat.mobKills";
- case Statistic::PigOneCm: return "stat.pigOneCm";
- case Statistic::PlayerKills: return "stat.playerKills";
- case Statistic::PlayOneMinute: return "stat.playOneMinute";
- case Statistic::SprintOneCm: return "stat.sprintOneCm";
- case Statistic::SwimOneCm: return "stat.swimOneCm";
- case Statistic::TalkedToVillager: return "stat.talkedToVillager";
- case Statistic::TimeSinceDeath: return "stat.timeSinceDeath";
- case Statistic::TradedWithVillager: return "stat.tradedWithVillager";
- case Statistic::WalkOneCm: return "stat.walkOneCm";
- case Statistic::WalkUnderWaterOneCm: return "stat.diveOneCm";
+ case CustomStatistic::AnimalsBred: return "stat.animalsBred";
+ case CustomStatistic::BoatOneCm: return "stat.boatOneCm";
+ case CustomStatistic::ClimbOneCm: return "stat.climbOneCm";
+ case CustomStatistic::CrouchOneCm: return "stat.crouchOneCm";
+ case CustomStatistic::DamageDealt: return "stat.damageDealt";
+ case CustomStatistic::DamageTaken: return "stat.damageTaken";
+ case CustomStatistic::Deaths: return "stat.deaths";
+ case CustomStatistic::Drop: return "stat.drop";
+ case CustomStatistic::FallOneCm: return "stat.fallOneCm";
+ case CustomStatistic::FishCaught: return "stat.fishCaught";
+ case CustomStatistic::FlyOneCm: return "stat.flyOneCm";
+ case CustomStatistic::HorseOneCm: return "stat.horseOneCm";
+ case CustomStatistic::Jump: return "stat.jump";
+ case CustomStatistic::LeaveGame: return "stat.leaveGame";
+ case CustomStatistic::MinecartOneCm: return "stat.minecartOneCm";
+ case CustomStatistic::MobKills: return "stat.mobKills";
+ case CustomStatistic::PigOneCm: return "stat.pigOneCm";
+ case CustomStatistic::PlayerKills: return "stat.playerKills";
+ case CustomStatistic::PlayOneMinute: return "stat.playOneMinute";
+ case CustomStatistic::SprintOneCm: return "stat.sprintOneCm";
+ case CustomStatistic::SwimOneCm: return "stat.swimOneCm";
+ case CustomStatistic::TalkedToVillager: return "stat.talkedToVillager";
+ case CustomStatistic::TimeSinceDeath: return "stat.timeSinceDeath";
+ case CustomStatistic::TradedWithVillager: return "stat.tradedWithVillager";
+ case CustomStatistic::WalkOneCm: return "stat.walkOneCm";
+ case CustomStatistic::WalkUnderWaterOneCm: return "stat.diveOneCm";
// V1.8.2 stats
- case Statistic::CleanArmor: return "stat.armorCleaned";
- case Statistic::CleanBanner: return "stat.bannerCleaned";
- case Statistic::EatCakeSlice: return "stat.cakeSlicesEaten";
- case Statistic::EnchantItem: return "stat.itemEnchanted";
- case Statistic::FillCauldron: return "stat.cauldronFilled";
- case Statistic::InspectDispenser: return "stat.dispenserInspected";
- case Statistic::InspectDropper: return "stat.dropperInspected";
- case Statistic::InspectHopper: return "stat.hopperInspected";
- case Statistic::InteractWithBeacon: return "stat.beaconInteraction";
- case Statistic::InteractWithBrewingstand: return "stat.brewingstandInteraction";
- case Statistic::InteractWithCraftingTable: return "stat.craftingTableInteraction";
- case Statistic::InteractWithFurnace: return "stat.furnaceInteraction";
- case Statistic::OpenChest: return "stat.chestOpened";
- case Statistic::OpenEnderchest: return "stat.enderchestOpened";
- case Statistic::PlayNoteblock: return "stat.noteblockPlayed";
- case Statistic::PlayRecord: return "stat.recordPlayed";
- case Statistic::PotFlower: return "stat.flowerPotted";
- case Statistic::TriggerTrappedChest: return "stat.trappedChestTriggered";
- case Statistic::TuneNoteblock: return "stat.noteblockTuned";
- case Statistic::UseCauldron: return "stat.cauldronUsed";
+ case CustomStatistic::CleanArmor: return "stat.armorCleaned";
+ case CustomStatistic::CleanBanner: return "stat.bannerCleaned";
+ case CustomStatistic::EatCakeSlice: return "stat.cakeSlicesEaten";
+ case CustomStatistic::EnchantItem: return "stat.itemEnchanted";
+ case CustomStatistic::FillCauldron: return "stat.cauldronFilled";
+ case CustomStatistic::InspectDispenser: return "stat.dispenserInspected";
+ case CustomStatistic::InspectDropper: return "stat.dropperInspected";
+ case CustomStatistic::InspectHopper: return "stat.hopperInspected";
+ case CustomStatistic::InteractWithBeacon: return "stat.beaconInteraction";
+ case CustomStatistic::InteractWithBrewingstand: return "stat.brewingstandInteraction";
+ case CustomStatistic::InteractWithCraftingTable: return "stat.craftingTableInteraction";
+ case CustomStatistic::InteractWithFurnace: return "stat.furnaceInteraction";
+ case CustomStatistic::OpenChest: return "stat.chestOpened";
+ case CustomStatistic::OpenEnderchest: return "stat.enderchestOpened";
+ case CustomStatistic::PlayNoteblock: return "stat.noteblockPlayed";
+ case CustomStatistic::PlayRecord: return "stat.recordPlayed";
+ case CustomStatistic::PotFlower: return "stat.flowerPotted";
+ case CustomStatistic::TriggerTrappedChest: return "stat.trappedChestTriggered";
+ case CustomStatistic::TuneNoteblock: return "stat.noteblockTuned";
+ case CustomStatistic::UseCauldron: return "stat.cauldronUsed";
// V1.9 stats
- case Statistic::AviateOneCm: return "stat.aviateOneCm";
- case Statistic::SleepInBed: return "stat.sleepInBed";
- case Statistic::SneakTime: return "stat.sneakTime";
+ case CustomStatistic::AviateOneCm: return "stat.aviateOneCm";
+ case CustomStatistic::SleepInBed: return "stat.sleepInBed";
+ case CustomStatistic::SneakTime: return "stat.sneakTime";
default: return "";
}
}
diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h
index 652ef69c5..faea84e57 100644
--- a/src/Protocol/Protocol_1_8.h
+++ b/src/Protocol/Protocol_1_8.h
@@ -113,7 +113,7 @@ public:
virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendSpawnEntity (const cEntity & a_Entity) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
- virtual void SendStatistics (const cStatManager & a_Manager) override;
+ virtual void SendStatistics (const StatisticsManager & a_Manager) override;
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
@@ -267,7 +267,7 @@ private:
/** Converts a statistic to a protocol-specific string.
Protocols <= 1.12 use strings, hence this is a static as the string-mapping was append-only for the versions that used it.
Returns an empty string, handled correctly by the client, for newer, unsupported statistics. */
- static const char * GetProtocolStatisticName(Statistic a_Statistic);
+ static const char * GetProtocolStatisticName(CustomStatistic a_Statistic);
/** Handle a complete packet stored in the given buffer. */
void HandlePacket(cByteBuffer & a_Buffer);
diff --git a/src/Registries/Statistics.h b/src/Registries/Statistics.h
index 82aef5442..c0edba191 100644
--- a/src/Registries/Statistics.h
+++ b/src/Registries/Statistics.h
@@ -1,7 +1,10 @@
#pragma once
-enum class Statistic
+// tolua_begin
+enum class CustomStatistic
{
+ // tolua_end
+
/* Achievements */
AchOpenInventory, /* Taking Inventory */
AchMineWood, /* Getting Wood */
@@ -37,6 +40,8 @@ enum class Statistic
AchBreedCow, /* Repopulation */
AchDiamondsToYou, /* Diamonds to you! */
+ // tolua_begin
+
/* Statistics */
AnimalsBred,
AviateOneCm,
@@ -117,3 +122,4 @@ enum class Statistic
JunkFished,
TreasureFished,
};
+// tolua_end
diff --git a/src/Statistics.cpp b/src/Statistics.cpp
index 7bc5ae413..f037ec7b1 100644
--- a/src/Statistics.cpp
+++ b/src/Statistics.cpp
@@ -9,61 +9,43 @@
-void cStatManager::SetValue(const Statistic a_Stat, const StatValue a_Value)
-{
- m_CustomStatistics[a_Stat] = a_Value;
-}
-
-
-
-
-
-cStatManager::StatValue cStatManager::AddValue(const Statistic a_Stat, const StatValue a_Delta)
-{
- return m_CustomStatistics[a_Stat] += a_Delta;
-}
-
-
-
-
-
-bool cStatManager::SatisfiesPrerequisite(const Statistic a_Stat)
+bool StatisticsManager::SatisfiesPrerequisite(const CustomStatistic a_Stat) const
{
switch (a_Stat)
{
- case Statistic::AchMineWood: return IsStatisticPresent(Statistic::AchOpenInventory);
- case Statistic::AchBuildWorkBench: return IsStatisticPresent(Statistic::AchMineWood);
- case Statistic::AchBuildHoe: return IsStatisticPresent(Statistic::AchBuildWorkBench);
- case Statistic::AchBakeCake: return IsStatisticPresent(Statistic::AchBuildHoe);
- case Statistic::AchMakeBread: return IsStatisticPresent(Statistic::AchBuildHoe);
- case Statistic::AchBuildSword: return IsStatisticPresent(Statistic::AchBuildWorkBench);
- case Statistic::AchKillCow: return IsStatisticPresent(Statistic::AchBuildSword);
- case Statistic::AchFlyPig: return IsStatisticPresent(Statistic::AchKillCow);
- case Statistic::AchBreedCow: return IsStatisticPresent(Statistic::AchKillCow);
- case Statistic::AchKillEnemy: return IsStatisticPresent(Statistic::AchBuildSword);
- case Statistic::AchSnipeSkeleton: return IsStatisticPresent(Statistic::AchKillEnemy);
- case Statistic::AchBuildPickaxe: return IsStatisticPresent(Statistic::AchBuildWorkBench);
- case Statistic::AchBuildBetterPickaxe: return IsStatisticPresent(Statistic::AchBuildPickaxe);
- case Statistic::AchBuildFurnace: return IsStatisticPresent(Statistic::AchBuildWorkBench);
- case Statistic::AchCookFish: return IsStatisticPresent(Statistic::AchBuildFurnace);
- case Statistic::AchAcquireIron: return IsStatisticPresent(Statistic::AchBuildFurnace);
- case Statistic::AchOnARail: return IsStatisticPresent(Statistic::AchAcquireIron);
- case Statistic::AchDiamonds: return IsStatisticPresent(Statistic::AchAcquireIron);
- case Statistic::AchPortal: return IsStatisticPresent(Statistic::AchDiamonds);
- case Statistic::AchGhast: return IsStatisticPresent(Statistic::AchPortal);
- case Statistic::AchBlazeRod: return IsStatisticPresent(Statistic::AchPortal);
- case Statistic::AchPotion: return IsStatisticPresent(Statistic::AchBlazeRod);
- case Statistic::AchTheEnd: return IsStatisticPresent(Statistic::AchBlazeRod);
- case Statistic::AchTheEnd2: return IsStatisticPresent(Statistic::AchTheEnd);
- case Statistic::AchEnchantments: return IsStatisticPresent(Statistic::AchDiamonds);
- case Statistic::AchOverkill: return IsStatisticPresent(Statistic::AchEnchantments);
- case Statistic::AchBookcase: return IsStatisticPresent(Statistic::AchEnchantments);
- case Statistic::AchExploreAllBiomes: return IsStatisticPresent(Statistic::AchTheEnd);
- case Statistic::AchSpawnWither: return IsStatisticPresent(Statistic::AchTheEnd2);
- case Statistic::AchKillWither: return IsStatisticPresent(Statistic::AchSpawnWither);
- case Statistic::AchFullBeacon: return IsStatisticPresent(Statistic::AchKillWither);
- case Statistic::AchDiamondsToYou: return IsStatisticPresent(Statistic::AchDiamonds);
- default: return true;
+ case CustomStatistic::AchMineWood: return IsStatisticPresent(CustomStatistic::AchOpenInventory);
+ case CustomStatistic::AchBuildWorkBench: return IsStatisticPresent(CustomStatistic::AchMineWood);
+ case CustomStatistic::AchBuildHoe: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench);
+ case CustomStatistic::AchBakeCake: return IsStatisticPresent(CustomStatistic::AchBuildHoe);
+ case CustomStatistic::AchMakeBread: return IsStatisticPresent(CustomStatistic::AchBuildHoe);
+ case CustomStatistic::AchBuildSword: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench);
+ case CustomStatistic::AchKillCow: return IsStatisticPresent(CustomStatistic::AchBuildSword);
+ case CustomStatistic::AchFlyPig: return IsStatisticPresent(CustomStatistic::AchKillCow);
+ case CustomStatistic::AchBreedCow: return IsStatisticPresent(CustomStatistic::AchKillCow);
+ case CustomStatistic::AchKillEnemy: return IsStatisticPresent(CustomStatistic::AchBuildSword);
+ case CustomStatistic::AchSnipeSkeleton: return IsStatisticPresent(CustomStatistic::AchKillEnemy);
+ case CustomStatistic::AchBuildPickaxe: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench);
+ case CustomStatistic::AchBuildBetterPickaxe: return IsStatisticPresent(CustomStatistic::AchBuildPickaxe);
+ case CustomStatistic::AchBuildFurnace: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench);
+ case CustomStatistic::AchCookFish: return IsStatisticPresent(CustomStatistic::AchBuildFurnace);
+ case CustomStatistic::AchAcquireIron: return IsStatisticPresent(CustomStatistic::AchBuildFurnace);
+ case CustomStatistic::AchOnARail: return IsStatisticPresent(CustomStatistic::AchAcquireIron);
+ case CustomStatistic::AchDiamonds: return IsStatisticPresent(CustomStatistic::AchAcquireIron);
+ case CustomStatistic::AchPortal: return IsStatisticPresent(CustomStatistic::AchDiamonds);
+ case CustomStatistic::AchGhast: return IsStatisticPresent(CustomStatistic::AchPortal);
+ case CustomStatistic::AchBlazeRod: return IsStatisticPresent(CustomStatistic::AchPortal);
+ case CustomStatistic::AchPotion: return IsStatisticPresent(CustomStatistic::AchBlazeRod);
+ case CustomStatistic::AchTheEnd: return IsStatisticPresent(CustomStatistic::AchBlazeRod);
+ case CustomStatistic::AchTheEnd2: return IsStatisticPresent(CustomStatistic::AchTheEnd);
+ case CustomStatistic::AchEnchantments: return IsStatisticPresent(CustomStatistic::AchDiamonds);
+ case CustomStatistic::AchOverkill: return IsStatisticPresent(CustomStatistic::AchEnchantments);
+ case CustomStatistic::AchBookcase: return IsStatisticPresent(CustomStatistic::AchEnchantments);
+ case CustomStatistic::AchExploreAllBiomes: return IsStatisticPresent(CustomStatistic::AchTheEnd);
+ case CustomStatistic::AchSpawnWither: return IsStatisticPresent(CustomStatistic::AchTheEnd2);
+ case CustomStatistic::AchKillWither: return IsStatisticPresent(CustomStatistic::AchSpawnWither);
+ case CustomStatistic::AchFullBeacon: return IsStatisticPresent(CustomStatistic::AchKillWither);
+ case CustomStatistic::AchDiamondsToYou: return IsStatisticPresent(CustomStatistic::AchDiamonds);
+ default: UNREACHABLE("Unsupported achievement type");
}
}
@@ -71,10 +53,10 @@ bool cStatManager::SatisfiesPrerequisite(const Statistic a_Stat)
-bool cStatManager::IsStatisticPresent(const Statistic a_Stat) const
+bool StatisticsManager::IsStatisticPresent(const CustomStatistic a_Stat) const
{
- const auto Result = m_CustomStatistics.find(a_Stat);
- if (Result != m_CustomStatistics.end())
+ const auto Result = Custom.find(a_Stat);
+ if (Result != Custom.end())
{
return Result->second > 0;
}
diff --git a/src/Statistics.h b/src/Statistics.h
index 5944ba8fa..38d2f0f7e 100644
--- a/src/Statistics.h
+++ b/src/Statistics.h
@@ -25,35 +25,19 @@ exported from the server https://wiki.vg/Data_Generators
/** Class that manages the statistics and achievements of a single player. */
-class cStatManager
+struct StatisticsManager
{
-public:
-
typedef unsigned StatValue;
- typedef std::unordered_map<Statistic, StatValue> CustomStore;
- /** Set the value of the specified statistic. */
- void SetValue(Statistic a_Stat, StatValue a_Value);
+ // TODO: Block tallies, entities killed, all the others
- /** Increments the specified statistic. Returns the new value. */
- StatValue AddValue(Statistic a_Stat, StatValue a_Delta = 1);
+ std::unordered_map<CustomStatistic, StatValue> Custom;
/** Returns whether the prerequisite for awarding an achievement are satisfied. */
- bool SatisfiesPrerequisite(Statistic a_Stat);
-
- /** Invokes the given callbacks for each category of tracked statistics. */
- template <class CustomCallback>
- void ForEachStatisticType(CustomCallback a_Custom) const
- {
- a_Custom(m_CustomStatistics);
- }
+ bool SatisfiesPrerequisite(CustomStatistic a_Stat) const;
private:
/** Returns if a statistic is both present and has nonzero value. */
- bool IsStatisticPresent(Statistic a_Stat) const;
-
- // TODO: Block tallies, entities killed, all the others
-
- CustomStore m_CustomStatistics;
+ bool IsStatisticPresent(CustomStatistic a_Stat) const;
};
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 2d5d0cedd..6d27ea834 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -766,16 +766,16 @@ void cSlotAreaCrafting::HandleCraftItem(const cItem & a_Result, cPlayer & a_Play
{
switch (a_Result.m_ItemType)
{
- case E_BLOCK_WORKBENCH: a_Player.AwardAchievement(Statistic::AchBuildWorkBench); break;
- case E_BLOCK_FURNACE: a_Player.AwardAchievement(Statistic::AchBuildFurnace); break;
- case E_BLOCK_CAKE: a_Player.AwardAchievement(Statistic::AchBakeCake); break;
- case E_BLOCK_ENCHANTMENT_TABLE: a_Player.AwardAchievement(Statistic::AchEnchantments); break;
- case E_BLOCK_BOOKCASE: a_Player.AwardAchievement(Statistic::AchBookcase); break;
- case E_ITEM_WOODEN_PICKAXE: a_Player.AwardAchievement(Statistic::AchBuildPickaxe); break;
- case E_ITEM_WOODEN_SWORD: a_Player.AwardAchievement(Statistic::AchBuildSword); break;
- case E_ITEM_STONE_PICKAXE: a_Player.AwardAchievement(Statistic::AchBuildBetterPickaxe); break;
- case E_ITEM_WOODEN_HOE: a_Player.AwardAchievement(Statistic::AchBuildHoe); break;
- case E_ITEM_BREAD: a_Player.AwardAchievement(Statistic::AchMakeBread); break;
+ case E_BLOCK_WORKBENCH: a_Player.AwardAchievement(CustomStatistic::AchBuildWorkBench); break;
+ case E_BLOCK_FURNACE: a_Player.AwardAchievement(CustomStatistic::AchBuildFurnace); break;
+ case E_BLOCK_CAKE: a_Player.AwardAchievement(CustomStatistic::AchBakeCake); break;
+ case E_BLOCK_ENCHANTMENT_TABLE: a_Player.AwardAchievement(CustomStatistic::AchEnchantments); break;
+ case E_BLOCK_BOOKCASE: a_Player.AwardAchievement(CustomStatistic::AchBookcase); break;
+ case E_ITEM_WOODEN_PICKAXE: a_Player.AwardAchievement(CustomStatistic::AchBuildPickaxe); break;
+ case E_ITEM_WOODEN_SWORD: a_Player.AwardAchievement(CustomStatistic::AchBuildSword); break;
+ case E_ITEM_STONE_PICKAXE: a_Player.AwardAchievement(CustomStatistic::AchBuildBetterPickaxe); break;
+ case E_ITEM_WOODEN_HOE: a_Player.AwardAchievement(CustomStatistic::AchBuildHoe); break;
+ case E_ITEM_BREAD: a_Player.AwardAchievement(CustomStatistic::AchMakeBread); break;
default: break;
}
}
@@ -2105,8 +2105,8 @@ void cSlotAreaFurnace::HandleSmeltItem(const cItem & a_Result, cPlayer & a_Playe
/** TODO 2014-05-12 xdot: Figure out when to call this method. */
switch (a_Result.m_ItemType)
{
- case E_ITEM_IRON: a_Player.AwardAchievement(Statistic::AchAcquireIron); break;
- case E_ITEM_COOKED_FISH: a_Player.AwardAchievement(Statistic::AchCookFish); break;
+ case E_ITEM_IRON: a_Player.AwardAchievement(CustomStatistic::AchAcquireIron); break;
+ case E_ITEM_COOKED_FISH: a_Player.AwardAchievement(CustomStatistic::AchCookFish); break;
default: break;
}
}
@@ -2255,7 +2255,7 @@ void cSlotAreaBrewingstand::HandleBrewedItem(cPlayer & a_Player, const cItem & a
// Award an achievement if the item is not a water bottle (is a real brewed potion)
if (a_ClickedItem.m_ItemDamage > 0)
{
- a_Player.AwardAchievement(Statistic::AchPotion);
+ a_Player.AwardAchievement(CustomStatistic::AchPotion);
}
}
diff --git a/src/WorldStorage/NamespaceSerializer.cpp b/src/WorldStorage/NamespaceSerializer.cpp
index 8a4c9ea9b..2e2e9302e 100644
--- a/src/WorldStorage/NamespaceSerializer.cpp
+++ b/src/WorldStorage/NamespaceSerializer.cpp
@@ -15,123 +15,123 @@ unsigned NamespaceSerializer::DataVersion()
-std::string_view NamespaceSerializer::From(const Statistic a_ID)
+std::string_view NamespaceSerializer::From(const CustomStatistic a_ID)
{
switch (a_ID)
{
- case Statistic::AnimalsBred: return "animals_bred";
- case Statistic::AviateOneCm: return "aviate_one_cm";
- case Statistic::BellRing: return "bell_ring";
- case Statistic::BoatOneCm: return "boat_one_cm";
- case Statistic::CleanArmor: return "clean_armor";
- case Statistic::CleanBanner: return "clean_banner";
- case Statistic::CleanShulkerBox: return "clean_shulker_box";
- case Statistic::ClimbOneCm: return "climb_one_cm";
- case Statistic::CrouchOneCm: return "crouch_one_cm";
- case Statistic::DamageAbsorbed: return "damage_absorbed";
- case Statistic::DamageBlockedByShield: return "damage_blocked_by_shield";
- case Statistic::DamageDealt: return "damage_dealt";
- case Statistic::DamageDealtAbsorbed: return "damage_dealt_absorbed";
- case Statistic::DamageDealtResisted: return "damage_dealt_resisted";
- case Statistic::DamageResisted: return "damage_resisted";
- case Statistic::DamageTaken: return "damage_taken";
- case Statistic::Deaths: return "deaths";
- case Statistic::Drop: return "drop";
- case Statistic::EatCakeSlice: return "eat_cake_slice";
- case Statistic::EnchantItem: return "enchant_item";
- case Statistic::FallOneCm: return "fall_one_cm";
- case Statistic::FillCauldron: return "fill_cauldron";
- case Statistic::FishCaught: return "fish_caught";
- case Statistic::FlyOneCm: return "fly_one_cm";
- case Statistic::HorseOneCm: return "horse_one_cm";
- case Statistic::InspectDispenser: return "inspect_dispenser";
- case Statistic::InspectDropper: return "inspect_dropper";
- case Statistic::InspectHopper: return "inspect_hopper";
- case Statistic::InteractWithAnvil: return "interact_with_anvil";
- case Statistic::InteractWithBeacon: return "interact_with_beacon";
- case Statistic::InteractWithBlastFurnace: return "interact_with_blast_furnace";
- case Statistic::InteractWithBrewingstand: return "interact_with_brewingstand";
- case Statistic::InteractWithCampfire: return "interact_with_campfire";
- case Statistic::InteractWithCartographyTable: return "interact_with_cartography_table";
- case Statistic::InteractWithCraftingTable: return "interact_with_crafting_table";
- case Statistic::InteractWithFurnace: return "interact_with_furnace";
- case Statistic::InteractWithGrindstone: return "interact_with_grindstone";
- case Statistic::InteractWithLectern: return "interact_with_lectern";
- case Statistic::InteractWithLoom: return "interact_with_loom";
- case Statistic::InteractWithSmithingTable: return "interact_with_smithing_table";
- case Statistic::InteractWithSmoker: return "interact_with_smoker";
- case Statistic::InteractWithStonecutter: return "interact_with_stonecutter";
- case Statistic::Jump: return "jump";
- case Statistic::LeaveGame: return "leave_game";
- case Statistic::MinecartOneCm: return "minecart_one_cm";
- case Statistic::MobKills: return "mob_kills";
- case Statistic::OpenBarrel: return "open_barrel";
- case Statistic::OpenChest: return "open_chest";
- case Statistic::OpenEnderchest: return "open_enderchest";
- case Statistic::OpenShulkerBox: return "open_shulker_box";
- case Statistic::PigOneCm: return "pig_one_cm";
- case Statistic::PlayNoteblock: return "play_noteblock";
- case Statistic::PlayOneMinute: return "play_one_minute";
- case Statistic::PlayRecord: return "play_record";
- case Statistic::PlayerKills: return "player_kills";
- case Statistic::PotFlower: return "pot_flower";
- case Statistic::RaidTrigger: return "raid_trigger";
- case Statistic::RaidWin: return "raid_win";
- case Statistic::SleepInBed: return "sleep_in_bed";
- case Statistic::SneakTime: return "sneak_time";
- case Statistic::SprintOneCm: return "sprint_one_cm";
- case Statistic::StriderOneCm: return "strider_one_cm";
- case Statistic::SwimOneCm: return "swim_one_cm";
- case Statistic::TalkedToVillager: return "talked_to_villager";
- case Statistic::TargetHit: return "target_hit";
- case Statistic::TimeSinceDeath: return "time_since_death";
- case Statistic::TimeSinceRest: return "time_since_rest";
- case Statistic::TradedWithVillager: return "traded_with_villager";
- case Statistic::TriggerTrappedChest: return "trigger_trapped_chest";
- case Statistic::TuneNoteblock: return "tune_noteblock";
- case Statistic::UseCauldron: return "use_cauldron";
- case Statistic::WalkOnWaterOneCm: return "walk_on_water_one_cm";
- case Statistic::WalkOneCm: return "walk_one_cm";
- case Statistic::WalkUnderWaterOneCm: return "walk_under_water_one_cm";
+ case CustomStatistic::AnimalsBred: return "animals_bred";
+ case CustomStatistic::AviateOneCm: return "aviate_one_cm";
+ case CustomStatistic::BellRing: return "bell_ring";
+ case CustomStatistic::BoatOneCm: return "boat_one_cm";
+ case CustomStatistic::CleanArmor: return "clean_armor";
+ case CustomStatistic::CleanBanner: return "clean_banner";
+ case CustomStatistic::CleanShulkerBox: return "clean_shulker_box";
+ case CustomStatistic::ClimbOneCm: return "climb_one_cm";
+ case CustomStatistic::CrouchOneCm: return "crouch_one_cm";
+ case CustomStatistic::DamageAbsorbed: return "damage_absorbed";
+ case CustomStatistic::DamageBlockedByShield: return "damage_blocked_by_shield";
+ case CustomStatistic::DamageDealt: return "damage_dealt";
+ case CustomStatistic::DamageDealtAbsorbed: return "damage_dealt_absorbed";
+ case CustomStatistic::DamageDealtResisted: return "damage_dealt_resisted";
+ case CustomStatistic::DamageResisted: return "damage_resisted";
+ case CustomStatistic::DamageTaken: return "damage_taken";
+ case CustomStatistic::Deaths: return "deaths";
+ case CustomStatistic::Drop: return "drop";
+ case CustomStatistic::EatCakeSlice: return "eat_cake_slice";
+ case CustomStatistic::EnchantItem: return "enchant_item";
+ case CustomStatistic::FallOneCm: return "fall_one_cm";
+ case CustomStatistic::FillCauldron: return "fill_cauldron";
+ case CustomStatistic::FishCaught: return "fish_caught";
+ case CustomStatistic::FlyOneCm: return "fly_one_cm";
+ case CustomStatistic::HorseOneCm: return "horse_one_cm";
+ case CustomStatistic::InspectDispenser: return "inspect_dispenser";
+ case CustomStatistic::InspectDropper: return "inspect_dropper";
+ case CustomStatistic::InspectHopper: return "inspect_hopper";
+ case CustomStatistic::InteractWithAnvil: return "interact_with_anvil";
+ case CustomStatistic::InteractWithBeacon: return "interact_with_beacon";
+ case CustomStatistic::InteractWithBlastFurnace: return "interact_with_blast_furnace";
+ case CustomStatistic::InteractWithBrewingstand: return "interact_with_brewingstand";
+ case CustomStatistic::InteractWithCampfire: return "interact_with_campfire";
+ case CustomStatistic::InteractWithCartographyTable: return "interact_with_cartography_table";
+ case CustomStatistic::InteractWithCraftingTable: return "interact_with_crafting_table";
+ case CustomStatistic::InteractWithFurnace: return "interact_with_furnace";
+ case CustomStatistic::InteractWithGrindstone: return "interact_with_grindstone";
+ case CustomStatistic::InteractWithLectern: return "interact_with_lectern";
+ case CustomStatistic::InteractWithLoom: return "interact_with_loom";
+ case CustomStatistic::InteractWithSmithingTable: return "interact_with_smithing_table";
+ case CustomStatistic::InteractWithSmoker: return "interact_with_smoker";
+ case CustomStatistic::InteractWithStonecutter: return "interact_with_stonecutter";
+ case CustomStatistic::Jump: return "jump";
+ case CustomStatistic::LeaveGame: return "leave_game";
+ case CustomStatistic::MinecartOneCm: return "minecart_one_cm";
+ case CustomStatistic::MobKills: return "mob_kills";
+ case CustomStatistic::OpenBarrel: return "open_barrel";
+ case CustomStatistic::OpenChest: return "open_chest";
+ case CustomStatistic::OpenEnderchest: return "open_enderchest";
+ case CustomStatistic::OpenShulkerBox: return "open_shulker_box";
+ case CustomStatistic::PigOneCm: return "pig_one_cm";
+ case CustomStatistic::PlayNoteblock: return "play_noteblock";
+ case CustomStatistic::PlayOneMinute: return "play_one_minute";
+ case CustomStatistic::PlayRecord: return "play_record";
+ case CustomStatistic::PlayerKills: return "player_kills";
+ case CustomStatistic::PotFlower: return "pot_flower";
+ case CustomStatistic::RaidTrigger: return "raid_trigger";
+ case CustomStatistic::RaidWin: return "raid_win";
+ case CustomStatistic::SleepInBed: return "sleep_in_bed";
+ case CustomStatistic::SneakTime: return "sneak_time";
+ case CustomStatistic::SprintOneCm: return "sprint_one_cm";
+ case CustomStatistic::StriderOneCm: return "strider_one_cm";
+ case CustomStatistic::SwimOneCm: return "swim_one_cm";
+ case CustomStatistic::TalkedToVillager: return "talked_to_villager";
+ case CustomStatistic::TargetHit: return "target_hit";
+ case CustomStatistic::TimeSinceDeath: return "time_since_death";
+ case CustomStatistic::TimeSinceRest: return "time_since_rest";
+ case CustomStatistic::TradedWithVillager: return "traded_with_villager";
+ case CustomStatistic::TriggerTrappedChest: return "trigger_trapped_chest";
+ case CustomStatistic::TuneNoteblock: return "tune_noteblock";
+ case CustomStatistic::UseCauldron: return "use_cauldron";
+ case CustomStatistic::WalkOnWaterOneCm: return "walk_on_water_one_cm";
+ case CustomStatistic::WalkOneCm: return "walk_one_cm";
+ case CustomStatistic::WalkUnderWaterOneCm: return "walk_under_water_one_cm";
// Old ones just for compatibility
- case Statistic::JunkFished: return "junk_fished";
- case Statistic::TreasureFished: return "treasure_fished";
+ case CustomStatistic::JunkFished: return "junk_fished";
+ case CustomStatistic::TreasureFished: return "treasure_fished";
// The old advancements
- case Statistic::AchOpenInventory: return "cuberite:achievement.openInventory";
- case Statistic::AchMineWood: return "cuberite:achievement.mineWood";
- case Statistic::AchBuildWorkBench: return "cuberite:achievement.buildWorkBench";
- case Statistic::AchBuildPickaxe: return "cuberite:achievement.buildPickaxe";
- case Statistic::AchBuildFurnace: return "cuberite:achievement.buildFurnace";
- case Statistic::AchAcquireIron: return "cuberite:achievement.acquireIron";
- case Statistic::AchBuildHoe: return "cuberite:achievement.buildHoe";
- case Statistic::AchMakeBread: return "cuberite:achievement.makeBread";
- case Statistic::AchBakeCake: return "cuberite:achievement.bakeCake";
- case Statistic::AchBuildBetterPickaxe: return "cuberite:achievement.buildBetterPickaxe";
- case Statistic::AchCookFish: return "cuberite:achievement.cookFish";
- case Statistic::AchOnARail: return "cuberite:achievement.onARail";
- case Statistic::AchBuildSword: return "cuberite:achievement.buildSword";
- case Statistic::AchKillEnemy: return "cuberite:achievement.killEnemy";
- case Statistic::AchKillCow: return "cuberite:achievement.killCow";
- case Statistic::AchFlyPig: return "cuberite:achievement.flyPig";
- case Statistic::AchSnipeSkeleton: return "cuberite:achievement.snipeSkeleton";
- case Statistic::AchDiamonds: return "cuberite:achievement.diamonds";
- case Statistic::AchPortal: return "cuberite:achievement.portal";
- case Statistic::AchGhast: return "cuberite:achievement.ghast";
- case Statistic::AchBlazeRod: return "cuberite:achievement.blazeRod";
- case Statistic::AchPotion: return "cuberite:achievement.potion";
- case Statistic::AchTheEnd: return "cuberite:achievement.theEnd";
- case Statistic::AchTheEnd2: return "cuberite:achievement.theEnd2";
- case Statistic::AchEnchantments: return "cuberite:achievement.enchantments";
- case Statistic::AchOverkill: return "cuberite:achievement.overkill";
- case Statistic::AchBookcase: return "cuberite:achievement.bookcase";
- case Statistic::AchExploreAllBiomes: return "cuberite:achievement.exploreAllBiomes";
- case Statistic::AchSpawnWither: return "cuberite:achievement.spawnWither";
- case Statistic::AchKillWither: return "cuberite:achievement.killWither";
- case Statistic::AchFullBeacon: return "cuberite:achievement.fullBeacon";
- case Statistic::AchBreedCow: return "cuberite:achievement.breedCow";
- case Statistic::AchDiamondsToYou: return "cuberite:achievement.diamondsToYou";
+ case CustomStatistic::AchOpenInventory: return "cuberite:achievement.openInventory";
+ case CustomStatistic::AchMineWood: return "cuberite:achievement.mineWood";
+ case CustomStatistic::AchBuildWorkBench: return "cuberite:achievement.buildWorkBench";
+ case CustomStatistic::AchBuildPickaxe: return "cuberite:achievement.buildPickaxe";
+ case CustomStatistic::AchBuildFurnace: return "cuberite:achievement.buildFurnace";
+ case CustomStatistic::AchAcquireIron: return "cuberite:achievement.acquireIron";
+ case CustomStatistic::AchBuildHoe: return "cuberite:achievement.buildHoe";
+ case CustomStatistic::AchMakeBread: return "cuberite:achievement.makeBread";
+ case CustomStatistic::AchBakeCake: return "cuberite:achievement.bakeCake";
+ case CustomStatistic::AchBuildBetterPickaxe: return "cuberite:achievement.buildBetterPickaxe";
+ case CustomStatistic::AchCookFish: return "cuberite:achievement.cookFish";
+ case CustomStatistic::AchOnARail: return "cuberite:achievement.onARail";
+ case CustomStatistic::AchBuildSword: return "cuberite:achievement.buildSword";
+ case CustomStatistic::AchKillEnemy: return "cuberite:achievement.killEnemy";
+ case CustomStatistic::AchKillCow: return "cuberite:achievement.killCow";
+ case CustomStatistic::AchFlyPig: return "cuberite:achievement.flyPig";
+ case CustomStatistic::AchSnipeSkeleton: return "cuberite:achievement.snipeSkeleton";
+ case CustomStatistic::AchDiamonds: return "cuberite:achievement.diamonds";
+ case CustomStatistic::AchPortal: return "cuberite:achievement.portal";
+ case CustomStatistic::AchGhast: return "cuberite:achievement.ghast";
+ case CustomStatistic::AchBlazeRod: return "cuberite:achievement.blazeRod";
+ case CustomStatistic::AchPotion: return "cuberite:achievement.potion";
+ case CustomStatistic::AchTheEnd: return "cuberite:achievement.theEnd";
+ case CustomStatistic::AchTheEnd2: return "cuberite:achievement.theEnd2";
+ case CustomStatistic::AchEnchantments: return "cuberite:achievement.enchantments";
+ case CustomStatistic::AchOverkill: return "cuberite:achievement.overkill";
+ case CustomStatistic::AchBookcase: return "cuberite:achievement.bookcase";
+ case CustomStatistic::AchExploreAllBiomes: return "cuberite:achievement.exploreAllBiomes";
+ case CustomStatistic::AchSpawnWither: return "cuberite:achievement.spawnWither";
+ case CustomStatistic::AchKillWither: return "cuberite:achievement.killWither";
+ case CustomStatistic::AchFullBeacon: return "cuberite:achievement.fullBeacon";
+ case CustomStatistic::AchBreedCow: return "cuberite:achievement.breedCow";
+ case CustomStatistic::AchDiamondsToYou: return "cuberite:achievement.diamondsToYou";
}
UNREACHABLE("Tried to save unhandled statistic");
}
@@ -274,123 +274,123 @@ std::string_view NamespaceSerializer::From(const BannerPattern a_Pattern)
-Statistic NamespaceSerializer::ToCustomStatistic(const std::string_view ID)
+CustomStatistic NamespaceSerializer::ToCustomStatistic(const std::string_view ID)
{
- static const std::unordered_map<std::string_view, Statistic> CustomStatistics
+ static const std::unordered_map<std::string_view, CustomStatistic> CustomStatistics
{
- { "animals_bred", Statistic::AnimalsBred },
- { "aviate_one_cm", Statistic::AviateOneCm },
- { "bell_ring", Statistic::BellRing },
- { "boat_one_cm", Statistic::BoatOneCm },
- { "clean_armor", Statistic::CleanArmor },
- { "clean_banner", Statistic::CleanBanner },
- { "clean_shulker_box", Statistic::CleanShulkerBox },
- { "climb_one_cm", Statistic::ClimbOneCm },
- { "crouch_one_cm", Statistic::CrouchOneCm },
- { "damage_absorbed", Statistic::DamageAbsorbed },
- { "damage_blocked_by_shield", Statistic::DamageBlockedByShield },
- { "damage_dealt", Statistic::DamageDealt },
- { "damage_dealt_absorbed", Statistic::DamageDealtAbsorbed },
- { "damage_dealt_resisted", Statistic::DamageDealtResisted },
- { "damage_resisted", Statistic::DamageResisted },
- { "damage_taken", Statistic::DamageTaken },
- { "deaths", Statistic::Deaths },
- { "drop", Statistic::Drop },
- { "eat_cake_slice", Statistic::EatCakeSlice },
- { "enchant_item", Statistic::EnchantItem },
- { "fall_one_cm", Statistic::FallOneCm },
- { "fill_cauldron", Statistic::FillCauldron },
- { "fish_caught", Statistic::FishCaught },
- { "fly_one_cm", Statistic::FlyOneCm },
- { "horse_one_cm", Statistic::HorseOneCm },
- { "inspect_dispenser", Statistic::InspectDispenser },
- { "inspect_dropper", Statistic::InspectDropper },
- { "inspect_hopper", Statistic::InspectHopper },
- { "interact_with_anvil", Statistic::InteractWithAnvil },
- { "interact_with_beacon", Statistic::InteractWithBeacon },
- { "interact_with_blast_furnace", Statistic::InteractWithBlastFurnace },
- { "interact_with_brewingstand", Statistic::InteractWithBrewingstand },
- { "interact_with_campfire", Statistic::InteractWithCampfire },
- { "interact_with_cartography_table", Statistic::InteractWithCartographyTable },
- { "interact_with_crafting_table", Statistic::InteractWithCraftingTable },
- { "interact_with_furnace", Statistic::InteractWithFurnace },
- { "interact_with_grindstone", Statistic::InteractWithGrindstone },
- { "interact_with_lectern", Statistic::InteractWithLectern },
- { "interact_with_loom", Statistic::InteractWithLoom },
- { "interact_with_smithing_table", Statistic::InteractWithSmithingTable },
- { "interact_with_smoker", Statistic::InteractWithSmoker },
- { "interact_with_stonecutter", Statistic::InteractWithStonecutter },
- { "jump", Statistic::Jump },
- { "leave_game", Statistic::LeaveGame },
- { "minecart_one_cm", Statistic::MinecartOneCm },
- { "mob_kills", Statistic::MobKills },
- { "open_barrel", Statistic::OpenBarrel },
- { "open_chest", Statistic::OpenChest },
- { "open_enderchest", Statistic::OpenEnderchest },
- { "open_shulker_box", Statistic::OpenShulkerBox },
- { "pig_one_cm", Statistic::PigOneCm },
- { "play_noteblock", Statistic::PlayNoteblock },
- { "play_one_minute", Statistic::PlayOneMinute },
- { "play_record", Statistic::PlayRecord },
- { "player_kills", Statistic::PlayerKills },
- { "pot_flower", Statistic::PotFlower },
- { "raid_trigger", Statistic::RaidTrigger },
- { "raid_win", Statistic::RaidWin },
- { "sleep_in_bed", Statistic::SleepInBed },
- { "sneak_time", Statistic::SneakTime },
- { "sprint_one_cm", Statistic::SprintOneCm },
- { "strider_one_cm", Statistic::StriderOneCm },
- { "swim_one_cm", Statistic::SwimOneCm },
- { "talked_to_villager", Statistic::TalkedToVillager },
- { "target_hit", Statistic::TargetHit },
- { "time_since_death", Statistic::TimeSinceDeath },
- { "time_since_rest", Statistic::TimeSinceRest },
- { "traded_with_villager", Statistic::TradedWithVillager },
- { "trigger_trapped_chest", Statistic::TriggerTrappedChest },
- { "tune_noteblock", Statistic::TuneNoteblock },
- { "use_cauldron", Statistic::UseCauldron },
- { "walk_on_water_one_cm", Statistic::WalkOnWaterOneCm },
- { "walk_one_cm", Statistic::WalkOneCm },
- { "walk_under_water_one_cm", Statistic::WalkUnderWaterOneCm },
+ { "animals_bred", CustomStatistic::AnimalsBred },
+ { "aviate_one_cm", CustomStatistic::AviateOneCm },
+ { "bell_ring", CustomStatistic::BellRing },
+ { "boat_one_cm", CustomStatistic::BoatOneCm },
+ { "clean_armor", CustomStatistic::CleanArmor },
+ { "clean_banner", CustomStatistic::CleanBanner },
+ { "clean_shulker_box", CustomStatistic::CleanShulkerBox },
+ { "climb_one_cm", CustomStatistic::ClimbOneCm },
+ { "crouch_one_cm", CustomStatistic::CrouchOneCm },
+ { "damage_absorbed", CustomStatistic::DamageAbsorbed },
+ { "damage_blocked_by_shield", CustomStatistic::DamageBlockedByShield },
+ { "damage_dealt", CustomStatistic::DamageDealt },
+ { "damage_dealt_absorbed", CustomStatistic::DamageDealtAbsorbed },
+ { "damage_dealt_resisted", CustomStatistic::DamageDealtResisted },
+ { "damage_resisted", CustomStatistic::DamageResisted },
+ { "damage_taken", CustomStatistic::DamageTaken },
+ { "deaths", CustomStatistic::Deaths },
+ { "drop", CustomStatistic::Drop },
+ { "eat_cake_slice", CustomStatistic::EatCakeSlice },
+ { "enchant_item", CustomStatistic::EnchantItem },
+ { "fall_one_cm", CustomStatistic::FallOneCm },
+ { "fill_cauldron", CustomStatistic::FillCauldron },
+ { "fish_caught", CustomStatistic::FishCaught },
+ { "fly_one_cm", CustomStatistic::FlyOneCm },
+ { "horse_one_cm", CustomStatistic::HorseOneCm },
+ { "inspect_dispenser", CustomStatistic::InspectDispenser },
+ { "inspect_dropper", CustomStatistic::InspectDropper },
+ { "inspect_hopper", CustomStatistic::InspectHopper },
+ { "interact_with_anvil", CustomStatistic::InteractWithAnvil },
+ { "interact_with_beacon", CustomStatistic::InteractWithBeacon },
+ { "interact_with_blast_furnace", CustomStatistic::InteractWithBlastFurnace },
+ { "interact_with_brewingstand", CustomStatistic::InteractWithBrewingstand },
+ { "interact_with_campfire", CustomStatistic::InteractWithCampfire },
+ { "interact_with_cartography_table", CustomStatistic::InteractWithCartographyTable },
+ { "interact_with_crafting_table", CustomStatistic::InteractWithCraftingTable },
+ { "interact_with_furnace", CustomStatistic::InteractWithFurnace },
+ { "interact_with_grindstone", CustomStatistic::InteractWithGrindstone },
+ { "interact_with_lectern", CustomStatistic::InteractWithLectern },
+ { "interact_with_loom", CustomStatistic::InteractWithLoom },
+ { "interact_with_smithing_table", CustomStatistic::InteractWithSmithingTable },
+ { "interact_with_smoker", CustomStatistic::InteractWithSmoker },
+ { "interact_with_stonecutter", CustomStatistic::InteractWithStonecutter },
+ { "jump", CustomStatistic::Jump },
+ { "leave_game", CustomStatistic::LeaveGame },
+ { "minecart_one_cm", CustomStatistic::MinecartOneCm },
+ { "mob_kills", CustomStatistic::MobKills },
+ { "open_barrel", CustomStatistic::OpenBarrel },
+ { "open_chest", CustomStatistic::OpenChest },
+ { "open_enderchest", CustomStatistic::OpenEnderchest },
+ { "open_shulker_box", CustomStatistic::OpenShulkerBox },
+ { "pig_one_cm", CustomStatistic::PigOneCm },
+ { "play_noteblock", CustomStatistic::PlayNoteblock },
+ { "play_one_minute", CustomStatistic::PlayOneMinute },
+ { "play_record", CustomStatistic::PlayRecord },
+ { "player_kills", CustomStatistic::PlayerKills },
+ { "pot_flower", CustomStatistic::PotFlower },
+ { "raid_trigger", CustomStatistic::RaidTrigger },
+ { "raid_win", CustomStatistic::RaidWin },
+ { "sleep_in_bed", CustomStatistic::SleepInBed },
+ { "sneak_time", CustomStatistic::SneakTime },
+ { "sprint_one_cm", CustomStatistic::SprintOneCm },
+ { "strider_one_cm", CustomStatistic::StriderOneCm },
+ { "swim_one_cm", CustomStatistic::SwimOneCm },
+ { "talked_to_villager", CustomStatistic::TalkedToVillager },
+ { "target_hit", CustomStatistic::TargetHit },
+ { "time_since_death", CustomStatistic::TimeSinceDeath },
+ { "time_since_rest", CustomStatistic::TimeSinceRest },
+ { "traded_with_villager", CustomStatistic::TradedWithVillager },
+ { "trigger_trapped_chest", CustomStatistic::TriggerTrappedChest },
+ { "tune_noteblock", CustomStatistic::TuneNoteblock },
+ { "use_cauldron", CustomStatistic::UseCauldron },
+ { "walk_on_water_one_cm", CustomStatistic::WalkOnWaterOneCm },
+ { "walk_one_cm", CustomStatistic::WalkOneCm },
+ { "walk_under_water_one_cm", CustomStatistic::WalkUnderWaterOneCm },
// Old ones just for compatibility
- { "junk_fished", Statistic::JunkFished },
- { "treasure_fished", Statistic::TreasureFished },
+ { "junk_fished", CustomStatistic::JunkFished },
+ { "treasure_fished", CustomStatistic::TreasureFished },
// The old advancements
- { "cuberite:achievement.openInventory", Statistic::AchOpenInventory },
- { "cuberite:achievement.mineWood", Statistic::AchMineWood },
- { "cuberite:achievement.buildWorkBench", Statistic::AchBuildWorkBench },
- { "cuberite:achievement.buildPickaxe", Statistic::AchBuildPickaxe },
- { "cuberite:achievement.buildFurnace", Statistic::AchBuildFurnace },
- { "cuberite:achievement.acquireIron", Statistic::AchAcquireIron },
- { "cuberite:achievement.buildHoe", Statistic::AchBuildHoe },
- { "cuberite:achievement.makeBread", Statistic::AchMakeBread },
- { "cuberite:achievement.bakeCake", Statistic::AchBakeCake },
- { "cuberite:achievement.buildBetterPickaxe", Statistic::AchBuildBetterPickaxe },
- { "cuberite:achievement.cookFish", Statistic::AchCookFish },
- { "cuberite:achievement.onARail", Statistic::AchOnARail },
- { "cuberite:achievement.buildSword", Statistic::AchBuildSword },
- { "cuberite:achievement.killEnemy", Statistic::AchKillEnemy },
- { "cuberite:achievement.killCow", Statistic::AchKillCow },
- { "cuberite:achievement.flyPig", Statistic::AchFlyPig },
- { "cuberite:achievement.snipeSkeleton", Statistic::AchSnipeSkeleton },
- { "cuberite:achievement.diamonds", Statistic::AchDiamonds },
- { "cuberite:achievement.portal", Statistic::AchPortal },
- { "cuberite:achievement.ghast", Statistic::AchGhast },
- { "cuberite:achievement.blazeRod", Statistic::AchBlazeRod },
- { "cuberite:achievement.potion", Statistic::AchPotion },
- { "cuberite:achievement.theEnd", Statistic::AchTheEnd },
- { "cuberite:achievement.theEnd2", Statistic::AchTheEnd2 },
- { "cuberite:achievement.enchantments", Statistic::AchEnchantments },
- { "cuberite:achievement.overkill", Statistic::AchOverkill },
- { "cuberite:achievement.bookcase", Statistic::AchBookcase },
- { "cuberite:achievement.exploreAllBiomes", Statistic::AchExploreAllBiomes },
- { "cuberite:achievement.spawnWither", Statistic::AchSpawnWither },
- { "cuberite:achievement.killWither", Statistic::AchKillWither },
- { "cuberite:achievement.fullBeacon", Statistic::AchFullBeacon },
- { "cuberite:achievement.breedCow", Statistic::AchBreedCow },
- { "cuberite:achievement.diamondsToYou", Statistic::AchDiamondsToYou}
+ { "cuberite:achievement.openInventory", CustomStatistic::AchOpenInventory },
+ { "cuberite:achievement.mineWood", CustomStatistic::AchMineWood },
+ { "cuberite:achievement.buildWorkBench", CustomStatistic::AchBuildWorkBench },
+ { "cuberite:achievement.buildPickaxe", CustomStatistic::AchBuildPickaxe },
+ { "cuberite:achievement.buildFurnace", CustomStatistic::AchBuildFurnace },
+ { "cuberite:achievement.acquireIron", CustomStatistic::AchAcquireIron },
+ { "cuberite:achievement.buildHoe", CustomStatistic::AchBuildHoe },
+ { "cuberite:achievement.makeBread", CustomStatistic::AchMakeBread },
+ { "cuberite:achievement.bakeCake", CustomStatistic::AchBakeCake },
+ { "cuberite:achievement.buildBetterPickaxe", CustomStatistic::AchBuildBetterPickaxe },
+ { "cuberite:achievement.cookFish", CustomStatistic::AchCookFish },
+ { "cuberite:achievement.onARail", CustomStatistic::AchOnARail },
+ { "cuberite:achievement.buildSword", CustomStatistic::AchBuildSword },
+ { "cuberite:achievement.killEnemy", CustomStatistic::AchKillEnemy },
+ { "cuberite:achievement.killCow", CustomStatistic::AchKillCow },
+ { "cuberite:achievement.flyPig", CustomStatistic::AchFlyPig },
+ { "cuberite:achievement.snipeSkeleton", CustomStatistic::AchSnipeSkeleton },
+ { "cuberite:achievement.diamonds", CustomStatistic::AchDiamonds },
+ { "cuberite:achievement.portal", CustomStatistic::AchPortal },
+ { "cuberite:achievement.ghast", CustomStatistic::AchGhast },
+ { "cuberite:achievement.blazeRod", CustomStatistic::AchBlazeRod },
+ { "cuberite:achievement.potion", CustomStatistic::AchPotion },
+ { "cuberite:achievement.theEnd", CustomStatistic::AchTheEnd },
+ { "cuberite:achievement.theEnd2", CustomStatistic::AchTheEnd2 },
+ { "cuberite:achievement.enchantments", CustomStatistic::AchEnchantments },
+ { "cuberite:achievement.overkill", CustomStatistic::AchOverkill },
+ { "cuberite:achievement.bookcase", CustomStatistic::AchBookcase },
+ { "cuberite:achievement.exploreAllBiomes", CustomStatistic::AchExploreAllBiomes },
+ { "cuberite:achievement.spawnWither", CustomStatistic::AchSpawnWither },
+ { "cuberite:achievement.killWither", CustomStatistic::AchKillWither },
+ { "cuberite:achievement.fullBeacon", CustomStatistic::AchFullBeacon },
+ { "cuberite:achievement.breedCow", CustomStatistic::AchBreedCow },
+ { "cuberite:achievement.diamondsToYou", CustomStatistic::AchDiamondsToYou}
};
return CustomStatistics.at(ID);
diff --git a/src/WorldStorage/NamespaceSerializer.h b/src/WorldStorage/NamespaceSerializer.h
index 876db740f..c521db201 100644
--- a/src/WorldStorage/NamespaceSerializer.h
+++ b/src/WorldStorage/NamespaceSerializer.h
@@ -15,11 +15,11 @@ namespace NamespaceSerializer
unsigned DataVersion();
- std::string_view From(Statistic a_ID);
+ std::string_view From(CustomStatistic a_ID);
std::string_view From(eMonsterType a_ID);
std::string_view From(BannerPattern a_ID);
- Statistic ToCustomStatistic(std::string_view a_ID);
+ CustomStatistic ToCustomStatistic(std::string_view a_ID);
eMonsterType ToMonsterType(std::string_view a_ID);
std::pair<Namespace, std::string_view> SplitNamespacedID(std::string_view ID);
diff --git a/src/WorldStorage/StatSerializer.cpp b/src/WorldStorage/StatSerializer.cpp
index 4721d7022..5432f6ab9 100644
--- a/src/WorldStorage/StatSerializer.cpp
+++ b/src/WorldStorage/StatSerializer.cpp
@@ -33,115 +33,112 @@ namespace StatSerializer
- static void SaveStatToJSON(const cStatManager & Manager, Json::Value & a_Out)
+ static void SaveStatToJSON(const StatisticsManager & Manager, Json::Value & a_Out)
{
- Manager.ForEachStatisticType([&a_Out](const cStatManager::CustomStore & Store)
+ if (Manager.Custom.empty())
{
- if (Store.empty())
- {
- // Avoid saving "custom": null to disk:
- return;
- }
+ // Avoid saving "custom": null to disk:
+ return;
+ }
- auto & Custom = a_Out["custom"];
- for (const auto & Item : Store)
- {
- Custom[NamespaceSerializer::From(Item.first).data()] = Item.second;
- }
- });
+ auto & Custom = a_Out["custom"];
+ for (const auto & [Statistic, Value] : Manager.Custom)
+ {
+ Custom[NamespaceSerializer::From(Statistic).data()] = Value;
+ }
}
- static void LoadLegacyFromJSON(cStatManager & Manager, const Json::Value & In)
+ static void LoadLegacyFromJSON(StatisticsManager & Manager, const Json::Value & In)
{
// Upgrade mapping from pre-1.13 names. TODO: remove on 2020-09-18
- static const std::unordered_map<std::string_view, Statistic> LegacyMapping
+ static const std::unordered_map<std::string_view, CustomStatistic> LegacyMapping
{
- { "achievement.openInventory", Statistic::AchOpenInventory },
- { "achievement.mineWood", Statistic::AchMineWood },
- { "achievement.buildWorkBench", Statistic::AchBuildWorkBench },
- { "achievement.buildPickaxe", Statistic::AchBuildPickaxe },
- { "achievement.buildFurnace", Statistic::AchBuildFurnace },
- { "achievement.acquireIron", Statistic::AchAcquireIron },
- { "achievement.buildHoe", Statistic::AchBuildHoe },
- { "achievement.makeBread", Statistic::AchMakeBread },
- { "achievement.bakeCake", Statistic::AchBakeCake },
- { "achievement.buildBetterPickaxe", Statistic::AchBuildBetterPickaxe },
- { "achievement.cookFish", Statistic::AchCookFish },
- { "achievement.onARail", Statistic::AchOnARail },
- { "achievement.buildSword", Statistic::AchBuildSword },
- { "achievement.killEnemy", Statistic::AchKillEnemy },
- { "achievement.killCow", Statistic::AchKillCow },
- { "achievement.flyPig", Statistic::AchFlyPig },
- { "achievement.snipeSkeleton", Statistic::AchSnipeSkeleton },
- { "achievement.diamonds", Statistic::AchDiamonds },
- { "achievement.portal", Statistic::AchPortal },
- { "achievement.ghast", Statistic::AchGhast },
- { "achievement.blazeRod", Statistic::AchBlazeRod },
- { "achievement.potion", Statistic::AchPotion },
- { "achievement.theEnd", Statistic::AchTheEnd },
- { "achievement.theEnd2", Statistic::AchTheEnd2 },
- { "achievement.enchantments", Statistic::AchEnchantments },
- { "achievement.overkill", Statistic::AchOverkill },
- { "achievement.bookcase", Statistic::AchBookcase },
- { "achievement.exploreAllBiomes", Statistic::AchExploreAllBiomes },
- { "achievement.spawnWither", Statistic::AchSpawnWither },
- { "achievement.killWither", Statistic::AchKillWither },
- { "achievement.fullBeacon", Statistic::AchFullBeacon },
- { "achievement.breedCow", Statistic::AchBreedCow },
- { "achievement.diamondsToYou", Statistic::AchDiamondsToYou },
- { "stat.animalsBred", Statistic::AnimalsBred },
- { "stat.boatOneCm", Statistic::BoatOneCm },
- { "stat.climbOneCm", Statistic::ClimbOneCm },
- { "stat.crouchOneCm", Statistic::CrouchOneCm },
- { "stat.damageDealt", Statistic::DamageDealt },
- { "stat.damageTaken", Statistic::DamageTaken },
- { "stat.deaths", Statistic::Deaths },
- { "stat.drop", Statistic::Drop },
- { "stat.fallOneCm", Statistic::FallOneCm },
- { "stat.fishCaught", Statistic::FishCaught },
- { "stat.flyOneCm", Statistic::FlyOneCm },
- { "stat.horseOneCm", Statistic::HorseOneCm },
- { "stat.jump", Statistic::Jump },
- { "stat.leaveGame", Statistic::LeaveGame },
- { "stat.minecartOneCm", Statistic::MinecartOneCm },
- { "stat.mobKills", Statistic::MobKills },
- { "stat.pigOneCm", Statistic::PigOneCm },
- { "stat.playerKills", Statistic::PlayerKills },
- { "stat.playOneMinute", Statistic::PlayOneMinute },
- { "stat.sprintOneCm", Statistic::SprintOneCm },
- { "stat.swimOneCm", Statistic::SwimOneCm },
- { "stat.talkedToVillager", Statistic::TalkedToVillager },
- { "stat.timeSinceDeath", Statistic::TimeSinceDeath },
- { "stat.tradedWithVillager", Statistic::TradedWithVillager },
- { "stat.walkOneCm", Statistic::WalkOneCm },
- { "stat.diveOneCm", Statistic::WalkUnderWaterOneCm },
- { "stat.armorCleaned", Statistic::CleanArmor },
- { "stat.bannerCleaned", Statistic::CleanBanner },
- { "stat.cakeSlicesEaten", Statistic::EatCakeSlice },
- { "stat.itemEnchanted", Statistic::EnchantItem },
- { "stat.cauldronFilled", Statistic::FillCauldron },
- { "stat.dispenserInspected", Statistic::InspectDispenser },
- { "stat.dropperInspected", Statistic::InspectDropper },
- { "stat.hopperInspected", Statistic::InspectHopper },
- { "stat.beaconInteraction", Statistic::InteractWithBeacon },
- { "stat.brewingstandInteraction", Statistic::InteractWithBrewingstand },
- { "stat.craftingTableInteraction", Statistic::InteractWithCraftingTable },
- { "stat.furnaceInteraction", Statistic::InteractWithFurnace },
- { "stat.chestOpened", Statistic::OpenChest },
- { "stat.enderchestOpened", Statistic::OpenEnderchest },
- { "stat.noteblockPlayed", Statistic::PlayNoteblock },
- { "stat.recordPlayed", Statistic::PlayRecord },
- { "stat.flowerPotted", Statistic::PotFlower },
- { "stat.trappedChestTriggered", Statistic::TriggerTrappedChest },
- { "stat.noteblockTuned", Statistic::TuneNoteblock },
- { "stat.cauldronUsed", Statistic::UseCauldron },
- { "stat.aviateOneCm", Statistic::AviateOneCm },
- { "stat.sleepInBed", Statistic::SleepInBed },
- { "stat.sneakTime", Statistic::SneakTime }
+ { "achievement.openInventory", CustomStatistic::AchOpenInventory },
+ { "achievement.mineWood", CustomStatistic::AchMineWood },
+ { "achievement.buildWorkBench", CustomStatistic::AchBuildWorkBench },
+ { "achievement.buildPickaxe", CustomStatistic::AchBuildPickaxe },
+ { "achievement.buildFurnace", CustomStatistic::AchBuildFurnace },
+ { "achievement.acquireIron", CustomStatistic::AchAcquireIron },
+ { "achievement.buildHoe", CustomStatistic::AchBuildHoe },
+ { "achievement.makeBread", CustomStatistic::AchMakeBread },
+ { "achievement.bakeCake", CustomStatistic::AchBakeCake },
+ { "achievement.buildBetterPickaxe", CustomStatistic::AchBuildBetterPickaxe },
+ { "achievement.cookFish", CustomStatistic::AchCookFish },
+ { "achievement.onARail", CustomStatistic::AchOnARail },
+ { "achievement.buildSword", CustomStatistic::AchBuildSword },
+ { "achievement.killEnemy", CustomStatistic::AchKillEnemy },
+ { "achievement.killCow", CustomStatistic::AchKillCow },
+ { "achievement.flyPig", CustomStatistic::AchFlyPig },
+ { "achievement.snipeSkeleton", CustomStatistic::AchSnipeSkeleton },
+ { "achievement.diamonds", CustomStatistic::AchDiamonds },
+ { "achievement.portal", CustomStatistic::AchPortal },
+ { "achievement.ghast", CustomStatistic::AchGhast },
+ { "achievement.blazeRod", CustomStatistic::AchBlazeRod },
+ { "achievement.potion", CustomStatistic::AchPotion },
+ { "achievement.theEnd", CustomStatistic::AchTheEnd },
+ { "achievement.theEnd2", CustomStatistic::AchTheEnd2 },
+ { "achievement.enchantments", CustomStatistic::AchEnchantments },
+ { "achievement.overkill", CustomStatistic::AchOverkill },
+ { "achievement.bookcase", CustomStatistic::AchBookcase },
+ { "achievement.exploreAllBiomes", CustomStatistic::AchExploreAllBiomes },
+ { "achievement.spawnWither", CustomStatistic::AchSpawnWither },
+ { "achievement.killWither", CustomStatistic::AchKillWither },
+ { "achievement.fullBeacon", CustomStatistic::AchFullBeacon },
+ { "achievement.breedCow", CustomStatistic::AchBreedCow },
+ { "achievement.diamondsToYou", CustomStatistic::AchDiamondsToYou },
+ { "stat.animalsBred", CustomStatistic::AnimalsBred },
+ { "stat.boatOneCm", CustomStatistic::BoatOneCm },
+ { "stat.climbOneCm", CustomStatistic::ClimbOneCm },
+ { "stat.crouchOneCm", CustomStatistic::CrouchOneCm },
+ { "stat.damageDealt", CustomStatistic::DamageDealt },
+ { "stat.damageTaken", CustomStatistic::DamageTaken },
+ { "stat.deaths", CustomStatistic::Deaths },
+ { "stat.drop", CustomStatistic::Drop },
+ { "stat.fallOneCm", CustomStatistic::FallOneCm },
+ { "stat.fishCaught", CustomStatistic::FishCaught },
+ { "stat.flyOneCm", CustomStatistic::FlyOneCm },
+ { "stat.horseOneCm", CustomStatistic::HorseOneCm },
+ { "stat.jump", CustomStatistic::Jump },
+ { "stat.leaveGame", CustomStatistic::LeaveGame },
+ { "stat.minecartOneCm", CustomStatistic::MinecartOneCm },
+ { "stat.mobKills", CustomStatistic::MobKills },
+ { "stat.pigOneCm", CustomStatistic::PigOneCm },
+ { "stat.playerKills", CustomStatistic::PlayerKills },
+ { "stat.playOneMinute", CustomStatistic::PlayOneMinute },
+ { "stat.sprintOneCm", CustomStatistic::SprintOneCm },
+ { "stat.swimOneCm", CustomStatistic::SwimOneCm },
+ { "stat.talkedToVillager", CustomStatistic::TalkedToVillager },
+ { "stat.timeSinceDeath", CustomStatistic::TimeSinceDeath },
+ { "stat.tradedWithVillager", CustomStatistic::TradedWithVillager },
+ { "stat.walkOneCm", CustomStatistic::WalkOneCm },
+ { "stat.diveOneCm", CustomStatistic::WalkUnderWaterOneCm },
+ { "stat.armorCleaned", CustomStatistic::CleanArmor },
+ { "stat.bannerCleaned", CustomStatistic::CleanBanner },
+ { "stat.cakeSlicesEaten", CustomStatistic::EatCakeSlice },
+ { "stat.itemEnchanted", CustomStatistic::EnchantItem },
+ { "stat.cauldronFilled", CustomStatistic::FillCauldron },
+ { "stat.dispenserInspected", CustomStatistic::InspectDispenser },
+ { "stat.dropperInspected", CustomStatistic::InspectDropper },
+ { "stat.hopperInspected", CustomStatistic::InspectHopper },
+ { "stat.beaconInteraction", CustomStatistic::InteractWithBeacon },
+ { "stat.brewingstandInteraction", CustomStatistic::InteractWithBrewingstand },
+ { "stat.craftingTableInteraction", CustomStatistic::InteractWithCraftingTable },
+ { "stat.furnaceInteraction", CustomStatistic::InteractWithFurnace },
+ { "stat.chestOpened", CustomStatistic::OpenChest },
+ { "stat.enderchestOpened", CustomStatistic::OpenEnderchest },
+ { "stat.noteblockPlayed", CustomStatistic::PlayNoteblock },
+ { "stat.recordPlayed", CustomStatistic::PlayRecord },
+ { "stat.flowerPotted", CustomStatistic::PotFlower },
+ { "stat.trappedChestTriggered", CustomStatistic::TriggerTrappedChest },
+ { "stat.noteblockTuned", CustomStatistic::TuneNoteblock },
+ { "stat.cauldronUsed", CustomStatistic::UseCauldron },
+ { "stat.aviateOneCm", CustomStatistic::AviateOneCm },
+ { "stat.sleepInBed", CustomStatistic::SleepInBed },
+ { "stat.sneakTime", CustomStatistic::SneakTime }
};
for (auto Entry = In.begin(); Entry != In.end(); ++Entry)
@@ -151,7 +148,7 @@ namespace StatSerializer
if ((FindResult != LegacyMapping.end()) && Entry->isInt())
{
- Manager.SetValue(FindResult->second, Entry->asUInt());
+ Manager.Custom[FindResult->second] = Entry->asUInt();
}
}
}
@@ -160,7 +157,7 @@ namespace StatSerializer
- static void LoadCustomStatFromJSON(cStatManager & Manager, const Json::Value & a_In)
+ static void LoadCustomStatFromJSON(StatisticsManager & Manager, const Json::Value & a_In)
{
for (auto it = a_In.begin(); it != a_In.end(); ++it)
{
@@ -175,7 +172,7 @@ namespace StatSerializer
const auto & StatName = StatInfo.second;
try
{
- Manager.SetValue(NamespaceSerializer::ToCustomStatistic(StatName), it->asUInt());
+ Manager.Custom[NamespaceSerializer::ToCustomStatistic(StatName)] = it->asUInt();
}
catch (const std::out_of_range &)
{
@@ -192,7 +189,7 @@ namespace StatSerializer
- void Load(cStatManager & Manager, const std::string & WorldPath, std::string && FileName)
+ void Load(StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName)
{
Json::Value Root;
InputFileStream(MakeStatisticsDirectory(WorldPath, std::move(FileName))) >> Root;
@@ -205,7 +202,7 @@ namespace StatSerializer
- void Save(const cStatManager & Manager, const std::string & WorldPath, std::string && FileName)
+ void Save(const StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName)
{
Json::Value Root;
diff --git a/src/WorldStorage/StatSerializer.h b/src/WorldStorage/StatSerializer.h
index 1a52b55b7..a178db79c 100644
--- a/src/WorldStorage/StatSerializer.h
+++ b/src/WorldStorage/StatSerializer.h
@@ -13,8 +13,7 @@
-// fwd:
-class cStatManager;
+struct StatisticsManager;
namespace Json { class Value; }
@@ -24,8 +23,8 @@ namespace Json { class Value; }
namespace StatSerializer
{
/* Try to load the player statistics. */
- void Load(cStatManager & Manager, const std::string & WorldPath, std::string && FileName);
+ void Load(StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName);
/* Try to save the player statistics. */
- void Save(const cStatManager & Manager, const std::string & WorldPath, std::string && FileName);
+ void Save(const StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName);
}