From 806746471e9a31b5830c1ac2b16d65b6f17a8434 Mon Sep 17 00:00:00 2001
From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com>
Date: Wed, 26 Jun 2024 21:11:05 +0200
Subject: [PATCH 1/5] use Vec2 more, some small issues fix, more unknown stuff
about camera and Hud
---
docs/game_data/spel2.lua | 39 +++++-
docs/src/includes/_types.md | 39 +++++-
src/game_api/containers/custom_allocator.cpp | 4 +-
src/game_api/entities_mounts.hpp | 13 +-
src/game_api/entity.cpp | 12 +-
src/game_api/entity.hpp | 6 +-
src/game_api/entity_db.hpp | 15 +--
src/game_api/game_api.hpp | 28 ++--
src/game_api/illumination.cpp | 14 +-
src/game_api/layer.cpp | 10 +-
src/game_api/level_api.cpp | 12 +-
src/game_api/level_api.hpp | 6 +-
src/game_api/render_api.hpp | 127 +++++++++++++++---
src/game_api/rpc.cpp | 14 +-
src/game_api/screen.hpp | 8 +-
src/game_api/script/lua_vm.cpp | 2 +-
src/game_api/script/usertypes/entity_lua.cpp | 4 +-
src/game_api/script/usertypes/screen_lua.cpp | 8 +-
src/game_api/script/usertypes/state_lua.cpp | 4 +
.../script/usertypes/vanilla_render_lua.cpp | 27 +++-
src/game_api/sound_manager.hpp | 2 +-
src/game_api/spawn_api.cpp | 54 ++++----
src/game_api/state.cpp | 18 +--
src/game_api/state.hpp | 8 +-
src/game_api/state_structs.hpp | 36 +++--
src/game_api/thread_utils.hpp | 1 -
src/injected/ui.cpp | 19 +--
src/injected/ui_util.cpp | 2 +-
28 files changed, 356 insertions(+), 176 deletions(-)
diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua
index 740da2263..42b3ba990 100644
--- a/docs/game_data/spel2.lua
+++ b/docs/game_data/spel2.lua
@@ -2236,8 +2236,12 @@ do
---@field shake_multiplier_x number
---@field shake_multiplier_y number
---@field uniform_shake boolean
- ---@field focused_entity_uid integer
+ ---@field focused_entity_uid integer @if set to -1, you have free control over camera focus through focus_x, focus_y
---@field inertia number @This is a bad name, but it represents the camera tweening speed. [0..5] where 0=still, 1=default (move 20% of distance per frame), 5=max (move 5*20% or 100% aka instantly to destination per frame)
+ ---@field peek_timer integer @amount of frames to freeze camera in place and move to the peek_layer
during the peek you can freely set camera position no matter if focused_entity_uid is set to -1 or not
+ ---@field peek_layer integer
+ ---@field get_bounds fun(self): AABB
+ ---@field set_bounds fun(self, bounds: AABB): nil
---@class Online
---@field online_players OnlinePlayer[] @size: 4
@@ -5418,11 +5422,12 @@ function VanillaRenderContext:draw_world_poly_filled(points, color) end
---@field ropes integer
---@field ankh boolean
---@field kapala boolean
- ---@field kapala_blood integer
+ ---@field kapala_sprite SpritePosition
---@field poison boolean
---@field curse boolean
---@field elixir boolean
---@field crown ENT_TYPE @Powerup type or 0
+ ---@field powerup_sprites SpritePosition[] @size: 18
---@field item_count integer @Amount of generic pickup items at the bottom. Set to 0 to not draw them.
---@class HudElement
@@ -5445,16 +5450,38 @@ function VanillaRenderContext:draw_world_poly_filled(points, color) end
---@field udjat boolean
---@field money_total integer
---@field money_counter integer
- ---@field time_total integer
- ---@field time_level integer
+ ---@field time_total integer @in ms
+ ---@field time_level integer @in ms
---@field world_num integer
---@field level_num integer
+ ---@field angry_shopkeeper boolean
+ ---@field seed_shown boolean
---@field seed integer
---@field opacity number
+ ---@field roll_in number
---@field players HudPlayer[] @size: MAX_PLAYERS
---@field money HudMoney
+ ---@field money_increase_sparkles ParticleEmitterInfo
---@field timer HudElement
---@field level HudElement
+ ---@field clover_falling_apart_timer number
+ ---@field player_cursed_paricles ParticleEmitterInfo[] @size: MAX_PLAYERS
+ ---@field player_poisoned_paricles ParticleEmitterInfo[] @size: MAX_PLAYERS
+ ---@field player_highlight TextureRenderingInfo @For player related icons, they use the same TextureRendering, just offset while drawing
+ ---@field player_heart TextureRenderingInfo
+ ---@field player_ankh TextureRenderingInfo
+ ---@field kapala_icon TextureRenderingInfo
+ ---@field player_crown TextureRenderingInfo
+ ---@field player_bomb TextureRenderingInfo
+ ---@field player_rope TextureRenderingInfo
+ ---@field udjat_icon TextureRenderingInfo
+ ---@field money_and_time_highlight TextureRenderingInfo @Money and time use the same TextureRendering, just offset while drawing
+ ---@field dollar_icon TextureRenderingInfo
+ ---@field hourglass_icon TextureRenderingInfo
+ ---@field clover_icon TextureRenderingInfo
+ ---@field level_highlight TextureRenderingInfo
+ ---@field level_icon TextureRenderingInfo
+ ---@field seed_background TextureRenderingInfo
---@class Hud
---@field y number
@@ -5644,7 +5671,7 @@ function Quad:is_point_inside(x, y, epsilon) end
---@field music SoundMeta
---@field torch_sound SoundMeta
----@class SpearDanglerAnimFrames
+---@class SpritePosition
---@field column integer
---@field row integer
@@ -5680,7 +5707,7 @@ function Quad:is_point_inside(x, y, epsilon) end
---@field transfer_to_menu_id integer
---@field menu_text_opacity number
---@field spear_position number[] @size: 6
- ---@field spear_dangler SpearDanglerAnimFrames[] @size: 6
+ ---@field spear_dangler SpritePosition[] @size: 6
---@field spear_dangle_momentum integer[] @size: 6
---@field spear_dangle_angle integer[] @size: 6
---@field play_scroll_descend_timer number
diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md
index 01bf3445b..12c89b278 100644
--- a/docs/src/includes/_types.md
+++ b/docs/src/includes/_types.md
@@ -501,11 +501,12 @@ int | [bombs](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=bombs) |
int | [ropes](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=ropes) |
bool | [ankh](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=ankh) |
bool | [kapala](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=kapala) |
-int | [kapala_blood](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=kapala_blood) |
+[SpritePosition](#SpritePosition) | [kapala_sprite](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=kapala_sprite) |
bool | [poison](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=poison) |
bool | [curse](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=curse) |
bool | [elixir](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=elixir) |
[ENT_TYPE](#ENT_TYPE) | [crown](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=crown) | [Powerup](#Powerup) type or 0
+array<[SpritePosition](#SpritePosition), 18> | [powerup_sprites](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=powerup_sprites) |
int | [item_count](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=item_count) | Amount of generic pickup items at the bottom. Set to 0 to not draw them.
### Inventory
@@ -706,16 +707,38 @@ array<[HudInventory](#HudInventory), MAX_PLAYERS> | [inventory](https://gi
bool | [udjat](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=udjat) |
int | [money_total](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=money_total) |
int | [money_counter](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=money_counter) |
-int | [time_total](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=time_total) |
-int | [time_level](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=time_level) |
+int | [time_total](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=time_total) | in ms
+int | [time_level](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=time_level) | in ms
int | [world_num](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=world_num) |
int | [level_num](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=level_num) |
+bool | [angry_shopkeeper](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=angry_shopkeeper) |
+bool | [seed_shown](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=seed_shown) |
int | [seed](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=seed) |
float | [opacity](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=opacity) |
+float | [roll_in](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=roll_in) |
array<[HudPlayer](#HudPlayer), MAX_PLAYERS> | [players](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=players) |
[HudMoney](#HudMoney) | [money](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=money) |
+[ParticleEmitterInfo](#ParticleEmitterInfo) | [money_increase_sparkles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=money_increase_sparkles) |
[HudElement](#HudElement) | [timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=timer) |
[HudElement](#HudElement) | [level](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=level) |
+float | [clover_falling_apart_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=clover_falling_apart_timer) |
+array<[ParticleEmitterInfo](#ParticleEmitterInfo), MAX_PLAYERS> | [player_cursed_paricles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_cursed_paricles) |
+array<[ParticleEmitterInfo](#ParticleEmitterInfo), MAX_PLAYERS> | [player_poisoned_paricles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_poisoned_paricles) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [player_highlight](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_highlight) | For player related icons, they use the same TextureRendering, just offset while drawing
+[TextureRenderingInfo](#TextureRenderingInfo) | [player_heart](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_heart) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [player_ankh](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_ankh) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [kapala_icon](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=kapala_icon) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [player_crown](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_crown) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [player_bomb](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_bomb) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [player_rope](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_rope) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [udjat_icon](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=udjat_icon) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [money_and_time_highlight](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=money_and_time_highlight) | Money and time use the same TextureRendering, just offset while drawing
+[TextureRenderingInfo](#TextureRenderingInfo) | [dollar_icon](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=dollar_icon) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [hourglass_icon](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=hourglass_icon) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [clover_icon](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=clover_icon) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [level_highlight](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=level_highlight) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [level_icon](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=level_icon) |
+[TextureRenderingInfo](#TextureRenderingInfo) | [seed_background](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=seed_background) |
### HudElement
@@ -998,7 +1021,7 @@ Type | Name | Description
float | [x](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=x) |
float | [y](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=y) |
-### SpearDanglerAnimFrames
+### SpritePosition
Type | Name | Description
@@ -2485,7 +2508,7 @@ int | [menu_id](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=menu_id
int | [transfer_to_menu_id](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=transfer_to_menu_id) |
float | [menu_text_opacity](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=menu_text_opacity) |
array<float, 6> | [spear_position](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=spear_position) |
-array<[SpearDanglerAnimFrames](#SpearDanglerAnimFrames), 6> | [spear_dangler](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=spear_dangler) |
+array<[SpritePosition](#SpritePosition), 6> | [spear_dangler](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=spear_dangler) |
array<int, 6> | [spear_dangle_momentum](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=spear_dangle_momentum) |
array<int, 6> | [spear_dangle_angle](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=spear_dangle_angle) |
float | [play_scroll_descend_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=play_scroll_descend_timer) |
@@ -2832,8 +2855,12 @@ float | [shake_amplitude](https://github.com/spelunky-fyi/overlunky/search?l=Lua
float | [shake_multiplier_x](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=shake_multiplier_x) |
float | [shake_multiplier_y](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=shake_multiplier_y) |
bool | [uniform_shake](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=uniform_shake) |
-int | [focused_entity_uid](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=focused_entity_uid) |
+int | [focused_entity_uid](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=focused_entity_uid) | if set to -1, you have free control over camera focus through focus_x, focus_y
float | [inertia](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=inertia) | This is a bad name, but it represents the camera tweening speed. [0..5] where 0=still, 1=default (move 20% of distance per frame), 5=max (move 5*20% or 100% aka instantly to destination per frame)
+int | [peek_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=peek_timer) | amount of frames to freeze camera in place and move to the peek_layer
during the peek you can freely set camera position no matter if focused_entity_uid is set to -1 or not
+int | [peek_layer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=peek_layer) |
+[AABB](#AABB) | [get_bounds()](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=get_bounds) |
+nil | [set_bounds(AABB bounds)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_bounds) |
### GameManager
diff --git a/src/game_api/containers/custom_allocator.cpp b/src/game_api/containers/custom_allocator.cpp
index 8237b9a2e..0c39c79e1 100644
--- a/src/game_api/containers/custom_allocator.cpp
+++ b/src/game_api/containers/custom_allocator.cpp
@@ -12,12 +12,12 @@ using CustomFreeFun = void*(void*, void*);
void* custom_malloc(std::size_t size)
{
static CustomMallocFun* _malloc = (CustomMallocFun*)get_address("custom_malloc"sv);
- static void* _alloc_base = OnHeapPointer(*(size_t*)get_address("malloc_base"sv)).decode();
+ static void* _alloc_base = OnHeapPointer(*(size_t*)get_address("malloc_base"sv)).decode(); // probably should be decode_local
return _malloc(_alloc_base, size);
}
void custom_free(void* mem)
{
static CustomFreeFun* _free = (CustomFreeFun*)get_address("custom_free"sv);
- static void* _alloc_base = OnHeapPointer(*(size_t*)get_address("malloc_base"sv)).decode();
+ static void* _alloc_base = OnHeapPointer(*(size_t*)get_address("malloc_base"sv)).decode(); // probably should be decode_local
_free(_alloc_base, mem);
}
diff --git a/src/game_api/entities_mounts.hpp b/src/game_api/entities_mounts.hpp
index 49f316254..41ee4d4a3 100644
--- a/src/game_api/entities_mounts.hpp
+++ b/src/game_api/entities_mounts.hpp
@@ -4,6 +4,7 @@
#include // for pair
#include "entities_chars.hpp" // for PowerupCapable
+#include "math.h" // for Vec2
class Movable;
struct SoundMeta;
@@ -28,12 +29,12 @@ class Mount : public PowerupCapable
void tame(bool value);
- virtual std::pair& get_special_offset(std::pair& offset) = 0; // gets special offset for the raider when jumping on mount
- virtual std::pair& v96(std::pair& value) = 0; // gets something for when crouching on mount
- virtual bool used_double_jump() = 0; // checks can_doublejump and unknown9b
- virtual uint32_t v98(bool) = 0; // returns some constant value
- virtual uint32_t v99() = 0; // returns some constant value
- virtual void play_jump_on_sound() = 0; // checks if it has rider
+ virtual Vec2& get_special_offset(Vec2& offset) = 0; // gets special offset for the raider when jumping on mount
+ virtual Vec2& v96(Vec2& value) = 0; // gets something for when crouching on mount
+ virtual bool used_double_jump() = 0; // checks can_doublejump and unknown9b
+ virtual uint32_t v98(bool) = 0; // returns some constant value
+ virtual uint32_t v99() = 0; // returns some constant value
+ virtual void play_jump_on_sound() = 0; // checks if it has rider
virtual void remove_rider() = 0;
virtual float v102() = 0; // get offset? mech returns 0.9, the rest 0.5
virtual uint32_t v103() = 0; // returns some constant value
diff --git a/src/game_api/entity.cpp b/src/game_api/entity.cpp
index 4d0f09f38..9d1ca68a2 100644
--- a/src/game_api/entity.cpp
+++ b/src/game_api/entity.cpp
@@ -168,7 +168,7 @@ void Entity::perform_teleport(uint8_t delta_x, uint8_t delta_y)
tp(this, delta_x, delta_y);
}
-std::pair Entity::position()
+Vec2 Entity::position()
{
auto [x_pos, y_pos] = position_self();
@@ -183,9 +183,9 @@ std::pair Entity::position()
return {x_pos, y_pos};
}
-std::pair Entity::position_self() const
+Vec2 Entity::position_self() const
{
- return std::pair(x, y);
+ return {x, y};
}
void Entity::remove_item(uint32_t item_uid)
@@ -257,7 +257,7 @@ std::tuple get_position(uint32_t uid)
{
Entity* ent = get_entity_ptr(uid);
if (ent)
- return std::make_tuple(ent->position().first, ent->position().second, ent->layer);
+ return std::make_tuple(ent->position().x, ent->position().y, ent->layer);
return {0.0f, 0.0f, (uint8_t)0};
}
@@ -290,8 +290,8 @@ std::tuple get_velocity(uint32_t uid)
else if (ent->is_liquid())
{
auto liquid_engine = State::get().get_correct_liquid_engine(ent->type->id);
- vx = liquid_engine->entity_velocities->first;
- vy = liquid_engine->entity_velocities->second;
+ vx = liquid_engine->entity_velocities->x;
+ vy = liquid_engine->entity_velocities->y;
}
if (ent->overlay)
{
diff --git a/src/game_api/entity.hpp b/src/game_api/entity.hpp
index 5a90e0137..203b81799 100644
--- a/src/game_api/entity.hpp
+++ b/src/game_api/entity.hpp
@@ -18,7 +18,7 @@
#include "entity_db.hpp" // for EntityDB
#include "entity_structs.hpp" // for CollisionInfo
#include "layer.hpp" // for EntityList
-#include "math.hpp" // for AABB
+#include "math.hpp" // for AABB, Vec2
struct RenderInfo;
struct Texture;
@@ -115,7 +115,7 @@ class Entity
return (size_t)this;
}
- std::pair position();
+ Vec2 position();
void teleport(float dx, float dy, bool s, float vx, float vy, bool snap);
void teleport_abs(float dx, float dy, float vx, float vy);
@@ -185,7 +185,7 @@ class Entity
return overlaps_with(other_left, other_bottom, other_right, other_top);
}
- std::pair position_self() const;
+ Vec2 position_self() const;
void remove_item(uint32_t item_uid);
TEXTURE get_texture();
diff --git a/src/game_api/entity_db.hpp b/src/game_api/entity_db.hpp
index 6cabb4fcd..ba8f3a268 100644
--- a/src/game_api/entity_db.hpp
+++ b/src/game_api/entity_db.hpp
@@ -14,6 +14,7 @@
#include "aliases.hpp" // for ENT_TYPE, LAYER, TEXTURE, STRINGID
#include "color.hpp" // for Color
+#include "containers/custom_vector.hpp" // for custom_vector
#include "containers/game_unordered_map.hpp" // for game_unordered_map
#include "containers/identity_hasher.hpp" // for identity_hasher
#include "entity_structs.hpp" // for CollisionInfo
@@ -127,12 +128,6 @@ struct EntityItem
}
};
-struct EntityBucket
-{
- void** begin;
- void** current; // Note, counts down from end to begin instead of up from begin to end :shrug:
- void** end;
-};
struct EntityPool
{
std::uint32_t slot_size;
@@ -140,15 +135,15 @@ struct EntityPool
std::uint32_t slots_growth;
std::uint32_t current_slots;
std::uint64_t _ulong_0;
- EntityBucket* _some_bucket;
- EntityBucket* bucket;
+ custom_vector* _some_bucket;
+ custom_vector* empty_buckets;
};
struct EntityFactory
{
EntityDB types[0x395];
bool type_set[0x395];
- std::unordered_map> entity_instance_map;
- EntityMap entity_map;
+ std::unordered_map> entity_instance_map; // game_unorderedmap probably
+ EntityMap entity_map; // game_unorderedmap probably
void* _ptr_7;
};
diff --git a/src/game_api/game_api.hpp b/src/game_api/game_api.hpp
index 025a018e3..aef0ea015 100644
--- a/src/game_api/game_api.hpp
+++ b/src/game_api/game_api.hpp
@@ -110,6 +110,20 @@ struct UnknownAPIStuff
uint32_t unknown7; // padding?
};
+struct STEAM_CALLBACK // just guessing
+{
+ size_t _vtable; // 4 functions, last one is destructor
+ uint8_t unknown1;
+ uint8_t padding1[3];
+ uint32_t padding2; // probably base class padding
+
+ // subclass OnGameOverlayActivated ?
+ bool steam_overlay_open;
+ uint32_t unknown_timer;
+ float unknown_timer_related;
+ uint32_t unknown11; // padding?
+};
+
struct GameAPI // size 0x60
{
static GameAPI* get();
@@ -125,15 +139,13 @@ struct GameAPI // size 0x60
uint32_t window_width;
uint32_t window_height;
- size_t unknown5; // garbage?
- size_t unknown6; // exe start
- size_t unknown7; // some offset
- size_t unknown8; // garbage?
- size_t SteamAPI_Callback; // just vtable? don't know much about steam stuff
+ // all this below can probably be steam related stuff
- uint8_t unknown10a; // bool ?
- uint32_t unknown10b;
+ size_t unknown5; // steam related?
+ size_t exe_begin;
+ size_t unknown7; // some offset, OnHeapPointer?
+ size_t unknown8; // function pointer?
+ STEAM_CALLBACK SteamAPI_Callback;
- size_t unknown11; // garbage?
size_t unknown12; // garbage?
};
diff --git a/src/game_api/illumination.cpp b/src/game_api/illumination.cpp
index 02590c1b0..491a1f31d 100644
--- a/src/game_api/illumination.cpp
+++ b/src/game_api/illumination.cpp
@@ -41,12 +41,14 @@ Illumination* create_illumination(Color color, float size, int32_t uid)
void refresh_illumination(Illumination* illumination)
{
- static uint32_t* offset = 0;
- if (offset == 0)
- {
- size_t** heap_offset = (size_t**)get_address("refresh_illumination_heap_offset");
- auto illumination_counter = OnHeapPointer(**heap_offset);
+ static size_t** heap_offset = (size_t**)get_address("refresh_illumination_heap_offset");
+ if (heap_offset == nullptr)
+ return;
+
+ auto illumination_counter = OnHeapPointer(**heap_offset);
+ uint32_t* offset = illumination_counter.decode_local();
+ if (offset == nullptr)
offset = illumination_counter.decode();
- }
+
illumination->timer = *offset;
}
diff --git a/src/game_api/layer.cpp b/src/game_api/layer.cpp
index 0a2bd6f9f..cbb932299 100644
--- a/src/game_api/layer.cpp
+++ b/src/game_api/layer.cpp
@@ -197,8 +197,8 @@ void Layer::move_grid_entity(Entity* ent, uint32_t x, uint32_t y, Layer* dest_la
if (ent)
{
const auto pos = ent->position();
- const uint32_t current_grid_x = static_cast(std::round(pos.first));
- const uint32_t current_grid_y = static_cast(std::round(pos.second));
+ const uint32_t current_grid_x = static_cast(std::round(pos.x));
+ const uint32_t current_grid_y = static_cast(std::round(pos.y));
if (current_grid_x < g_level_max_x && current_grid_y < g_level_max_y)
{
if (grid_entities[current_grid_y][current_grid_x] == ent)
@@ -231,14 +231,14 @@ void Layer::destroy_grid_entity(Entity* ent)
}
const auto pos = ent->position();
- const uint32_t current_grid_x = static_cast(std::round(pos.first));
- const uint32_t current_grid_y = static_cast(std::round(pos.second));
+ const uint32_t current_grid_x = static_cast(std::round(pos.x));
+ const uint32_t current_grid_y = static_cast(std::round(pos.y));
if (current_grid_x < g_level_max_x && current_grid_y < g_level_max_y)
{
if (grid_entities[current_grid_y][current_grid_x] == ent)
{
grid_entities[current_grid_y][current_grid_x] = nullptr;
- update_liquid_collision_at(pos.first, pos.second, false);
+ update_liquid_collision_at(pos.x, pos.y, false);
}
}
diff --git a/src/game_api/level_api.cpp b/src/game_api/level_api.cpp
index bf199eb50..abc0493ec 100644
--- a/src/game_api/level_api.cpp
+++ b/src/game_api/level_api.cpp
@@ -760,7 +760,7 @@ struct ExtraSpawnLogicProviderImpl
std::uint32_t transient_num_remaining_spawns_backlayer;
};
};
- std::vector> transient_valid_positions;
+ std::vector transient_valid_positions;
};
std::mutex g_extra_spawn_logic_providers_lock;
std::uint32_t g_current_extra_spawn_id{0};
@@ -1875,15 +1875,11 @@ void LevelGenSystem::do_procedural_spawn_hook(ThemeInfo* self, SpawnInfo* spawn_
std::pair LevelGenSystem::get_room_index(float x, float y)
{
- return std::pair{
- static_cast(std::ceil(x - 3.5f)) / 10,
- static_cast(std::ceil(121.5f - y)) / 8};
+ return {static_cast(std::ceil(x - 3.5f)) / 10, static_cast(std::ceil(121.5f - y)) / 8};
}
-std::pair LevelGenSystem::get_room_pos(uint32_t x, uint32_t y)
+Vec2 LevelGenSystem::get_room_pos(uint32_t x, uint32_t y)
{
- return std::pair{
- static_cast(x * 10) + 2.5f,
- 122.5f - static_cast(y * 8)};
+ return {static_cast(x * 10) + 2.5f, 122.5f - static_cast(y * 8)};
}
std::optional LevelGenSystem::get_room_template(uint32_t x, uint32_t y, uint8_t l)
{
diff --git a/src/game_api/level_api.hpp b/src/game_api/level_api.hpp
index f85562239..32ee8c5ca 100644
--- a/src/game_api/level_api.hpp
+++ b/src/game_api/level_api.hpp
@@ -385,9 +385,7 @@ struct LevelGenRoomsMeta
class SpecialLevelGeneration
{
public:
- virtual ~SpecialLevelGeneration()
- {
- }
+ virtual ~SpecialLevelGeneration(){};
// For bees, sets rooms to be behive rooms.
virtual void set_rooms() = 0;
@@ -530,7 +528,7 @@ struct LevelGenSystem
uint32_t unknown52;
static std::pair get_room_index(float x, float y);
- static std::pair get_room_pos(uint32_t x, uint32_t y);
+ static Vec2 get_room_pos(uint32_t x, uint32_t y);
std::optional get_room_template(uint32_t x, uint32_t y, uint8_t l);
bool set_room_template(uint32_t x, uint32_t y, int l, uint16_t room_template);
diff --git a/src/game_api/render_api.hpp b/src/game_api/render_api.hpp
index d0c90d1f7..71d52cec0 100644
--- a/src/game_api/render_api.hpp
+++ b/src/game_api/render_api.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include // for array
#include // for size_t
#include // for uint32_t, uint8_t, uint16_t, int32_t
#include // for equal_to
@@ -10,10 +11,13 @@
#include // for _Umap_traits<>::allocator_type, unordered_map
#include // for pair
-#include "aliases.hpp" // for TEXTURE
-#include "color.hpp" // for Color
-#include "math.hpp" // for Quad, AABB (ptr only)
-#include "texture.hpp" // for Texture
+#include "aliases.hpp" // for TEXTURE
+#include "color.hpp" // for Color
+#include "containers/game_unordered_map.hpp" // for game_unordered_map
+#include "containers/game_vector.hpp" // for game_vector
+#include "math.hpp" // for Quad, AABB (ptr only)
+#include "particles.hpp" // for ParticleEmitterInfo
+#include "texture.hpp" // for Texture
struct JournalUI;
struct Layer;
@@ -367,6 +371,12 @@ void on_open_journal_chapter(JournalUI* journal_ui, uint8_t chapter, bool instan
void render_draw_depth(Layer* layer, uint8_t draw_depth, float bbox_left, float bbox_bottom, float bbox_right, float bbox_top);
float get_layer_transition_zoom_offset(uint8_t layer);
+struct SpritePosition
+{
+ uint32_t column;
+ uint32_t row;
+};
+
struct HudInventory
{
bool enabled;
@@ -378,36 +388,35 @@ struct HudInventory
bool ankh;
bool kapala;
uint8_t b03;
+ float kapala_scale;
- uint32_t u03;
-
- uint32_t kapala_blood;
-
- uint32_t u0c;
-
+ union
+ {
+ /// NoDoc
+ uint32_t kapala_blood;
+ SpritePosition kapala_sprite;
+ };
bool poison;
bool curse;
bool elixir;
uint8_t b13;
-
/// Powerup type or 0
ENT_TYPE crown;
-
- uint8_t skip[176 - 7 * 4 - 4]; // TODO: individual item icons
+ std::array powerup_sprites;
/// Amount of generic pickup items at the bottom. Set to 0 to not draw them.
- uint32_t item_count;
+ uint32_t powerup_count;
};
static_assert(sizeof(HudInventory) == 176);
struct HudElement
{
/// Hide background and dim if using the auto adjust setting.
- bool dim;
+ bool dim; // it acutally 3 states: 0 - bright, 1 - dim, anything above - hide completely
/// Background will be drawn if this is not 0.5
float opacity;
/// Level time when element should dim again after hilighted, INT_MAX if dimmed on auto adjust. 0 on opaque.
- int32_t time_dim;
+ int32_t time_dim; // it's set to INT_MAX after it was dimmed
};
struct HudPlayer : HudElement
@@ -415,6 +424,7 @@ struct HudPlayer : HudElement
int16_t health;
int16_t bombs;
int16_t ropes;
+ // int16_t padding;
int32_t idunno;
};
static_assert(sizeof(HudPlayer) == 24);
@@ -424,28 +434,103 @@ struct HudMoney : HudElement
int32_t total;
int32_t counter;
uint8_t timer;
- // padding?
+ // uint8_t padding[3];
};
struct HudData
{
std::array inventory;
bool udjat;
+ // uint8_t padding[3];
int32_t money_total;
int32_t money_counter;
- uint32_t time_total;
+ /// in ms
uint32_t time_level;
+ /// in ms
+ uint32_t time_total;
uint8_t world_num;
uint8_t level_num;
+ bool angry_shopkeeper;
+ bool seed_shown;
uint32_t seed;
float opacity;
- uint8_t skip[1640]; // TODO: probably rendering coordinates all the way down
+
+ /// For player related icons, they use the same TextureRendering, just offset while drawing
+ TextureRenderingInfo player_highlight;
+ TextureRenderingInfo player_heart;
+ TextureRenderingInfo player_ankh;
+ TextureRenderingInfo kapala_icon;
+ TextureRenderingInfo player_crown;
+ TextureRenderingInfo unknown_texture5;
+ TextureRenderingInfo player_bomb;
+ TextureRenderingInfo player_rope;
+ TextureRenderingInfo unknown_texture8;
+ TextureRenderingInfo unknown_texture9;
+ TextureRenderingInfo unknown_texture10;
+ TextureRenderingInfo unknown_texture11;
+ TextureRenderingInfo unknown_texture12;
+ TextureRenderingInfo udjat_icon;
+ TextureRenderingInfo unknown_texture14;
+ /// Money and time use the same TextureRendering, just offset while drawing
+ TextureRenderingInfo money_and_time_highlight;
+ TextureRenderingInfo dollar_icon;
+ TextureRenderingInfo hourglass_icon;
+ TextureRenderingInfo clover_icon;
+ TextureRenderingInfo level_highlight;
+ TextureRenderingInfo level_icon;
+ TextureRenderingInfo seed_background;
+ float roll_in;
+ float unknown6;
+ float unknown7;
+ float unknown8;
+ float unknown9;
+ float unknown10;
+ std::array player_zoom; // ?
+ float unknown15;
+ float unknown16;
+ float unknown17;
+ float unknown18;
+
std::array players;
HudMoney money;
- size_t p9c0;
+ ParticleEmitterInfo* money_increase_sparkles;
HudElement timer;
HudElement level;
- // there's a few pointers and some timer missing, doesn't seem important
+ game_vector elements; // not sure what's for, just lists all the elements above, even for the unactive players
+
+ uint32_t unknown20;
+ uint8_t unknown21;
+ uint8_t unknown22;
+ uint16_t unknown23;
+ float clover_falling_apart_timer;
+ float unknown25;
+ ParticleEmitterInfo* unknown26;
+ TextureRenderingInfo unknown27;
+ TextureRenderingInfo unknown28;
+ TextureRenderingInfo unknown29;
+ float unknown30;
+ // uint32_t unknown31; // probably padding
+ game_unordered_map unknown32;
+ float unknown33;
+ float unknown34;
+ float unknown35;
+ float unknown36;
+ float unknown37;
+ float unknown38;
+ float unknown39;
+ TextureRenderingInfo loading_dragon;
+ float loading_dragon_visibility;
+ float unknown42;
+ float unknown43;
+ TextureRenderingInfo loading_cog;
+ float unknown45;
+ uint32_t loading_cog_timer;
+ uint32_t unknown47;
+ bool unknown48;
+ // uint8_t unknown49[3]; //probably padding
+ float unknown51;
+ std::array player_cursed_paricles;
+ std::array player_poisoned_paricles;
};
// static_assert(sizeof(HudData) <= 0xa00);
diff --git a/src/game_api/rpc.cpp b/src/game_api/rpc.cpp
index a54751d14..cfb3ca82b 100644
--- a/src/game_api/rpc.cpp
+++ b/src/game_api/rpc.cpp
@@ -169,15 +169,15 @@ void move_entity_abs(uint32_t uid, float x, float y, float vx, float vy, LAYER l
auto ent = get_entity_ptr(uid);
if (ent)
{
- std::pair offset;
+ Vec2 offset;
enum_to_layer(layer, offset);
if (ent->is_liquid())
{
- move_liquid_abs(uid, offset.first + x, offset.second + y, vx, vy);
+ move_liquid_abs(uid, offset.x + x, offset.y + y, vx, vy);
}
else
{
- ent->teleport_abs(offset.first + x, offset.second + y, vx, vy);
+ ent->teleport_abs(offset.x + x, offset.y + y, vx, vy);
ent->set_layer(layer);
}
}
@@ -283,7 +283,7 @@ float screen_distance(float x)
{
auto a = State::screen_position(0, 0);
auto b = State::screen_position(x, 0);
- return b.first - a.first;
+ return b.x - a.x;
}
std::vector filter_entities(std::vector entities, std::function predicate)
@@ -1211,10 +1211,10 @@ void move_grid_entity(int32_t uid, float x, float y, LAYER layer)
if (auto entity = get_entity_ptr(uid))
{
auto& state = State::get();
- std::pair offset;
+ Vec2 offset;
const auto actual_layer = enum_to_layer(layer, offset);
- state.layer(entity->layer)->move_grid_entity(entity, offset.first + x, offset.first + y, state.layer(actual_layer));
- entity->teleport_abs(offset.first + x, offset.first + y, 0, 0);
+ state.layer(entity->layer)->move_grid_entity(entity, offset.x + x, offset.y + y, state.layer(actual_layer));
+ entity->teleport_abs(offset.x + x, offset.y + y, 0, 0);
entity->set_layer(layer);
}
}
diff --git a/src/game_api/screen.hpp b/src/game_api/screen.hpp
index 2200623c2..8e317acf5 100644
--- a/src/game_api/screen.hpp
+++ b/src/game_api/screen.hpp
@@ -145,12 +145,6 @@ class ScreenTitle : public Screen // ID: 3
SoundMeta* torch_sound;
};
-struct SpearDanglerAnimFrames
-{
- uint32_t column;
- uint32_t row;
-};
-
struct MenuOption
{
// return and first param are the same, pointer on stack, it really seam to be just two 32bit fields
@@ -241,7 +235,7 @@ class ScreenMenu : public Screen // ID: 4
uint32_t transfer_to_menu_id;
float menu_text_opacity;
std::array spear_position;
- std::array spear_dangler;
+ std::array spear_dangler;
std::array spear_dangle_momentum;
std::array spear_dangle_angle;
diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp
index f6845ecc9..1dda7a8e6 100644
--- a/src/game_api/script/lua_vm.cpp
+++ b/src/game_api/script/lua_vm.cpp
@@ -1261,7 +1261,7 @@ end
if (ea == nullptr || eb == nullptr)
return -1.0f;
else
- return (float)std::sqrt(std::pow(ea->position().first - eb->position().first, 2) + std::pow(ea->position().second - eb->position().second, 2));
+ return (float)std::sqrt(std::pow(ea->position().x - eb->position().x, 2) + std::pow(ea->position().y - eb->position().y, 2));
};
/// Basically gets the absolute coordinates of the area inside the unbreakable bedrock walls, from wall to wall. Every solid entity should be
/// inside these boundaries. The order is: left x, top y, right x, bottom y
diff --git a/src/game_api/script/usertypes/entity_lua.cpp b/src/game_api/script/usertypes/entity_lua.cpp
index 7e4e0ec5e..bfac166e6 100644
--- a/src/game_api/script/usertypes/entity_lua.cpp
+++ b/src/game_api/script/usertypes/entity_lua.cpp
@@ -234,14 +234,14 @@ void register_usertypes(sol::state& lua)
entity_type["abs_x"] = sol::property([](Entity& e) -> float
{
if (e.abs_x == -FLT_MAX)
- return e.position().first;
+ return e.position().x;
return e.abs_x; });
// entity_type["abs_y"] = &Entity::abs_y;
/// NoDoc
entity_type["abs_y"] = sol::property([](Entity& e) -> float
{
if (e.abs_y == -FLT_MAX)
- return e.position().second;
+ return e.position().y;
return e.abs_y; });
entity_type["layer"] = &Entity::layer;
entity_type["width"] = &Entity::w;
diff --git a/src/game_api/script/usertypes/screen_lua.cpp b/src/game_api/script/usertypes/screen_lua.cpp
index f6ed822b2..737dfbed1 100644
--- a/src/game_api/script/usertypes/screen_lua.cpp
+++ b/src/game_api/script/usertypes/screen_lua.cpp
@@ -181,12 +181,12 @@ void register_usertypes(sol::state& lua)
sol::base_classes,
sol::bases());
- lua.new_usertype(
- "SpearDanglerAnimFrames",
+ lua.new_usertype(
+ "SpritePosition",
"column",
- &SpearDanglerAnimFrames::column,
+ &SpritePosition::column,
"row",
- &SpearDanglerAnimFrames::row);
+ &SpritePosition::row);
auto screenmenu_type = lua.new_usertype("ScreenMenu", sol::base_classes, sol::bases());
screenmenu_type["state"] = &ScreenMenu::state;
diff --git a/src/game_api/script/usertypes/state_lua.cpp b/src/game_api/script/usertypes/state_lua.cpp
index 1b4a5615a..8fa709e6c 100644
--- a/src/game_api/script/usertypes/state_lua.cpp
+++ b/src/game_api/script/usertypes/state_lua.cpp
@@ -492,6 +492,10 @@ void register_usertypes(sol::state& lua)
camera_type["uniform_shake"] = &Camera::uniform_shake;
camera_type["focused_entity_uid"] = &Camera::focused_entity_uid;
camera_type["inertia"] = &Camera::inertia;
+ camera_type["peek_timer"] = &Camera::peek_timer;
+ camera_type["peek_layer"] = &Camera::peek_layer;
+ camera_type["get_bounds"] = &Camera::get_bounds;
+ camera_type["set_bounds"] = &Camera::set_bounds;
/// Can be accessed via global [online](#online)
lua.new_usertype(
diff --git a/src/game_api/script/usertypes/vanilla_render_lua.cpp b/src/game_api/script/usertypes/vanilla_render_lua.cpp
index 072cb0218..c5fad4003 100644
--- a/src/game_api/script/usertypes/vanilla_render_lua.cpp
+++ b/src/game_api/script/usertypes/vanilla_render_lua.cpp
@@ -903,11 +903,13 @@ void register_usertypes(sol::state& lua)
hudinventory_type["ankh"] = &HudInventory::ankh;
hudinventory_type["kapala"] = &HudInventory::kapala;
hudinventory_type["kapala_blood"] = &HudInventory::kapala_blood;
+ hudinventory_type["kapala_sprite"] = &HudInventory::kapala_sprite;
hudinventory_type["poison"] = &HudInventory::poison;
hudinventory_type["curse"] = &HudInventory::curse;
hudinventory_type["elixir"] = &HudInventory::elixir;
hudinventory_type["crown"] = &HudInventory::crown;
- hudinventory_type["item_count"] = &HudInventory::item_count;
+ hudinventory_type["powerup_sprites"] = &HudInventory::powerup_sprites;
+ hudinventory_type["item_count"] = &HudInventory::powerup_count;
auto hudelement_type = lua.new_usertype("HudElement");
hudelement_type["dim"] = &HudElement::dim;
@@ -933,12 +935,35 @@ void register_usertypes(sol::state& lua)
huddata_type["time_level"] = &HudData::time_level;
huddata_type["world_num"] = &HudData::world_num;
huddata_type["level_num"] = &HudData::level_num;
+ huddata_type["angry_shopkeeper"] = &HudData::angry_shopkeeper;
+ huddata_type["seed_shown"] = &HudData::seed_shown;
huddata_type["seed"] = &HudData::seed;
huddata_type["opacity"] = &HudData::opacity;
+ huddata_type["roll_in"] = &HudData::roll_in;
huddata_type["players"] = &HudData::players;
huddata_type["money"] = &HudData::money;
+ huddata_type["money_increase_sparkles"] = &HudData::money_increase_sparkles;
huddata_type["timer"] = &HudData::timer;
huddata_type["level"] = &HudData::level;
+ huddata_type["clover_falling_apart_timer"] = &HudData::clover_falling_apart_timer;
+ huddata_type["player_cursed_paricles"] = &HudData::player_cursed_paricles;
+ huddata_type["player_poisoned_paricles"] = &HudData::player_poisoned_paricles;
+
+ huddata_type["player_highlight"] = &HudData::player_highlight;
+ huddata_type["player_heart"] = &HudData::player_heart;
+ huddata_type["player_ankh"] = &HudData::player_ankh;
+ huddata_type["kapala_icon"] = &HudData::kapala_icon;
+ huddata_type["player_crown"] = &HudData::player_crown;
+ huddata_type["player_bomb"] = &HudData::player_bomb;
+ huddata_type["player_rope"] = &HudData::player_rope;
+ huddata_type["udjat_icon"] = &HudData::udjat_icon;
+ huddata_type["money_and_time_highlight"] = &HudData::money_and_time_highlight;
+ huddata_type["dollar_icon"] = &HudData::dollar_icon;
+ huddata_type["hourglass_icon"] = &HudData::hourglass_icon;
+ huddata_type["clover_icon"] = &HudData::clover_icon;
+ huddata_type["level_highlight"] = &HudData::level_highlight;
+ huddata_type["level_icon"] = &HudData::level_icon;
+ huddata_type["seed_background"] = &HudData::seed_background;
auto hud_type = lua.new_usertype("Hud");
hud_type["y"] = &Hud::y;
diff --git a/src/game_api/sound_manager.hpp b/src/game_api/sound_manager.hpp
index c23011705..bb59e0ef1 100644
--- a/src/game_api/sound_manager.hpp
+++ b/src/game_api/sound_manager.hpp
@@ -257,7 +257,7 @@ struct SoundInfo
int64_t unknown1;
uint32_t sound_id;
int32_t unknown2; // padding probably
- std::string sound_name; // not 100% sure it's standard
+ std::string sound_name; // not 100% sure if it's standard
};
struct SoundMeta
diff --git a/src/game_api/spawn_api.cpp b/src/game_api/spawn_api.cpp
index 28013a6dd..4ed5b0a21 100644
--- a/src/game_api/spawn_api.cpp
+++ b/src/game_api/spawn_api.cpp
@@ -171,10 +171,10 @@ int32_t spawn_entity_abs(ENT_TYPE entity_type, float x, float y, LAYER layer, fl
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- return State::get().layer(actual_layer)->spawn_entity(entity_type, x + offset_position.first, y + offset_position.second, false, vx, vy, false)->uid;
+ return State::get().layer(actual_layer)->spawn_entity(entity_type, x + offset_position.x, y + offset_position.y, false, vx, vy, false)->uid;
}
int32_t spawn_entity_snap_to_floor(ENT_TYPE entity_type, float x, float y, LAYER layer)
@@ -183,10 +183,10 @@ int32_t spawn_entity_snap_to_floor(ENT_TYPE entity_type, float x, float y, LAYER
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- return State::get().layer(actual_layer)->spawn_entity_snap_to_floor(entity_type, x + offset_position.first, y + offset_position.second)->uid;
+ return State::get().layer(actual_layer)->spawn_entity_snap_to_floor(entity_type, x + offset_position.x, y + offset_position.y)->uid;
}
int32_t spawn_entity_snap_to_grid(ENT_TYPE entity_type, float x, float y, LAYER layer)
@@ -195,10 +195,10 @@ int32_t spawn_entity_snap_to_grid(ENT_TYPE entity_type, float x, float y, LAYER
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- return State::get().layer(actual_layer)->spawn_entity(entity_type, x + offset_position.first, y + offset_position.second, false, 0.0f, 0.0f, true)->uid;
+ return State::get().layer(actual_layer)->spawn_entity(entity_type, x + offset_position.x, y + offset_position.y, false, 0.0f, 0.0f, true)->uid;
}
int32_t spawn_entity_abs_nonreplaceable(ENT_TYPE entity_type, float x, float y, LAYER layer, float vx, float vy)
@@ -232,10 +232,10 @@ int32_t spawn_door_abs(float x, float y, LAYER layer, uint8_t w, uint8_t l, uint
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- return State::get().layer(actual_layer)->spawn_door(x + offset_position.first, y + offset_position.second, w, l, t)->uid;
+ return State::get().layer(actual_layer)->spawn_door(x + offset_position.x, y + offset_position.y, w, l, t)->uid;
}
void spawn_backdoor_abs(float x, float y)
@@ -260,10 +260,10 @@ int32_t spawn_apep(float x, float y, LAYER layer, bool right)
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- return State::get().layer(actual_layer)->spawn_apep(x + offset_position.first, y + offset_position.second, right)->uid;
+ return State::get().layer(actual_layer)->spawn_apep(x + offset_position.x, y + offset_position.y, right)->uid;
}
int32_t spawn_tree(float x, float y, LAYER layer)
@@ -276,11 +276,11 @@ int32_t spawn_tree(float x, float y, LAYER layer, uint16_t height)
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- x = std::roundf(x + offset_position.first);
- y = std::roundf(y + offset_position.second);
+ x = std::roundf(x + offset_position.x);
+ y = std::roundf(y + offset_position.y);
Layer* layer_ptr = State::get().layer(actual_layer);
@@ -335,13 +335,13 @@ int32_t spawn_tree(float x, float y, LAYER layer, uint16_t height)
};
auto test_pos = current_piece->position();
- if (static_cast(test_pos.first) + 1 < g_level_max_x && layer_ptr->get_grid_entity_at(test_pos.first + 1, test_pos.second) == nullptr &&
+ if (static_cast(test_pos.x) + 1 < g_level_max_x && layer_ptr->get_grid_entity_at(test_pos.x + 1, test_pos.y) == nullptr &&
prng.random_chance(2, PRNG::PRNG_CLASS::ENTITY_VARIATION))
{
Entity* branch = layer_ptr->spawn_entity_over(tree_branch, current_piece, 1.02f, 0.0f);
spawn_deco(branch, false);
}
- if (static_cast(test_pos.first) - 1 > 0 && layer_ptr->get_grid_entity_at(test_pos.first - 1, test_pos.second) == nullptr &&
+ if (static_cast(test_pos.x) - 1 > 0 && layer_ptr->get_grid_entity_at(test_pos.x - 1, test_pos.y) == nullptr &&
prng.random_chance(2, PRNG::PRNG_CLASS::ENTITY_VARIATION))
{
Entity* branch = layer_ptr->spawn_entity_over(tree_branch, current_piece, -1.02f, 0.0f);
@@ -364,11 +364,11 @@ int32_t spawn_mushroom(float x, float y, LAYER l, uint16_t height) // height rel
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset(0.0f, 0.0f);
+ Vec2 offset(0.0f, 0.0f);
const auto actual_layer = enum_to_layer(l, offset);
const auto layer_ptr = State::get().layer(actual_layer);
- const uint32_t i_x = static_cast(x + offset.first + 0.5f);
- uint32_t i_y = static_cast(y + offset.second + 0.5f);
+ const uint32_t i_x = static_cast(x + offset.x + 0.5f);
+ uint32_t i_y = static_cast(y + offset.y + 0.5f);
static const auto base = to_id("ENT_TYPE_FLOOR_MUSHROOM_BASE");
static const auto trunk = to_id("ENT_TYPE_FLOOR_MUSHROOM_TRUNK");
static const auto top = to_id("ENT_TYPE_FLOOR_MUSHROOM_TOP");
@@ -433,11 +433,11 @@ int32_t spawn_unrolled_player_rope(float x, float y, LAYER layer, TEXTURE textur
static const auto setup_top_rope_rendering_info_two = (setup_top_rope_rendering_info_two_fun*)get_address("setup_top_rope_rendering_info_two"sv);
static const auto rope_ent = to_id("ENT_TYPE_ITEM_CLIMBABLE_ROPE");
- std::pair offset(0.0f, 0.0f);
+ Vec2 offset(0.0f, 0.0f);
const auto actual_layer = enum_to_layer(layer, offset);
const auto layer_ptr = State::get().layer(actual_layer);
- const uint32_t i_x = static_cast(x + offset.first + 0.5f);
- const uint32_t i_y = static_cast(y + offset.second + 0.5f);
+ const uint32_t i_x = static_cast(x + offset.x + 0.5f);
+ const uint32_t i_y = static_cast(y + offset.y + 0.5f);
const float g_x = static_cast(i_x);
const float g_y = static_cast(i_y);
@@ -523,10 +523,10 @@ Entity* spawn_impostor_lake(AABB aabb, LAYER layer, ENT_TYPE impostor_type, floa
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset_position;
+ Vec2 offset_position;
uint8_t actual_layer = enum_to_layer(layer, offset_position);
- aabb.offset(offset_position.first, offset_position.second);
+ aabb.offset(offset_position.x, offset_position.y);
auto [x, y] = aabb.center();
@@ -735,10 +735,10 @@ int32_t spawn_companion(ENT_TYPE companion_type, float x, float y, LAYER layer)
typedef Player* spawn_companion_func(StateMemory*, float x, float y, size_t layer, uint32_t entity_type);
static spawn_companion_func* sc = (spawn_companion_func*)(offset);
- std::pair pos_offset;
+ Vec2 pos_offset;
const auto actual_layer = enum_to_layer(layer, pos_offset);
- Player* spawned = sc(state, x + pos_offset.first, y + pos_offset.second, actual_layer, companion_type);
+ Player* spawned = sc(state, x + pos_offset.x, y + pos_offset.y, actual_layer, companion_type);
return spawned->uid;
}
return -1;
@@ -796,7 +796,7 @@ int32_t spawn_playerghost(ENT_TYPE char_type, float x, float y, LAYER layer)
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }};
- std::pair offset;
+ Vec2 offset;
const auto l = enum_to_layer(layer, offset);
auto level_layer = State::get().layer(l);
@@ -809,7 +809,7 @@ int32_t spawn_playerghost(ENT_TYPE char_type, float x, float y, LAYER layer)
if (char_type < ana || char_type > egg_child)
return -1;
- auto player_ghost_entity = level_layer->spawn_entity(player_ghost, x + offset.first, y + offset.second, false, 0, 0, false)->as();
+ auto player_ghost_entity = level_layer->spawn_entity(player_ghost, x + offset.x, y + offset.y, false, 0, 0, false)->as();
if (player_ghost_entity)
{
player_ghost_entity->player_inputs = &dummy_player_controls;
diff --git a/src/game_api/state.cpp b/src/game_api/state.cpp
index 20e010c2f..583bc1dcf 100644
--- a/src/game_api/state.cpp
+++ b/src/game_api/state.cpp
@@ -72,10 +72,10 @@ void fix_liquid_out_of_bounds()
for (uint32_t i = 0; i < it.physics_engine->entity_count; ++i)
{
auto liquid_coordinates = it.physics_engine->entity_coordinates + i;
- if (liquid_coordinates->second < 0 // y < 0
- || liquid_coordinates->first < 0 // x < 0
- || liquid_coordinates->first > g_level_max_x // x > g_level_max_x
- || liquid_coordinates->second > g_level_max_y + 16) // y > g_level_max_y
+ if (liquid_coordinates->y < 0 // y < 0
+ || liquid_coordinates->x < 0 // x < 0
+ || liquid_coordinates->x > g_level_max_x // x > g_level_max_x
+ || liquid_coordinates->y > g_level_max_y + 16) // y > g_level_max_y
{
if (!*(it.physics_engine->unknown61 + i)) // just some bs
continue;
@@ -356,7 +356,7 @@ float get_zoom_level()
return game_api->get_current_zoom();
}
-std::pair State::click_position(float x, float y)
+Vec2 State::click_position(float x, float y)
{
float cz = get_zoom_level();
auto [cx, cy] = get_camera_position();
@@ -365,7 +365,7 @@ std::pair State::click_position(float x, float y)
return {rx, ry};
}
-std::pair State::screen_position(float x, float y)
+Vec2 State::screen_position(float x, float y)
{
float cz = get_zoom_level();
auto [cx, cy] = get_camera_position();
@@ -458,7 +458,7 @@ void State::darkmode(bool g)
}
}
-std::pair State::get_camera_position()
+Vec2 State::get_camera_position()
{
static const auto addr = (float*)get_address("camera_position");
auto cx = *addr;
@@ -539,7 +539,7 @@ void State::set_seed(uint32_t seed)
SaveData* State::savedata()
{
auto gm = get_game_manager();
- return gm->save_related->savedata.decode();
+ return gm->save_related->savedata.decode(); // wondering if it matters if it's local or not?
}
uint32_t lowbias32(uint32_t x)
{
@@ -811,7 +811,7 @@ void init_game_loop_hook()
}
}
-uint8_t enum_to_layer(const LAYER layer, std::pair& player_position)
+uint8_t enum_to_layer(const LAYER layer, Vec2& player_position)
{
if (layer == LAYER::FRONT)
{
diff --git a/src/game_api/state.hpp b/src/game_api/state.hpp
index 68bd709d2..3abe16348 100644
--- a/src/game_api/state.hpp
+++ b/src/game_api/state.hpp
@@ -355,8 +355,8 @@ struct State
void zoom(float level);
void zoom_reset();
- static std::pair click_position(float x, float y);
- static std::pair screen_position(float x, float y);
+ static Vec2 click_position(float x, float y);
+ static Vec2 screen_position(float x, float y);
uint32_t flags() const
{
@@ -380,7 +380,7 @@ struct State
static Entity* find(StateMemory* state, uint32_t uid);
- static std::pair get_camera_position();
+ static Vec2 get_camera_position();
void set_camera_position(float cx, float cy);
void warp(uint8_t w, uint8_t l, uint8_t t);
void set_seed(uint32_t seed);
@@ -399,7 +399,7 @@ void init_state_update_hook();
void init_process_input_hook();
void init_game_loop_hook();
-uint8_t enum_to_layer(const LAYER layer, std::pair& player_position);
+uint8_t enum_to_layer(const LAYER layer, Vec2& player_position);
uint8_t enum_to_layer(const LAYER layer);
uint32_t lowbias32(uint32_t x);
diff --git a/src/game_api/state_structs.hpp b/src/game_api/state_structs.hpp
index a34d6a108..a30eeea7d 100644
--- a/src/game_api/state_structs.hpp
+++ b/src/game_api/state_structs.hpp
@@ -4,6 +4,7 @@
#include "containers/custom_map.hpp"
#include "containers/custom_vector.hpp"
#include "layer.hpp"
+#include "math.h" // for AABB, Vec2
#include "render_api.hpp"
#include
#include
@@ -137,17 +138,30 @@ struct Camera
float shake_multiplier_x; // set to 0 to eliminate horizontal shake; negative inverts direction
float shake_multiplier_y; // set to 0 to eliminate vertical shake; negative inverts direction
bool uniform_shake; // if false, the shake gets randomized a bit
- uint8_t padding1;
- uint8_t padding2;
- uint8_t padding3;
- int32_t focused_entity_uid; // if set to -1, you have free control over camera focus through focus_x, focus_y
- uint32_t freeze_timer; // if > 0, disables camera movement for this amount of frames
- uint32_t unknown4;
+ uint8_t padding1[3];
+ /// if set to -1, you have free control over camera focus through focus_x, focus_y
+ int32_t focused_entity_uid;
+ /// amount of frames to freeze camera in place and move to the peek_layer
+ /// during the peek you can freely set camera position no matter if focused_entity_uid is set to -1 or not
+ uint32_t peek_timer;
+ uint8_t peek_layer;
+ uint8_t padding2[3];
+
/// This is a bad name, but it represents the camera tweening speed. [0..5] where 0=still, 1=default (move 20% of distance per frame), 5=max (move 5*20% or 100% aka instantly to destination per frame)
float inertia;
uint32_t unknown5;
- uint32_t unknown6;
- uint32_t unknown7;
+
+ AABB get_bounds() const
+ {
+ return AABB(bounds_left, bounds_top, bounds_right, bounds_bottom);
+ }
+ void set_bounds(const AABB& bounds)
+ {
+ bounds_left = bounds.left;
+ bounds_right = bounds.right;
+ bounds_bottom = bounds.bottom;
+ bounds_top = bounds.top;
+ }
};
struct JournalProgressStickerSlot
@@ -721,10 +735,10 @@ struct LiquidPhysicsEngine
uint32_t* liquid_flags; // array
int32_t unknown47a; // size related for the array above
int32_t unknown47b; // padding
- std::pair* entity_coordinates; // array
+ Vec2* entity_coordinates; // array
int32_t unknown49a; // size related for the array above
int32_t unknown49b; // padding
- std::pair* entity_velocities; // array
+ Vec2* entity_velocities; // array
int32_t unknown51a; // size related for the array above
int32_t unknown51b; // padding
std::pair* unknown52; // not sure about the type, it's defenetly a 64bit
@@ -1018,7 +1032,7 @@ struct MultiLineTextRendering
size_t* timer; // some struct? game increments this value and one at +0x40, seam to be related to rendering, touching just the first one freezes the game
std::vector lines; // each line is separete TextRenderingInfo
float x; // center of the text box?
- float z; // center of the text box?
+ float y; // center of the text box?
};
struct EntityLookup
diff --git a/src/game_api/thread_utils.hpp b/src/game_api/thread_utils.hpp
index 007a5dbff..d36fd826d 100644
--- a/src/game_api/thread_utils.hpp
+++ b/src/game_api/thread_utils.hpp
@@ -15,7 +15,6 @@ class OnHeapPointer
int64_t ptr_;
public:
- OnHeapPointer() = default;
explicit OnHeapPointer(size_t ptr)
: ptr_(ptr)
{
diff --git a/src/injected/ui.cpp b/src/injected/ui.cpp
index affa782d5..af72ef7f0 100644
--- a/src/injected/ui.cpp
+++ b/src/injected/ui.cpp
@@ -518,7 +518,7 @@ void version_check(bool force = false)
version_check_status.state = VERSION_CHECK::CHECKING;
DEBUG("UpdateCheck: {}", version_check_messages[(int)version_check_status.state].message);
- new HttpRequest(std::move(version_check_url), get_version_info);
+ new HttpRequest(version_check_url, get_version_info);
}
void hook_savegame()
@@ -825,7 +825,7 @@ void refresh_script_files()
unload_scripts.push_back(script.second->get_file());
}
}
- for (auto id : unload_scripts)
+ for (auto& id : unload_scripts)
{
auto it = g_scripts.find(id);
if (it != g_scripts.end())
@@ -853,7 +853,7 @@ void refresh_script_files()
unload_scripts.push_back(script.second->get_file());
}
}
- for (auto id : unload_scripts)
+ for (auto& id : unload_scripts)
{
auto it = g_scripts.find(id);
if (it != g_scripts.end())
@@ -869,7 +869,7 @@ void refresh_script_files()
void autorun_scripts()
{
- for (auto file : g_script_autorun)
+ for (auto& file : g_script_autorun)
{
std::string script = scriptpath + "/" + file;
if (std::filesystem::exists(script) && std::filesystem::is_regular_file(script))
@@ -1336,15 +1336,15 @@ void smart_delete(Entity* ent, bool unsafe = false)
{
auto pos = ent->position();
auto layer = (LAYER)ent->layer;
- UI::cleanup_at(pos.first, pos.second, layer, ent->type->id);
+ UI::cleanup_at(pos.x, pos.y, layer, ent->type->id);
}
if (ent->type->search_flags & 0x180)
{
auto pos = ent->position();
auto layer = (LAYER)ent->layer;
ENT_TYPE type = ent->type->id;
- fix_decorations_at(std::round(pos.first), std::round(pos.second), layer);
- UI::cleanup_at(std::round(pos.first), std::round(pos.second), layer, type);
+ fix_decorations_at(std::round(pos.x), std::round(pos.y), layer);
+ UI::cleanup_at(std::round(pos.x), std::round(pos.y), layer, type);
}
}
@@ -4938,16 +4938,17 @@ void render_messages()
auto in_time_t = std::chrono::system_clock::to_time_t(now);
std::tm time_buf;
localtime_s(&time_buf, &in_time_t);
- std::vector messages;
+
for (auto& [name, script] : g_scripts)
{
+ std::vector messages;
for (auto&& message : script->consume_messages())
messages.push_back(message);
if (messages.size() > 0)
g_Console->push_history(fmt::format("--- [{}] at {:%Y-%m-%d %X}", script->get_name(), time_buf), std::move(messages));
}
- messages.clear();
{
+ std::vector messages;
for (auto&& message : g_Console->consume_messages())
messages.push_back(message);
if (messages.size() > 0)
diff --git a/src/injected/ui_util.cpp b/src/injected/ui_util.cpp
index 33e427fe2..8be35fc2a 100644
--- a/src/injected/ui_util.cpp
+++ b/src/injected/ui_util.cpp
@@ -109,7 +109,7 @@ float UI::screen_distance(float x)
{
auto a = State::screen_position(0, 0);
auto b = State::screen_position(x, 0);
- return b.first - a.first;
+ return b.x - a.x;
}
Entity* UI::get_entity_at(float x, float y, bool s, float radius, uint32_t mask)
{
From ce28897b55e6097d09f2bfdbf0c028fefc6ab302 Mon Sep 17 00:00:00 2001
From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com>
Date: Thu, 27 Jun 2024 18:23:41 +0200
Subject: [PATCH 2/5] fix the weird error?
---
src/game_api/render_api.hpp | 2 +-
src/game_api/script/usertypes/vanilla_render_lua.cpp | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/game_api/render_api.hpp b/src/game_api/render_api.hpp
index 71d52cec0..9cf53850c 100644
--- a/src/game_api/render_api.hpp
+++ b/src/game_api/render_api.hpp
@@ -16,13 +16,13 @@
#include "containers/game_unordered_map.hpp" // for game_unordered_map
#include "containers/game_vector.hpp" // for game_vector
#include "math.hpp" // for Quad, AABB (ptr only)
-#include "particles.hpp" // for ParticleEmitterInfo
#include "texture.hpp" // for Texture
struct JournalUI;
struct Layer;
class Entity;
struct Renderer;
+struct ParticleEmitterInfo;
using VANILLA_TEXT_ALIGNMENT = uint32_t;
using VANILLA_FONT_STYLE = uint32_t;
diff --git a/src/game_api/script/usertypes/vanilla_render_lua.cpp b/src/game_api/script/usertypes/vanilla_render_lua.cpp
index c5fad4003..9047087f2 100644
--- a/src/game_api/script/usertypes/vanilla_render_lua.cpp
+++ b/src/game_api/script/usertypes/vanilla_render_lua.cpp
@@ -9,6 +9,7 @@
#include // for get
#include // for move, declval
+#include "particles.hpp" // for ParticleEmitterInfo
#include "render_api.hpp" // for TextureRenderingInfo, WorldShader, TextRen...
#include "state.hpp" // for enum_to_layer
#include "texture.hpp" // for Texture, get_texture
From 416e27820bbb12e58f78f995715774959f33d2b3 Mon Sep 17 00:00:00 2001
From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com>
Date: Fri, 28 Jun 2024 20:07:44 +0200
Subject: [PATCH 3/5] thing in `EntityPool`
---
src/game_api/entity_db.hpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/game_api/entity_db.hpp b/src/game_api/entity_db.hpp
index ba8f3a268..2cc86e3f3 100644
--- a/src/game_api/entity_db.hpp
+++ b/src/game_api/entity_db.hpp
@@ -134,9 +134,9 @@ struct EntityPool
std::uint32_t initial_slots;
std::uint32_t slots_growth;
std::uint32_t current_slots;
- std::uint64_t _ulong_0;
- custom_vector* _some_bucket;
- custom_vector* empty_buckets;
+ std::uint64_t unknown;
+ custom_vector* pools_begin; // saved the first entity address that causes the slot size to increase (including the initial)
+ custom_vector* empty_buckets; // empty entity slots
};
struct EntityFactory
{
From 931c063585836ef6c82903d65baf44628b7489d5 Mon Sep 17 00:00:00 2001
From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com>
Date: Thu, 11 Jul 2024 18:57:32 +0200
Subject: [PATCH 4/5] fix size
---
src/game_api/game_api.hpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/game_api/game_api.hpp b/src/game_api/game_api.hpp
index a63a68ff1..d60a5c601 100644
--- a/src/game_api/game_api.hpp
+++ b/src/game_api/game_api.hpp
@@ -112,13 +112,14 @@ struct UnknownAPIStuff
struct STEAM_CALLBACK // just guessing
{
- size_t _vtable; // 4 functions, last one is destructor
- uint8_t unknown1;
+ size_t _vtable; // 4 functions, last one is destructor
+ uint8_t unknown1; // probably bool?
uint8_t padding1[3];
uint32_t padding2; // probably base class padding
// subclass OnGameOverlayActivated ?
bool steam_overlay_open;
+ // padding
uint32_t unknown_timer;
float unknown_timer_related;
uint32_t unknown11; // padding?
@@ -149,6 +150,4 @@ struct GameAPI
size_t unknown7; // some offset, OnHeapPointer?
size_t unknown8; // function pointer?
STEAM_CALLBACK SteamAPI_Callback;
-
- size_t unknown12; // garbage?
};
From bbc2224f8a4d610a364f70085e1f0652b0b217dc Mon Sep 17 00:00:00 2001
From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com>
Date: Tue, 30 Jul 2024 13:27:12 +0200
Subject: [PATCH 5/5] typo
---
docs/game_data/spel2.lua | 6 +++---
docs/src/includes/_types.md | 6 +++---
src/game_api/render_api.hpp | 4 ++--
src/game_api/script/usertypes/vanilla_render_lua.cpp | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua
index 971579b85..98c78065f 100644
--- a/docs/game_data/spel2.lua
+++ b/docs/game_data/spel2.lua
@@ -2435,7 +2435,7 @@ function PRNG:random(min, max) end
---@field hitboxy number
---@field draw_depth integer
---@field collision2_mask integer @MASK, will only call collision2 when colliding with entities that match this mask.
- ---@field collision_mask integer @MASK used for collision with floors.
+ ---@field collision_mask integer @MASK used for collision with floors, walls etc.
---@field friction number
---@field elasticity number
---@field weight number
@@ -5489,8 +5489,8 @@ function VanillaRenderContext:draw_world_poly_filled(points, color) end
---@field timer HudElement
---@field level HudElement
---@field clover_falling_apart_timer number
- ---@field player_cursed_paricles ParticleEmitterInfo[] @size: MAX_PLAYERS
- ---@field player_poisoned_paricles ParticleEmitterInfo[] @size: MAX_PLAYERS
+ ---@field player_cursed_particles ParticleEmitterInfo[] @size: MAX_PLAYERS
+ ---@field player_poisoned_particles ParticleEmitterInfo[] @size: MAX_PLAYERS
---@field player_highlight TextureRenderingInfo @For player related icons, they use the same TextureRendering, just offset while drawing
---@field player_heart TextureRenderingInfo
---@field player_ankh TextureRenderingInfo
diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md
index 1360e6094..af595c64c 100644
--- a/docs/src/includes/_types.md
+++ b/docs/src/includes/_types.md
@@ -462,7 +462,7 @@ float | [hitboxx](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=hitbo
float | [hitboxy](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=hitboxy) |
int | [draw_depth](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=draw_depth) |
int | [collision2_mask](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=collision2_mask) | [MASK](#MASK), will only call collision2 when colliding with entities that match this mask.
-int | [collision_mask](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=collision_mask) | [MASK](#MASK) used for collision with floors.
+int | [collision_mask](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=collision_mask) | [MASK](#MASK) used for collision with floors, walls etc.
float | [friction](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=friction) |
float | [elasticity](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=elasticity) |
float | [weight](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=weight) |
@@ -719,8 +719,8 @@ array<[HudPlayer](#HudPlayer), MAX_PLAYERS> | [players](https://github.com
[HudElement](#HudElement) | [timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=timer) |
[HudElement](#HudElement) | [level](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=level) |
float | [clover_falling_apart_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=clover_falling_apart_timer) |
-array<[ParticleEmitterInfo](#ParticleEmitterInfo), MAX_PLAYERS> | [player_cursed_paricles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_cursed_paricles) |
-array<[ParticleEmitterInfo](#ParticleEmitterInfo), MAX_PLAYERS> | [player_poisoned_paricles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_poisoned_paricles) |
+array<[ParticleEmitterInfo](#ParticleEmitterInfo), MAX_PLAYERS> | [player_cursed_particles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_cursed_particles) |
+array<[ParticleEmitterInfo](#ParticleEmitterInfo), MAX_PLAYERS> | [player_poisoned_particles](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_poisoned_particles) |
[TextureRenderingInfo](#TextureRenderingInfo) | [player_highlight](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_highlight) | For player related icons, they use the same TextureRendering, just offset while drawing
[TextureRenderingInfo](#TextureRenderingInfo) | [player_heart](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_heart) |
[TextureRenderingInfo](#TextureRenderingInfo) | [player_ankh](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_ankh) |
diff --git a/src/game_api/render_api.hpp b/src/game_api/render_api.hpp
index 02b1408f2..dcca080de 100644
--- a/src/game_api/render_api.hpp
+++ b/src/game_api/render_api.hpp
@@ -529,8 +529,8 @@ struct HudData
bool unknown48;
// uint8_t unknown49[3]; //probably padding
float unknown51;
- std::array player_cursed_paricles;
- std::array player_poisoned_paricles;
+ std::array player_cursed_particles;
+ std::array player_poisoned_particles;
};
// static_assert(sizeof(HudData) <= 0xa00);
diff --git a/src/game_api/script/usertypes/vanilla_render_lua.cpp b/src/game_api/script/usertypes/vanilla_render_lua.cpp
index 9047087f2..5e5f4246f 100644
--- a/src/game_api/script/usertypes/vanilla_render_lua.cpp
+++ b/src/game_api/script/usertypes/vanilla_render_lua.cpp
@@ -947,8 +947,8 @@ void register_usertypes(sol::state& lua)
huddata_type["timer"] = &HudData::timer;
huddata_type["level"] = &HudData::level;
huddata_type["clover_falling_apart_timer"] = &HudData::clover_falling_apart_timer;
- huddata_type["player_cursed_paricles"] = &HudData::player_cursed_paricles;
- huddata_type["player_poisoned_paricles"] = &HudData::player_poisoned_paricles;
+ huddata_type["player_cursed_particles"] = &HudData::player_cursed_particles;
+ huddata_type["player_poisoned_particles"] = &HudData::player_poisoned_particles;
huddata_type["player_highlight"] = &HudData::player_highlight;
huddata_type["player_heart"] = &HudData::player_heart;