Merge branch 'main' into visuals-restoration

This commit is contained in:
MihailRis 2025-12-16 01:12:00 +03:00
commit c017273374
20 changed files with 105 additions and 54 deletions

View file

@ -9,6 +9,7 @@ block.__perform_ticks = function(delta)
for id, entry in pairs(updating_blocks) do
entry.timer = entry.timer + delta
local steps = math.floor(entry.timer / entry.delta * #entry / 3)
steps = math.min(steps, #entry / 3)
if steps == 0 then
goto continue
end
@ -28,6 +29,7 @@ block.__perform_ticks = function(delta)
for id, queue in pairs(present_queues) do
queue.timer = queue.timer + delta
local steps = math.floor(queue.timer / queue.delta * #queue / 3)
steps = math.min(steps, #queue / 3)
if steps == 0 then
goto continue
end

View file

@ -523,8 +523,10 @@ function __process_post_runnables()
fn_audio_reset_fetch_buffer()
debug.pull_events()
network.__process_events()
block.__process_register_events()
block.__perform_ticks(time.delta())
if not hud or not hud.is_paused() then
block.__process_register_events()
block.__perform_ticks(time.delta())
end
end
function time.post_runnable(runnable)

View file

@ -15,9 +15,9 @@
#include "ContentPack.hpp"
ContentIndices::ContentIndices(
ContentUnitIndices<Block> blocks,
ContentUnitIndices<ItemDef> items,
ContentUnitIndices<EntityDef> entities
ContentUnitIndices<Block, blockid_t> blocks,
ContentUnitIndices<ItemDef, itemid_t> items,
ContentUnitIndices<EntityDef, entitydefid_t> entities
)
: blocks(std::move(blocks)),
items(std::move(items)),

View file

@ -36,48 +36,57 @@ public:
}
};
template <class T>
template <class T, typename IdType>
class ContentUnitIndices {
std::vector<T*> defs;
public:
ContentUnitIndices(std::vector<T*> defs) : defs(std::move(defs)) {
}
inline const T* get(blockid_t id) const {
const T* get(IdType id) const {
if (id >= defs.size()) {
return nullptr;
}
return defs[id];
}
inline const T& require(blockid_t id) const {
return *defs.at(id);
const T& require(IdType id) const {
if (id >= defs.size()) {
invalidId(id);
}
return *defs[id];
}
inline size_t count() const {
size_t count() const {
return defs.size();
}
inline const auto& getIterable() const {
const auto& getIterable() const {
return defs;
}
inline const T* const* getDefs() const {
const T* const* getDefs() const {
return defs.data();
}
private:
void invalidId(IdType id) const {
throw std::runtime_error(
"invalid content unit id: " + std::to_string(id)
);
}
};
/// @brief Runtime defs cache: indices
class ContentIndices {
public:
ContentUnitIndices<Block> blocks;
ContentUnitIndices<ItemDef> items;
ContentUnitIndices<EntityDef> entities;
ContentUnitIndices<Block, blockid_t> blocks;
ContentUnitIndices<ItemDef, itemid_t> items;
ContentUnitIndices<EntityDef, entitydefid_t> entities;
ContentIndices(
ContentUnitIndices<Block> blocks,
ContentUnitIndices<ItemDef> items,
ContentUnitIndices<EntityDef> entities
ContentUnitIndices<Block, blockid_t> blocks,
ContentUnitIndices<ItemDef, itemid_t> items,
ContentUnitIndices<EntityDef, entitydefid_t> entities
);
};

View file

@ -22,9 +22,9 @@ ContentReport::ContentReport(
regionsVersion(regionsVersion) {
}
template <class T>
template <class T, typename IdType>
static constexpr size_t get_entries_count(
const ContentUnitIndices<T>& indices, const dv::value& list
const ContentUnitIndices<T, IdType>& indices, const dv::value& list
) {
return list != nullptr ? std::max(list.size(), indices.count())
: indices.count();

View file

@ -51,7 +51,7 @@ class ContentUnitLUT {
public:
ContentUnitLUT(
size_t count,
const ContentUnitIndices<U>& unitIndices,
const ContentUnitIndices<U, T>& unitIndices,
T missingValue,
ContentType type
)

View file

@ -404,22 +404,22 @@ void BlocksRenderer::blockCube(
}
} else {
if (isOpen(coord + Z, block, variant)) {
face(coord, X, Y, Z, texfaces[5], pickLight(coord + Z), lights);
face(coord, X, Y, Z, texfaces[5], lights ? pickLight(coord + Z) : glm::vec4(1,1,1,0), lights);
}
if (isOpen(coord - Z, block, variant)) {
face(coord, -X, Y, -Z, texfaces[4], pickLight(coord - Z), lights);
face(coord, -X, Y, -Z, texfaces[4], lights ? pickLight(coord - Z) : glm::vec4(1,1,1,0), lights);
}
if (isOpen(coord + Y, block, variant)) {
face(coord, X, -Z, Y, texfaces[3], pickLight(coord + Y), lights);
face(coord, X, -Z, Y, texfaces[3], lights ? pickLight(coord + Y) : glm::vec4(1,1,1,0), lights);
}
if (isOpen(coord - Y, block, variant)) {
face(coord, X, Z, -Y, texfaces[2], pickLight(coord - Y), lights);
face(coord, X, Z, -Y, texfaces[2], lights ? pickLight(coord - Y) : glm::vec4(1,1,1,0), lights);
}
if (isOpen(coord + X, block, variant)) {
face(coord, -Z, Y, X, texfaces[1], pickLight(coord + X), lights);
face(coord, -Z, Y, X, texfaces[1], lights ? pickLight(coord + X) : glm::vec4(1,1,1,0), lights);
}
if (isOpen(coord - X, block, variant)) {
face(coord, Z, Y, -X, texfaces[0], pickLight(coord - X), lights);
face(coord, Z, Y, -X, texfaces[0], lights ? pickLight(coord - X) : glm::vec4(1,1,1,0), lights);
}
}
}

View file

@ -146,11 +146,18 @@ void GUI::actMouse(float delta, const CursorState& cursor) {
}
this->hover = hover;
auto node = hover;
while (node) {
if (mouseOver.find(hover) != mouseOver.end()) {
break;
if (std::find_if(
mouseOver.begin(),
mouseOver.end(),
[&hover](const std::weak_ptr<UINode>& weak) {
auto locked = weak.lock();
return locked && locked == hover;
}) != mouseOver.end()) {
break;
}
mouseOver.insert(node);
mouseOver.push_back(node);
node->setMouseOver(true);
auto parent = node->getParent();
if (parent) {
@ -159,12 +166,14 @@ void GUI::actMouse(float delta, const CursorState& cursor) {
}
for (auto it = mouseOver.begin(); it != mouseOver.end(); ) {
auto node = *it;
if (node->isInside(cursor.pos)) {
++it;
continue;
auto node = it->lock();
if (node) {
if (node->isInside(cursor.pos)) {
++it;
continue;
}
node->setMouseOver(false);
}
node->setMouseOver(false);
it = mouseOver.erase(it);
}
@ -270,6 +279,7 @@ void GUI::draw(const DrawContext& pctx, const Assets& assets) {
auto& page = menu->getCurrent();
if (page.panel) {
menu->setSize(page.panel->getSize());
page.panel->refresh();
if (auto panel = std::dynamic_pointer_cast<gui::Panel>(page.panel)) {
panel->cropToContent();
}

View file

@ -81,7 +81,7 @@ namespace gui {
std::unique_ptr<Camera> uicamera;
std::shared_ptr<Menu> menu;
std::queue<runnable> postRunnables;
std::set<std::shared_ptr<UINode>> mouseOver;
std::vector<std::weak_ptr<UINode>> mouseOver;
PageLoaderFunc pagesLoader;

View file

@ -1,9 +1,10 @@
#include "Inventories.hpp"
#include <algorithm>
#include "world/Level.hpp"
#include "world/World.hpp"
#include "content/Content.hpp"
#include <algorithm>
Inventories::Inventories(Level& level) : level(level) {
}
@ -32,8 +33,9 @@ std::shared_ptr<Inventory> Inventories::createVirtual(size_t size) {
});
}
void Inventories::store(const std::shared_ptr<Inventory>& inv) {
map[inv->getId()] = inv;
void Inventories::store(const std::shared_ptr<Inventory>& inventory) {
inventory->check(*level.content.getIndices());
map[inventory->getId()] = inventory;
}
void Inventories::remove(int64_t id) {

View file

@ -11,7 +11,7 @@ class Level;
using inventories_map = std::unordered_map<int64_t, std::shared_ptr<Inventory>>;
/* Inventories runtime storage */
/// @brief Inventories runtime storage
class Inventories {
Level& level;
inventories_map map;
@ -20,21 +20,22 @@ public:
Inventories(Level& level);
~Inventories();
/* Create new inventory with new id */
/// @brief Create new inventory with new id
std::shared_ptr<Inventory> create(size_t size);
/* Create runtime-only inventory (has negative id) */
/// @brief Create runtime-only inventory (has negative id)
std::shared_ptr<Inventory> createVirtual(size_t size);
/* Store inventory */
/// @brief Check and add inventory to the storage
void store(const std::shared_ptr<Inventory>& inv);
/* Remove inventory from map */
/// @brief Remove inventory from map
void remove(int64_t id);
/* Get inventory by id (works with both real and virtual)*/
/// @brief Get inventory by id (works with both real and virtual)
std::shared_ptr<Inventory> get(int64_t id);
/// @brief Create inventory non-virtual copy
std::shared_ptr<Inventory> clone(int64_t id);
const inventories_map& getMap() const;

View file

@ -1,6 +1,9 @@
#include "Inventory.hpp"
#include "content/ContentReport.hpp"
#include "debug/Logger.hpp"
static debug::Logger logger("inventory");
Inventory::Inventory(int64_t id, size_t size) : id(id), slots(size) {
}
@ -104,6 +107,22 @@ dv::value Inventory::serialize() const {
return map;
}
void Inventory::check(const ContentIndices& indices) {
for (size_t i = 0; i < slots.size(); i++) {
auto& slot = slots[i];
if (indices.items.get(slot.getItemId()) == nullptr) {
#ifdef NDEBUG
logger.error() << "invalid item id " << slot.getItemId()
<< " found in inventory #" << id << " slot #" << i
<< "; will reset";
slot.clear();
#else
abort();
#endif
}
}
}
void Inventory::convert(const ContentReport* report) {
for (auto& slot : slots) {
itemid_t id = slot.getItemId();

View file

@ -39,6 +39,7 @@ public:
dv::value serialize() const override;
void check(const ContentIndices& indices);
void convert(const ContentReport* report);
static void convert(dv::value& data, const ContentReport* report);

View file

@ -73,6 +73,7 @@ static int l_set(lua::State* L, ItemStack& item) {
if (!data.isObject() && data != nullptr) {
throw std::runtime_error("invalid data argument type (table expected)");
}
validate_itemid(itemid);
item.set(ItemStack(itemid, count, std::move(data)));
return 0;
}

View file

@ -253,9 +253,9 @@ void scripting::process_post_runnables() {
}
}
template <class T>
template <class T, typename IdType>
static int push_properties_tables(
lua::State* L, const ContentUnitIndices<T>& indices
lua::State* L, const ContentUnitIndices<T, IdType>& indices
) {
const auto units = indices.getDefs();
size_t size = indices.count();

View file

@ -4,6 +4,7 @@
#include <glm/gtx/norm.hpp>
#include "Player.hpp"
#include "content/Content.hpp"
#include "items/Inventories.hpp"
#include "world/Level.hpp"
#include "world/World.hpp"
@ -147,6 +148,6 @@ void Players::deserialize(const dv::value& src) {
if (inventory->getId() == 0) {
inventory->setId(level.getWorld()->getNextInventoryId());
}
level.inventories->store(player->getInventory());
level.inventories->store(inventory);
}
}

View file

@ -21,6 +21,7 @@ using ubyte = uint8_t;
// content indices
using itemid_t = uint32_t;
using blockid_t = uint16_t;
using entitydefid_t = uint16_t;
using entityid_t = uint64_t;
using itemcount_t = uint32_t;

View file

@ -70,7 +70,7 @@ void GlobalChunks::erase(int x, int z) {
static inline auto load_inventories(
WorldRegions& regions,
const Chunk& chunk,
const ContentUnitIndices<Block>& defs
const ContentUnitIndices<Block, blockid_t>& defs
) {
auto invs = regions.fetchInventories(chunk.x, chunk.z);
auto iterator = invs.begin();

View file

@ -11,11 +11,13 @@
#include <unordered_set>
#include <vector>
#include "typedefs.hpp"
class Block;
class Level;
class GlobalChunks;
template <typename T>
template <typename T, typename IdType>
class ContentUnitIndices;
namespace voxels {
@ -82,7 +84,7 @@ namespace voxels {
private:
const Level& level;
const GlobalChunks& chunks;
const ContentUnitIndices<Block>& blockDefs;
const ContentUnitIndices<Block, blockid_t>& blockDefs;
std::unordered_map<int, Agent> agents;
int nextAgent = 1;

View file

@ -104,9 +104,9 @@ void WorldFiles::writePacks(const std::vector<ContentPack>& packs) {
io::write_string(packsFile, ss.str());
}
template <class T>
template <class T, typename IdType>
static void write_indices(
const ContentUnitIndices<T>& indices, dv::value& list
const ContentUnitIndices<T, IdType>& indices, dv::value& list
) {
for (auto unit : indices.getIterable()) {
list.add(unit->name);