Mods
This commit is contained in:
parent
a8be025870
commit
91040eb390
|
@ -17,9 +17,9 @@ class Ant:
|
||||||
self.updated = now
|
self.updated = now
|
||||||
self.name = ""
|
self.name = ""
|
||||||
self.status = ""
|
self.status = ""
|
||||||
|
self.method = "normal"
|
||||||
self.triumph = 0
|
self.triumph = 0
|
||||||
self.hits = 0
|
self.hits = 0
|
||||||
self.color: tuple[int, int, int]
|
|
||||||
|
|
||||||
def to_dict(self) -> dict[str, Any]:
|
def to_dict(self) -> dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
|
@ -27,9 +27,9 @@ class Ant:
|
||||||
"updated": self.updated,
|
"updated": self.updated,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"status": self.status,
|
"status": self.status,
|
||||||
|
"method": self.method,
|
||||||
"hits": self.hits,
|
"hits": self.hits,
|
||||||
"triumph": self.triumph,
|
"triumph": self.triumph,
|
||||||
"color": self.color,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def from_dict(self, data: dict[str, Any]) -> None:
|
def from_dict(self, data: dict[str, Any]) -> None:
|
||||||
|
@ -37,12 +37,10 @@ class Ant:
|
||||||
self.updated = data["updated"]
|
self.updated = data["updated"]
|
||||||
self.name = data["name"]
|
self.name = data["name"]
|
||||||
self.status = data["status"]
|
self.status = data["status"]
|
||||||
|
self.method = data["method"]
|
||||||
self.hits = data["hits"]
|
self.hits = data["hits"]
|
||||||
self.triumph = data["triumph"]
|
self.triumph = data["triumph"]
|
||||||
|
|
||||||
c = data["color"]
|
|
||||||
self.color = (c[0], c[1], c[2])
|
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
return self.name or "Nameless"
|
return self.name or "Nameless"
|
||||||
|
|
||||||
|
@ -76,7 +74,6 @@ class Ants:
|
||||||
ant.created = now
|
ant.created = now
|
||||||
ant.updated = now
|
ant.updated = now
|
||||||
ant.name = Utils.random_name()
|
ant.name = Utils.random_name()
|
||||||
ant.color = Utils.random_color(ant.name)
|
|
||||||
|
|
||||||
Ants.ants.append(ant)
|
Ants.ants.append(ant)
|
||||||
image_path = Config.hatched_image_path
|
image_path = Config.hatched_image_path
|
||||||
|
@ -136,16 +133,14 @@ class Ants:
|
||||||
return min(Ants.ants, key=lambda ant: ant.updated)
|
return min(Ants.ants, key=lambda ant: ant.updated)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_status(ant: Ant, status: str) -> None:
|
def set_status(ant: Ant, status: str, method: str) -> None:
|
||||||
from .game import Game
|
from .game import Game
|
||||||
|
|
||||||
status = status.strip()
|
status = status.strip()
|
||||||
|
|
||||||
if not status:
|
|
||||||
return
|
|
||||||
|
|
||||||
ant.status = status
|
ant.status = status
|
||||||
|
ant.method = method
|
||||||
ant.updated = Utils.now()
|
ant.updated = Utils.now()
|
||||||
|
|
||||||
Game.add_status(ant)
|
Game.add_status(ant)
|
||||||
Ants.save()
|
Ants.save()
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,19 @@ class Config:
|
||||||
space_1: int = 20
|
space_1: int = 20
|
||||||
max_messages: int = 200
|
max_messages: int = 200
|
||||||
loop_delay_fast: int = 3_000
|
loop_delay_fast: int = 3_000
|
||||||
loop_delay_normal: int = 30_000
|
loop_delay_normal: int = 60_000
|
||||||
loop_delay_slow: int = 60_000
|
loop_delay_slow: int = 120_000
|
||||||
hatch_burst: int = 3
|
hatch_burst: int = 3
|
||||||
font_size: int = 20
|
font_size: int = 20
|
||||||
info_separator: str = " - "
|
info_separator: str = " - "
|
||||||
font_path: Path
|
font_path: Path
|
||||||
emoji_font_path: Path
|
emoji_font_path: Path
|
||||||
|
triumph_color: tuple[int, int, int] = (255, 255, 0)
|
||||||
|
hit_color: tuple[int, int, int] = (255, 0, 77)
|
||||||
|
triumph_icon: str = "😀"
|
||||||
|
hit_icon: str = "🎃"
|
||||||
|
triumph_message: str = "Scored a triumph"
|
||||||
|
hit_message: str = "Took a hit"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def prepare() -> None:
|
def prepare() -> None:
|
||||||
|
|
|
@ -31,8 +31,22 @@ class Game:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_status(ant: Ant) -> None:
|
def add_status(ant: Ant) -> None:
|
||||||
container = QHBoxLayout()
|
container = QHBoxLayout()
|
||||||
image_label = Game.get_image(Config.status_image_path, ant.color)
|
status = ant.status
|
||||||
right_container = Game.make_right_container(ant.name, ant.status)
|
color = None
|
||||||
|
|
||||||
|
if ant.method == "triumph":
|
||||||
|
total = f"({ant.triumph} total)"
|
||||||
|
status = f"{Config.triumph_icon} {Config.triumph_message} {total}"
|
||||||
|
color = Config.triumph_color
|
||||||
|
elif ant.method == "hit":
|
||||||
|
total = f"({ant.hits} total)"
|
||||||
|
status = f"{Config.hit_icon} {Config.hit_message} {total}"
|
||||||
|
color = Config.hit_color
|
||||||
|
elif ant.method == "thinking":
|
||||||
|
status = f"Thinking about {status}"
|
||||||
|
|
||||||
|
image_label = Game.get_image(Config.status_image_path, color)
|
||||||
|
right_container = Game.make_right_container(ant.name, status)
|
||||||
|
|
||||||
container.addWidget(image_label)
|
container.addWidget(image_label)
|
||||||
container.addSpacing(Config.space_1)
|
container.addSpacing(Config.space_1)
|
||||||
|
@ -40,9 +54,14 @@ class Game:
|
||||||
Game.add_view_container(container)
|
Game.add_view_container(container)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_message(title: str, message: str, image_path: Path) -> None:
|
def add_message(
|
||||||
|
title: str,
|
||||||
|
message: str,
|
||||||
|
image_path: Path,
|
||||||
|
color: tuple[int, int, int] = (255, 255, 255),
|
||||||
|
) -> None:
|
||||||
container = QHBoxLayout()
|
container = QHBoxLayout()
|
||||||
image_label = Game.get_image(image_path, (255, 255, 255))
|
image_label = Game.get_image(image_path, color)
|
||||||
right_container = Game.make_right_container(title, message)
|
right_container = Game.make_right_container(title, message)
|
||||||
|
|
||||||
container.addWidget(image_label)
|
container.addWidget(image_label)
|
||||||
|
@ -65,7 +84,7 @@ class Game:
|
||||||
def make_right_container(title: str, message: str) -> QWidget:
|
def make_right_container(title: str, message: str) -> QWidget:
|
||||||
root = QWidget()
|
root = QWidget()
|
||||||
container = QVBoxLayout()
|
container = QVBoxLayout()
|
||||||
container.setAlignment(Qt.AlignmentFlag.AlignTop)
|
container.setAlignment(Qt.AlignTop)
|
||||||
|
|
||||||
title_label = QLabel(title)
|
title_label = QLabel(title)
|
||||||
title_label.setStyleSheet("font-weight: bold;")
|
title_label.setStyleSheet("font-weight: bold;")
|
||||||
|
@ -83,24 +102,25 @@ class Game:
|
||||||
return root
|
return root
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_image(image_path: Path, border_color: tuple[int, int, int]) -> QLabel:
|
def get_image(
|
||||||
|
image_path: Path, color: tuple[int, int, int] | None = None
|
||||||
|
) -> QLabel:
|
||||||
image_label = QLabel()
|
image_label = QLabel()
|
||||||
pixmap = QPixmap(str(image_path))
|
pixmap = QPixmap(str(image_path))
|
||||||
|
|
||||||
scaled_pixmap = pixmap.scaled(
|
scaled_pixmap = pixmap.scaled(
|
||||||
Config.image_size,
|
Config.image_size,
|
||||||
pixmap.height(),
|
pixmap.height(),
|
||||||
Qt.AspectRatioMode.KeepAspectRatio,
|
Qt.KeepAspectRatio,
|
||||||
Qt.TransformationMode.SmoothTransformation,
|
Qt.SmoothTransformation,
|
||||||
)
|
)
|
||||||
|
|
||||||
image_label.setPixmap(scaled_pixmap)
|
image_label.setPixmap(scaled_pixmap)
|
||||||
image_label.setFixedSize(scaled_pixmap.size())
|
image_label.setFixedSize(scaled_pixmap.size())
|
||||||
border_rgb = Utils.get_rgb(border_color)
|
|
||||||
|
|
||||||
image_label.setStyleSheet(
|
if color:
|
||||||
f"border: 2px solid {border_rgb};"
|
rgb = Utils.get_rgb(color)
|
||||||
)
|
image_label.setStyleSheet(f"border: 2px solid {rgb};")
|
||||||
|
|
||||||
return image_label
|
return image_label
|
||||||
|
|
||||||
|
@ -115,26 +135,31 @@ class Game:
|
||||||
num = random.randint(1, 10)
|
num = random.randint(1, 10)
|
||||||
s = RandomSentence()
|
s = RandomSentence()
|
||||||
status = ""
|
status = ""
|
||||||
|
method = "normal"
|
||||||
|
|
||||||
if num == 1:
|
if num == 1:
|
||||||
ant.triumph += 1
|
ant.triumph += 1
|
||||||
status = f"😀 Scored a triumph ({ant.triumph} total)"
|
method = "triumph"
|
||||||
elif num == 2:
|
elif num == 2:
|
||||||
ant.hits += 1
|
ant.hits += 1
|
||||||
status = f"🎃 Took a hit ({ant.hits} total)"
|
method = "hit"
|
||||||
elif (num == 3) and (num_ants > 1):
|
elif (num == 3) and (num_ants > 1):
|
||||||
other = Ants.get_other(ant)
|
other = Ants.get_other(ant)
|
||||||
status = f"🫠 Is thinking about {other.name}"
|
status = other.name
|
||||||
|
method = "thinking"
|
||||||
elif num == 4:
|
elif num == 4:
|
||||||
status = s.simple_sentence()
|
status = s.simple_sentence()
|
||||||
elif num == 5:
|
elif num == 5:
|
||||||
status = s.bare_bone_sentence()
|
status = s.bare_bone_sentence()
|
||||||
elif num == 6:
|
elif num == 6:
|
||||||
status = s.bare_bone_with_adjective()
|
status = s.bare_bone_with_adjective()
|
||||||
|
elif num == 7:
|
||||||
|
status = Utils.get_random_emoji(3)
|
||||||
|
method = "thinking"
|
||||||
else:
|
else:
|
||||||
status = s.sentence()
|
status = s.sentence()
|
||||||
|
|
||||||
Ants.set_status(ant, status)
|
Ants.set_status(ant, status, method)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def initial_fill() -> None:
|
def initial_fill() -> None:
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import colorsys
|
import colorsys
|
||||||
import time
|
import time
|
||||||
from typing import ClassVar
|
from typing import ClassVar
|
||||||
|
from fontTools.ttLib import TTFont # type: ignore
|
||||||
|
|
||||||
|
from .config import Config
|
||||||
from .storage import Storage
|
from .storage import Storage
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,3 +95,16 @@ class Utils:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_rgb(color: tuple[int, int, int]) -> str:
|
def get_rgb(color: tuple[int, int, int]) -> str:
|
||||||
return f"rgb{color}"
|
return f"rgb{color}"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_random_character(font_path: str, num: int) -> str:
|
||||||
|
font = TTFont(font_path)
|
||||||
|
cmap = font["cmap"]
|
||||||
|
unicode_map = cmap.getBestCmap()
|
||||||
|
characters = [chr(code_point) for code_point in unicode_map]
|
||||||
|
selected = random.sample(characters, num)
|
||||||
|
return " ".join(selected)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_random_emoji(num: int) -> str:
|
||||||
|
return Utils.get_random_character(str(Config.emoji_font_path), num)
|
||||||
|
|
|
@ -29,7 +29,7 @@ class SpecialButton(QPushButton): # type: ignore
|
||||||
middleClicked = Signal()
|
middleClicked = Signal()
|
||||||
|
|
||||||
def mousePressEvent(self, e: QMouseEvent) -> None:
|
def mousePressEvent(self, e: QMouseEvent) -> None:
|
||||||
if e.button() == Qt.MouseButton.MiddleButton:
|
if e.button() == Qt.MiddleButton:
|
||||||
self.middleClicked.emit()
|
self.middleClicked.emit()
|
||||||
else:
|
else:
|
||||||
super().mousePressEvent(e)
|
super().mousePressEvent(e)
|
||||||
|
@ -63,7 +63,7 @@ class Window:
|
||||||
central_widget = QWidget()
|
central_widget = QWidget()
|
||||||
Window.root = QVBoxLayout()
|
Window.root = QVBoxLayout()
|
||||||
central_widget.setLayout(Window.root)
|
central_widget.setLayout(Window.root)
|
||||||
Window.root.setAlignment(Qt.AlignmentFlag.AlignTop)
|
Window.root.setAlignment(Qt.AlignTop)
|
||||||
Window.window.setCentralWidget(central_widget)
|
Window.window.setCentralWidget(central_widget)
|
||||||
Window.window.setWindowIcon(QIcon(str(Config.icon_path)))
|
Window.window.setWindowIcon(QIcon(str(Config.icon_path)))
|
||||||
|
|
||||||
|
@ -102,7 +102,9 @@ class Window:
|
||||||
btn_hatch.middleClicked.connect(lambda: Ants.hatch_burst())
|
btn_hatch.middleClicked.connect(lambda: Ants.hatch_burst())
|
||||||
|
|
||||||
btn_terminate = SpecialButton("Terminate")
|
btn_terminate = SpecialButton("Terminate")
|
||||||
btn_terminate.setToolTip("Terminate a random ant\nMiddle Click to terminate all")
|
btn_terminate.setToolTip(
|
||||||
|
"Terminate a random ant\nMiddle Click to terminate all"
|
||||||
|
)
|
||||||
btn_terminate.clicked.connect(lambda e: Ants.terminate())
|
btn_terminate.clicked.connect(lambda e: Ants.terminate())
|
||||||
btn_terminate.middleClicked.connect(lambda: Ants.terminate_all())
|
btn_terminate.middleClicked.connect(lambda: Ants.terminate_all())
|
||||||
|
|
||||||
|
@ -135,7 +137,7 @@ class Window:
|
||||||
Window.view = QVBoxLayout()
|
Window.view = QVBoxLayout()
|
||||||
parent.addLayout(Window.view)
|
parent.addLayout(Window.view)
|
||||||
|
|
||||||
Window.view.setAlignment(Qt.AlignmentFlag.AlignTop)
|
Window.view.setAlignment(Qt.AlignTop)
|
||||||
Window.scroll_area.setWidget(container)
|
Window.scroll_area.setWidget(container)
|
||||||
Window.root.addWidget(Window.scroll_area)
|
Window.root.addWidget(Window.scroll_area)
|
||||||
|
|
||||||
|
@ -204,7 +206,9 @@ class Window:
|
||||||
root.setContentsMargins(0, 0, 0, 0)
|
root.setContentsMargins(0, 0, 0, 0)
|
||||||
container = QHBoxLayout()
|
container = QHBoxLayout()
|
||||||
Window.info = SpecialButton("---")
|
Window.info = SpecialButton("---")
|
||||||
Window.info.setToolTip("Scroll to the bottom\nMiddle Click to scroll to the top")
|
Window.info.setToolTip(
|
||||||
|
"Scroll to the bottom\nMiddle Click to scroll to the top"
|
||||||
|
)
|
||||||
Window.info.clicked.connect(Window.to_bottom)
|
Window.info.clicked.connect(Window.to_bottom)
|
||||||
Window.info.middleClicked.connect(Window.to_top)
|
Window.info.middleClicked.connect(Window.to_top)
|
||||||
Window.info.setMinimumSize(35, 35)
|
Window.info.setMinimumSize(35, 35)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
PySide6 == 6.7.2
|
PySide6 == 6.7.2
|
||||||
appdirs == 1.4.4
|
appdirs == 1.4.4
|
||||||
wonderwords == 2.2.0
|
wonderwords == 2.2.0
|
||||||
|
fonttools == 4.53.1
|
Loading…
Reference in New Issue