#!/usr/bin/env python3 """ Character Status Node This node represents the character's status. It has no input ports and four output ports: - HP, MP, FP, EXP. It polls an API endpoint (http://127.0.0.1:5000/data) every 500 ms to update its values. If the API call is successful, the node's title is set to "Character Status (API Connected)". If the API is down or returns an error, the title is set to "Character Status (API Disconnected)". """ from NodeGraphQt import BaseNode from Qt import QtCore, QtGui import requests def get_draw_stat_port(color, border_color=None, alpha=127): """ Returns a custom port painter function that draws a circular port with a semi-transparent fill and then draws text (port label and current value) next to it. """ if border_color is None: border_color = color def painter_func(painter, rect, info): painter.save() # Draw the port circle. pen = QtGui.QPen(QtGui.QColor(*border_color)) pen.setWidth(1.8) painter.setPen(pen) semi_transparent_color = QtGui.QColor(color[0], color[1], color[2], alpha) painter.setBrush(semi_transparent_color) painter.drawEllipse(rect) # Draw the label and current value. port = info.get('port') if port is not None: node = port.node() stat = port.name() # Use the node's 'values' dictionary if available. value = node.values.get(stat, "N/A") if hasattr(node, 'values') else "N/A" text_rect = rect.adjusted(rect.width() + 4, 0, rect.width() + 70, 0) painter.setPen(QtGui.QColor(0, 0, 0)) painter.drawText(text_rect, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignLeft, f"{stat}: {value}") painter.restore() return painter_func class CharacterStatusNode(BaseNode): __identifier__ = 'io.github.nicole.status' NODE_NAME = 'Character Status' def __init__(self): super(CharacterStatusNode, self).__init__() # Initialize the output values as a dictionary. self.values = {"HP": "N/A", "MP": "N/A", "FP": "N/A", "EXP": "N/A"} # Add output ports for each stat with custom painters. self.add_output("HP", painter_func=get_draw_stat_port((255, 0, 0))) # Red for HP self.add_output("MP", painter_func=get_draw_stat_port((0, 0, 255))) # Blue for MP self.add_output("FP", painter_func=get_draw_stat_port((0, 255, 0))) # Green for FP self.add_output("EXP", painter_func=get_draw_stat_port((127, 255, 212))) # Aquamarine for EXP # Set an initial title. self.set_name("Character Status (API Disconnected)") # Create a QTimer that polls the API every 500ms. self.timer = QtCore.QTimer() self.timer.timeout.connect(self.poll_api) self.timer.start(500) def poll_api(self): """ Polls the API endpoint to retrieve the latest character stats and updates the node's internal values. Expects a JSON response with keys: - "hp", "mp", "fp", "exp" """ try: response = requests.get("http://127.0.0.1:5000/data", timeout=1) if response.status_code == 200: data = response.json() # Update the values dictionary. self.values["HP"] = data.get("hp", "0/0") self.values["MP"] = data.get("mp", "0/0") self.values["FP"] = data.get("fp", "0/0") self.values["EXP"] = data.get("exp", "0.0000") self.set_name("Character Status (API Connected)") self.update() else: self.set_name("Character Status (API Disconnected)") except Exception as e: self.set_name("Character Status (API Disconnected)") print("Error polling API in CharacterStatusNode:", e)