#pragma once #include #include #include namespace rage { class scrNativeCallContext { public: constexpr void reset() { m_arg_count = 0; m_data_count = 0; } template constexpr void push_arg(T&& value) { static_assert(sizeof(T) <= sizeof(std::uint64_t)); *reinterpret_cast>*>(reinterpret_cast(m_args) + (m_arg_count++)) = std::forward(value); } template constexpr T& get_arg(std::size_t index) { static_assert(sizeof(T) <= sizeof(std::uint64_t)); return *reinterpret_cast(reinterpret_cast(m_args) + index); } template constexpr void set_arg(std::size_t index, T&& value) { static_assert(sizeof(T) <= sizeof(std::uint64_t)); *reinterpret_cast>*>(reinterpret_cast(m_args) + index) = std::forward(value); } template constexpr T* get_return_value() { return reinterpret_cast(m_return_value); } template constexpr void set_return_value(T&& value) { *reinterpret_cast>*>(m_return_value) = std::forward(value); } protected: void* m_return_value; std::uint32_t m_arg_count; void* m_args; std::int32_t m_data_count; std::uint32_t m_data[48]; }; static_assert(sizeof(scrNativeCallContext) == 0xE0); using scrNativeHash = std::int64_t; using scrNativePair = std::pair; using scrNativeHandler = void(*)(scrNativeCallContext*); }