Skip to content

Commit

Permalink
dnf hitboxes updated
Browse files Browse the repository at this point in the history
  • Loading branch information
WistfulHopes committed Mar 7, 2024
1 parent f847458 commit 1be30c4
Show file tree
Hide file tree
Showing 13 changed files with 1,137 additions and 1 deletion.
1 change: 1 addition & 0 deletions DNFHitboxes/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/x64
15 changes: 15 additions & 0 deletions DNFHitboxes/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.18)

set(TARGET DNFHitboxes)
project(${TARGET})

set(${TARGET}_Sources
"${CMAKE_CURRENT_SOURCE_DIR}/src/arcsys.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/dllmain.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/math_util.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/sigscan.cpp"
)

add_library(${TARGET} SHARED ${${TARGET}_Sources})
target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(${TARGET} PUBLIC UE4SS)
2 changes: 2 additions & 0 deletions DNFHitboxes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# StriveHitboxes-UE4SS
Strive hitbox viewer for UE4SS.
140 changes: 140 additions & 0 deletions DNFHitboxes/include/arcsys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#pragma once

#include <Unreal/AActor.hpp>
#include "struct_util.h"

void ASWInitFunctions();

bool IsValidUObject(RC::Unreal::UObject* Object);

struct FVector
{
float X, Y, Z;
};

class AGameState : public RC::Unreal::AActor {};

class UWorld : public RC::Unreal::UObject {
public:
FIELD(0x130, AGameState*, GameState);
};

class AREDGameState_Battle : public AGameState {
public:
FIELD(0xB10, class asw_engine*, Engine);
FIELD(0xB18, class asw_scene*, Scene);
};

AREDGameState_Battle* GetGameState();

class player_block {
char pad[0x280];
public:
FIELD(0x10, class asw_entity*, entity);
};

static_assert(sizeof(player_block) == 0x280);

// Used by the shared GG/BB/DBFZ engine code
class asw_engine {
public:
static constexpr auto COORD_SCALE = .43f; // 458f

static asw_engine *get();

ARRAY_FIELD(0x0, player_block[2], players);
FIELD(0xAE0, int, entity_count);
ARRAY_FIELD(0x1170, class asw_entity*[110], entities);
};


class asw_scene {
public:
static asw_scene *get();

// "delta" is the difference between input and output position
// position gets written in place
// position/angle can be null
void camera_transform(FVector *delta, FVector *position, FVector *angle) const;
void camera_transform(FVector *position, FVector *angle) const;
};

class hitbox {
public:
enum class box_type : int {
hurt = 0,
hit = 1,
grab = 2 // Not used by the game
};

box_type type;
float x, y;
float w, h;
};

enum class direction : int {
right = 0,
left = 1
};

class asw_entity {
public:
//FIELD(0x28, int, is_active_value);
FIELD(0x15, bool, is_player);
FIELD(0x50, unsigned int, player_index);
FIELD(0x90, hitbox*, hitboxes);
FIELD(0x134, int, hurtbox_count);
FIELD(0x138, int, hitbox_count);

// _____ ____ _ _ _ _ _______ ______ _____
// / ____| / __ \ | | | | | \ | | |__ __| | ____| | __ \
// | | | | | | | | | | | \| | | | | |__ | |__) |
// | | | | | | | | | | | . ` | | | | __| | _ /
// | |____ | |__| | | |__| | | |\ | | | | |____ | | \ \
// \_____| \____/ \____/ |_| \_| |_| |______| |_| \_\
BIT_FIELD(0x198, 0x4000000, cinematic_counter);
FIELD(0x1B8, int, state_frames); //outdated*bad offset
FIELD(0x2A8, asw_entity*, opponent); //outdated*bad offset
// FIELD(0x2BC, asw_entity*, parent); //outdated*bad offset
FIELD(0x318, asw_entity*, attached); //outdated*bad offset

BIT_FIELD(0x364, 1, airborne);
BIT_FIELD(0x364, 0x8000000, counterhit);

BIT_FIELD(0x378, 16, strike_invuln);
BIT_FIELD(0x378, 32, throw_invuln);
BIT_FIELD(0x378, 64, wakeup);

FIELD(0x384, direction, facing);

FIELD(0x388, int, pos_x);
FIELD(0x38C, int, pos_y);
FIELD(0x390, int, pos_z);
FIELD(0x3A0, int, angle_x);
FIELD(0x3A4, int, angle_y);
FIELD(0x3A8, int, angle_z);
FIELD(0x3BC, int, scale_x);
FIELD(0x3C0, int, scale_y);
FIELD(0x3C4, int, scale_z);

FIELD(0x59C, int, pushbox_front_offset);

FIELD(0x868, int, throw_box_top); // 0x860
FIELD(0x86C, int, throw_box_bottom); // 0x868
FIELD(0x870, int, throw_range); // 0x86C


FIELD( 0x3E48, unsigned int, is_active_player_bit );
//FIELD(0x828, int, backdash_invuln); //850

bool is_active() const;
bool is_pushbox_active() const;
bool is_strike_invuln() const;
bool is_throw_invuln() const;
int get_pos_x() const;
int get_pos_y() const;
int pushbox_width() const;
int pushbox_height() const;
int pushbox_bottom() const;
void get_pushbox(int *left, int *top, int *right, int *bottom) const;
};
20 changes: 20 additions & 0 deletions DNFHitboxes/include/bitmask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

template<size_t N>
class bitmask {
unsigned int words[(N + 31) / 32];

public:
bool get(int bit)
{
return words[bit / 32] >> (bit % 32);
}

void set(int bit, bool value)
{
if (value)
words[bit / 32] |= 1 << (bit % 32);
else
words[bit / 32] &= ~(1 << (bit % 32));
}
};
73 changes: 73 additions & 0 deletions DNFHitboxes/include/math_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once
#include <cmath>

struct FVector2D {
float X, Y;

FVector2D()
: X(0)
, Y(0) {}
FVector2D(float X, float Y)
: X(X)
, Y(Y) {}
FVector2D(double X, double Y)
: X(static_cast<float>(X))
, Y(static_cast<float>(Y)) {}
FVector2D(int X, int Y)
: X(static_cast<float>(X))
, Y(static_cast<float>(Y)) {}

FVector2D Rotate(const float angle) const
{
const auto ca = cosf(angle);
const auto sa = sinf(angle);
return FVector2D(X * ca + Y * -sa, X * sa + Y * ca);
}

float SizeSquared() const
{
return X * X + Y * Y;
}

float Size() const
{
return sqrt(SizeSquared());
}

FVector2D operator+(const FVector2D& other) const
{
return FVector2D(X + other.X, Y + other.Y);
}

FVector2D operator-(const FVector2D& other) const
{
return FVector2D(X - other.X, Y - other.Y);
}

FVector2D operator*(float scalar) const
{
return FVector2D(X * scalar, Y * scalar);
}

FVector2D operator/(float scalar) const
{
return FVector2D(X / scalar, Y / scalar);
}
};

template<typename T>
T min_(T a, T b)
{
return a < b ? a : b;
}

template<typename T>
T max_(T a, T b)
{
return a > b ? a : b;
}

bool line_box_intersection(
const FVector2D& box_min, const FVector2D& box_max,
const FVector2D& line_a, const FVector2D& line_b,
float* entry_fraction, float* exit_fraction);
21 changes: 21 additions & 0 deletions DNFHitboxes/include/sigscan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <cstdint>

class sigscan
{
uintptr_t start, end;

public:
sigscan(const char *name);

// Needs a singleton so it can be used in global initializers
static const sigscan &get();

uintptr_t scan(const char *sig, const char *mask) const;
};

inline void *get_rip_relative(uintptr_t offset)
{
return (void*)(offset + 4 + *(int32_t*)offset);
}
58 changes: 58 additions & 0 deletions DNFHitboxes/include/struct_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once

#include <type_traits>

template<typename T>
using array_elem_type = std::remove_reference_t<decltype(std::declval<T>()[0])>;

template<typename T>
constexpr auto array_elem_count = sizeof(std::declval<T>()) / sizeof(std::declval<T>()[0]);

#define FIELD(OFFSET, TYPE, NAME) \
void set_##OFFSET(std::add_const_t<std::add_lvalue_reference_t<TYPE>> value) \
{ \
*(std::add_pointer_t<TYPE>)((char*)this + OFFSET) = value; \
} \
\
void set_##OFFSET(std::add_rvalue_reference_t<TYPE> value) \
{ \
*(std::add_pointer_t<TYPE>)((char*)this + OFFSET) = std::move(value); \
} \
\
std::add_lvalue_reference_t<TYPE> get_##OFFSET() const \
{ \
return *(std::add_pointer_t<TYPE>)((char*)this + OFFSET); \
} \
__declspec(property(get=get_##OFFSET, put=set_##OFFSET)) TYPE NAME

#define ARRAY_FIELD(OFFSET, TYPE, NAME) \
void set_##OFFSET(int index, std::add_const_t<std::add_lvalue_reference_t<array_elem_type<TYPE>>> value) \
{ \
((std::decay_t<TYPE>)((char*)this + OFFSET))[index] = value; \
} \
\
void set_##OFFSET(int index, std::add_rvalue_reference_t<array_elem_type<TYPE>> value) \
{ \
((std::decay_t<TYPE>)((char*)this + OFFSET))[index] = std::move(value); \
} \
\
std::add_lvalue_reference_t<array_elem_type<TYPE>> get_##OFFSET(int index) const \
{ \
return ((std::decay_t<TYPE>)((char*)this + OFFSET))[index]; \
} \
__declspec(property(get=get_##OFFSET, put=set_##OFFSET)) array_elem_type<TYPE> NAME[array_elem_count<TYPE>]

#define BIT_FIELD(OFFSET, MASK, NAME) \
void set_##OFFSET_##MASK(bool value) \
{ \
if (value) \
*(int*)((char*)this + OFFSET) |= MASK; \
else \
*(int*)((char*)this + OFFSET) &= ~MASK; \
} \
\
bool get_##OFFSET_##MASK() const \
{ \
return (*(int*)((char*)this + OFFSET) & MASK) != 0; \
} \
__declspec(property(get=get_##OFFSET_##MASK, put=set_##OFFSET_##MASK)) bool NAME
Loading

0 comments on commit 1be30c4

Please sign in to comment.