2021-05-02 15:39:59 +00:00
|
|
|
import logging
|
2021-05-13 08:53:54 +00:00
|
|
|
import math
|
2021-05-02 15:39:59 +00:00
|
|
|
import pickle
|
2021-05-15 12:20:38 +00:00
|
|
|
import time
|
2021-05-02 15:39:59 +00:00
|
|
|
|
|
|
|
import typing
|
|
|
|
|
|
|
|
from fishy.engine.fullautofisher.mode.imode import IMode
|
|
|
|
from fishy.engine.semifisher import fishing_event, fishing_mode
|
|
|
|
|
|
|
|
if typing.TYPE_CHECKING:
|
|
|
|
from fishy.engine.fullautofisher.engine import FullAuto
|
|
|
|
|
|
|
|
from fishy.helper import helper
|
|
|
|
from fishy.helper.config import config
|
|
|
|
|
|
|
|
|
2021-05-13 12:04:50 +00:00
|
|
|
def get_rec_file():
|
2021-05-02 15:39:59 +00:00
|
|
|
file = config.get("full_auto_rec_file")
|
|
|
|
|
|
|
|
if not file:
|
|
|
|
logging.error("Please select a fishy file first from config")
|
|
|
|
return None
|
|
|
|
|
|
|
|
file = open(file, 'rb')
|
|
|
|
data = pickle.load(file)
|
|
|
|
file.close()
|
|
|
|
if "full_auto_path" not in data:
|
|
|
|
logging.error("invalid file")
|
|
|
|
return None
|
|
|
|
return data["full_auto_path"]
|
|
|
|
|
|
|
|
|
2021-05-13 12:04:50 +00:00
|
|
|
def find_nearest(timeline, current):
|
|
|
|
"""
|
|
|
|
:param timeline: recording timeline
|
|
|
|
:param current: current coord
|
|
|
|
:return: Tuple[index, distance, target_coord]
|
|
|
|
"""
|
|
|
|
distances = [(i, math.sqrt((target[0] - current[0]) ** 2 + (target[1] - current[1]) ** 2), target)
|
|
|
|
for i, (command, target) in enumerate(timeline) if command == "move_to"]
|
|
|
|
return min(distances, key=lambda d: d[1])
|
|
|
|
|
|
|
|
|
2021-05-02 15:39:59 +00:00
|
|
|
class Player(IMode):
|
|
|
|
def __init__(self, engine: 'FullAuto'):
|
|
|
|
self.recording = False
|
|
|
|
self.engine = engine
|
|
|
|
self.hole_complete_flag = False
|
|
|
|
self.start_moving_flag = False
|
|
|
|
self.i = 0
|
|
|
|
self.forward = True
|
|
|
|
self.timeline = None
|
|
|
|
|
|
|
|
def run(self):
|
2022-02-01 11:27:14 +00:00
|
|
|
if not self._init():
|
|
|
|
return
|
|
|
|
|
2021-05-02 15:39:59 +00:00
|
|
|
while self.engine.start:
|
|
|
|
self._loop()
|
2021-05-15 12:20:38 +00:00
|
|
|
time.sleep(0.1)
|
2022-02-01 11:27:14 +00:00
|
|
|
|
2021-05-02 15:39:59 +00:00
|
|
|
logging.info("player stopped")
|
|
|
|
|
2022-02-01 11:27:14 +00:00
|
|
|
def _init(self) -> bool:
|
2021-05-13 12:04:50 +00:00
|
|
|
self.timeline = get_rec_file()
|
2021-05-02 15:39:59 +00:00
|
|
|
if not self.timeline:
|
2022-02-01 11:27:14 +00:00
|
|
|
logging.error("data not found, can't start")
|
|
|
|
return False
|
2021-05-02 15:39:59 +00:00
|
|
|
|
2021-05-15 12:20:38 +00:00
|
|
|
coords = self.engine.get_coords()
|
|
|
|
if not coords:
|
2022-02-01 11:27:14 +00:00
|
|
|
logging.error("QR not found")
|
|
|
|
return False
|
2021-05-15 12:20:38 +00:00
|
|
|
|
|
|
|
self.i = find_nearest(self.timeline, coords)[0]
|
2022-02-01 11:27:14 +00:00
|
|
|
logging.info("starting player")
|
2021-05-13 08:53:54 +00:00
|
|
|
|
2021-05-02 15:39:59 +00:00
|
|
|
def _loop(self):
|
|
|
|
action = self.timeline[self.i]
|
|
|
|
|
|
|
|
if action[0] == "move_to":
|
2021-05-15 12:20:38 +00:00
|
|
|
if not self.engine.move_to(action[1]):
|
|
|
|
return
|
2021-05-02 15:39:59 +00:00
|
|
|
elif action[0] == "check_fish":
|
2021-05-15 12:20:38 +00:00
|
|
|
if not self.engine.move_to(action[1]):
|
|
|
|
return
|
|
|
|
|
|
|
|
if not self.engine.rotate_to(action[1][2]):
|
|
|
|
return
|
|
|
|
|
2022-02-01 11:27:14 +00:00
|
|
|
self.engine.fisher.turn_on()
|
2021-05-02 15:39:59 +00:00
|
|
|
# scan for fish hole
|
|
|
|
logging.info("scanning")
|
|
|
|
# if found start fishing and wait for hole to complete
|
|
|
|
if self.engine.look_for_hole():
|
|
|
|
logging.info("starting fishing")
|
2022-02-01 11:27:14 +00:00
|
|
|
fishing_mode.subscribers.append(self._hole_complete_callback)
|
2021-05-02 15:39:59 +00:00
|
|
|
self.hole_complete_flag = False
|
|
|
|
helper.wait_until(lambda: self.hole_complete_flag or not self.engine.start)
|
2022-02-01 11:27:14 +00:00
|
|
|
fishing_mode.subscribers.remove(self._hole_complete_callback)
|
|
|
|
|
2021-05-02 15:39:59 +00:00
|
|
|
self.engine.rotate_back()
|
|
|
|
else:
|
|
|
|
logging.info("no hole found")
|
|
|
|
# continue when hole completes
|
2022-02-01 11:27:14 +00:00
|
|
|
self.engine.fisher.turn_off()
|
2021-05-02 15:39:59 +00:00
|
|
|
|
2021-05-15 12:20:38 +00:00
|
|
|
self.next()
|
|
|
|
|
|
|
|
def next(self):
|
2021-05-02 15:39:59 +00:00
|
|
|
self.i += 1 if self.forward else -1
|
|
|
|
if self.i >= len(self.timeline):
|
|
|
|
self.forward = False
|
|
|
|
self.i = len(self.timeline) - 1
|
|
|
|
elif self.i < 0:
|
|
|
|
self.forward = True
|
|
|
|
self.i = 0
|
|
|
|
|
|
|
|
def _hole_complete_callback(self, e):
|
|
|
|
if e == fishing_event.State.IDLE:
|
|
|
|
self.hole_complete_flag = True
|