Borealis-Legacy/Nodes/character_status_node.py

90 lines
3.8 KiB
Python

#!/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)