* Adding clipper to generate the terrain's negative powder-contour offset. * Fixing RDB issues (fracture, active trigger, performances) * Fixing blood emission * Fixing the freezing formula on liquids * Fixing Steve spawning due to a missed test. * Reaction table properly build
55 lines
2.8 KiB
C++
55 lines
2.8 KiB
C++
#pragma once
|
|
#include <cmath>
|
|
#include <cstdint>
|
|
namespace ng {
|
|
// 00ab9a90 and real-particle constructor 00716af0. RNG supplied by caller.
|
|
inline int hit_liquid_count(float u, float entity, float incoming, int world) {
|
|
return int(((u * 20.0f + 20.0f) * entity + 0.5f) * incoming) * world;
|
|
}
|
|
inline bool hit_liquid_enabled(float damage, float incoming, int fx, bool frozen) {
|
|
return damage > 0.0f && incoming > 0.0f && fx != 0 && !frozen;
|
|
}
|
|
inline float projectile_hit_liquid_speed(float ragdollForce) {
|
|
return ragdollForce != 0.0f ? std::sqrt(0.005f / ragdollForce) : 1.0f;
|
|
}
|
|
inline bool inventory_hit_liquid_enabled(float damage, float hp, float probability, float threshold, float u, bool emitter) {
|
|
return probability > 0 && damage < hp && damage > threshold && u < probability && emitter;
|
|
}
|
|
inline void hit_liquid_local_point(float& x, float& y, float sx, float sy, float angle, bool hitbox, const float* bounds) {
|
|
if (sx != 0) x /= sx;
|
|
if (sy != 0) y /= sy;
|
|
const float c = std::cos(angle), s = std::sin(angle), nx = c * x + s * y;
|
|
y = -s * x + c * y; x = nx;
|
|
if (hitbox) {
|
|
x = x < bounds[0] ? bounds[0] : (x > bounds[1] ? bounds[1] : x);
|
|
y = y < bounds[2] ? bounds[2] : (y > bounds[3] ? bounds[3] : y);
|
|
} else if (x * x + y * y > 65536.0f) x = y = 0;
|
|
}
|
|
struct HitLiquidDrop { float x, y, vx, vy; };
|
|
inline HitLiquidDrop hit_liquid_drop(float x, float y, float& vx, float& vy,
|
|
float speedScale, float speedU, float angleU, float yU, float xU) {
|
|
const float a = -0.6f + 1.2f * angleU, c = std::cos(a), s = std::sin(a);
|
|
const float nx = vx * c - vy * s;
|
|
vy = vx * s + vy * c; vx = nx;
|
|
const float speed = (20.0f / 60.0f) * (0.5f + 0.75f * speedU) * speedScale;
|
|
return {x - 1.0f + 3.0f * xU, y - 1.0f + 3.0f * yU, vx * speed, vy * speed};
|
|
}
|
|
inline int ragdoll_hit_liquid_reserve(float u, float world, float ragdoll, double partMass, double totalMass, int absolute) {
|
|
const double amount = absolute < 0 || totalMass <= 0 ? partMass * 1000.0 : partMass / totalMass * absolute;
|
|
return int((0.8f + 0.40000004f * u) * float(int(world * ragdoll) * int(amount)));
|
|
}
|
|
// std430 ABI: binding 67; one entry per entity, then one per projectile type.
|
|
struct HitLiquidPolicy { uint32_t materials = 0, multiplier = 0, baseColour = 0, sprayColour = 0;
|
|
uint32_t flags = 0, reserved[3] = {};
|
|
float bounds[4] = {}; // min x, max x, min y, max y
|
|
float inventory[4] = {0, 0.09f, 1, 1}; // probability, minimum damage, entity scale x/y
|
|
float pressure[4] = {0.7f, 1.1f, 0, 0}; // pressure range, trail gap, reserved
|
|
};
|
|
struct HitLiquidTable {
|
|
int32_t settings[4] = {1, 0, 0, 0};
|
|
HitLiquidPolicy entities[4096];
|
|
float projectile[512][4] = {};
|
|
};
|
|
static_assert(sizeof(HitLiquidPolicy) == 80);
|
|
}
|