LUA скрипт [ UMBRELLA ] Simple vector

Nike.lua
Олдфаг
Статус
Оффлайн
Регистрация
13 Окт 2020
Сообщения
2,747
Реакции[?]
1,465
Поинты[?]
2K
Простая обертка Vector класса для чита амбрелла.

Что изменилось?:
1. Все методы и конструктор переписаны под snake_case.

2. Никаких больше vec:GetX( ), vec:GetY( ), vec:GetZ( ). Теперь все координаты можно доставать прямо из объекта.
Было:
code_language.lua:
print( vector:GetX( ) )
Cтало:
code_language.lua:
print( vector.x )
3. Адекватные математические операции:
Было:
code_language.lua:
print( vec:__add( vec2 ) ) --Сложение двух векторов
print( vec:__sub( vec2 ) ) --Вычитание двух векторов
print( vec:__mul( vec2 ) ) --Умножение двух векторов
print( vec:__div( vec2 ) ) --Деление двух векторов
Стало:
code_language.lua:
print( vec + vec2 ) --Сложение двух векторов
print( vec - vec2 ) --Вычитание двух векторов
print( vec * vec2 ) --Умножение двух векторо
print( vec / vec2 ) --Деление двух векторов
Так же добавлены перегрузки для каждого оператора для того чтобы можно было складывать/умножать/делить/вычитать вектор и число:
code_language.lua:
local vector = vector( 1, 2, 3 )
print( vector + 1 ) --Output: vector(2.0, 3.0, 4.0)
print( vector - 1 ) --Output: vector(0.0, 1.0, 2.0)
print( vector * 2 ) --Output: vector(2.0, 4.0, 6.0)
print( vector / 2 ) --Output: vector(0.5, 1.0, 1.5)
4. Переработанный метод tostring:
Теперь при попытке привести вектор к строке в консоль будет выводиться конструктор класса с необходимыми параметрами:
code_language.lua:
local vec = vector( 1, 2, 3 )
local vec_str = tostring( vec )
print( vec_str ) --Output: vector(1.0, 2.0, 3.0)
5. Конструкторы класса:
Вектор можно создавать двумя способами:
code_language.lua:
local vec1 = vector( 1, 2, 3 ) --Прямой конструктор
local vec2 = vector.new( 1, 2, 3 ) --Конструктор через метод new
6. Взаимодействие с векторами амбреллы:
Чтобы создать вектор. который будет иметь данные вектора амбреллы делаем так:
code_language.lua:
local vec_from_umbr = vector( ):as_umbrella( umbrella_obj )
Под umbrella_obj подразумевается вектор, созданный через конструктор класса самого чита

Чтобы привести наш вектор к вектору амбреллы делаем так:
code_language.lua:
local umbr_from_vec = vector( 1, 2, 3 ):to_umbrella( )
или так:
code_language.lua:
local vec = vector( 1, 2, 3 )
local umbr_from_vec = vec( ) --Вызов объекта вернет вектор амбреллы
7. Методы:
1. vec_obj:clone( ) - Вернет копию текущего объекта
2. vec_obj:as_umbrella( umbrella_obj ) - Скопирует данные из вектора чита umbrella_obj в наш вектор
3. vec_obj:to_umbrella( ) - Вернет вектор чита с текущими значениями
4. vec_obj:floor( ) - Применит math.floor ко всем координатам вектора и вернет самого себя.
5. vec_obj:сeil( ) - Применит math.ceil ко всем координатам вектора и вернет самого себя.
6. vec_obj:length( ) - Вернет длину вектора
7. vec_obj:length_sqr( ) - Вернет квадратную длину вектора
8. vec_obj:length2d( ) - Вернет 2D длину вектора ( без оси Z )
9. vec_obj:length2d_sqr( ) - Вернет квадратную 2D длину вектора
10. vec_obj:dist( vector_obj2 ) - Вернет дистанцию до другого вектора
11. vec_obj:dist_sqr( vector_obj2 ) - Вернет квадратную дистанцию до другого вектора
12. vec_obj:dist2d( vector_obj2 ) - Вернет 2D дистанцию до другого вектора
13. vec_obj:dist2d_sqr( vector_obj2 ) - Вернет квадратную 2D дистанцию до другого вектора
14. vec_obj:normalize( ) - Нормализует вектор и возвращает его длину
15. vec_obj:normalized( ) - Нормализует вектор и возвращает его копию
16. vec_obj:dot( vector_obj2 ) - Возвращает dot-product между двумя векторами
17. vec_obj:cross( vector_obj2 ) - Возвращает cross-product между двумя векторами

src:
code_language.lua:
local utils = { }
utils.type = function( value )
  if type( getmetatable( value ) ) == "table" and value.__name then
    return value.__name
  end
  return type( value )
end
---------------< VECTOR >-------------
local vector = { }
local vector_mt = { } do
  vector_mt.__index = vector
  vector_mt.__newindex = function( self, key, value )
    assert(
      false,
      "Attempting to add a key to a vector object"
    )
  end
  vector_mt.__tostring = function( self )
    return string.format(
      "vector(%.1f, %.1f, %.1f)", self.x, self.y, self.z
    )
  end
  vector_mt.__eq = function( self, eq_value )
    local eq_type = utils.type( eq_value )
    if eq_type == "vector" then
      return ( self.x == eq_value.x ) and ( self.y == eq_value.y ) and ( self.z == eq_value.z )
    elseif eq_type == "number" then
      return ( self.x == eq_value ) and ( self.y == eq_value ) and ( self.z == eq_value )
    end
    return false
  end
  vector_mt.__add = function( self, add_value )
    local add_type = utils.type( add_value )
    assert(
      add_type == "vector" or add_type == "number",
      string.format( "Attempt to add vector to a forbidden data type (recieved %s)", add_type )
    )
    if add_type == "vector" then
      return vector.new(
        self.x + add_value.x,
        self.y + add_value.y,
        self.z + add_value.z
      )
    elseif add_type == "number" then
      return vector.new(
        self.x + add_value,
        self.y + add_value,
        self.z + add_value
      )
    end
  end
  vector_mt.__sub = function( self, sub_value )
    local sub_type = utils.type( sub_value )
    assert(
      sub_type == "vector" or sub_type == "number",
      string.format( "Attempt to sub vector with a forbidden data type (recieved %s)", sub_type )
    )
    if sub_type == "vector" then
      return vector.new(
        self.x - sub_value.x,
        self.y - sub_value.y,
        self.z - sub_value.z
      )
    elseif sub_type == "number" then
      return vector.new(
        self.x - sub_value,
        self.y - sub_value,
        self.z - sub_value
      )
    end
  end
  vector_mt.__mul = function( self, mul_value )
    local mul_type = utils.type( mul_value )
    assert(
      mul_type == "vector" or mul_type == "number",
      string.format( "Attempt to mul vector with a forbidden data type (recieved %s)", mul_type )
    )
    if mul_type == "vector" then
      return vector.new(
        self.x * mul_value.x,
        self.y * mul_value.y,
        self.z * mul_type.z
      )
    elseif mul_type == "number" then
      return vector.new(
        self.x * mul_value,
        self.y * mul_value,
        self.z * mul_value
      )
    end
  end
  vector_mt.__div = function( self, div_value )
    local div_type = utils.type( div_value )
    assert(
      div_type == "vector" or div_type == "number",
      string.format( "Attempt to div vector with a forbidden data type (recieved %s)", div_type )
    )
    if div_type == "vector" then
      return vector.new(
        self.x / div_value.x,
        self.y / div_value.y,
        self.z / div_value.z
      )
    elseif div_type == "number" and div_value ~= 0 then
      return vector.new(
        self.x / div_value,
        self.y / div_value,
        self.z / div_value
      )
    end
  end
  vector_mt.__call = function( self )
    return self:to_umbrella( )
  end
end
vector.new = function( x, y, z )
  local vector = { __name = "vector" }
    vector.x = x or 0.0
    vector.y = y or 0.0
    vector.z = z or 0.0
    vector.unpack = function( self )
      return self.x, self.y, self.z
    end
    vector.clone = function( self )
      return vector.new( self.x, self.y, self.z )
    end
    vector.as_umbrella = function( self, umbrella_obj )
      self.x = umbrella_obj:GetX( )
      self.y = umbrella_obj:GetY( )
      self.z = umbrella_obj:GetZ( )
      return self
    end
    vector.to_umbrella = function( self )
      return Vector( self.x, self.y, self.z )
    end
    vector.floor = function( self )
      self.x = math.floor( self.x )
      self.y = math.floor( self.y )
      self.z = math.floor( self.z )
      return self
    end
    vector.ceil = function( self )
      self.x = math.ceil( self.x )
      self.y = math.ceil( self.y )
      self.z = math.ceil( self.z )
      return self
    end
    vector.length = function( self )
      return math.sqrt(
        math.pow( self.x, 2 ) + math.pow( self.y, 2 ) + math.pow( self.z, 2 )
      )
    end
    vector.length_sqr = function( self )
      return math.pow( self.x, 2 ) + math.pow( self.y, 2 ) + math.pow( self.z, 2 )
    end
    vector.length2d = function( self )
      return math.sqrt(
        math.pow( self.x, 2 ) + math.pow( self.y, 2 )
      )
    end
    vector.length2d_sqr = function( self )
      return math.pow( self.x, 2 ) + math.pow( self.y, 2 )
    end
    vector.dist = function( self, v_other )
      assert(
        utils.type( v_other ) == "vector",
        string.format( "Attempt to get the distance to a non-vector (received %s)", utils.type( v_other ) )
      )
      return math.sqrt(
        math.pow( v_other.x - self.x, 2 ) + math.pow( v_other.y - self.y, 2 ) + math.pow( v_other.z - self.z, 2 )
      )
    end
    vector.dist_sqr = function( self, v_other )
      assert(
        utils.type( v_other ) == "vector",
        string.format( "Attempt to get the squared distance to a non-vector (received %s)", utils.type( v_other ) )
      )
      return math.pow( v_other.x - self.x, 2 ) + math.pow( v_other.y - self.y, 2 ) + math.pow( v_other.z - self.z, 2 )
    end
    vector.dist2d = function( self, v_other )
      assert(
        utils.type( v_other ) == "vector",
        string.format( "Attempt to get the 2d distance to a non-vector (received %s)", utils.type( v_other ) )
      )
      return math.sqrt(
        math.pow( v_other.x - self.x, 2 ) + math.pow( v_other.y - self.y, 2 )
      )
    end
    vector.dist2d_sqr = function( self, v_other )
      assert(
        utils.type( v_other ) == "vector",
        string.format( "Attempt to get the squared 2d distance to a non-vector (received %s)", utils.type( v_other ) )
      )
      return math.pow( v_other.x - self.x, 2 ) + math.pow( v_other.y - self.y, 2 )
    end
    vector.normalize = function( self )
      local length = self:length( )
      if length > 0.0 then
        self.x = self.x / length
        self.y = self.y / length
        self.z = self.z / length
      end
      return length
    end
    vector.normalized = function( self )
      local copy = self:clone( )
      copy:normalize( )
      return copy
    end
    vector.dot = function( self, v_other )
      assert(
        utils.type( v_other ) == "vector",
        string.format( "Attempt to get the dot product with a non-vector (received %s)", utils.type( v_other ) )
      )
      return ( self.x * v_other.x ) + ( self.y * v_other.y ) + ( self.z * v_other.z )
    end
    vector.cross = function( self, v_other )
      assert(
        utils.type( v_other ) == "vector",
        string.format( "Attempt to get the cross product with a non-vector (received %s)", utils.type( v_other ) )
      )
      return vector.new(
        self.y * v_other.z - self.z * v_other.y,
        self.z * v_other.x - self.x * v_other.z,
        self.x * v_other.y - self.y * v_other.z
      )
    end
  return setmetatable( vector, vector_mt )
end
setmetatable( vector, {
  __index = vector,
  __call = vector.new
} )
 
Последнее редактирование:
Сверху Снизу