1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-15 18:57:08 +00:00

Tool specific pointing and blocking pointable type (#13992)

This commit is contained in:
cx384 2024-01-22 18:27:08 +01:00 committed by GitHub
parent fb461d21a5
commit 5958714309
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 676 additions and 67 deletions

View file

@ -8,6 +8,7 @@ set(UTIL_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pointabilities.cpp
${CMAKE_CURRENT_SOURCE_DIR}/quicktune.cpp
${CMAKE_CURRENT_SOURCE_DIR}/serialize.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sha1.cpp

147
src/util/pointabilities.cpp Normal file
View file

@ -0,0 +1,147 @@
/*
Minetest
Copyright (C) 2023 cx384
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "pointabilities.h"
#include "serialize.h"
#include "exceptions.h"
#include <sstream>
PointabilityType Pointabilities::deSerializePointabilityType(std::istream &is)
{
PointabilityType pointable_type = static_cast<PointabilityType>(readU8(is));
switch(pointable_type) {
case PointabilityType::POINTABLE:
case PointabilityType::POINTABLE_NOT:
case PointabilityType::POINTABLE_BLOCKING:
break;
default:
// Default to POINTABLE in case of unknown PointabilityType type.
pointable_type = PointabilityType::POINTABLE;
break;
}
return pointable_type;
}
void Pointabilities::serializePointabilityType(std::ostream &os, PointabilityType pointable_type)
{
writeU8(os, static_cast<u8>(pointable_type));
}
std::string Pointabilities::toStringPointabilityType(PointabilityType pointable_type)
{
switch(pointable_type) {
case PointabilityType::POINTABLE:
return "true";
case PointabilityType::POINTABLE_NOT:
return "false";
case PointabilityType::POINTABLE_BLOCKING:
return "\"blocking\"";
}
return "unknown";
}
std::optional<PointabilityType> Pointabilities::matchNode(const std::string &name,
const ItemGroupList &groups) const
{
auto i = nodes.find(name);
return i == nodes.end() ? matchGroups(groups, node_groups) : i->second;
}
std::optional<PointabilityType> Pointabilities::matchObject(const std::string &name,
const ItemGroupList &groups) const
{
auto i = objects.find(name);
return i == objects.end() ? matchGroups(groups, object_groups) : i->second;
}
std::optional<PointabilityType> Pointabilities::matchPlayer(const ItemGroupList &groups) const
{
return matchGroups(groups, object_groups);
}
std::optional<PointabilityType> Pointabilities::matchGroups(const ItemGroupList &groups,
const std::unordered_map<std::string, PointabilityType> &pointable_groups)
{
// prefers POINTABLE over POINTABLE_NOT over POINTABLE_BLOCKING
bool blocking = false;
bool not_pointable = false;
for (auto const &ability : pointable_groups) {
if (itemgroup_get(groups, ability.first) > 0) {
switch(ability.second) {
case PointabilityType::POINTABLE:
return PointabilityType::POINTABLE;
case PointabilityType::POINTABLE_NOT:
not_pointable = true;
break;
default:
blocking = true;
break;
}
}
}
if (not_pointable)
return PointabilityType::POINTABLE_NOT;
if (blocking)
return PointabilityType::POINTABLE_BLOCKING;
return std::nullopt;
}
void Pointabilities::serializeTypeMap(std::ostream &os,
const std::unordered_map<std::string, PointabilityType> &map)
{
writeU32(os, map.size());
for (const auto &entry : map) {
os << serializeString16(entry.first);
writeU8(os, (u8)entry.second);
}
}
void Pointabilities::deSerializeTypeMap(std::istream &is,
std::unordered_map<std::string, PointabilityType> &map)
{
map.clear();
u32 size = readU32(is);
for (u32 i = 0; i < size; i++) {
std::string name = deSerializeString16(is);
PointabilityType type = Pointabilities::deSerializePointabilityType(is);
map[name] = type;
}
}
void Pointabilities::serialize(std::ostream &os) const
{
writeU8(os, 0); // version
serializeTypeMap(os, nodes);
serializeTypeMap(os, node_groups);
serializeTypeMap(os, objects);
serializeTypeMap(os, object_groups);
}
void Pointabilities::deSerialize(std::istream &is)
{
int version = readU8(is);
if (version != 0)
throw SerializationError("unsupported Pointabilities version");
deSerializeTypeMap(is, nodes);
deSerializeTypeMap(is, node_groups);
deSerializeTypeMap(is, objects);
deSerializeTypeMap(is, object_groups);
}

70
src/util/pointabilities.h Normal file
View file

@ -0,0 +1,70 @@
/*
Minetest
Copyright (C) 2023 cx384
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include <string>
#include <unordered_map>
#include "itemgroup.h"
#include <optional>
#include "irrlichttypes.h"
enum class PointabilityType : u8
{
POINTABLE,
POINTABLE_NOT, // Can be pointed through.
POINTABLE_BLOCKING,
};
// An object to store overridden pointable properties
struct Pointabilities
{
// Nodes
std::unordered_map<std::string, PointabilityType> nodes;
std::unordered_map<std::string, PointabilityType> node_groups;
// Objects
std::unordered_map<std::string, PointabilityType> objects;
std::unordered_map<std::string, PointabilityType> object_groups; // armor_groups
// Match functions return fitting pointability,
// otherwise the default pointability should be used.
std::optional<PointabilityType> matchNode(const std::string &name,
const ItemGroupList &groups) const;
std::optional<PointabilityType> matchObject(const std::string &name,
const ItemGroupList &groups) const;
// For players only armor groups will work
std::optional<PointabilityType> matchPlayer(const ItemGroupList &groups) const;
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
// For a save enum conversion.
static PointabilityType deSerializePointabilityType(std::istream &is);
static void serializePointabilityType(std::ostream &os, PointabilityType pointable_type);
static std::string toStringPointabilityType(PointabilityType pointable_type);
private:
static std::optional<PointabilityType> matchGroups(const ItemGroupList &groups,
const std::unordered_map<std::string, PointabilityType> &pointable_groups);
static void serializeTypeMap(std::ostream &os,
const std::unordered_map<std::string, PointabilityType> &map);
static void deSerializeTypeMap(std::istream &is,
std::unordered_map<std::string, PointabilityType> &map);
};

View file

@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PointedThing::PointedThing(const v3s16 &under, const v3s16 &above,
const v3s16 &real_under, const v3f &point, const v3f &normal,
u16 box_id, f32 distSq):
u16 box_id, f32 distSq, PointabilityType pointab):
type(POINTEDTHING_NODE),
node_undersurface(under),
node_abovesurface(above),
@ -33,17 +33,19 @@ PointedThing::PointedThing(const v3s16 &under, const v3s16 &above,
intersection_point(point),
intersection_normal(normal),
box_id(box_id),
distanceSq(distSq)
distanceSq(distSq),
pointability(pointab)
{}
PointedThing::PointedThing(u16 id, const v3f &point,
const v3f &normal, const v3f &raw_normal, f32 distSq) :
PointedThing::PointedThing(u16 id, const v3f &point, const v3f &normal,
const v3f &raw_normal, f32 distSq, PointabilityType pointab) :
type(POINTEDTHING_OBJECT),
object_id(id),
intersection_point(point),
intersection_normal(normal),
raw_intersection_normal(raw_normal),
distanceSq(distSq)
distanceSq(distSq),
pointability(pointab)
{}
std::string PointedThing::dump() const
@ -118,12 +120,13 @@ bool PointedThing::operator==(const PointedThing &pt2) const
{
if ((node_undersurface != pt2.node_undersurface)
|| (node_abovesurface != pt2.node_abovesurface)
|| (node_real_undersurface != pt2.node_real_undersurface))
|| (node_real_undersurface != pt2.node_real_undersurface)
|| (pointability != pt2.pointability))
return false;
}
else if (type == POINTEDTHING_OBJECT)
{
if (object_id != pt2.object_id)
if (object_id != pt2.object_id || pointability != pt2.pointability)
return false;
}
return true;

View file

@ -23,8 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h"
#include <iostream>
#include <string>
#include "pointabilities.h"
enum PointedThingType : u8
enum PointedThingType :u8
{
POINTEDTHING_NOTHING,
POINTEDTHING_NODE,
@ -90,15 +91,20 @@ struct PointedThing
* ray's start point and the intersection point in irrlicht coordinates.
*/
f32 distanceSq = 0;
/*!
* How the object or node has been pointed at.
*/
PointabilityType pointability = PointabilityType::POINTABLE_NOT;
//! Constructor for POINTEDTHING_NOTHING
PointedThing() = default;
//! Constructor for POINTEDTHING_NODE
PointedThing(const v3s16 &under, const v3s16 &above,
const v3s16 &real_under, const v3f &point, const v3f &normal,
u16 box_id, f32 distSq);
u16 box_id, f32 distSq, PointabilityType pointability);
//! Constructor for POINTEDTHING_OBJECT
PointedThing(u16 id, const v3f &point, const v3f &normal, const v3f &raw_normal, f32 distSq);
PointedThing(u16 id, const v3f &point, const v3f &normal, const v3f &raw_normal, f32 distSq,
PointabilityType pointability);
std::string dump() const;
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);