Skip to content

Commit

Permalink
Add gibs based on RF PS2 demo
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalh committed Feb 9, 2025
1 parent 352a41e commit 5516bbb
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Name | Description
`mute_player` | toggle processing of chat messages from a specific player
`fps_counter` | toggle FPS counter
`debug_event_msg` | toggle tracking of event messages in console
`gibs` | toggle gibs (characters exploding into parts)

### Server commands

Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Version 1.9.0 (not released yet)
- Enable loading RFL version 300
- Log a warning when RFL uses unsupported event class
- Add support for high resolution GeoMod textures
- Add gibs support based on RF PS2 demo (use `gibs` command to enable)

[@GooberRF](https://github.com/GooberRF)
- Fix crash when `verify_level` command is run without a level being loaded
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,13 +3,16 @@
#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/weapon.h"
#include "../rf/player/player.h"
#include "../rf/particle_emitter.h"
#include "../rf/os/frametime.h"
#include "../rf/sound/sound.h"
#include "../rf/debris.h"
#include "../rf/misc.h"
#include "../main/main.h"

rf::Timestamp g_player_jump_timestamp;
Expand Down Expand Up @@ -201,6 +204,86 @@ CodeInjection entity_process_pre_hide_riot_shield_injection{
},
};

constexpr int gore_setting_gibs = 2;

static FunHook entity_blood_throw_gibs_hook{
0x0042E3C0,
[](int handle) {
static const char *gib_chunk_filenames[] = {
"meatchunk1.v3d",
"meatchunk2.v3d",
"meatchunk3.v3d",
"meatchunk4.v3d",
"meatchunk5.v3d",
};
auto& gib_impact_sound_set = addr_as_ref<rf::ImpactSoundSet*>(0x0062F75C);

if (rf::player_gore_setting < gore_setting_gibs) {
return;
}

constexpr int eif_ambient = 0x800000;
rf::Entity* ep = rf::entity_from_handle(handle);
if (ep && ep->info->flags & eif_ambient) {
// bats and fish
return;
}

constexpr int flash_material = 3;
rf::Object* objp = rf::obj_from_handle(handle);

if (objp && (objp->type == rf::OT_ENTITY || objp->type == rf::OT_CORPSE) && objp->material == flash_material) {
rf::DebrisCreateStruct dcs{};
for (int i = 0; i < 10; ++i) {
dcs.pos = objp->pos;
dcs.vel.rand_quick();
dcs.vel *= 10.0; // PS2 demo uses 15
dcs.vel += objp->p_data.vel * 0.5;
dcs.orient.rand_quick();
dcs.spin.rand_quick();
float scale = rf::fl_rand_range(10.0, 25.0);
dcs.spin *= scale;
dcs.lifespan_ms = 5000; // 5 sec. PS2 demo uses 2.7 sec.
dcs.material = flash_material;
dcs.explosion_index = -1;
dcs.debris_flags = 4;
dcs.obj_flags = 0x8000; // OF_START_HIDDEN
dcs.iss = gib_impact_sound_set;
int file_index = rand() % std::size(gib_chunk_filenames);
auto dp = rf::debris_create(objp->handle, gib_chunk_filenames[file_index], 0.3, &dcs, 0, -1.0);
if (dp) {
dp->obj_flags |= rf::OF_INVULNERABLE;
}
}
}
},
};

static FunHook<float(rf::Entity*, float, int, int, int)> entity_damage_hook{
0x0041A350,
[](rf::Entity *damaged_ep, float damage, int killer_handle, int damage_type, int killer_uid) {
float result = entity_damage_hook.call_target(damaged_ep, damage, killer_handle, damage_type, killer_uid);
if (
rf::player_gore_setting >= gore_setting_gibs
&& damaged_ep->life < -100.0 // high damage taken
&& damaged_ep->material == 3 // flash material
&& (damage_type == 3 || damage_type == 9) // armor piercing bullet or scalding
&& damaged_ep->radius < 2.0 // make sure only small entities use gibs
) {
damaged_ep->entity_flags = damaged_ep->entity_flags | 0x80; // throw gibs
}
return result;
},
};

ConsoleCommand2 gibs_cmd{
"gibs",
[]() {
rf::player_gore_setting = rf::player_gore_setting == gore_setting_gibs ? 1 : gore_setting_gibs;
rf::console::print("Gibs are {}", rf::player_gore_setting == gore_setting_gibs ? "enabled" : "disabled");
},
};

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 +335,9 @@ 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();

// Add gibs support
entity_blood_throw_gibs_hook.install();
entity_damage_hook.install();
gibs_cmd.register_cmd();
}
29 changes: 29 additions & 0 deletions game_patch/rf/debris.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include "object.h"
#include "weapon.h"

namespace rf {
struct DebrisCreateStruct
{
Vector3 pos;
Matrix3 orient;
Vector3 vel;
Vector3 spin;
int lifespan_ms = 1000;
int material = 0;
int explosion_index = -1;
int debris_flags = 0;
int obj_flags = 0;
GRoom *room = nullptr;
ImpactSoundSet *iss = nullptr;

DebrisCreateStruct()
{
orient.make_identity();
}
};
using Debris = Object;

auto& debris_create = addr_as_ref<Debris *(int parent_handle, const char *vmesh_filename, float mass, DebrisCreateStruct *dcs, int mesh_num, float collision_radius)>(0x00412E70);
}
5 changes: 5 additions & 0 deletions game_patch/rf/math/matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ namespace rf
AddrCaller{0x004FC8A0}.this_call(this, &result);
return result;
}

void rand_quick()
{
AddrCaller{0x004FCCC0}.this_call(this);
}
};
static_assert(sizeof(Matrix3) == 0x24);

Expand Down
5 changes: 5 additions & 0 deletions game_patch/rf/math/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ namespace rf
{
*this /= len();
}

void rand_quick()
{
AddrCaller{0x004FAD60}.this_call(this);
}
};
static_assert(sizeof(Vector3) == 0xC);

Expand Down
1 change: 1 addition & 0 deletions game_patch/rf/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ namespace rf
static auto& default_player_weapon = addr_as_ref<String>(0x007C7600);

static auto& get_file_checksum = addr_as_ref<unsigned(const char* filename)>(0x00436630);
static auto& fl_rand_range = addr_as_ref<float(float min, float max)>(0x00504E40);
}
1 change: 1 addition & 0 deletions game_patch/rf/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace rf
enum ObjectFlags
{
OF_DELAYED_DELETE = 0x2,
OF_INVULNERABLE = 0x4,
OF_WAS_RENDERED = 0x10,
OF_IN_LIQUID = 0x80000,
OF_HAS_ALPHA = 0x100000,
Expand Down
1 change: 1 addition & 0 deletions game_patch/rf/player/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ namespace rf

static auto& player_list = addr_as_ref<Player*>(0x007C75CC);
static auto& local_player = addr_as_ref<Player*>(0x007C75D4);
static auto& player_gore_setting = addr_as_ref<int>(0x005A00F0);

static auto& player_from_entity_handle = addr_as_ref<Player*(int entity_handle)>(0x004A3740);
static auto& player_is_dead = addr_as_ref<bool(const Player *player)>(0x004A4920);
Expand Down
6 changes: 6 additions & 0 deletions resources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ add_packfile(dashfaction.vpp
images/mtl_archway04-mip1.tga
images/pls_airlockmat01-mip2.tga
images/consolebutton2A.tga
images/gore1.tga # https://www.filterforge.com/filters/7459.html

fonts/biggerfont.vf
fonts/regularfont.ttf
Expand All @@ -87,6 +88,11 @@ add_packfile(dashfaction.vpp
meshes/Vat1.v3m
meshes/coffeesmokedtbl2.v3m
meshes/coffeesmokedtblAlt.v3m
meshes/meatchunk1.v3m
meshes/meatchunk2.v3m
meshes/meatchunk3.v3m
meshes/meatchunk4.v3m
meshes/meatchunk5.v3m

standard_vs:${CMAKE_BINARY_DIR}/shaders/standard_vs.bin
character_vs:${CMAKE_BINARY_DIR}/shaders/character_vs.bin
Expand Down
Binary file added resources/gore.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/gore1.tga
Binary file not shown.
Binary file added resources/meshes/meatchunk1.v3m
Binary file not shown.
Binary file added resources/meshes/meatchunk2.v3m
Binary file not shown.
Binary file added resources/meshes/meatchunk3.v3m
Binary file not shown.
Binary file added resources/meshes/meatchunk4.v3m
Binary file not shown.
Binary file added resources/meshes/meatchunk5.v3m
Binary file not shown.

0 comments on commit 5516bbb

Please sign in to comment.