Botcraft 1.21.10
Loading...
Searching...
No Matches
Blockstate.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <bitset>
4#include <deque>
5#include <map>
6#include <string>
7#include <vector>
8
10
13
14namespace Botcraft
15{
16#if USE_GUI
17 namespace Renderer
18 {
19 class Atlas;
20 }
21#endif
22
29
30#if PROTOCOL_VERSION < 347 /* < 1.13 */
31 using BlockstateId = std::pair<int, unsigned char>;
32#else
33 using BlockstateId = unsigned int;
34#endif
35
37 {
38#if PROTOCOL_VERSION < 347 /* < 1.13 */
39 int id = -1;
40 unsigned char metadata = 0;
41#else
42 int id = -1;
43#endif
44 /// @brief True if the block is air (air, cave_air, void and structure_void are counted as air)
45 bool air = false;
46 /// @brief True if can't go through it
48 /// @brief True if not a full 1x1x1 block OR at least one face texture has transparency
49 bool transparent = false;
50 /// @brief True for lava
51 bool lava = false;
52 /// @brief True for water
53 bool water = false;
54 /// @brief True for blocks that are always waterlogged (kelp, seagrass...)
56 /// @brief True if can be used as a ladder
57 bool climbable = false;
58 /// @brief True if block can hurt when walking in/on it
59 bool hazardous = false;
60 /// @brief True if this block drops item when broken with no tool
61 bool any_tool_harvest = false;
62 /// @brief True if this block is slime
63 bool slime = false;
64 /// @brief True if this block has the BEDS tag
65 bool bed = false;
66 /// @brief True if this block is soul_sand
67 bool soul_sand = false;
68 /// @brief True if this block is honey
69 bool honey = false;
70 /// @brief True if this block is scaffolding
71 bool scaffolding = false;
72 /// @brief True if this block is cobweb
73 bool cobweb = false;
74 /// @brief True if this block is a bubble column going up
76 /// @brief True if this block is a bubble column going down
78 /// @brief True if this block is sweet_berry_bush
79 bool berry_bush = false;
80 /// @brief True if this block is powder_snow
81 bool powder_snow = false;
82 /// @brief Max horizontal offset value of the colliders (for bamboo and pointed dripstone)
83 float horizontal_offset = 0.0f;
84 /// @brief Digging hardness
85 float hardness = -2.0f;
86 /// @brief Slipperiness coefficient
87 float friction = 0.6f;
88 /// @brief True if the model is a custom one (chests/banners etc...)
89 bool custom = false;
91 std::string name = "";
92 std::string path = "";
93 std::vector<std::string> variables = std::vector<std::string>(0);
94 std::vector<BestTool> best_tools = std::vector<BestTool>(0);
96 };
97
99 {
100 public:
101 /// @brief Create a blockstate reading files from properties path
102 /// @param properties The properties of this blockstate
103 Blockstate(const BlockstateProperties& properties);
104
105 /// @brief Create a blockstate from a given model, ignoring path in properties
106 /// @param properties The properties of this blockstate
107 /// @param model_ The model of this blockstate
108 Blockstate(const BlockstateProperties& properties, const Model& model_);
109
110 BlockstateId GetId() const;
111 const Model& GetModel(const unsigned short index) const;
112 unsigned char GetModelId(const Position& pos) const;
113 size_t GetNumModels() const;
114 const std::string& GetName() const;
115 /// @brief Return a map with all the variables set for this block (powered, facing, opened...)
116 /// @return A map (note it's a copy, as it's stored in a fancy way in here to save memory°.
117 /// To access individual variable efficiently, use GetVariableValue instead
118 std::map<std::string, std::string> GetVariables() const;
119 /// @brief Access the value of the variable
120 /// @param variable The key to fetch (must exist for this blockstate, you can fetch all existing values with GetVariables instead)
121 /// @return The string value of this variable as defined in Blocks.json
122 const std::string& GetVariableValue(const std::string& variable) const;
124 std::set<AABB> GetCollidersAtPos(const Position& pos) const;
125 /// @brief Get the closest point on this blockstate placed at block_pos from a reference pos
126 /// @param block_pos Block position
127 /// @param pos Reference position to find the closest point from
128 /// @return The closest point inside the block AABB shapes
129 Vector3<double> GetClosestPoint(const Position& block_pos, const Vector3<double>& pos) const;
130
131 bool IsAir() const;
132 bool IsSolid() const;
133 bool IsTransparent() const;
134 bool IsFluid() const;
135 bool IsFluidOrWaterlogged() const;
136 bool IsLava() const;
137 bool IsFluidFalling() const;
138 bool IsWater() const;
139 bool IsWaterlogged() const;
140 bool IsWaterOrWaterlogged() const;
141 bool IsClimbable() const;
142 bool IsHazardous() const;
143 bool IsSlime() const;
144 bool IsBed() const;
145 bool IsSoulSand() const;
146 bool IsHoney() const;
147 bool IsScaffolding() const;
148 bool IsCobweb() const;
149 bool IsBubbleColumn() const;
150 bool IsUpBubbleColumn() const;
151 bool IsDownBubbleColumn() const;
152 bool IsBerryBush() const;
153 bool IsPowderSnow() const;
154
155 bool CanJumpWhenFeetInside() const;
156
157 float GetHardness() const;
158 float GetFriction() const;
159 TintType GetTintType() const;
160 /// @brief Get fluid height for this block. Does not take into account neighbouring blocks
161 /// @return Height of fluid in this block, between 0 and 1
162 float GetFluidHeight() const;
163
164 /// @brief Compute the amount of time (in s) required to mine this block
165 /// @param tool_type The tool used to mine
166 /// @param tool_material The material the tool is made of
167 /// @param tool_efficiency_additional_speed Additional speed added by current tool level of efficiency enchantment (efficiency˛ + (efficiency > 0))
168 /// @param haste Level of haste applied to the player
169 /// @param fatigue Level of mining fatigue applied to the player
170 /// @param on_ground Boolean indicating whether or not the player is currently on the ground
171 /// @param speed_factor Speed multiplier to apply (e.g. 0.2 if under water with no aqua affinity)
172 /// @return The time required to mine this block in these conditions, or -1 if can't be mined
173 float GetMiningTimeSeconds(const ToolType tool_type, const ToolMaterial tool_material,
174 const float tool_efficiency_additional_speed = 0.0f, const unsigned char haste = 0, const unsigned char fatigue = 0,
175 const bool on_ground = true, const float speed_factor = 1.0f) const;
176
177#if PROTOCOL_VERSION < 347 /* < 1.13 */
178 static unsigned int IdMetadataToId(const int id_, const unsigned char metadata_);
179 static void IdToIdMetadata(const unsigned int input_id, int& output_id, unsigned char& output_metadata);
180#endif
181 static void ClearCache();
182
183#if USE_GUI
184 static void UpdateModelsWithAtlasData(const Renderer::Atlas* atlas);
185#endif
186
187 private:
188 void LoadProperties(const BlockstateProperties& properties);
189 void LoadWeightedModels(const std::deque<std::pair<Model, int>>& models_to_load);
190 bool GetBoolFromCondition(const ProtocolCraft::Json::Value& condition) const;
191 /// @brief Check if a given string condition match this blockstate variables
192 /// @param condition String to check, example: "layers=1"
193 /// @return True if variables values match, false otherwise
194 bool MatchCondition(const std::string& condition) const;
195
196 // std::set does not invalidate pointers when growing
197 static std::set<std::string> unique_strings;
198 static const std::string* GetUniqueStringPtr(const std::string& s);
199 static std::deque<Model> unique_models;
200 static size_t GetUniqueModelIndex(const Model& model);
201 static std::map<std::string, ProtocolCraft::Json::Value> cached_jsons;
202
204 {
205 bool operator()(const std::string* a, const std::string* b) const
206 {
207 return *a < *b;
208 }
209 };
210
211 private:
213
214
215 enum class BlockstateFlags : size_t
216 {
217 Air = 0,
218 Solid,
220 Lava,
221 Water,
227 Climbable,
228 Hazardous,
230 Slime,
231 Bed,
232 SoulSand,
233 Honey,
235 Cobweb,
238 BerryBush,
243 };
244
245 std::bitset<static_cast<size_t>(BlockstateFlags::NUM_FLAGS)> flags;
246 float hardness;
247 float friction;
249 const std::string* m_name;
250
251 std::vector<size_t> models_indices;
252 std::vector<int> models_weights;
254
255 std::vector<BestTool> best_tools;
256
257 std::map<const std::string*, const std::string*, string_ptr_compare> variables; // map is smaller in RAM than unordered_map
258 };
259} // Botcraft
bool IsHazardous() const
bool IsBerryBush() const
Vector3< double > GetClosestPoint(const Position &block_pos, const Vector3< double > &pos) const
Get the closest point on this blockstate placed at block_pos from a reference pos.
static const std::string * GetUniqueStringPtr(const std::string &s)
bool IsWaterOrWaterlogged() const
const std::string & GetName() const
bool IsCobweb() const
BlockstateId GetId() const
bool IsDownBubbleColumn() const
bool IsTransparent() const
bool IsFluidOrWaterlogged() const
bool IsClimbable() const
static std::set< std::string > unique_strings
bool MatchCondition(const std::string &condition) const
Check if a given string condition match this blockstate variables.
std::set< AABB > GetCollidersAtPos(const Position &pos) const
std::vector< size_t > models_indices
unsigned char GetModelId(const Position &pos) const
std::map< const std::string *, const std::string *, string_ptr_compare > variables
bool CanJumpWhenFeetInside() const
void LoadWeightedModels(const std::deque< std::pair< Model, int > > &models_to_load)
float GetHardness() const
bool IsFluidFalling() const
bool IsBubbleColumn() const
TintType GetTintType() const
bool IsPowderSnow() const
Vector3< double > GetHorizontalOffsetAtPos(const Position &pos) const
size_t GetNumModels() const
std::map< std::string, std::string > GetVariables() const
Return a map with all the variables set for this block (powered, facing, opened......
void LoadProperties(const BlockstateProperties &properties)
static void UpdateModelsWithAtlasData(const Renderer::Atlas *atlas)
std::vector< int > models_weights
std::vector< BestTool > best_tools
bool IsUpBubbleColumn() const
static std::deque< Model > unique_models
bool IsWaterlogged() const
std::bitset< static_cast< size_t >(BlockstateFlags::NUM_FLAGS)> flags
BlockstateId blockstate_id
float GetFriction() const
const std::string * m_name
static void ClearCache()
static size_t GetUniqueModelIndex(const Model &model)
float GetFluidHeight() const
Get fluid height for this block.
const std::string & GetVariableValue(const std::string &variable) const
Access the value of the variable.
static std::map< std::string, ProtocolCraft::Json::Value > cached_jsons
bool IsScaffolding() const
bool IsSoulSand() const
const Model & GetModel(const unsigned short index) const
float GetMiningTimeSeconds(const ToolType tool_type, const ToolMaterial tool_material, const float tool_efficiency_additional_speed=0.0f, const unsigned char haste=0, const unsigned char fatigue=0, const bool on_ground=true, const float speed_factor=1.0f) const
Compute the amount of time (in s) required to mine this block.
bool GetBoolFromCondition(const ProtocolCraft::Json::Value &condition) const
Main class, basically a JsonVariant with extra utility functions it doesn't inherit JsonVariant direc...
Definition Json.hpp:45
unsigned int BlockstateId
ToolMaterial min_material
bool climbable
True if can be used as a ladder.
bool powder_snow
True if this block is powder_snow.
ProtocolCraft::Json::Value down_bubble_column
True if this block is a bubble column going down.
bool cobweb
True if this block is cobweb.
bool water
True for water.
std::vector< std::string > variables
bool honey
True if this block is honey.
float friction
Slipperiness coefficient.
std::vector< BestTool > best_tools
bool slime
True if this block is slime.
float horizontal_offset
Max horizontal offset value of the colliders (for bamboo and pointed dripstone)
float hardness
Digging hardness.
bool berry_bush
True if this block is sweet_berry_bush.
ProtocolCraft::Json::Value colliders
bool transparent
True if not a full 1x1x1 block OR at least one face texture has transparency.
ProtocolCraft::Json::Value solid
True if can't go through it.
bool soul_sand
True if this block is soul_sand.
bool custom
True if the model is a custom one (chests/banners etc...)
ProtocolCraft::Json::Value waterlogged
True for blocks that are always waterlogged (kelp, seagrass...)
bool any_tool_harvest
True if this block drops item when broken with no tool.
bool air
True if the block is air (air, cave_air, void and structure_void are counted as air)
bool hazardous
True if block can hurt when walking in/on it.
ProtocolCraft::Json::Value up_bubble_column
True if this block is a bubble column going up.
bool scaffolding
True if this block is scaffolding.
bool bed
True if this block has the BEDS tag.
bool operator()(const std::string *a, const std::string *b) const