Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement cut stock game gibbing feature #294

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Version 1.9.0 (not released yet)
- Add `server_password` command
- Add `$DF CTF Flag Return Time` option in dedicated server config
- Add mod name to main menu
- Add `gore_level` command
- Add gibbing when enemies die from explosives (gore level 2)

[@is-this-c](https://github.com/is-this-c)
- Support `©` in TrueType fonts
Expand Down
12 changes: 12 additions & 0 deletions game_patch/multi/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,18 @@ FunHook<float(rf::Entity*, float, int, int, int)> entity_damage_hook{
}
}

// should entity gib?
if (damaged_ep->life < -100.0f && damage_type == 3 && // explosive
damaged_ep->material == 3 && // flesh
rf::game_get_gore_level() >= 2 &&
!(damaged_ep->entity_flags & 0x2000000) && // custom_corpse (used by snakes and sea creature)
!(damaged_ep->entity_flags & 0x1) && // dying
!(damaged_ep->entity_flags & 0x1000) && // in_water
!(damaged_ep->entity_flags & 0x2000)) // eye_under_water
{
damaged_ep->entity_flags |= 0x80;
}

float real_damage = entity_damage_hook.call_target(damaged_ep, damage, killer_handle, damage_type, killer_uid);

if (rf::is_server && is_pvp_damage && real_damage > 0.0f) {
Expand Down
88 changes: 88 additions & 0 deletions game_patch/object/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
#include <patch_common/CallHook.h>
#include <patch_common/AsmWriter.h>
#include <xlog/xlog.h>
#include "../os/console.h"
#include "../rf/entity.h"
#include "../rf/corpse.h"
#include "../rf/multi.h"
#include "../rf/weapon.h"
#include "../rf/player/player.h"
#include "../rf/particle_emitter.h"
Expand Down Expand Up @@ -201,6 +203,85 @@ CodeInjection entity_process_pre_hide_riot_shield_injection{
},
};

// avoids gibbing if gore level is too low or if this specific corpse shouldn't gib
CodeInjection corpse_damage_patch{
0x00417C6A,
GooberRF marked this conversation as resolved.
Show resolved Hide resolved
[](auto& regs) {
rf::Corpse* cp = regs.esi;

if (rf::game_get_gore_level() < 2 ||
cp->corpse_flags & 0x400 || // drools_slime (used by snakes)
cp->corpse_flags & 0x4) // custom_state_anim (used by sea creature)
{
regs.eip = 0x00417C97;
}
}
};

FunHook<void(int)> entity_blood_throw_gibs_hook{
0x0042E3C0, [](int handle) {
rf::Object* objp = rf::obj_from_handle(handle);

if (!objp) {
return;
}

int explode_vclip_index = rf::vclip_lookup("bloodsplat");
int chunk_explode_vclip_index = rf::vclip_lookup("bloodsplat");
float explode_vclip_radius = 1.0f;
const char* debris_filename = "df_meatchunks0.V3D";

static const int debris_max_lifetime = 7000; // ms
static const float debris_velocity = 8.5f;
static const float damage_scale = 1.0f;
static rf::String cust_snd_set = "gib bounce";

if (objp->type == rf::OT_ENTITY) { // use overrides from associated entity.tbl class if present
rf::Entity* ep = static_cast<rf::Entity*>(objp);

explode_vclip_index = (ep->info->explode_vclip_index > 0)
? ep->info->explode_vclip_index : explode_vclip_index;

explode_vclip_radius = (ep->info->explode_vclip_radius > 0.0f)
? ep->info->explode_vclip_radius : explode_vclip_radius;

debris_filename = (!ep->info->debris_filename.empty())
? ep->info->debris_filename.c_str() : debris_filename;
}
else if (objp->type != rf::OT_CORPSE) { // do not gib anything except entities and corpses
return;
}

rf::game_do_explosion(
explode_vclip_index, objp->room, 0, &objp->pos, explode_vclip_radius, damage_scale, 0);

rf::debris_spawn_from_object(
objp, debris_filename, chunk_explode_vclip_index, debris_max_lifetime, debris_velocity, &cust_snd_set);
}
};

ConsoleCommand2 gore_level_cmd{
"gore_level",
[](std::optional<int> gore_setting) {
if (gore_setting) {
if (*gore_setting >= 0 && *gore_setting <= 2) {
rf::game_set_gore_level(*gore_setting);
rf::console::print("Set gore level to {}", rf::game_get_gore_level());
}
else {
rf::console::print("Invalid gore level specified. Allowed range is 0 (minimal) to 2 (maximum).");
}
}
else {
rf::console::print("Gore level is {}", rf::game_get_gore_level());
}


},
"Set gore level.",
"gore_level [level]"
};

void entity_do_patch()
{
// Fix player being stuck to ground when jumping, especially when FPS is greater than 200
Expand Down Expand Up @@ -252,4 +333,11 @@ void entity_do_patch()

// Hide riot shield third person model if entity is hidden (e.g. in cutscenes)
entity_process_pre_hide_riot_shield_injection.install();

// Restore cut stock game feature for entities and corpses exploding into chunks
corpse_damage_patch.install();
entity_blood_throw_gibs_hook.install();

// Commands
gore_level_cmd.register_cmd();
}
3 changes: 3 additions & 0 deletions game_patch/rf/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ namespace rf
static auto& entity_turn_weapon_on = addr_as_ref<void __cdecl(int entity_handle, int weapon_type, bool alt_fire)>(0x0041A870);
static auto& entity_turn_weapon_off = addr_as_ref<void __cdecl(int entity_handle, int weapon_type)>(0x0041AE70);
static auto& entity_restore_mesh = addr_as_ref<void(Entity *ep, const char *mesh_name)>(0x0042C570);
static auto& game_do_explosion = addr_as_ref<void(int vclip, GRoom* src_room, const Vector3* src_pos,
const Vector3* pos, float radius, float damage_scale, const Vector3* dir)>(0x00436490);
static auto& vclip_lookup = addr_as_ref<int(const char*)>(0x004C1D00);

static auto& entity_list = addr_as_ref<Entity>(0x005CB060);
static auto& local_player_entity = addr_as_ref<Entity*>(0x005CB054);
Expand Down
3 changes: 3 additions & 0 deletions game_patch/rf/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ namespace rf
static auto& obj_light_calculate = addr_as_ref<void()>(0x0048B0E0);

static auto& object_list = addr_as_ref<Object>(0x0073D880);

static auto& debris_spawn_from_object = addr_as_ref<void(Object* objp, const char* debris_v3d_filename,
int explode_index, int max_lifetime_ms, float velocity, rf::String* cust_snd_set)>(0x004133C0);
GooberRF marked this conversation as resolved.
Show resolved Hide resolved
}

template<>
Expand Down
2 changes: 2 additions & 0 deletions game_patch/rf/player/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,6 @@ namespace rf
static auto& player_do_frame = addr_as_ref<void(Player*)>(0x004A2700);
static auto& player_make_weapon_current_selection = addr_as_ref<void(Player *player, int weapon_type)>(0x004A4980);
static auto& player_start_death_fade = addr_as_ref<void(Player *pp, float time_sec, void (*callback)(Player *))>(0x004A73E0);
static auto& game_get_gore_level = addr_as_ref<int()>(0x00436A20);
static auto& game_set_gore_level = addr_as_ref<int(int gore_setting)>(0x00436A10);
GooberRF marked this conversation as resolved.
Show resolved Hide resolved
}
2 changes: 2 additions & 0 deletions resources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ add_packfile(dashfaction.vpp
images/bullet_icon_powercell_1.tga
images/bullet_icon_rocket_1.tga
images/bullet_icon_shotgun_1.tga
images/df_gore1.tga
images/enviro0_1.tga
images/enviro10_1.tga
images/enviro20_1.tga
Expand Down Expand Up @@ -87,6 +88,7 @@ add_packfile(dashfaction.vpp
meshes/Vat1.v3m
meshes/coffeesmokedtbl2.v3m
meshes/coffeesmokedtblAlt.v3m
meshes/df_meatchunks0.v3m
GooberRF marked this conversation as resolved.
Show resolved Hide resolved

standard_vs:${CMAKE_BINARY_DIR}/shaders/standard_vs.bin
character_vs:${CMAKE_BINARY_DIR}/shaders/character_vs.bin
Expand Down
Binary file added resources/images/df_gore1.tga
Binary file not shown.
1 change: 1 addition & 0 deletions resources/licensing-info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Chris "Goober" Parsons:
* HUD textures for the big mode
* symbol glyphs in ttf fonts
* launcher header
* texture and mesh for gibs
GooberRF marked this conversation as resolved.
Show resolved Hide resolved

natalie <[email protected]>:
* code contributions
Expand Down
Binary file added resources/meshes/df_meatchunks0.v3m
Binary file not shown.