aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2021-11-21 17:35:40 -0800
committerTrumeet <yuuta@yuuta.moe>2021-11-21 17:35:40 -0800
commitf2558ff0c2ef20fa884c2f23ecbcf6d6d7b00e00 (patch)
treeffb9713f6d0e3f85edf37a7a6696918e85cf39fa
downloadmcal-f2558ff0c2ef20fa884c2f23ecbcf6d6d7b00e00.tar
mcal-f2558ff0c2ef20fa884c2f23ecbcf6d6d7b00e00.tar.gz
mcal-f2558ff0c2ef20fa884c2f23ecbcf6d6d7b00e00.tar.bz2
mcal-f2558ff0c2ef20fa884c2f23ecbcf6d6d7b00e00.zip
First commit
-rw-r--r--.gitignore3
-rw-r--r--Makefile12
-rw-r--r--README.md13
-rw-r--r--expvc.c159
4 files changed, 187 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aaef89d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+a.out
+*.o
+expvc
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f53dfc5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+.POSIX:
+CFLAGS += -std=c99
+CFLAGS += -Wall
+LDLIBS += -lm
+BIN = expvc
+
+all: $(BIN)
+
+expvc: expvc.c
+
+clean:
+ rm -rf $(BIN)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..78c6bcf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Minecraft calculators (mcal)
+
+This repository contains codes for:
+
+* `expvc`: Explosion entity velocity and damage calculator.
+
+## Compile
+
+Just `make(1)`. How to build on Windows is left as an exercise to the reader.
+
+## License
+
+WTFPL
diff --git a/expvc.c b/expvc.c
new file mode 100644
index 0000000..7cd3af8
--- /dev/null
+++ b/expvc.c
@@ -0,0 +1,159 @@
+/*
+ * Explosion entity velocity and damage calculator.
+ *
+ * @1.17.1
+ *
+ */
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <math.h>
+
+struct vec3d {
+ double x;
+ double y;
+ double z;
+};
+
+static int vec3d_parse(char *in, struct vec3d *out)
+{
+ int i = 0;
+ char *p = strtok(in, ",");
+ while (p != NULL)
+ {
+ double *ptr;
+ switch (i ++)
+ {
+ case 0:
+ ptr = &out->x;
+ break;
+ case 1:
+ ptr = &out->y;
+ break;
+ case 2:
+ ptr = &out->z;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ sscanf(p, "%lf", ptr);
+ p = strtok(NULL, ",");
+ }
+ if (i != 3)
+ {
+ fprintf(stderr, "Invalid Vec3D: %s. Example: -1,1,1.\n", in);
+ return 64;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ struct vec3d tnt = { 0.0, 0.0, 0.0 };
+ struct vec3d entity = { 0.0, 0.0, 0.0 };
+ struct vec3d velocity = { 0.0, 0.0, 0.0 };
+ double entity_eye_y = 0.0;
+ int is_tnt = 1;
+ double power = 4.0;
+ double exposure = 1.0;
+ if (argc <= 1)
+ {
+ goto usage;
+usage:
+ fprintf(stderr, "Usage: %s -t 0,0,0 -e 0,0,0 [-v 0,0,0]\n"
+ "\n"
+ "Options:\n"
+ "\t-t vec3d\tTNT entity coords [Mandatory]\n"
+ "\t-e vec3d\tTarget entity coords [Mandatory]\n"
+ "\t-p double\tExplosion power [Optional, defaults to 4.0 (TNT)]\n"
+ "\t-ey vec3d\tTarget entity eye Y [Optional if the target is a TNT]\n"
+ "\t-v vec3d\tTarget entity initial velocity [Optional, defaults to 0,0,0]\n"
+ "\t-x double\tExposure of explosion. Percentage. 1.0 if no blocks blocking the ray. [Optional, defaults to 1.0]\n"
+ "\t-h\t\tPrint usage to stderr\n"
+ "\n"
+ "Vec3D Format: x,y,z. No spaces or brackets allowed.\n", argv[0]);
+ return 64;
+ }
+ int r = 0;
+ for (int i = 1; i < argc; i ++)
+ {
+ const char *arg = argv[i];
+ if (!strcmp("-h", arg)) goto usage;
+ if (i == argc - 1)
+ {
+ fprintf(stderr, "%s requires an argument.\n", arg);
+ goto usage;
+ }
+ char *val = argv[++i];
+ if (!strcmp("-t", arg)) { if ((r = vec3d_parse(val, &tnt))) return r; }
+ else if (!strcmp("-e", arg)) { if ((r = vec3d_parse(val, &entity))) return r; }
+ else if (!strcmp("-v", arg)) { if ((r = vec3d_parse(val, &velocity))) return r; }
+ else if (!strcmp("-ey", arg))
+ {
+ sscanf(val, "%lf", &entity_eye_y);
+ is_tnt = 0;
+ }
+ else if (!strcmp("-p", arg)) sscanf(val, "%lf", &power);
+ else if (!strcmp("-x", arg))
+ {
+ sscanf(val, "%lf", &exposure);
+ if (exposure < 0.0 || exposure > 1.0)
+ {
+ fprintf(stderr, "Invalid exposure: [0.0, 1.0]\n");
+ goto usage;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Unknown argument: %s\n", arg);
+ goto usage;
+ }
+ }
+ printf("(%.5f, %.5f, %.5f) -> %.2f -> %c(%.5f, %.5f, %.5f)\n",
+ tnt.x,
+ tnt.y,
+ tnt.z,
+ power,
+ is_tnt ? 'T' : 'E',
+ entity.x,
+ entity.y,
+ entity.z);
+ double power2 = 2.0 * power;
+ double xx = entity.x - tnt.x;
+ double zz = entity.z - tnt.z;
+ double yy = (is_tnt ? entity.y : entity_eye_y) - tnt.y;
+ double dist = sqrt(xx * xx + (entity.y - tnt.y) * (entity.y - tnt.y) + zz * zz);
+ printf("Square distance: %.5f\n", dist);
+ if (dist / power2 > 1)
+ {
+ printf("Not affected, to too far. (Square distance = %.5f).\n", dist);
+ return 0;
+ }
+ printf("Delta distance: %.5f, %.5f, %.5f\n", xx, yy, zz);
+ double dist_eye_y = sqrt(xx * xx + yy * yy + zz * zz);
+ if (dist_eye_y == 0)
+ {
+ printf("Not affected due to dist_eye_y == 0.\n");
+ return 0;
+ }
+ xx /= dist_eye_y;
+ yy /= dist_eye_y;
+ zz /= dist_eye_y;
+ printf("Delta distance final: %.5f, %.5f, %.5f\n", xx, yy, zz);
+ double accel = (1.0 - (dist / power2)) * exposure;
+ printf("Accel: %.5f\n", accel);
+ int damage = (int) ((accel * accel + accel) / 2.0 * 7.0 * power2 + 1.0);
+ printf("Damage: %d\n", damage);
+ struct vec3d delta_v = {
+ xx * accel,
+ yy * accel,
+ zz * accel
+ };
+ printf("Delta velocity: (%.5f, %.5f, %.5f)\n", delta_v.x, delta_v.y, delta_v.z);
+ velocity.x += delta_v.x;
+ velocity.y += delta_v.y;
+ velocity.z += delta_v.z;
+ printf("Final velocity: (%.5f, %.5f, %.5f)\n", velocity.x, velocity.y, velocity.z);
+ return 0;
+}