Name the tiles to make everything better because I'm a bloody idiot
[SmugglerRL.git] / src / util.d
blob22c55402dd52a1c4b9bc1a57902dff2346918f18
1 import std.exception: Exception;
2 import std.functional: memoize;
4 import colour;
5 import constants;
6 import game;
7 import stdlib;
10 // provides dynamic function dispatch with objects, not classes
11 mixin template funcwrapper(alias func) {
12 import std.traits: ReturnType;
13 mixin(ReturnType!func.stringof ~ " "
14 ~ __traits(identifier, func)[1 .. $] // [1:$] to get rid of the leading _
15 ~ "(T...)(T args) {" // (Parameters!func).stringof
16 ~ (ReturnType!func.stringof == "void" ? "" : "return ")
17 ~ __traits(identifier, func) ~ " ? " // if the function exists, call it. Otherwise, do nothing (call pass)
18 ~ __traits(identifier, func) ~ "(this, args)"
19 ~ " : " ~ (ReturnType!func.stringof == "void" ? "pass" : (ReturnType!func.stringof ~ ".init")) ~ ";"
20 ~ "}");
23 /*mixin template funcwrappers(funcs...) {
24 static foreach (func; funcs) {
25 mixin funcwrapper!func;
27 }*/
29 // example:
31 struct Bla {
32 int n;
34 void delegate(ref Bla self) _func;
36 mixin funcwrapper!_func;
39 void main() {
40 Bla bla;
41 bla.n = 15;
42 bla._func = (ref Bla self) {
43 writefln("I have %s", self.n);
46 bla.func();
51 class DException: Exception {
52 pragma(inline, true) pure this(T...)(T args) {
53 super(format(args));
57 class InternalError: DException {
58 pragma(inline, true) pure this(T...)(T args) {
59 super(args);
63 void exit(ubyte code) {
64 import core.runtime: Runtime;
65 static import core.stdc.stdlib;
66 Runtime.terminate();
67 core.stdc.stdlib.exit(code);
70 pure string fillstr(size_t length, char ch=' ') {
71 string buf;
72 while (length --> 0) {
73 buf ~= ch;
75 return buf;
80 // Taken directly from http://stackoverflow.com/a/41978310
81 /* It's supposed to be incredibly performant...but honestly I used it because
82 * I could copy-paste it easily.
84 alias get256colour = memoize!((RGBColour colour) {
85 enum ubyte[6] i2cv = [0, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
86 pragma(inline, true) {
87 auto v2ci = (int v) => v < 48 ? 0 : v < 115 ? 1 : (v - 35) / 40;
88 auto colour_index = (int r, int g, int b) => 36*r + 6*g + b;
89 auto distance = (int r1, int g1, int b1, int r2, int g2, int b2) => (r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2);
92 int ir = v2ci(colour.r), ig = v2ci(colour.g), ib = v2ci(colour.b);
93 int average = (colour.r + colour.g + colour.b) / 3;
94 int igray = average > 238 ? 23 : (average-3) / 10;
95 int cr = i2cv[ir], cg = i2cv[ig], cb = i2cv[ib];
96 int gv = 8 + 10 * igray;
98 int colour_err = distance(cr, cg, cb, colour.r, colour.g, colour.b);
99 int gray_err = distance(gv, gv, gv, colour.r, colour.g, colour.b);
101 return cast(ubyte)(colour_err <= gray_err ? 16 + colour_index(ir, ig, ib) : 232 + igray);
105 // Overloads...
106 pragma(inline, true) ubyte get256colour(ubyte r, ubyte g, ubyte b) { return get256colour(RGBColour(r, g, b)); }
107 pragma(inline, true) ubyte get256colour(string colour) { return get256colour(RGBColour(colour)); }