|
|
@@ -4,6 +4,7 @@ import math |
|
|
|
import os |
|
|
|
import random |
|
|
|
import sys |
|
|
|
import wave |
|
|
|
from datetime import datetime, timedelta |
|
|
|
from enum import Enum, auto |
|
|
|
from typing import Callable, TypedDict |
|
|
@@ -24,10 +25,12 @@ from pygame.time import Clock |
|
|
|
from pytchat.core.pytchat import PytchatCore |
|
|
|
from pytchat.processors.default.processor import Chat |
|
|
|
|
|
|
|
from aques import Aques |
|
|
|
from common_module import CommonModule |
|
|
|
from nizika_ai.config import DB |
|
|
|
from nizika_ai.consts import (AnswerType, Character, GPTModel, Platform, |
|
|
|
QueryType) |
|
|
|
from nizika_ai.models import Answer, AnsweredFlag, Query, User |
|
|
|
from nizika_ai.consts import AnswerType, Character, GPTModel, Platform, QueryType |
|
|
|
|
|
|
|
pygame.init () |
|
|
|
|
|
|
@@ -42,12 +45,11 @@ def main ( |
|
|
|
) -> None: |
|
|
|
game = Game () |
|
|
|
Bg (game) |
|
|
|
Deerjika (game, DeerjikaPattern.RELAXED, x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120) |
|
|
|
Deerjika (game, DeerjikaPattern.RELAXED, x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120) |
|
|
|
Deerjika (game, DeerjikaPattern.RELAXED, x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120) |
|
|
|
Deerjika (game, DeerjikaPattern.RELAXED, x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120) |
|
|
|
Deerjika (game, DeerjikaPattern.RELAXED, x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120) |
|
|
|
balloon = Balloon (game) |
|
|
|
deerjika = Deerjika (game, DeerjikaPattern.RELAXED, |
|
|
|
x = CWindow.WIDTH * 3 / 4, |
|
|
|
y = CWindow.HEIGHT - 120, |
|
|
|
balloon = balloon) |
|
|
|
CurrentTime (game, SYSTEM_FONT) |
|
|
|
broadcast = Broadcast (os.environ['BROADCAST_CODE']) |
|
|
|
try: |
|
|
@@ -60,6 +62,7 @@ def main ( |
|
|
|
pygame.quit () |
|
|
|
sys.exit () |
|
|
|
if not balloon.enabled: |
|
|
|
DB.begin_transaction () |
|
|
|
answer_flags = (AnsweredFlag.where ('platform', Platform.YOUTUBE.value) |
|
|
|
.where ('answered', False) |
|
|
|
.get ()) |
|
|
@@ -68,9 +71,10 @@ def main ( |
|
|
|
answer = Answer.find (answer_flag.answer_id) |
|
|
|
if answer.answer_type == AnswerType.YOUTUBE_REPLY.value: |
|
|
|
query = Query.find (answer.query_id) |
|
|
|
balloon.talk (query.content, answer.content) |
|
|
|
deerjika.talk (query.content, answer.content) |
|
|
|
answer_flag.answered = True |
|
|
|
answer_flag.save () |
|
|
|
DB.commit () |
|
|
|
add_query (broadcast) |
|
|
|
game.redraw () |
|
|
|
|
|
|
@@ -297,7 +301,16 @@ class BgGrass (GameObject): |
|
|
|
super ().redraw () |
|
|
|
|
|
|
|
|
|
|
|
class Deerjika (GameObject): |
|
|
|
class Creature (GameObject): |
|
|
|
sound: Sound |
|
|
|
|
|
|
|
def bell ( |
|
|
|
self, |
|
|
|
) -> None: |
|
|
|
self.sound.play () |
|
|
|
|
|
|
|
|
|
|
|
class Deerjika (Creature): |
|
|
|
""" |
|
|
|
伊地知ニジカ |
|
|
|
|
|
|
@@ -309,9 +322,12 @@ class Deerjika (GameObject): |
|
|
|
""" |
|
|
|
|
|
|
|
height: int |
|
|
|
scale: float = .8 |
|
|
|
scale: float = .8 |
|
|
|
surfaces: list[Surface] |
|
|
|
width: int |
|
|
|
talking: bool = False |
|
|
|
wav: bytearray | None = None |
|
|
|
balloon: Balloon |
|
|
|
|
|
|
|
def __init__ ( |
|
|
|
self, |
|
|
@@ -321,10 +337,14 @@ class Deerjika (GameObject): |
|
|
|
layer: int | None = None, |
|
|
|
x: float = 0, |
|
|
|
y: float = 0, |
|
|
|
balloon: Balloon | None = None, |
|
|
|
): |
|
|
|
if balloon is None: |
|
|
|
raise Exception |
|
|
|
super ().__init__ (game, layer, x = x, y = y) |
|
|
|
self.pattern = pattern |
|
|
|
self.direction = direction |
|
|
|
self.balloon = balloon |
|
|
|
match pattern: |
|
|
|
case DeerjikaPattern.NORMAL: |
|
|
|
... |
|
|
@@ -340,6 +360,7 @@ class Deerjika (GameObject): |
|
|
|
surface.subsurface (x, 0, self.width, self.height)) |
|
|
|
case Direction.RIGHT: |
|
|
|
... |
|
|
|
self.sound = Sound ('assets/noon.wav') |
|
|
|
|
|
|
|
def redraw ( |
|
|
|
self, |
|
|
@@ -348,9 +369,44 @@ class Deerjika (GameObject): |
|
|
|
(self.width * self.scale, self.height * self.scale)) |
|
|
|
self.game.screen.blit (surface, surface.get_rect (center = (self.x, self.y))) |
|
|
|
super ().redraw () |
|
|
|
self.x = random.randrange (CWindow.WIDTH) |
|
|
|
self.y = random.randrange (CWindow.HEIGHT) |
|
|
|
self.arg = math.radians (random.randrange (360)) |
|
|
|
if (not self.balloon.enabled) and self.talking: |
|
|
|
self.talking = False |
|
|
|
if (self.balloon.enabled and self.balloon.frame >= FPS * 3 |
|
|
|
and not self.talking): |
|
|
|
self.read_out () |
|
|
|
|
|
|
|
|
|
|
|
def talk ( |
|
|
|
self, |
|
|
|
query: str, |
|
|
|
answer: str, |
|
|
|
) -> None: |
|
|
|
self.bell () |
|
|
|
self._create_wav (answer) |
|
|
|
length = 300 |
|
|
|
if self.wav is not None: |
|
|
|
with wave.open ('./nizika_talking.wav', 'rb') as f: |
|
|
|
length = int (FPS * (f.getnframes () / f.getframerate () + 4)) |
|
|
|
self.balloon.talk (query, answer, length = length) |
|
|
|
|
|
|
|
def read_out ( |
|
|
|
self, |
|
|
|
) -> None: |
|
|
|
Sound ('./nizika_talking.wav').play () |
|
|
|
self.talking = True |
|
|
|
|
|
|
|
def _create_wav ( |
|
|
|
self, |
|
|
|
message: str, |
|
|
|
) -> None: |
|
|
|
try: |
|
|
|
self.wav = Aques.main (message, False) |
|
|
|
except: |
|
|
|
self.wav = None |
|
|
|
if self.wav is None: |
|
|
|
return |
|
|
|
with open ('./nizika_talking.wav', 'wb') as f: |
|
|
|
f.write (self.wav) |
|
|
|
|
|
|
|
|
|
|
|
class CurrentTime (GameObject): |
|
|
|