This repository has been archived on 2023-09-02. You can view files and clone it, but cannot push or open issues or pull requests.
csh/utils.py

164 lines
4.1 KiB
Python
Raw Normal View History

2023-03-31 02:40:11 +02:00
from math import atan2, hypot, pi
class Vec:
"""Support : `Vec2i | Vec2f | Vec3i | Vec3f`"""
2023-05-05 16:04:06 +02:00
def __init__(
self,
x: int | float | None = None,
y: int | float | None = None,
z: int | float | None = None,
) -> None:
if x is not None:
2023-03-31 02:40:11 +02:00
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:
"""Change values of Vector"""
2023-05-05 16:04:06 +02:00
if y is 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)
2023-05-05 16:04:06 +02:00
if z is None:
2023-03-31 02:40:11 +02:00
self.z = None
else:
self.z = self.type(z)
def __str__(self):
max_precision = 3
x = round(self.x, max_precision)
y = round(self.y, max_precision)
2023-05-05 16:04:06 +02:00
z = None if self.z is None else round(self.z, max_precision)
2023-05-05 16:04:06 +02:00
return f"{self.__class__.__name__}({x}, {y}{'' if z is None else f', {z}'})"
2023-05-05 16:04:06 +02:00
def plus(self, other: "Vec") -> "Vec":
"""Add 2 vectors"""
2023-03-31 02:40:11 +02:00
x = self.x + other.x
y = self.y + other.y
2023-05-05 16:04:06 +02:00
if self.z is None or other.z is None:
2023-03-31 02:40:11 +02:00
return Vec(x, y)
return Vec(x, y, self.z + other.z)
2023-05-05 16:04:06 +02:00
def minus(self, other: "Vec") -> "Vec":
"""Subtracts 2 vectors"""
2023-03-31 02:40:11 +02:00
x = self.x - other.x
y = self.y - other.y
2023-05-05 16:04:06 +02:00
if self.z is None or other.z is None:
2023-03-31 02:40:11 +02:00
return Vec(x, y)
return Vec(x, y, self.z - other.z)
2023-05-05 16:04:06 +02:00
def times(self, factor: float) -> "Vec":
"""Multiplies 2 vectors"""
2023-03-31 04:08:18 +02:00
x = self.x * factor
y = self.y * factor
2023-05-05 16:04:06 +02:00
if self.z is None:
2023-03-31 04:08:18 +02:00
return Vec(x, y)
return Vec(x, y, self.z * factor)
2023-05-05 16:04:06 +02:00
def div(self, factor: float) -> "Vec":
"""Divides 2 vectors"""
x = self.x / factor
y = self.y / factor
2023-03-31 02:40:11 +02:00
2023-05-05 16:04:06 +02:00
if self.z is None:
2023-03-31 02:40:11 +02:00
return Vec(x, y)
return Vec(x, y, self.z / factor)
2023-03-31 02:40:11 +02:00
def to_angle(self):
"""Transforms a Vec3 into a Vec2 angle"""
2023-05-05 16:04:06 +02:00
if self.z is None:
2023-03-31 02:40:11 +02:00
raise TypeError
2023-05-05 16:04:06 +02:00
deg_to_rad = 180.0 / pi
2023-03-31 02:40:11 +02:00
return Vec(
atan2(-self.z, hypot(self.x, self.y)) * deg_to_rad,
2023-05-05 16:04:06 +02:00
atan2(self.y, self.x) * deg_to_rad,
2023-03-31 02:40:11 +02:00
)
def is_zero(self):
"""Check if the vector is zero"""
2023-05-05 16:04:06 +02:00
xy = (float(self.x) == 0.0) and (float(self.y) == 0.0)
if self.z is None:
2023-03-31 02:40:11 +02:00
return xy
2023-05-05 16:04:06 +02:00
return xy and float(self.z) == 0.0
2023-03-31 02:40:11 +02:00
def angle_normalizer(angle: Vec) -> Vec:
"""Force the angle to respect game limitation"""
# Limit of pitch in game is ]-89; 180[
2023-05-05 16:04:06 +02:00
if angle.x > 89.0:
angle.x = 89.0
if angle.x < -89.0:
angle.x = -89
# Limit of yaw in game is ]-180; 360[
2023-05-05 16:04:06 +02:00
while angle.y > 180.0:
angle.y -= 360.0
while angle.y < -180.0:
angle.y += 360.0
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
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
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})"
def errors_unload():
"""Return error who can occurs when unloading cheats"""
return (TypeError, AttributeError)