Skip to content

Commit 4dfc765

Browse files
committed
fix(Lua): handles enum value pushing/setting based on size
Improves enum property handling by dynamically determining the underlying type size and signedness rather than using uint8 for all.
1 parent f0329fd commit 4dfc765

File tree

1 file changed

+51
-6
lines changed

1 file changed

+51
-6
lines changed

UE4SS/src/LuaType/LuaUObject.cpp

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,16 +1497,61 @@ namespace RC::LuaType
14971497
table.make_global(prop_name);
14981498
// Make global table to store enum name/value pairs -> END
14991499

1500-
// Push the actual enum value to the Lua stack
1501-
params.lua.set_integer(*static_cast<uint8_t*>(params.data));
1500+
// Push the enum value to the Lua stack based on underlying type size and signedness
1501+
auto underlying_prop = static_cast<Unreal::FEnumProperty*>(params.property)->GetUnderlyingProperty();
1502+
auto cast_flags = underlying_prop->GetClass().GetClassCastFlags();
1503+
constexpr auto unsigned_flags = Unreal::CASTCLASS_FByteProperty | Unreal::CASTCLASS_FUInt16Property |
1504+
Unreal::CASTCLASS_FUInt32Property | Unreal::CASTCLASS_FUInt64Property;
1505+
bool is_unsigned = (cast_flags & unsigned_flags) != 0;
1506+
1507+
switch (underlying_prop->GetElementSize())
1508+
{
1509+
case 1:
1510+
params.lua.set_integer(is_unsigned ? static_cast<int64_t>(*static_cast<uint8_t*>(params.data))
1511+
: static_cast<int64_t>(*static_cast<int8_t*>(params.data)));
1512+
break;
1513+
case 2:
1514+
params.lua.set_integer(is_unsigned ? static_cast<int64_t>(*static_cast<uint16_t*>(params.data))
1515+
: static_cast<int64_t>(*static_cast<int16_t*>(params.data)));
1516+
break;
1517+
case 4:
1518+
params.lua.set_integer(is_unsigned ? static_cast<int64_t>(*static_cast<uint32_t*>(params.data))
1519+
: static_cast<int64_t>(*static_cast<int32_t*>(params.data)));
1520+
break;
1521+
case 8:
1522+
params.lua.set_integer(*static_cast<int64_t*>(params.data));
1523+
break;
1524+
default:
1525+
params.throw_error("push_enumproperty", "Unsupported enum underlying type size");
1526+
break;
1527+
}
15021528

15031529
return;
15041530
}
1505-
case Operation::Set:
1506-
// TODO: Verify that this works
1507-
// TODO: Bounds checking to make sure we don't set an invalid uint8_t because Lua can send us up to 64 bits
1508-
*static_cast<uint8_t*>(params.data) = static_cast<uint8_t>(params.lua.get_integer(params.stored_at_index));
1531+
case Operation::Set: {
1532+
// For Set, signedness doesn't matter - bit pattern is preserved
1533+
auto underlying_prop = static_cast<Unreal::FEnumProperty*>(params.property)->GetUnderlyingProperty();
1534+
int64_t value = params.lua.get_integer(params.stored_at_index);
1535+
switch (underlying_prop->GetElementSize())
1536+
{
1537+
case 1:
1538+
*static_cast<uint8_t*>(params.data) = static_cast<uint8_t>(value);
1539+
break;
1540+
case 2:
1541+
*static_cast<uint16_t*>(params.data) = static_cast<uint16_t>(value);
1542+
break;
1543+
case 4:
1544+
*static_cast<uint32_t*>(params.data) = static_cast<uint32_t>(value);
1545+
break;
1546+
case 8:
1547+
*static_cast<uint64_t*>(params.data) = static_cast<uint64_t>(value);
1548+
break;
1549+
default:
1550+
params.throw_error("push_enumproperty", "Unsupported enum underlying type size");
1551+
break;
1552+
}
15091553
return;
1554+
}
15101555
case Operation::GetParam:
15111556
// TODO: Verify that this works
15121557
RemoteUnrealParam::construct(params.lua, params.data, params.base, params.property);

0 commit comments

Comments
 (0)