36 public T
Get(
int x,
int y,
int z) {
47 int explosionPower = y >> 4;
49 int num4 = num + (explosionPower << 4) + (num3 << 4 << 4);
55 int num8 = num5 + (num6 << 4) + (num7 << 4 << 4);
63 public void Set(
int x,
int y,
int z, T value) {
74 int explosionPower = y >> 4;
76 int num4 = num + (explosionPower << 4) + (num3 << 4 << 4);
85 int num8 = num5 + (num6 << 4) + (num7 << 4 << 4);
91 for (
int i = 0; i <
m_data.Length; i++) {
97 Dictionary<Point3, T> dictionary =
new();
98 for (
int i = 0; i <
m_data.Length; i++) {
104 int explosionPower =
m_originY + (((i >> 4) & 0xF) << 4);
105 int num3 =
m_originZ + (((i >> 8) & 0xF) << 4);
106 for (
int j = 0; j < array.Length; j++) {
107 if (!Equals(array[j],
default(T))) {
109 int num5 = (j >> 4) & 0xF;
110 int num6 = (j >> 8) & 0xF;
111 dictionary.Add(
new Point3(num + num4, explosionPower + num5, num3 + num6), array[j]);
197 if (explosionPressure > 0f) {
198 AddExplosion(x, y, z, explosionPressure, explosionIncendiary,
false);
204 public void AddExplosion(
int x,
int y,
int z,
float pressure,
bool isIncendiary,
bool noExplosionSound) {
207 new ExplosionData { X = x, Y = y, Z = z, Pressure = pressure, IsIncendiary = isIncendiary, NoExplosionSound = noExplosionSound }
233 if (MathF.Abs(explosionData.
X - x) <= 4
234 && MathF.Abs(explosionData.
Y - y) <= 4
235 && MathF.Abs(explosionData.
Z - z) <= 4) {
312 float num =
MathUtils.
Max(0.13f * MathF.Pow(pressure, 0.5f), 1f);
314 SparseSpatialArray<bool> processed =
new(x, y, z,
true);
315 List<ProcessPoint> list =
new();
316 List<ProcessPoint> list2 =
new();
317 List<ProcessPoint> list3 =
new();
328 int explosionPower = 0;
339 while (list.Count > 0
340 || list2.Count > 0) {
341 explosionPower += list.Count;
344 float num5 = pressure / (MathF.Pow(explosionPower, 0.66f) + num4);
348 float num7 = num5 + num6;
350 if (item.
Axis == 0) {
412 else if (item.
Axis == 1) {
474 else if (item.
Axis == 2) {
600 List<ProcessPoint> list4 = list;
612 float currentPressure,
614 List<ProcessPoint> toProcess,
615 SparseSpatialArray<bool> processed) {
616 if (processed.
Get(x, y, z)) {
622 int explosionPower = (int)(
MathUtils.
Hash((uint)(x + 913 * y + 217546 * z)) % 100u);
624 if (explosionPower % 8 == 0) {
635 float num6 = num4 / num5;
648 float probability = num6 > 5f ? 0.95f : 0.75f;
655 List<BlockDropValue> list =
new();
664 if (list.Count == 0) {
677 if (!(
m_random.Float(0f, 1f) < num8)) {
680 Vector3 velocity = impulse +
m_random.Vector3(0.05f * impulse.Length());
682 velocity *=
m_random.Float(0.5f, 1f);
685 float num9 = flag2 ? 0f :
689 new Vector3(x + 0.5f, y + 0.5f, z + 0.5f),
694 projectile.ProjectileStoppedAction = !(
m_random.Float(0f, 1f) < num9)
713 projectile.IsIncendiary = isIncendiary;
727 toProcess.Add(
new ProcessPoint { X = x, Y = y, Z = z, Axis = axis });
728 processed.
Set(x, y, z,
true);
739 float num =
float.MaxValue;
742 pressure += item.Value;
748 float num4 = 0.001f * MathF.Pow(pressure, 0.5f);
755 "CalculateExplosionPower",
757 loader.CalculateExplosionPower(
this, ref pressure);
762 int cellValue =
m_subsystemTerrain.Terrain.GetCellValue(item2.Key.X, item2.Key.Y, item2.Key.Z);
765 if (blockBehaviors.Length != 0) {
766 for (
int i = 0; i < blockBehaviors.Length; i++) {
767 blockBehaviors[i].
OnExplosion(cellValue, item2.Key.X, item2.Key.Y, item2.Key.Z, item2.Value.Pressure);
770 float probability = item2.Value.IsIncendiary ? 0.5f : 0.2f;
806 Vector3 position =
new(point.X, point.Y, point.Z);
808 if (pressure > 2000000f) {
809 if (playExplosionSound) {
814 else if (pressure > 400000f) {
815 if (playExplosionSound) {
820 else if (pressure > 80000f) {
821 if (playExplosionSound) {
826 else if (pressure > 16000f) {
827 if (playExplosionSound) {
832 else if (pressure > 3500f) {
833 if (playExplosionSound) {
838 else if (pressure > 80f) {
839 if (playExplosionSound) {
844 else if (pressure > 0f) {
845 if (playExplosionSound) {
867 for (
int i = -1; i <= 1; i++) {
868 for (
int j = -1; j <= 1; j++) {
869 for (
int k = -1; k <= 1; k++) {
870 int pressure = point.X + i;
871 int num3 = point.Y + j;
872 int num4 = point.Z + k;
874 ? obstaclePressure.Value
887 damage = 2.59259248f * MathF.Sqrt(num) / num6;
static float Saturate(float x)
static int Max(int x1, int x2)
static float Lerp(float x1, float x2, float f)
virtual void GetDropValues(SubsystemTerrain subsystemTerrain, int oldValue, int newValue, int toolLevel, List< BlockDropValue > dropValues, out bool showDebris)
virtual bool GetExplosionIncendiary(int value)
virtual float GetExplosionResilience(int value)
virtual float GetExplosionPressure(int value)
virtual bool IsCollidable_(int value)
virtual float GetFireDuration(int value)
virtual BoundingBox BoundingBox
virtual void UnderExplosionStart(Vector3 explosionCenter, float explosionPressure)
virtual void UnderExplosion(Vector3 impulse, float damage)
override void UnderExplosion(Vector3 impulse, float damage)
override void UnderExplosion(Vector3 impulse, float damage)
virtual void OnExplosion(int value, int x, int y, int z, float damage)
void Set(int x, int y, int z, T value)
Dictionary< Point3, T > ToDictionary()
SparseSpatialArray(int centerX, int centerY, int centerZ, T outside)
T Get(int x, int y, int z)
SubsystemTerrain m_subsystemTerrain
SubsystemProjectiles m_subsystemProjectiles
override void Load(ValuesDictionary valuesDictionary)
SparseSpatialArray< float > m_pressureByPoint
SubsystemBlockBehaviors m_subsystemBlockBehaviors
void TryAddPoint(int x, int y, int z, int axis, float currentPressure, bool isIncendiary, List< ProcessPoint > toProcess, SparseSpatialArray< bool > processed)
virtual void CalculateImpulseAndDamage(ComponentBody componentBody, float? obstaclePressure, out Vector3 impulse, out float damage)
virtual void CalculateImpulseAndDamage(Vector3 position, float mass, float? obstaclePressure, out Vector3 impulse, out float damage)
bool ShowExplosionPressure
SparseSpatialArray< SurroundingPressurePoint > m_surroundingPressureByPoint
SubsystemNoise m_subsystemNoise
ExplosionParticleSystem m_explosionParticleSystem
void SimulateExplosion(int x, int y, int z, float pressure, bool isIncendiary)
SubsystemPickables m_subsystemPickables
SubsystemBodies m_subsystemBodies
void AddExplosion(int x, int y, int z, float pressure, bool isIncendiary, bool noExplosionSound)
SubsystemAudio m_subsystemAudio
bool TryExplodeBlock(int x, int y, int z, int value)
Dictionary< Projectile, bool > m_generatedProjectiles
virtual void PostprocessExplosions(bool playExplosionSound)
virtual void ApplyBodiesShaking(Vector3 center, float pressure)
SubsystemParticles m_subsystemParticles
virtual void Update(float dt)
SubsystemFireBlockBehavior m_subsystemFireBlockBehavior
List< ExplosionData > m_queuedExplosions
static int ExtractContents(int value)
static int ToCell(float x)
static int MakeBlockValue(int contents)
ValuesDictionary ValuesDictionary
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static readonly Point3 Zero
static Vector3 Normalize(Vector3 v)
static readonly Vector3 Zero
ValuesDictionary ValuesDictionaryForMods
模组如果需要添加或使用额外信息,可以在这个ValuesDictionary读写元素