Clean up vector library, standardize parameter orders, conform to docs.
parent
c00ee72529
commit
c7c2e38c38
|
@ -1,9 +1,126 @@
|
|||
-- Zepha Vector Library
|
||||
-- Version 1.0
|
||||
|
||||
_G["vector"] = {}
|
||||
|
||||
-- create_vector
|
||||
-- Create a new vector, and give it a metatable.
|
||||
-- x, y, and z must all be numbers.
|
||||
local function create_vector(x, y, z)
|
||||
local v = {x, y, z}
|
||||
setmetatable(v, vector._mt)
|
||||
return v
|
||||
end
|
||||
|
||||
-- vector.add
|
||||
-- Add two vectors or a vector and number
|
||||
function vector.add(v1, v2)
|
||||
if not vector.is_vector(v1) then return end
|
||||
if vector.is_vector(v2) then
|
||||
return create_vector(rawget(v1, 1) + rawget(v2, 1), rawget(v1, 2) + rawget(v2, 2), rawget(v1, 3) + rawget(v2, 3))
|
||||
elseif type(v2) == "number" then
|
||||
return create_vector(rawget(v1, 1) + v2, rawget(v1, 2) + v2, rawget(v1, 3) + v2)
|
||||
end
|
||||
end
|
||||
|
||||
-- vector.negative
|
||||
-- Flips a vector's content's signs
|
||||
function vector.negative(v)
|
||||
if not vector.is_vector(v) then return end
|
||||
return create_vector(-rawget(v, 1), -rawget(v, 2), -rawget(v, 3))
|
||||
end
|
||||
|
||||
-- vector.subtract
|
||||
-- Subtract v2 from v1
|
||||
function vector.subtract(v1, v2)
|
||||
return vector.add(v1, vector.negative(v2))
|
||||
end
|
||||
|
||||
-- vector.multiply
|
||||
-- Multiply v1 by a vector or number
|
||||
function vector.multiply(v1, m)
|
||||
if not vector.is_vector(v1) then return end
|
||||
if vector.is_vector(m) then
|
||||
return create_vector(rawget(v1, 1) * rawget(m, 1), rawget(v1, 2) * rawget(m, 2), rawget(v1, 3) * rawget(m, 3))
|
||||
elseif type(m) == "number" then
|
||||
return create_vector(rawget(v1, 1) * m, rawget(v1, 2) * m, rawget(v1, 3) * m)
|
||||
end
|
||||
end
|
||||
|
||||
-- vector.divide
|
||||
-- Divice v1 by a vector or number
|
||||
function vector.divide(v1, m)
|
||||
if not vector.is_vector(v1) then return end
|
||||
if vector.is_vector(m) then
|
||||
return create_vector(rawget(v1, 1) / rawget(m, 1), rawget(v1, 2) / rawget(m, 2), rawget(v1, 3) / rawget(m, 3))
|
||||
elseif type(m) == "number" then
|
||||
return create_vector(rawget(v1, 1) / m, rawget(v1, 2) / m, rawget(v1, 3) / m)
|
||||
end
|
||||
end
|
||||
|
||||
-- vector.pow
|
||||
-- Return v to the power of p
|
||||
function vector.pow(v, m)
|
||||
if not vector.is_vector(v) then return end
|
||||
local res = create_vector(rawget(v, 1), rawget(v, 2), rawget(v, 3))
|
||||
for i = 1, power - 1 do res = res * v end
|
||||
return res
|
||||
end
|
||||
|
||||
-- vector.equal
|
||||
-- Return a boolean indicating if v1 == v2
|
||||
function vector.equal(v1, v2)
|
||||
if not vector.is_vector(v1) or not vector.is_vector(v2) then return end
|
||||
return (rawget(v1, 1) == rawget(v2, 1) and rawget(v1, 2) == rawget(v2, 2) and rawget(v1, 3) == rawget(v2, 3))
|
||||
end
|
||||
|
||||
-- vector.abs
|
||||
-- Return the absolute value of v
|
||||
function vector.abs(v)
|
||||
if not vector.is_vector(v) then return end
|
||||
return create_vector(math.abs(rawget(v, 1)), math.abs(rawget(v, 2)), math.abs(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.round
|
||||
-- Round each vector value to the nearest integer
|
||||
function vector.round(v)
|
||||
if not vector.is_vector(v) then return end
|
||||
return create_vector(math.round(rawget(v, 1)), math.round(rawget(v, 2)), math.round(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.floor
|
||||
-- Floor each vector value to the lowest integer
|
||||
function vector.floor(v)
|
||||
if not vector.is_vector(v) then return end
|
||||
return create_vector(math.floor(rawget(v, 1)), math.floor(rawget(v, 2)), math.floor(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.ceil
|
||||
-- Ceil each vector value to the highest integer
|
||||
function vector.ceil(v)
|
||||
if not vector.is_vector(v) then return end
|
||||
return create_vector(math.ceil(rawget(v, 1)), math.ceil(rawget(v, 2)), math.ceil(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.distance_squared
|
||||
-- Get the square of the distance between two vectors
|
||||
-- This function is faster if you only need to compare two distances
|
||||
function vector.distance_squared(v1, v2)
|
||||
if not vector.is_vector(v1) or not vector.is_vector(v2) then return end
|
||||
local diff = vector.abs(vector.subtract(v1, v2))
|
||||
return diff.x ^ 2 + diff.y ^ 2 + diff.z ^ 2
|
||||
end
|
||||
|
||||
-- vector.distance
|
||||
-- Get the distance between two vectors
|
||||
function vector.distance(v1, v2)
|
||||
if not vector.is_vector(v1) or not vector.is_vector(v2) then return end
|
||||
return math.sqrt(vector.distance_squared(v1, v2))
|
||||
end
|
||||
|
||||
-- Vector metatable
|
||||
-- A metatable to be assigned to vectors which applies mathematic operators
|
||||
local vector_mt = {
|
||||
vector._mt = {
|
||||
__is_vector = true,
|
||||
|
||||
-- Value manipulation functions
|
||||
|
@ -54,44 +171,23 @@ local vector_mt = {
|
|||
end,
|
||||
|
||||
-- Higher level methods
|
||||
abs = function(tbl)
|
||||
return vector.abs(tbl)
|
||||
end,
|
||||
round = function(tbl)
|
||||
return vector.round(tbl)
|
||||
end,
|
||||
floor = function(tbl)
|
||||
return vector.floor(tbl)
|
||||
end,
|
||||
ceil = function(tbl)
|
||||
return vector.ceil(tbl)
|
||||
end,
|
||||
distance_squared = function(tbl, o)
|
||||
return vector.distance_squared(tbl, o)
|
||||
end,
|
||||
distance = function(tbl, o)
|
||||
return vector.distance(tbl, o)
|
||||
end
|
||||
abs = vector.abs,
|
||||
round = vector.round,
|
||||
floor = vector.floor,
|
||||
ceil = vector.ceil,
|
||||
dist = vector.distance,
|
||||
distance, vector.distance,
|
||||
dist2 = vector.distance_squared,
|
||||
distance_squared = vector.distance_squared
|
||||
}
|
||||
|
||||
-- create_vector
|
||||
-- Create a new vector, and give it a metatable.
|
||||
-- x, y, and z must all be numbers.
|
||||
local function create_vector(x, y, z)
|
||||
local vector = {x, y, z}
|
||||
setmetatable(vector, vector_mt)
|
||||
return vector
|
||||
end
|
||||
|
||||
-- check_vector
|
||||
-- vector.is_vector
|
||||
-- Checks if a value is a vector.
|
||||
local function check_vector(v)
|
||||
function vector.is_vector(v)
|
||||
if type(v) ~= "table" or not v.__is_vector then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
_G["vector"] = {}
|
||||
|
||||
-- vector.new
|
||||
-- Constructor function for creating vectors from a table or 2-3 values.
|
||||
-- Table constructor works with 1-3 values
|
||||
|
@ -111,110 +207,4 @@ vector.new = function(x, y, z)
|
|||
end
|
||||
|
||||
-- vector.new shorthand
|
||||
_G["V"] = vector.new
|
||||
|
||||
-- vector.add
|
||||
-- Add two vectors or a vector and number
|
||||
vector.add = function(v1, v2)
|
||||
if not check_vector(v1) then return end
|
||||
if check_vector(v2) then
|
||||
return create_vector(rawget(v1, 1) + rawget(v2, 1), rawget(v1, 2) + rawget(v2, 2), rawget(v1, 3) + rawget(v2, 3))
|
||||
elseif type(v2) == "number" then
|
||||
return create_vector(rawget(v1, 1) + v2, rawget(v1, 2) + v2, rawget(v1, 3) + v2)
|
||||
end
|
||||
end
|
||||
|
||||
-- vector.negative
|
||||
-- Flips a vector's content's signs
|
||||
vector.negative = function(v)
|
||||
if not check_vector(v) then return end
|
||||
return create_vector(-rawget(v, 1), -rawget(v, 2), -rawget(v, 3))
|
||||
end
|
||||
|
||||
-- vector.subtract
|
||||
-- Subtract v2 from v1
|
||||
vector.subtract = function(v1, v2)
|
||||
return vector.add(v1, vector.negative(v2))
|
||||
end
|
||||
|
||||
-- vector.multiply
|
||||
-- Multiply v1 by a vector or number
|
||||
vector.multiply = function(v1, m)
|
||||
if not check_vector(v1) then return end
|
||||
if check_vector(m) then
|
||||
return create_vector(rawget(v1, 1) * rawget(m, 1), rawget(v1, 2) * rawget(m, 2), rawget(v1, 3) * rawget(m, 3))
|
||||
elseif type(m) == "number" then
|
||||
return create_vector(rawget(v1, 1) * m, rawget(v1, 2) * m, rawget(v1, 3) * m)
|
||||
end
|
||||
end
|
||||
|
||||
-- vector.divide
|
||||
-- Divice v1 by a vector or number
|
||||
vector.divide = function(v1, m)
|
||||
if not check_vector(v1) then return end
|
||||
if check_vector(m) then
|
||||
return create_vector(rawget(v1, 1) / rawget(m, 1), rawget(v1, 2) / rawget(m, 2), rawget(v1, 3) / rawget(m, 3))
|
||||
elseif type(m) == "number" then
|
||||
return create_vector(rawget(v1, 1) / m, rawget(v1, 2) / m, rawget(v1, 3) / m)
|
||||
end
|
||||
end
|
||||
|
||||
-- vector.pow
|
||||
-- Return v to the power of p
|
||||
vector.pow = function(v, m)
|
||||
if not check_vector(v) then return end
|
||||
local res = create_vector(rawget(v, 1), rawget(v, 2), rawget(v, 3))
|
||||
for i = 1, power - 1 do res = res * v end
|
||||
return res
|
||||
end
|
||||
|
||||
-- vector.equal
|
||||
-- Return a boolean indicating if v1 == v2
|
||||
vector.equal = function(v1, v2)
|
||||
if not check_vector(v1) or not check_vector(v2) then return end
|
||||
return (rawget(v1, 1) == rawget(v2, 1) and rawget(v1, 2) == rawget(v2, 2) and rawget(v1, 3) == rawget(v2, 3))
|
||||
end
|
||||
|
||||
-- vector.abs
|
||||
-- Return the absolute value of v
|
||||
vector.abs = function(v)
|
||||
if not check_vector(v) then return end
|
||||
return create_vector(math.abs(rawget(v, 1)), math.abs(rawget(v, 2)), math.abs(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.round
|
||||
-- Round each vector value to the nearest integer
|
||||
vector.round = function(v)
|
||||
if not check_vector(v) then return end
|
||||
return create_vector(math.round(rawget(v, 1)), math.round(rawget(v, 2)), math.round(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.floor
|
||||
-- Floor each vector value to the lowest integer
|
||||
vector.floor = function(v)
|
||||
if not check_vector(v) then return end
|
||||
return create_vector(math.floor(rawget(v, 1)), math.floor(rawget(v, 2)), math.floor(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.ceil
|
||||
-- Ceil each vector value to the highest integer
|
||||
vector.ceil = function(v)
|
||||
if not check_vector(v) then return end
|
||||
return create_vector(math.ceil(rawget(v, 1)), math.ceil(rawget(v, 2)), math.ceil(rawget(v, 3)))
|
||||
end
|
||||
|
||||
-- vector.distance_squared
|
||||
-- Get the square of the distance between two vectors
|
||||
-- This function is faster if you only need to compare two distances
|
||||
vector.distance_squared = function(v1, v2)
|
||||
if not check_vector(v1) or not check_vector(v2) then return end
|
||||
local diff = vector.abs(vector.subtract(v1, v2))
|
||||
return diff.x ^ 2 + diff.y ^ 2 + diff.z ^ 2
|
||||
end
|
||||
|
||||
-- vector.distance
|
||||
-- Get the distance between two vectors
|
||||
vector.distance = function(v1, v2)
|
||||
if not check_vector(v1) or not check_vector(v2) then return end
|
||||
return math.sqrt(vector.distance_squared(v1, v2))
|
||||
end
|
||||
_G["V"] = vector.new
|
|
@ -12,9 +12,9 @@ namespace Api {
|
|||
zepha.__builtin.trigger_event = function(event, ...)
|
||||
if zepha.registered_callbacks[event] == nil then return nil end
|
||||
|
||||
for _, v in pairs(zepha.registered_callbacks[event]) do
|
||||
if (type(v) == "function") then
|
||||
v(...)
|
||||
for _, EVENT_CALLBACK in pairs(zepha.registered_callbacks[event]) do
|
||||
if (type(EVENT_CALLBACK) == "function") then
|
||||
EVENT_CALLBACK(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,9 +17,9 @@ namespace Api {
|
|||
static void add_entity_c(sol::state& lua, sol::table& core, ClientGame& defs, LocalWorld& world) {
|
||||
core["entities"] = lua.create_table();
|
||||
|
||||
core.set_function("add_entity", [&](sol::optional<std::string> identifier, sol::optional<sol::table> pos, sol::object staticData) {
|
||||
if (!identifier || !identifier->length()) throw std::runtime_error("expected a string as the first argument.");
|
||||
if (!pos) throw std::runtime_error("expected a vector as the second argument.");
|
||||
core.set_function("add_entity", [&](sol::optional<sol::table> pos, sol::optional<std::string> identifier, sol::object staticData) {
|
||||
if (!identifier || !identifier->length()) throw std::runtime_error("Expected an identifier as the second argument.");
|
||||
if (!pos) throw std::runtime_error("Expected a position as the first argument.");
|
||||
|
||||
if (core["registered_entities"][*identifier] == sol::nil) throw std::runtime_error("identifier '" + *identifier + "' is not a valid entity identifier.");
|
||||
sol::table entityDef = core["registered_entities"][*identifier];
|
||||
|
@ -55,9 +55,9 @@ namespace Api {
|
|||
static void add_entity_s(sol::state& lua, sol::table& core, ServerGame& defs, ServerWorld& world) {
|
||||
core["entities"] = lua.create_table();
|
||||
|
||||
core.set_function("add_entity", [&](sol::optional<std::string> identifier, sol::optional<sol::table> pos, sol::object staticData) {
|
||||
if (!identifier || !identifier->length()) throw std::runtime_error("expected a string as the first argument.");
|
||||
if (!pos) throw std::runtime_error("expected a vector as the second argument.");
|
||||
core.set_function("add_entity", [&](sol::optional<sol::table> pos, sol::optional<std::string> identifier, sol::object staticData) {
|
||||
if (!identifier || !identifier->length()) throw std::runtime_error("Expected an identifier as the second argument.");
|
||||
if (!pos) throw std::runtime_error("Expected a position as the first argument.");
|
||||
|
||||
if (core["registered_entities"][*identifier] == sol::nil) throw std::runtime_error("identifier '" + *identifier + "' is not a valid entity identifier.");
|
||||
sol::table entityDef = core["registered_entities"][*identifier];
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
namespace Api {
|
||||
static void get_block(sol::table &core, DefinitionAtlas& defs, World& world) {
|
||||
core.set_function("get_block", [&](sol::table pos) -> std::string {
|
||||
if (!pos["x"] || !pos["y"] || !pos["z"]) throw std::runtime_error("expected a vector as the first argument.");
|
||||
if (!pos.get<sol::optional<float>>("x") || !pos.get<sol::optional<float>>("y") || !pos.get<sol::optional<float>>("z"))
|
||||
throw std::runtime_error("Expected a vector as the first argument.");
|
||||
|
||||
return defs.fromId(world.getBlock({pos.get<float>("x"), pos.get<float>("y"), pos.get<float>("z")})).identifier;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
local function collides(entity)
|
||||
return zepha.get_block(entity.pos + V{0, 0.5, 0}) ~= "air"
|
||||
return zepha.get_block((entity.pos - V{0, 0.5, 0}):floor()) ~= "air"
|
||||
end
|
||||
|
||||
zepha.register_entity("@aurailus:item_collection:dropped_item", {
|
||||
|
@ -73,7 +73,7 @@ zepha.register_entity("@aurailus:item_collection:dropped_item", {
|
|||
end,
|
||||
check_collect = function(self)
|
||||
for _,p in pairs(zepha.players) do
|
||||
if vector.distance(p.pos, self.object.pos) < 2 then
|
||||
if p.pos:dist(self.object.pos) < 2 then
|
||||
self.object.pos = p.pos + V{0, 0.90, 0}
|
||||
self.scooping = true
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@ if zepha.server then
|
|||
local yields = get_yield(pos)
|
||||
if yields == nil then return end
|
||||
|
||||
zepha.add_entity("@aurailus:item_collection:dropped_item", pos + 0.5, { item = yields });
|
||||
zepha.add_entity(pos + 0.5, "@aurailus:item_collection:dropped_item", { item = yields });
|
||||
end)
|
||||
end
|
|
@ -18,5 +18,5 @@ zepha.register_entity("zeus:default:test", {
|
|||
})
|
||||
|
||||
if zepha.client then
|
||||
local entity = zepha.add_entity("zeus:default:test", V{})
|
||||
local entity = zepha.add_entity(V{}, "zeus:default:test")
|
||||
end
|
Loading…
Reference in New Issue