2023-03-31 02:40:11 +02:00
|
|
|
from math import atan2, hypot, pi
|
|
|
|
|
|
|
|
|
|
|
|
class Vec:
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Support : `Vec2i | Vec2f | Vec3i | Vec3f`"""
|
|
|
|
|
2023-03-31 02:40:11 +02:00
|
|
|
def __init__(self, x: int | float | None = None, y: int | float | None = None, z: int | float | None = None) -> None:
|
|
|
|
if x != None:
|
|
|
|
self.new(x, y, z)
|
|
|
|
else:
|
|
|
|
self.x = 0
|
|
|
|
self.y = 0
|
|
|
|
self.z = 0
|
|
|
|
|
|
|
|
def new(self, x: int | float, y: int | float | None, z: int | float | None) -> None:
|
2023-03-31 03:38:59 +02:00
|
|
|
"""Change values of Vector"""
|
|
|
|
if y == None:
|
|
|
|
raise TypeError
|
|
|
|
|
2023-03-31 02:40:11 +02:00
|
|
|
# Determine type of class
|
|
|
|
self.type = int
|
|
|
|
if type(x) == float:
|
|
|
|
self.type = float
|
|
|
|
|
|
|
|
# Verify other type
|
|
|
|
if type(y) != self.type:
|
|
|
|
raise TypeError
|
|
|
|
|
|
|
|
self.x = self.type(x)
|
|
|
|
self.y = self.type(y)
|
|
|
|
|
|
|
|
if z == None:
|
|
|
|
self.z = None
|
|
|
|
else:
|
|
|
|
self.z = self.type(z)
|
|
|
|
|
2023-03-31 03:38:59 +02:00
|
|
|
def __str__(self):
|
|
|
|
max_precision = 3
|
|
|
|
|
|
|
|
x = round(self.x, max_precision)
|
|
|
|
y = round(self.y, max_precision)
|
|
|
|
z = None if self.z == None else round(self.z, max_precision)
|
|
|
|
|
|
|
|
return f"{self.__class__.__name__}({x}, {y}{'' if z == None else f', {z}'})"
|
|
|
|
|
2023-03-31 02:40:11 +02:00
|
|
|
def plus(self, other: 'Vec') -> 'Vec':
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Add 2 vectors"""
|
2023-03-31 02:40:11 +02:00
|
|
|
x = self.x + other.x
|
|
|
|
y = self.y + other.y
|
|
|
|
|
|
|
|
if self.z == None or other.z == None:
|
|
|
|
return Vec(x, y)
|
|
|
|
|
|
|
|
return Vec(x, y, self.z + other.z)
|
|
|
|
|
|
|
|
def minus(self, other: 'Vec') -> 'Vec':
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Subtracts 2 vectors"""
|
2023-03-31 02:40:11 +02:00
|
|
|
x = self.x - other.x
|
|
|
|
y = self.y - other.y
|
|
|
|
|
|
|
|
if self.z == None or other.z == None:
|
|
|
|
return Vec(x, y)
|
|
|
|
|
|
|
|
return Vec(x, y, self.z - other.z)
|
|
|
|
|
2023-03-31 04:08:18 +02:00
|
|
|
def times(self, factor: float) -> 'Vec':
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Multiplies 2 vectors"""
|
2023-03-31 04:08:18 +02:00
|
|
|
x = self.x * factor
|
|
|
|
y = self.y * factor
|
|
|
|
|
|
|
|
if self.z == None:
|
|
|
|
return Vec(x, y)
|
|
|
|
|
|
|
|
return Vec(x, y, self.z * factor)
|
|
|
|
|
2023-03-31 03:38:59 +02:00
|
|
|
def div(self, factor: float) -> 'Vec':
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Divides 2 vectors"""
|
2023-03-31 03:38:59 +02:00
|
|
|
x = self.x / factor
|
|
|
|
y = self.y / factor
|
2023-03-31 02:40:11 +02:00
|
|
|
|
|
|
|
if self.z == None:
|
|
|
|
return Vec(x, y)
|
|
|
|
|
2023-03-31 03:38:59 +02:00
|
|
|
return Vec(x, y, self.z / factor)
|
2023-03-31 02:40:11 +02:00
|
|
|
|
|
|
|
def to_angle(self):
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Transforms a Vec3 into a Vec2 angle"""
|
2023-03-31 02:40:11 +02:00
|
|
|
if self.z == None:
|
|
|
|
raise TypeError
|
|
|
|
|
|
|
|
deg_to_rad = (180. / pi)
|
|
|
|
|
|
|
|
return Vec(
|
|
|
|
atan2(-self.z, hypot(self.x, self.y)) * deg_to_rad,
|
2023-03-31 03:38:59 +02:00
|
|
|
atan2(self.y, self.x) * deg_to_rad
|
2023-03-31 02:40:11 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def is_zero(self):
|
2023-04-01 16:20:46 +02:00
|
|
|
"""Check if the vector is zero"""
|
2023-03-31 02:43:15 +02:00
|
|
|
xy = (float(self.x) == 0.) and (float(self.y) == 0.)
|
2023-03-31 02:40:11 +02:00
|
|
|
if self.z == None:
|
|
|
|
return xy
|
|
|
|
|
|
|
|
return xy and float(self.z) == 0.
|
|
|
|
|
|
|
|
|
2023-04-01 16:20:46 +02:00
|
|
|
def angle_normalizer(angle: Vec) -> Vec:
|
2023-03-31 03:38:59 +02:00
|
|
|
"""Force the angle to respect game limitation"""
|
|
|
|
# Limit of pitch in game is ]-89; 180[
|
|
|
|
if angle.x > 89.:
|
|
|
|
angle.x = 89.
|
|
|
|
if angle.x < -89.:
|
|
|
|
angle.x = -89
|
|
|
|
|
|
|
|
# Limit of yaw in game is ]-180; 360[
|
|
|
|
while (angle.y > 180.):
|
|
|
|
angle.y -= 360.
|
|
|
|
while (angle.y < -180.):
|
|
|
|
angle.y += 360.
|
|
|
|
|
|
|
|
return angle
|
2023-03-31 21:58:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
class Color3i:
|
|
|
|
"""Color RGB as integer"""
|
|
|
|
|
|
|
|
def __init__(self, r: int, g: int, b: int) -> None:
|
|
|
|
self.r = r
|
|
|
|
self.g = g
|
|
|
|
self.b = b
|
|
|
|
|
2023-04-03 02:36:54 +02:00
|
|
|
def __str__(self):
|
|
|
|
return f"{self.__class__.__name__}({self.r}, {self.g}, {self.b})"
|
|
|
|
|
2023-03-31 21:58:07 +02:00
|
|
|
|
|
|
|
class Color4f:
|
|
|
|
"""Color RGBA as float"""
|
|
|
|
|
|
|
|
def __init__(self, r: float, g: float, b: float, a: float) -> None:
|
|
|
|
self.r = r
|
|
|
|
self.g = g
|
|
|
|
self.b = b
|
|
|
|
self.a = a
|
2023-04-03 02:36:54 +02:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
max_precision = 3
|
|
|
|
|
|
|
|
r = round(self.r, max_precision)
|
|
|
|
g = round(self.g, max_precision)
|
|
|
|
b = round(self.b, max_precision)
|
|
|
|
a = round(self.a, max_precision)
|
|
|
|
|
|
|
|
return f"{self.__class__.__name__}({r}, {g}, {b}, {a})"
|
2023-04-04 11:14:10 +02:00
|
|
|
|
|
|
|
|
|
|
|
def errors_unload():
|
|
|
|
"""Return error who can occurs when unloading cheats"""
|
|
|
|
return (TypeError, AttributeError)
|