Skip to content

Commit

Permalink
some more vtable hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Dregu committed Sep 24, 2023
1 parent b9cb66f commit d9d57f0
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 96 deletions.
76 changes: 38 additions & 38 deletions src/game_api/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,57 +226,57 @@ class Entity
inline static std::function<std::uint32_t(Entity*, std::function<void(Entity*)>)> hook_dtor_impl{};
inline static std::function<void(Entity*, std::uint32_t)> clear_dtor_impl{};

virtual ~Entity() = 0; // vritual 0
virtual void create_rendering_info() = 0;
virtual void handle_state_machine() = 0;
virtual ~Entity() = 0; // vritual 0
virtual void create_rendering_info() = 0; // 1
virtual void handle_state_machine() = 0; // 2

/// Kills the entity, you can set responsible to `nil` to ignore it
virtual void kill(bool destroy_corpse, Entity* responsible) = 0;
virtual void kill(bool destroy_corpse, Entity* responsible) = 0; // 3

virtual void on_collision1(Entity* other_entity) = 0; // triggers on collision between whip and hit object
virtual void on_collision1(Entity* other_entity) = 0; // 4, triggers on collision between whip and hit object

/// Completely removes the entity from existence
virtual void destroy() = 0;

virtual void apply_texture(Texture*) = 0;
virtual void format_shopitem_name(char16_t*) = 0;
virtual void generate_stomp_damage_particles(Entity* victim) = 0; // particles when jumping on top of enemy
virtual float get_type_field_a8() = 0;
virtual bool can_be_pushed() = 0; // (runs only for activefloors?) checks if entity type is pushblock, for chained push block checks ChainedPushBlock.is_chained, is only a check that allows for the pushing animation
virtual bool v11() = 0; // for arrows: returns true if it's moving (for y possibily checks for some speed as well?)
virtual void destroy() = 0; // 5

virtual void apply_texture(Texture*) = 0; // 6
virtual void format_shopitem_name(char16_t*) = 0; // 7
virtual void generate_stomp_damage_particles(Entity* victim) = 0; // 8, particles when jumping on top of enemy
virtual float get_type_field_a8() = 0; // 9
virtual bool can_be_pushed() = 0; // 10, (runs only for activefloors?) checks if entity type is pushblock, for chained push block checks ChainedPushBlock.is_chained, is only a check that allows for the pushing animation
virtual bool v11() = 0; // 11, for arrows: returns true if it's moving (for y possibily checks for some speed as well?)
/// Returns true if entity is in water/lava
virtual bool is_in_liquid() = 0;
virtual bool check_type_properties_flags_19() = 0; // checks (properties_flags >> 0x12) & 1; for hermitcrab checks if he's invisible; can't get it to trigger
virtual uint32_t get_type_field_60() = 0;
virtual void set_invisible(bool value) = 0;
virtual void handle_turning_left(bool apply) = 0; // if disabled, monsters don't turn left and keep walking in the wall (and other right-left issues)
virtual void set_draw_depth(uint8_t draw_depth) = 0;
virtual void resume_ai() = 0; // works on entities with ai_func != 0; runs when companions are let go from being held. AI resumes anyway in 1.23.3
virtual float friction() = 0;
virtual void set_as_sound_source(SoundMeta*) = 0; // update sound position to entity position?
virtual void remove_item_ptr(Entity*) = 0;
virtual Entity* get_held_entity() = 0;
virtual void v23(Entity* logical_trigger, Entity* who_triggered_it) = 0; // spawns LASERTRAP_SHOT from LASERTRAP, also some trigger entities use this, seam to be called right after "on_collision2", tiggers use self as the first parameter
virtual bool is_in_liquid() = 0; // 12
virtual bool check_type_properties_flags_19() = 0; // 13, checks (properties_flags >> 0x12) & 1; for hermitcrab checks if he's invisible; can't get it to trigger
virtual uint32_t get_type_field_60() = 0; // 14
virtual void set_invisible(bool value) = 0; // 15
virtual void handle_turning_left(bool apply) = 0; // 16, if disabled, monsters don't turn left and keep walking in the wall (and other right-left issues)
virtual void set_draw_depth(uint8_t draw_depth) = 0; // 17
virtual void resume_ai() = 0; // 18, works on entities with ai_func != 0; runs when companions are let go from being held. AI resumes anyway in 1.23.3
virtual float friction() = 0; // 19
virtual void set_as_sound_source(SoundMeta*) = 0; // 20, update sound position to entity position?
virtual void remove_item_ptr(Entity*) = 0; // 21
virtual Entity* get_held_entity() = 0; // 22
virtual void v23(Entity* logical_trigger, Entity* who_triggered_it) = 0; // 23, spawns LASERTRAP_SHOT from LASERTRAP, also some trigger entities use this, seam to be called right after "on_collision2", tiggers use self as the first parameter
/// Triggers weapons and other held items like teleportter, mattock etc. You can check the [virtual-availability.md](https://github.com/spelunky-fyi/overlunky/blob/main/docs/virtual-availability.md), if entity has `open` in the `on_open` you can use this function, otherwise it does nothing. Returns false if action could not be performed (cooldown is not 0, no arrow loaded in etc. the animation could still be played thou)
virtual bool trigger_action(Entity* user) = 0;
virtual bool trigger_action(Entity* user) = 0; // 24
/// Activates a button prompt (with the Use door/Buy button), e.g. buy shop item, activate drill, read sign, interact in camp, ... `get_entity(<udjat socket uid>):activate(players[1])` (make sure player 1 has the udjat eye though)
virtual void activate(Entity* activator) = 0;
virtual void activate(Entity* activator) = 0; // 25

virtual void on_collision2(Entity* other_entity) = 0; // needs investigating, difference between this and on_collision1, maybe this is on_hitbox_overlap as it works for logical tiggers
virtual void on_collision2(Entity* other_entity) = 0; // 26, needs investigating, difference between this and on_collision1, maybe this is on_hitbox_overlap as it works for logical tiggers

/// e.g. for turkey: stores health, poison/curse state, for mattock: remaining swings (returned value is transferred)
virtual uint16_t get_metadata() = 0;
virtual void apply_metadata(uint16_t metadata) = 0;
virtual void on_walked_on_by(Entity* walker) = 0; // hits when monster/player walks on a floor, does something when walker.velocityy<-0.21 (falling onto) and walker.hitboxy * hitboxx > 0.09
virtual void on_walked_off_by(Entity* walker) = 0; // appears to be disabled in 1.23.3? hits when monster/player walks off a floor, it checks whether the walker has floor as overlay, and if so, removes walker from floor's items by calling virtual remove_item_ptr
virtual void on_ledge_grab(Entity* who) = 0; // only ACTIVEFLOOR_FALLING_PLATFORM, does something with game menager
virtual void on_stood_on_by(Entity* entity) = 0; // e.g. pots, skulls, pushblocks, ... standing on floors
virtual void toggle_backlayer_illumination() = 0; // only for CHAR_*: when going to the backlayer, turns on player emitted light
virtual void v34() = 0; // only ITEM_TORCH, calls Torch.light_up(false), can't get it to trigger
virtual void liberate_from_shop() = 0; // can also be seen as event: when you anger the shopkeeper, this function gets called for each item; can be called on shopitems individually as well and they become 'purchased'
virtual uint16_t get_metadata() = 0; // 27
virtual void apply_metadata(uint16_t metadata) = 0; // 28
virtual void on_walked_on_by(Entity* walker) = 0; // 29, hits when monster/player walks on a floor, does something when walker.velocityy<-0.21 (falling onto) and walker.hitboxy * hitboxx > 0.09
virtual void on_walked_off_by(Entity* walker) = 0; // 30, appears to be disabled in 1.23.3? hits when monster/player walks off a floor, it checks whether the walker has floor as overlay, and if so, removes walker from floor's items by calling virtual remove_item_ptr
virtual void on_ledge_grab(Entity* who) = 0; // 31, only ACTIVEFLOOR_FALLING_PLATFORM, does something with game menager
virtual void on_stood_on_by(Entity* entity) = 0; // 32, e.g. pots, skulls, pushblocks, ... standing on floors
virtual void toggle_backlayer_illumination() = 0; // 33, only for CHAR_*: when going to the backlayer, turns on player emitted light
virtual void v34() = 0; // 34, only ITEM_TORCH, calls Torch.light_up(false), can't get it to trigger
virtual void liberate_from_shop() = 0; // 35, can also be seen as event: when you anger the shopkeeper, this function gets called for each item; can be called on shopitems individually as well and they become 'purchased'

/// Applies changes made in `entity.type`
virtual void apply_db() = 0; // This is actually just an initialize call that is happening once after the entity is created
virtual void apply_db() = 0; // 36, This is actually just an initialize call that is happening once after the entity is created
};

std::tuple<float, float, uint8_t> get_position(uint32_t uid);
Expand Down
110 changes: 55 additions & 55 deletions src/game_api/movable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,65 +119,65 @@ class Movable : public Entity
/// Set the absolute position of an entity and offset all rendering related things accordingly to teleport without any interpolation or graphical glitches. If the camera is focused on the entity, it is also moved.
void set_position(float to_x, float to_y);

virtual bool can_jump() = 0;
virtual void get_collision_info(CollisionInfo*) = 0;
virtual float sprint_factor() = 0;
virtual void calculate_jump_height() = 0; // when disabled, jump height is very high
virtual std::unordered_map<uint8_t, Animation>& get_animation_map() = 0;
virtual void apply_velocity(float* velocities) = 0; // param is pointer to an array of two floats: velocity x and y
virtual int8_t stomp_damage() = 0; // calculates the amount of stomp damage applied (checks spike shoes, movable.state and stand_counter resulting in different damage values)
virtual int8_t stomp_damage_trampoline() = 0; // simply jumps to the 43rd virtual function, aka stomp_damage...
virtual bool is_on_fire() = 0;
virtual void v46() = 0;
virtual void v47() = 0;
virtual bool on_damage(Entity* damage_dealer, int8_t damage_amount, DAMAGE_TYPE damage_flags, Vec2* velocity, uint8_t unknown_damage_phase, uint16_t stun_amount, uint8_t iframes, bool unknown_is_final) = 0;
virtual bool can_jump() = 0; // 37
virtual void get_collision_info(CollisionInfo*) = 0; // 38
virtual float sprint_factor() = 0; // 39
virtual void calculate_jump_height() = 0; // 40, when disabled, jump height is very high
virtual std::unordered_map<uint8_t, Animation>& get_animation_map() = 0; // 41
virtual void apply_velocity(Vec2* velocities) = 0; // 42, param is pointer to an array of two floats: velocity x and y
virtual int8_t stomp_damage() = 0; // 43, calculates the amount of stomp damage applied (checks spike shoes, movable.state and stand_counter resulting in different damage values)
virtual int8_t stomp_damage_trampoline() = 0; // 44, simply jumps to the 43rd virtual function, aka stomp_damage...
virtual bool is_on_fire() = 0; // 45
virtual void v46() = 0; // 46
virtual void v47() = 0; // 47
virtual bool on_damage(Entity* damage_dealer, int8_t damage_amount, DAMAGE_TYPE damage_flags, Vec2* velocity, uint8_t unknown_damage_phase, uint16_t stun_amount, uint8_t iframes, bool unknown_is_final) = 0; // 48
/// Hit by broken arrows etc that don't deal damage, calls on_damage with 0 damage.
virtual void on_hit(Entity* damage_dealer) = 0;
virtual void v50() = 0;
virtual void stun(uint16_t framecount) = 0;
virtual void freeze(uint8_t framecount) = 0;
virtual void on_hit(Entity* damage_dealer) = 0; // 49
virtual void v50() = 0; // 50
virtual void stun(uint16_t framecount) = 0; // 51
virtual void freeze(uint8_t framecount) = 0; // 52
/// Does not damage entity
virtual void light_on_fire(uint8_t time) = 0;
virtual void set_cursed(bool b) = 0;
virtual void on_spiderweb_collision() = 0;
virtual void set_last_owner_uid_b127(Entity* owner) = 0; // assigns player as last_owner_uid and also manipulates movable.b127
virtual uint32_t get_last_owner_uid() = 0; // for players, it checks !stunned && !frozen && !cursed && !has_overlay; for others: just returns last_owner_uid
virtual void check_out_of_bounds() = 0; // kills with the 'still falling' death cause, is called for any item/fx/mount/monster/player but not for liquid :(
virtual void v59() = 0;
virtual Entity* standing_on() = 0; // looks up movable.standing_on_uid in state.instance_id_to_pointer
virtual void on_stomped_on_by(Entity* stomper) = 0;
virtual void on_thrown_by(Entity* thrower) = 0; // implemented for special cases like hired hand (player with ai_func), horned lizard...
virtual void on_clonegunshot_hit(Entity* clone) = 0; // implemented for player/hired hand: copies health to clone etc
virtual uint32_t get_type_id() = 0;
virtual bool doesnt_have_spikeshoes() = 0;
virtual bool is_player_mount_or_monster() = 0;
virtual void pick_up(Entity* entity_to_pick_up) = 0;
virtual void on_picked_up_by(Entity* entity_picking_up) = 0;
virtual void drop(Entity* entity_to_drop) = 0; // also used when throwing
virtual void light_on_fire(uint8_t time) = 0; // 53
virtual void set_cursed(bool b) = 0; // 54
virtual void on_spiderweb_collision() = 0; // 55
virtual void set_last_owner_uid_b127(Entity* owner) = 0; // 56, assigns player as last_owner_uid and also manipulates movable.b127
virtual uint32_t get_last_owner_uid() = 0; // 57, for players, it checks !stunned && !frozen && !cursed && !has_overlay; for others: just returns last_owner_uid
virtual void check_out_of_bounds() = 0; // 58, kills with the 'still falling' death cause, is called for any item/fx/mount/monster/player but not for liquid :(
virtual void v59() = 0; // 59
virtual Entity* standing_on() = 0; // 60, looks up movable.standing_on_uid in state.instance_id_to_pointer
virtual void on_stomped_on_by(Entity* stomper) = 0; // 61
virtual void on_thrown_by(Entity* thrower) = 0; // 62, implemented for special cases like hired hand (player with ai_func), horned lizard...
virtual void on_clonegunshot_hit(Entity* clone) = 0; // 63, implemented for player/hired hand: copies health to clone etc
virtual uint32_t get_type_id() = 0; // 64
virtual bool doesnt_have_spikeshoes() = 0; // 65
virtual bool is_player_mount_or_monster() = 0; // 66
virtual void pick_up(Entity* entity_to_pick_up) = 0; // 67
virtual void on_picked_up_by(Entity* entity_picking_up) = 0; // 68
virtual void drop(Entity* entity_to_drop) = 0; // 69, also used when throwing

/// Adds or subtracts the specified amount of money to the movable's (player's) inventory. Shows the calculation animation in the HUD.
virtual void add_money(uint32_t money) = 0;
virtual void add_money(uint32_t money) = 0; // 70

virtual void apply_movement() = 0; // disable this function and things can't move, some spin in place
virtual void damage_entity(Entity* victim) = 0; // can't trigger, maybe extra params are needed
virtual bool is_monster_or_player() = 0;
virtual void initialize() = 0; // e.g. cobra: set random spit_timer; bat: set random stand_counter; emerald: set price
virtual void check_is_falling() = 0; // sets more_flags.falling by comparing velocityy to 0
virtual void handle_stun_transition_animation() = 0; // e.g. the wiggle the dog does when waking up from being stunned
virtual void process_input() = 0; // unsure of params
virtual void post_collision_damage_related() = 0; // used for enemies attacks as well?
virtual void on_picked_up() = 0; // gets called after on_picked_up_by
virtual void hired_hand_related() = 0; // checks ai_func, gets triggered just after throwing hired hand
virtual void generate_fall_poof_particles() = 0; // entity.velocityy must be < -0.12 to generate a poof, might do other stuff regarding falling/landing
virtual void handle_fall_logic() = 0; // adjusts entity.velocityy when falling
virtual void apply_friction() = 0; // applies entity.type.friction to entity.velocityx
virtual void boss_related() = 0; // when disabled, quillback keeps stomping through the level, including border tiles
virtual void v85() = 0; // triggers when tusk is angered, calls get_last_owner_uid
virtual void gravity_related() = 0;
virtual void v87() = 0;
virtual void v88() = 0;
virtual void stack_plus_28_is_0() = 0; // unknown; triggers on item_rubble
virtual void on_crushed_by(Entity*) = 0; // e.g. crushed by elevator, punishball, pushblock, crushtrap (not quillback or boulder)
virtual void apply_movement() = 0; // 71, disable this function and things can't move, some spin in place
virtual void damage_entity(Entity* victim) = 0; // 72, can't trigger, maybe extra params are needed
virtual void v73() = 0; // 73
virtual bool is_monster_or_player() = 0; // 74
virtual void initialize() = 0; // 75, e.g. cobra: set random spit_timer; bat: set random stand_counter; emerald: set price
virtual void check_is_falling() = 0; // 76, sets more_flags.falling by comparing velocityy to 0
virtual void handle_stun_transition_animation() = 0; // 77, e.g. the wiggle the dog does when waking up from being stunned
virtual void process_input() = 0; // 78, unsure of params
virtual void post_collision_damage_related() = 0; // 79, used for enemies attacks as well?
virtual void on_picked_up() = 0; // 80, gets called after on_picked_up_by
virtual void hired_hand_related() = 0; // 81, checks ai_func, gets triggered just after throwing hired hand
virtual void generate_fall_poof_particles() = 0; // 82, entity.velocityy must be < -0.12 to generate a poof, might do other stuff regarding falling/landing
virtual void handle_fall_logic() = 0; // 83, adjusts entity.velocityy when falling
virtual void apply_friction() = 0; // 84, applies entity.type.friction to entity.velocityx
virtual void boss_related() = 0; // 85, when disabled, quillback keeps stomping through the level, including border tiles
virtual void v86() = 0; // 86, triggers when tusk is angered, calls get_last_owner_uid
virtual void gravity_related() = 0; // 87
virtual void v88() = 0; // 88
virtual void stack_plus_28_is_0() = 0; // 89, unknown; triggers on item_rubble
virtual void on_crushed_by(Entity*) = 0; // 90, e.g. crushed by elevator, punishball, pushblock, crushtrap (not quillback or boulder)
virtual void on_fall_onto(uint32_t unknown, Entity* fell_on_entity) = 0;
virtual void on_instakill_death() = 0; // seems to only trigger for enemies that die in one hit, // virtual 92
virtual void on_instakill_death() = 0; // 92, seems to only trigger for enemies that die in one hit
};
Loading

0 comments on commit d9d57f0

Please sign in to comment.