aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile4
-rw-r--r--README.md2
-rw-r--r--expexc.c62
4 files changed, 68 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index aaef89d..41db595 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
a.out
*.o
expvc
+expexc
diff --git a/Makefile b/Makefile
index 45abb28..99614c1 100644
--- a/Makefile
+++ b/Makefile
@@ -3,11 +3,13 @@ CFLAGS += -I.
CFLAGS += -std=c99
CFLAGS += -Wall
LDLIBS += -lm
-BIN = expvc
+BIN = expvc expexc
all: $(BIN)
expvc: expvc.c
+expexc: expexc.c
+
clean:
rm -rf $(BIN)
diff --git a/README.md b/README.md
index 78c6bcf..496cb31 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ This repository contains codes for:
* `expvc`: Explosion entity velocity and damage calculator.
+* `expexc`: Explosion entity exposure ray casting simulator.
+
## Compile
Just `make(1)`. How to build on Windows is left as an exercise to the reader.
diff --git a/expexc.c b/expexc.c
new file mode 100644
index 0000000..2ca52d3
--- /dev/null
+++ b/expexc.c
@@ -0,0 +1,62 @@
+/*
+ * Explosion exposure rays simulator.
+ *
+ * @1.17.1
+ */
+
+#include "common.h"
+
+static inline double lerp(double delta, double start, double end) { return start + delta * (end - start); }
+
+int main(int argc, char **argv)
+{
+ struct box bbox = { BOX, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+ if (argc <= 1)
+ {
+ goto usage;
+usage:
+ fprintf(stderr, "Usage: %s minX,minY,minZ,maxX,maxY,maxZ (Bounding box of the target entity)\n"
+ "\n"
+ "Use this tool to simulate the rays to cast for exposure rate calculation.\n"
+ "Whenever an entity is to be affected by an explosion, Minecraft will cast lots of rays from the explosion center to the target entity to see how many of them are blocked. The percentage of successful casts will be used for acceleration and damage calculation (see expvc(1) -x).\n"
+ "\n"
+ "Output: Destination coords for ray casting. The source coord is the explosion center.\n"
+ , argv[0]);
+ return 64;
+ }
+ if (val_parse(argv[1], (struct val *)&bbox)) goto usage;
+ fprintf(stderr, "Box(%.2f, %.2f, %.2f -> %.2f, %.2f, %.2f)\n",
+ bbox.min_x,
+ bbox.min_y,
+ bbox.min_z,
+ bbox.max_x,
+ bbox.max_y,
+ bbox.max_z);
+ double x_step = 1.0 / ((bbox.max_x - bbox.min_x) * 2.0 + 1.0);
+ double y_step = 1.0 / ((bbox.max_y - bbox.min_y) * 2.0 + 1.0);
+ double z_step = 1.0 / ((bbox.max_z - bbox.min_z) * 2.0 + 1.0);
+ double x_half_remain = (1.0 - floor(1.0 / x_step) * x_step) / 2.0;
+ double z_half_remain = (1.0 - floor(1.0 / z_step) * z_step) / 2.0;
+ if (x_step < 0.0 || y_step < 0.0 || z_step < 0.0) {
+ fprintf(stderr, "Iteration step length is less than zero. This means that the max dimensions are smaller than the min dimensions. No ray is possible.\n");
+ return 0;
+ }
+ for (float x_samp_pos_delta_percentage = 0.0f; x_samp_pos_delta_percentage <= 1.0f; x_samp_pos_delta_percentage += x_step)
+ {
+ for (float y_samp_pos_delta_percentage = 0.0f; y_samp_pos_delta_percentage <= 1.0f; y_samp_pos_delta_percentage += y_step)
+ {
+ for (float z_samp_pos_delta_percentage = 0.0f; z_samp_pos_delta_percentage <= 1.0f; z_samp_pos_delta_percentage += z_step)
+ {
+ double x_samp_pos = lerp(x_samp_pos_delta_percentage, bbox.min_x, bbox.max_x);
+ double y_samp_pos = lerp(y_samp_pos_delta_percentage, bbox.min_y, bbox.max_y);
+ double z_samp_pos = lerp(z_samp_pos_delta_percentage, bbox.min_z, bbox.max_z);
+ printf("%.5f,%.5f,%.5f\n",
+ x_samp_pos + x_half_remain,
+ y_samp_pos,
+ z_samp_pos + z_half_remain);
+ }
+ }
+ }
+ return 0;
+}
+