Cmdr icon indicating copy to clipboard operation
Cmdr copied to clipboard

Relative Vector3 type

Open LoganDark opened this issue 5 years ago • 4 comments

Like a relative3 type that accepts ~ coordinates like Minecraft does. to @ ~, ~500, ~ would teleport you 500 studs into the air. to @ ~, ~-500, ~ 500 studs down.

Interpreting what these coordinates are relative to would be at the command's discretion.

LoganDark avatar Feb 17 '19 06:02 LoganDark

Could the relative Vector3s contain some absolute coordinates or do they all have to be relative?

evaera avatar Feb 17 '19 06:02 evaera

~~Separate types for both perhaps? position3 and delta3 maybe?~~

No, if a command accepted only relative coordinates it'd probably just use a regular vector3, I think a position3/relative3 should accept both absolute and relative.

It's TBD how commands will distinguish relative and absolute coordinates, though.

LoganDark avatar Feb 17 '19 06:02 LoganDark

@LoganDark Yeah, I was thinking the same thing. So I think the best approach here would be to make a new class that allows mixing relative and absolute coordinates. Then the class could contain a method, relativeFrom(vec: Vector3) where absolute coordinates are passed through in the resultant Vector3 but relative coordinates are summed with the respective coordinate from the given Vector3.

evaera avatar Feb 17 '19 07:02 evaera

Not gonna make a pr for this but if anyone is interested, here is a botched type implementation of a relative vector3 using the executor's position.

Simply prepend a tilde ~ at the start of coordinate args and the output vector will be relative-ized.

example usage:

image image

type def: not heavily tested

local Util = require(script.Parent.Parent.Shared.Util)

local function validateVector(value, i)
	return pcall(assert, value ~= nil, `Invalid or missing number at position {i} in RelativeVector type.`)
end

local relativeVector3Type = {
	Transform = function (text, executor)
		local currentPos = executor.Character:GetPivot().Position
		return Util.Map(Util.SplitPrioritizedDelimeter(text, {",", "%s"}), function(value, index)
			if value:sub(1,1) ~= "~" then
				return tonumber(value)
			end

			local currentCoord = 0
			if index == 1 then currentCoord = currentPos.X
			elseif index == 2 then currentCoord = currentPos.Y
			elseif index == 3 then currentCoord = currentPos.Z
			end

			if value == "~" then
				return currentCoord
			end

			return tonumber(value:sub(2)) + currentCoord
		end)
	end;

	Validate = function (components)
		if #components > 3 then
			return false, "Maximum of 3 values allowed in sequence"
		end

		for i = 1, 3 or #components do
			local valid, reason = validateVector(components[i], i)

			if not valid then
				return false, reason
			end
		end

		return true
	end;

	Parse = function(components)
		return Vector3.new(unpack(components))
	end
}

return function (cmdr)
	cmdr:RegisterType("relativeVector3", relativeVector3Type)
	cmdr:RegisterType("relativeVector3s", Util.MakeListableType(relativeVector3Type))
end

itsrenderman avatar Aug 03 '23 01:08 itsrenderman