diff --git a/code/_macros.dm b/code/_macros.dm index 07e70914bc..8f967776e4 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -62,3 +62,11 @@ //check if all bitflags specified are present #define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) ((flagvar & (flags)) == flags) + + +/// Right-shift of INT by BITS +#define SHIFTR(INT, BITS) ((INT) >> (BITS)) + + +/// Left-shift of INT by BITS +#define SHIFTL(INT, BITS) ((INT) << (BITS)) diff --git a/code/_version.dm b/code/_version.dm new file mode 100644 index 0000000000..ecb80cc17d --- /dev/null +++ b/code/_version.dm @@ -0,0 +1,69 @@ +#if DM_VERSION < 515 + +#define call_ext(ARGS...) call(ARGS) + +/proc/ceil(number) + return -round(-number) + +/proc/floor(number) + return round(number) + +/proc/fract(number) + return number - trunc(number) + +/proc/ftime() + throw EXCEPTION("ftime not available below 515") + +/proc/get_steps_to() + throw EXCEPTION("get_steps_to not available below 515") + +/proc/isinf(number) + return number == POSITIVE_INFINITY || number == NEGATIVE_INFINITY + +/proc/isnan(number) + return isnum(number) && number != number + +/proc/ispointer() + throw EXCEPTION("ispointer not available below 515") + +/proc/nameof(thing) + throw EXCEPTION("nameof not available below 515") + +/proc/noise_hash() + throw EXCEPTION("noise_hash not available below 515") + +/proc/refcount(datum) + throw EXCEPTION("refcount not available below 515") + +/proc/trimtext(text) + var/static/regex/pattern + if (!pattern) + pattern = regex(@"^\s*(.*?)\s*$", "g") + return replacetext_char(text, pattern, "$1") + +/proc/trunc(number) + if (number < 0) + return -round(-number) + return round(number) + +/client/proc/RenderIcon(atom) + throw EXCEPTION("client::RenderIcon() not available below 515") + +/* lists cannot have new procs. But if they could: +/list/proc/RemoveAll() + var/result = 0 + for (var/entry in args) + while (Remove(entry)) + ++result + return result +*/ + +#define ANIMATION_SLICE 8 +#define ANIMATION_CONTINUE 512 + +#define JSON_PRETTY_PRINT 1 + +#define JSON_STRICT 1 +#define JSON_ALLOW_COMMENTS 2 + +#endif diff --git a/code/core/math/math.dm b/code/core/math/math.dm new file mode 100644 index 0000000000..a03526de49 --- /dev/null +++ b/code/core/math/math.dm @@ -0,0 +1,119 @@ +/// IEEE 754-1985 positive infinity. As text, win: 1.#INF, lin: inf +var/global/const/POSITIVE_INFINITY = 1#INF + +/// IEEE 754-1985 negative infinity. As text, win: -1.#INF, -lin: inf +var/global/const/NEGATIVE_INFINITY = -1#INF + +// IEEE 754-1985 positive NaN. Creatable but not useful. As text, win: 1.#QNAN, lin: nan +//var/const/POSITIVE_NAN = -(1#INF/1#INF) + +// IEEE 754-1985 nevative NaN. Creatable but not useful. As text, win: -1.#IND, lin: -nan +//var/const/NEGATIVE_NAN = (1#INF/1#INF) + +/// Multiplier for converting degrees to radians, rounded to 10 places +var/global/const/DEG_TO_RAD = 0.0174532925 + +/// Multiplier for converting radians to degrees, rounded to 10 places +var/global/const/RAD_TO_DEG = 57.295779513 + +/// The mathematical constant pi, rounded to 10 places +var/global/const/PI = 3.1415926536 + +/// Twice the mathematical constant pi, rounded to 10 places +var/global/const/TWO_PI = 6.2831853072 + +/// Half the mathematical constant pi, rounded to 10 places +var/global/const/HALF_PI = 1.5707963268 + + +/// True if number is a number that is not nan or an infinity. +/proc/isfinite(number) + return isnum(number) && !isnan(number) && !isinf(number) + + +/** +Sample t(0..1) into a quadratic binomial polynomial. +Generally this is useful for shaping rand() distribution. +see tools/polyvis.html for a parameter picker. +*/ +/proc/poly_interp2(t, p0, p1, p2) + var/mt = 1 - t + return p0 * mt * mt +\ + 2 * p1 * mt * t +\ + p2 * t * t + +/** +Sample t(0..1) into a cubic binomial polynomial. +Generally this is useful for shaping rand() distribution. +see tools/polyvis.html for a parameter picker. +More expensive than poly_interp2. +*/ +/proc/poly_interp3(t, p0, p1, p2, p3) + var/t2 = t * t + var/mt = 1 - t + var/mt2 = mt * mt + return p0 * mt2 * mt +\ + 3 * p1 * mt2 * t +\ + 3 * p2 * mt * t2 +\ + p3 * t2 * t + +/** +Sample t(0..1) into a quartic binomial polynomial. +Generally this is useful for shaping rand() distribution. +see tools/polyvis.html for a parameter picker. +More expensive than poly_interp3. +*/ +/proc/poly_interp4(t, p0, p1, p2, p3, p4) + var/t2 = t * t + var/t3 = t2 * t + var/mt = 1 - t + var/mt2 = mt * mt + var/mt3 = mt2 * mt + return p0 * mt3 * mt +\ + 4 * p1 * mt3 * t +\ + 6 * p2 * mt2 * t2 +\ + 4 * p3 * mt * t3 +\ + p4 * t3 * t + + +/** +Get the coordinates that make up a circle of radius on center, packed as (x | y left shift 12). +These coordinates are able to be outside the world: check (v < 1 || v > world.maxV) for safety. +Implements the Bresenham Circle Drawing Algorithm for the actual point picking. +*/ +/proc/get_circle_coordinates(radius, center_x, center_y) + var/static/list/cache = list() + radius = round(radius, 1) + if (radius < 1) + return list(center_x | SHIFTL(center_y, 12)) + center_x = round(center_x, 1) + center_y = round(center_y, 1) + var/list/points = length(cache) ? cache["[radius]"] : null + if (!points) + points = list() + var/y = radius + var/gradient = 3 - 2 * radius + for (var/x = 0 to radius) + points |= list( + radius + x | SHIFTL(radius + y, 12), + radius + x | SHIFTL(radius - y, 12), + radius - x | SHIFTL(radius + y, 12), + radius - x | SHIFTL(radius - y, 12), + radius + y | SHIFTL(radius + x, 12), + radius + y | SHIFTL(radius - x, 12), + radius - y | SHIFTL(radius + x, 12), + radius - y | SHIFTL(radius - x, 12) + ) + if (x >= y) + break + if (gradient < 0) + gradient = gradient + 4 * x + 6 + else + gradient = gradient + 4 * (x - y) + 10 + --y + cache["[radius]"] = points + var/list/result = points.Copy() + var/center = center_x - radius | SHIFTL(center_y - radius, 12) + for (var/i = 1 to length(result)) + result[i] += center + return result diff --git a/code/modules/food/food/sandwich.dm b/code/modules/food/food/sandwich.dm index 8f5fd828b8..8a2dfc2ad7 100644 --- a/code/modules/food/food/sandwich.dm +++ b/code/modules/food/food/sandwich.dm @@ -71,7 +71,7 @@ name = lowertext("[fullname] sandwich") if(length(name) > 80) name = "[pick(list("absurd","colossal","enormous","ridiculous"))] sandwich" - w_class = n_ceil(clamp((ingredients.len/2),2,4)) + w_class = ceil(clamp((ingredients.len/2),2,4)) /obj/item/reagent_containers/food/snacks/csandwich/Destroy() for(var/obj/item/O in ingredients) diff --git a/code/modules/random_map/drop/droppod.dm b/code/modules/random_map/drop/droppod.dm index 492719ccb7..2d004955e7 100644 --- a/code/modules/random_map/drop/droppod.dm +++ b/code/modules/random_map/drop/droppod.dm @@ -41,8 +41,8 @@ /datum/random_map/droppod/generate_map() // No point calculating these 200 times. - var/x_midpoint = n_ceil(limit_x / 2) - var/y_midpoint = n_ceil(limit_y / 2) + var/x_midpoint = ceil(limit_x / 2) + var/y_midpoint = ceil(limit_y / 2) // Draw walls/floors/doors. for(var/x = 1, x <= limit_x, x++) @@ -80,7 +80,7 @@ /datum/random_map/droppod/apply_to_map() if(placement_explosion_dev || placement_explosion_heavy || placement_explosion_light || placement_explosion_flash) - var/turf/T = locate((origin_x + n_ceil(limit_x / 2)-1), (origin_y + n_ceil(limit_y / 2)-1), origin_z) + var/turf/T = locate((origin_x + ceil(limit_x / 2)-1), (origin_y + ceil(limit_y / 2)-1), origin_z) if(istype(T)) explosion(T, placement_explosion_dev, placement_explosion_heavy, placement_explosion_light, placement_explosion_flash) sleep(15) // Let the explosion finish proccing before we ChangeTurf(), otherwise it might destroy our spawned objects. @@ -97,8 +97,8 @@ // Pods are circular. Get the direction this object is facing from the center of the pod. /datum/random_map/droppod/get_spawn_dir(var/x, var/y) - var/x_midpoint = n_ceil(limit_x / 2) - var/y_midpoint = n_ceil(limit_y / 2) + var/x_midpoint = ceil(limit_x / 2) + var/y_midpoint = ceil(limit_y / 2) if(x == x_midpoint && y == y_midpoint) return null var/turf/target = locate(origin_x+x-1, origin_y+y-1, origin_z) @@ -224,4 +224,4 @@ else return - new /datum/random_map/droppod(null, usr.x-1, usr.y-1, usr.z, supplied_drops = spawned_mobs, automated = automatic_pod) \ No newline at end of file + new /datum/random_map/droppod(null, usr.x-1, usr.y-1, usr.z, supplied_drops = spawned_mobs, automated = automatic_pod) diff --git a/code/modules/random_map/meteor/meteor.dm b/code/modules/random_map/meteor/meteor.dm index 33a9a2f934..2ee4669c51 100644 --- a/code/modules/random_map/meteor/meteor.dm +++ b/code/modules/random_map/meteor/meteor.dm @@ -34,8 +34,8 @@ /datum/random_map/meteor/generate_map() // No point calculating these 200 times. - var/x_midpoint = n_ceil(limit_x / 2) - var/y_midpoint = n_ceil(limit_y / 2) + var/x_midpoint = ceil(limit_x / 2) + var/y_midpoint = ceil(limit_y / 2) // Draw walls/floors for(var/x = 1, x <= limit_x, x++) @@ -72,7 +72,7 @@ if(!applied) applied = TRUE if(placement_explosion_dev || placement_explosion_heavy || placement_explosion_light || placement_explosion_flash) - var/turf/T = locate((origin_x + n_ceil(limit_x / 2)-1), (origin_y + n_ceil(limit_y / 2)-1), origin_z) + var/turf/T = locate((origin_x + ceil(limit_x / 2)-1), (origin_y + ceil(limit_y / 2)-1), origin_z) if(istype(T)) explosion(T, placement_explosion_dev, placement_explosion_heavy, placement_explosion_light, placement_explosion_flash) sleep(15) // Let the explosion finish proccing before we ChangeTurf(), otherwise it might destroy our spawned objects. @@ -89,8 +89,8 @@ // Meteors are circular. Get the direction this object is facing from the center of the pod. /datum/random_map/meteor/get_spawn_dir(var/x, var/y) - var/x_midpoint = n_ceil(limit_x / 2) - var/y_midpoint = n_ceil(limit_y / 2) + var/x_midpoint = ceil(limit_x / 2) + var/y_midpoint = ceil(limit_y / 2) if(x == x_midpoint && y == y_midpoint) return null var/turf/target = locate(origin_x+x-1, origin_y+y-1, origin_z) diff --git a/polaris.dme b/polaris.dme index dd603ee034..aefc5ed3f1 100644 --- a/polaris.dme +++ b/polaris.dme @@ -14,6 +14,7 @@ #include "code\_macros.dm" #include "code\_map_tests.dm" #include "code\_unit_tests.dm" +#include "code\_version.dm" #include "code\global.dm" #include "code\global_init.dm" #include "code\hub.dm" @@ -266,6 +267,7 @@ #include "code\core\atom\Transform.dm" #include "code\core\datum\IsAbstract.dm" #include "code\core\image\Transform.dm" +#include "code\core\math\math.dm" #include "code\core\matrix\Transform.dm" #include "code\datums\ai_law_sets.dm" #include "code\datums\ai_laws.dm" diff --git a/tools/polyvis.html b/tools/polyvis.html new file mode 100644 index 0000000000..d364c48323 --- /dev/null +++ b/tools/polyvis.html @@ -0,0 +1,168 @@ + + +
+ +red line: the sample curve.
+blue bars: the distribution, given random 0..1 numbers.
+white numbers: rough min/max values possible.
+dm call:
+ + +