From f2558ff0c2ef20fa884c2f23ecbcf6d6d7b00e00 Mon Sep 17 00:00:00 2001 From: Trumeet Date: Sun, 21 Nov 2021 17:35:40 -0800 Subject: First commit --- .gitignore | 3 ++ Makefile | 12 +++++ README.md | 13 +++++ expvc.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 expvc.c 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 +#include +#include +#include + +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; +} -- cgit v1.2.3