1
0
mirror of https://github.com/luanti-org/luanti.git synced 2026-01-01 10:45:32 +01:00

Clarify that punch toolcaps are not optional (#16720)

This commit is contained in:
sfan5
2025-12-28 15:30:25 +01:00
committed by GitHub
parent f18d122a8e
commit 1dbb3eae32
17 changed files with 69 additions and 85 deletions

View File

@@ -1791,8 +1791,8 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
const ItemStack *hand_item, float time_from_last_punch)
{
assert(punchitem); // pre-condition
const ToolCapabilities *toolcap =
&punchitem->getToolCapabilities(m_client->idef(), hand_item);
const ToolCapabilities &toolcap =
punchitem->getToolCapabilities(m_client->idef(), hand_item);
PunchDamageResult result = getPunchDamage(
m_armor_groups,
toolcap,

View File

@@ -1046,7 +1046,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
ItemStack selected_item, hand_item;
ItemStack tool_item = playersao->getWieldedItem(&selected_item, &hand_item);
ToolCapabilities toolcap =
const ToolCapabilities &toolcap =
tool_item.getToolCapabilities(m_itemdef, &hand_item);
v3f dir = (pointed_object->getBasePosition() -
(playersao->getBasePosition() + playersao->getEyeOffset())
@@ -1054,7 +1054,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
float time_from_last_punch =
playersao->resetTimeFromLastPunch();
u32 wear = pointed_object->punch(dir, &toolcap, playersao,
u32 wear = pointed_object->punch(dir, toolcap, playersao,
time_from_last_punch, tool_item.wear);
// Callback may have changed item, so get it again

View File

@@ -1665,9 +1665,11 @@ ToolCapabilities read_tool_capabilities(
lua_State *L, int table)
{
ToolCapabilities toolcap;
luaL_checktype(L, table, LUA_TTABLE);
getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
getintfield(L, table, "punch_attack_uses", toolcap.punch_attack_uses);
lua_getfield(L, table, "groupcaps");
if(lua_istable(L, -1)){
int table_groupcaps = lua_gettop(L);
@@ -1686,7 +1688,7 @@ ToolCapabilities read_tool_capabilities(
float maxwear = 0;
if (getfloatfield(L, table_groupcap, "maxwear", maxwear)){
if (maxwear != 0)
groupcap.uses = 1.0/maxwear;
groupcap.uses = 1.0f/maxwear;
else
groupcap.uses = 0;
warningstream << "Field \"maxwear\" is deprecated; "
@@ -1748,7 +1750,7 @@ PointabilityType read_pointability_type(lua_State *L, int index)
return PointabilityType::POINTABLE_BLOCKING;
}
}
throw LuaError("Invalid pointable type.");
throw LuaError("Invalid pointable type");
}
/******************************************************************************/
@@ -1756,6 +1758,7 @@ Pointabilities read_pointabilities(lua_State *L, int index)
{
Pointabilities pointabilities;
luaL_checktype(L, index, LUA_TTABLE);
lua_getfield(L, index, "nodes");
if(lua_istable(L, -1)){
int ti = lua_gettop(L);
@@ -1815,6 +1818,9 @@ void push_pointability_type(lua_State *L, PointabilityType pointable)
case PointabilityType::POINTABLE_BLOCKING:
lua_pushliteral(L, "blocking");
break;
default:
assert(false);
break;
}
}

View File

@@ -247,7 +247,7 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime,
// tool_capabilities, direction, damage)
bool ScriptApiEntity::luaentity_Punch(u16 id,
ServerActiveObject *puncher, float time_from_last_punch,
const ToolCapabilities *toolcap, v3f dir, s32 damage)
const ToolCapabilities &toolcap, v3f dir, s32 damage)
{
SCRIPTAPI_PRECHECKHEADER
@@ -270,7 +270,7 @@ bool ScriptApiEntity::luaentity_Punch(u16 id,
else
lua_pushnil(L);
lua_pushnumber(L, time_from_last_punch);
push_tool_capabilities(L, *toolcap);
push_tool_capabilities(L, toolcap);
push_v3f(L, dir);
lua_pushnumber(L, damage);

View File

@@ -28,7 +28,7 @@ public:
const collisionMoveResult *moveresult);
bool luaentity_Punch(u16 id,
ServerActiveObject *puncher, float time_from_last_punch,
const ToolCapabilities *toolcap, v3f dir, s32 damage);
const ToolCapabilities &toolcap, v3f dir, s32 damage);
bool luaentity_on_death(u16 id, ServerActiveObject *killer);
void luaentity_Rightclick(u16 id, ServerActiveObject *clicker);
void luaentity_on_attach_child(u16 id, ServerActiveObject *child);

View File

@@ -42,7 +42,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player, const PlayerHPCha
bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
ServerActiveObject *hitter,
float time_from_last_punch,
const ToolCapabilities *toolcap,
const ToolCapabilities &toolcap,
v3f dir,
s32 damage)
{
@@ -57,7 +57,7 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
else
lua_pushnil(L);
lua_pushnumber(L, time_from_last_punch);
push_tool_capabilities(L, *toolcap);
push_tool_capabilities(L, toolcap);
push_v3f(L, dir);
lua_pushnumber(L, damage);
runCallbacks(6, RUN_CALLBACKS_MODE_OR);

View File

@@ -30,7 +30,7 @@ public:
void on_leaveplayer(ServerActiveObject *player, bool timeout);
void on_cheat(ServerActiveObject *player, const std::string &cheat_type);
bool on_punchplayer(ServerActiveObject *player, ServerActiveObject *hitter,
float time_from_last_punch, const ToolCapabilities *toolcap,
float time_from_last_punch, const ToolCapabilities &toolcap,
v3f dir, s32 damage);
void on_rightclickplayer(ServerActiveObject *player, ServerActiveObject *clicker);
s32 on_player_hpchange(ServerActiveObject *player, s32 hp_change,

View File

@@ -204,7 +204,7 @@ int ObjectRef::l_punch(lua_State *L)
return 0;
float time_from_last_punch = readParam<float>(L, 3, 1000000.0f);
ToolCapabilities toolcap = read_tool_capabilities(L, 4);
ToolCapabilities toolcap = read_tool_capabilities(L, 4); // not optional!
v3f dir;
if (puncher) {
dir = readParam<v3f>(L, 5, sao->getBasePosition() - puncher->getBasePosition());
@@ -213,7 +213,7 @@ int ObjectRef::l_punch(lua_State *L)
dir = readParam<v3f>(L, 5, v3f(0));
}
u32 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch);
u32 wear = sao->punch(dir, toolcap, puncher, time_from_last_punch);
lua_pushnumber(L, wear);
return 1;

View File

@@ -195,12 +195,12 @@ int ModApiUtil::l_get_dig_params(lua_State *L)
int ModApiUtil::l_get_hit_params(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
std::unordered_map<std::string, int> groups;
ItemGroupList groups;
read_groups(L, 1, groups);
ToolCapabilities tp = read_tool_capabilities(L, 2);
float time_from_last_punch = readParam<float>(L, 3, 1000000);
int wear = readParam<int>(L, 4, 0);
push_hit_params(L, getHitParams(groups, &tp,
push_hit_params(L, getHitParams(groups, tp,
time_from_last_punch, wear));
return 1;
}

View File

@@ -323,7 +323,7 @@ void LuaEntitySAO::getStaticData(std::string *result) const
}
u32 LuaEntitySAO::punch(v3f dir,
const ToolCapabilities *toolcap,
const ToolCapabilities &toolcap,
ServerActiveObject *puncher,
float time_from_last_punch,
u16 initial_wear)

View File

@@ -29,7 +29,7 @@ public:
bool shouldUnload() const { return true; }
void getStaticData(std::string *result) const;
u32 punch(v3f dir, const ToolCapabilities *toolcap = nullptr,
u32 punch(v3f dir, const ToolCapabilities &toolcap,
ServerActiveObject *puncher = nullptr,
float time_from_last_punch = 1000000.0f,
u16 initial_wear = 0);

View File

@@ -450,14 +450,11 @@ void PlayerSAO::setLookPitchAndSend(const float pitch)
}
u32 PlayerSAO::punch(v3f dir,
const ToolCapabilities *toolcap,
const ToolCapabilities &toolcap,
ServerActiveObject *puncher,
float time_from_last_punch,
u16 initial_wear)
{
if (!toolcap)
return 0;
// No effect if PvP disabled or if immortal
if (isImmortal() || !g_settings->getBool("enable_pvp")) {
if (puncher && puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {

View File

@@ -101,7 +101,7 @@ public:
Interaction interface
*/
u32 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher,
u32 punch(v3f dir, const ToolCapabilities &toolcap, ServerActiveObject *puncher,
float time_from_last_punch, u16 initial_wear = 0) override;
void rightClick(ServerActiveObject *clicker) override;
void setHP(s32 hp, const PlayerHPChangeReason &reason) override
@@ -141,7 +141,7 @@ public:
float resetTimeFromLastPunch()
{
float r = m_time_from_last_punch;
m_time_from_last_punch = 0.0;
m_time_from_last_punch = 0;
return r;
}
void noCheatDigStart(const v3s16 &p)

View File

@@ -129,7 +129,7 @@ public:
// Returns added tool wear
virtual u32 punch(v3f dir,
const ToolCapabilities *toolcap = nullptr,
const ToolCapabilities &toolcap,
ServerActiveObject *puncher = nullptr,
float time_from_last_punch = 1000000.0f,
u16 initial_wear = 0)

View File

@@ -421,21 +421,21 @@ DigParams getDigParams(const ItemGroupList &groups,
}
HitParams getHitParams(const ItemGroupList &armor_groups,
const ToolCapabilities *tp, float time_from_last_punch,
const ToolCapabilities &tp, float time_from_last_punch,
u16 initial_wear)
{
s32 damage = 0;
float result_wear = 0.0f;
float punch_interval_multiplier =
rangelim(time_from_last_punch / tp->full_punch_interval, 0.0f, 1.0f);
rangelim(time_from_last_punch / tp.full_punch_interval, 0.0f, 1.0f);
for (const auto &damageGroup : tp->damageGroups) {
for (const auto &damageGroup : tp.damageGroups) {
s16 armor = itemgroup_get(armor_groups, damageGroup.first);
damage += damageGroup.second * punch_interval_multiplier * armor / 100.0;
}
if (tp->punch_attack_uses > 0) {
result_wear = calculateResultWear(tp->punch_attack_uses, initial_wear);
if (tp.punch_attack_uses > 0) {
result_wear = calculateResultWear(tp.punch_attack_uses, initial_wear);
result_wear *= punch_interval_multiplier;
}
// Keep damage in sane bounds for simplicity
@@ -445,36 +445,30 @@ HitParams getHitParams(const ItemGroupList &armor_groups,
return {damage, wear_i};
}
HitParams getHitParams(const ItemGroupList &armor_groups,
const ToolCapabilities *tp)
{
return getHitParams(armor_groups, tp, 1000000);
}
PunchDamageResult getPunchDamage(
const ItemGroupList &armor_groups,
const ToolCapabilities *toolcap,
const ToolCapabilities &toolcap,
const ItemStack *punchitem,
float time_from_last_punch,
u16 initial_wear
){
bool do_hit = true;
{
if (do_hit && punchitem) {
if (itemgroup_get(armor_groups, "punch_operable") &&
(toolcap == NULL || punchitem->name.empty()))
do_hit = false;
}
if (do_hit && punchitem) {
// FIXME: punch_operable is supposed to apply to "non-tool" items too
// 1. We don't have the itemdef available here to check
// 2. how is this supposed to interact with overridable toolcaps?
if (itemgroup_get(armor_groups, "punch_operable") &&
punchitem->name.empty())
do_hit = false;
}
if (do_hit) {
if(itemgroup_get(armor_groups, "immortal"))
do_hit = false;
}
if (do_hit) {
if (itemgroup_get(armor_groups, "immortal"))
do_hit = false;
}
PunchDamageResult result;
if(do_hit)
{
if (do_hit) {
HitParams hitparams = getHitParams(armor_groups, toolcap,
time_from_last_punch,
punchitem ? punchitem->wear : 0);

View File

@@ -149,11 +149,14 @@ struct HitParams
};
HitParams getHitParams(const ItemGroupList &armor_groups,
const ToolCapabilities *tp, float time_from_last_punch,
const ToolCapabilities &tp, float time_from_last_punch,
u16 initial_wear = 0);
HitParams getHitParams(const ItemGroupList &armor_groups,
const ToolCapabilities *tp);
inline HitParams getHitParams(const ItemGroupList &armor_groups,
const ToolCapabilities &tp)
{
return getHitParams(armor_groups, tp, 1000000);
}
struct PunchDamageResult
{
@@ -168,12 +171,13 @@ struct ItemStack;
PunchDamageResult getPunchDamage(
const ItemGroupList &armor_groups,
const ToolCapabilities *toolcap,
const ToolCapabilities &toolcap,
const ItemStack *punchitem,
float time_from_last_punch,
u16 initial_wear = 0
);
u32 calculateResultWear(const u32 uses, const u16 initial_wear);
f32 getToolRange(const ItemStack &wielded_item, const ItemStack &hand_item,
const IItemDefManager *itemdef_manager);