#!/usr/bin/env python3 """ Standardized Flyff Low Health Alert Node: - Monitors an input value (1 = health alert, 0 = normal). - Displays a visual alert and plays a sound if enabled. - Uses a global update timer for processing. - Automatically processes float, int, and string values. """ import time from OdenGraphQt import BaseNode from Qt import QtCore, QtWidgets, QtGui try: import winsound HAS_WINSOUND = True except ImportError: HAS_WINSOUND = False class OverlayCanvas(QtWidgets.QWidget): """ UI overlay for displaying a red warning box, which can be repositioned by dragging. """ def __init__(self, parent=None): super().__init__(parent) screen_geo = QtWidgets.QApplication.primaryScreen().geometry() self.setGeometry(screen_geo) self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) self.setVisible(False) self.helper_LowHealthAlert = QtCore.QRect(250, 300, 900, 35) self.dragging = False self.drag_offset = None def paintEvent(self, event): if not self.isVisible(): return painter = QtGui.QPainter(self) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(QtGui.QColor(255, 0, 0)) painter.drawRect(self.helper_LowHealthAlert) font = QtGui.QFont("Arial", 14, QtGui.QFont.Bold) painter.setFont(font) painter.setPen(QtGui.QColor(255, 255, 255)) text_x = self.helper_LowHealthAlert.center().x() - 50 text_y = self.helper_LowHealthAlert.center().y() + 5 painter.drawText(text_x, text_y, "LOW HEALTH") def toggle_alert(self, state): self.setVisible(state == 1) self.update() def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: if self.helper_LowHealthAlert.contains(event.pos()): self.dragging = True self.drag_offset = event.pos() - self.helper_LowHealthAlert.topLeft() super().mousePressEvent(event) def mouseMoveEvent(self, event): if self.dragging: new_top_left = event.pos() - self.drag_offset self.helper_LowHealthAlert.moveTo(new_top_left) self.update() super().mouseMoveEvent(event) def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.dragging = False super().mouseReleaseEvent(event) class FlyffLowHealthAlertNode(BaseNode): __identifier__ = 'bunny-lab.io.flyff_low_health_alert_node' NODE_NAME = 'Flyff - Low Health Alert' overlay_instance = None last_beep_time = 0 BEEP_INTERVAL_SECONDS = 2 def __init__(self): super(FlyffLowHealthAlertNode, self).__init__() self.add_checkbox('cb_1', '', 'Sound Alert', True) self.add_checkbox('cb_2', '', 'Visual Alert', True) self.add_input('Toggle (1 = On | 0 = Off)', color=(200, 100, 0)) self.add_text_input('value', 'Current Value', text='0') self.add_combo_menu('beep_interval', 'Beep Interval', items=["0.5s", "1.0s", "2.0s"]) if not FlyffLowHealthAlertNode.overlay_instance: FlyffLowHealthAlertNode.overlay_instance = OverlayCanvas() FlyffLowHealthAlertNode.overlay_instance.show() def process_input(self): input_port = self.input(0) value = input_port.connected_ports()[0].node().get_property('value') if input_port.connected_ports() else "0" self.receive_data(value) def receive_data(self, data, source_port_name=None): try: if isinstance(data, str): data = float(data) if '.' in data else int(data) if isinstance(data, (float, int)): data = 1 if data > 1 else 0 if data <= 0 else int(data) else: data = 0 except ValueError: data = 0 self.set_property('value', str(data)) if self.get_property('cb_2'): FlyffLowHealthAlertNode.overlay_instance.toggle_alert(data) self.handle_beep(data) def handle_beep(self, input_value): # Update beep interval from the dropdown property interval_str = self.get_property('beep_interval') if interval_str.endswith("s"): interval_seconds = float(interval_str[:-1]) else: interval_seconds = float(interval_str) self.BEEP_INTERVAL_SECONDS = interval_seconds if input_value == 1 and self.get_property('cb_1'): current_time = time.time() if (current_time - FlyffLowHealthAlertNode.last_beep_time) >= self.BEEP_INTERVAL_SECONDS: FlyffLowHealthAlertNode.last_beep_time = current_time self.play_beep() def play_beep(self): if HAS_WINSOUND: winsound.Beep(376, 100) else: print('\a', end='')