[REQUEST] Persona 5 : The Phantom X
Re: [REQUEST] Persona 5 : The Phantom X
I look forward to when someone makes it for a perfect score for the rhythm band minigames and for home runs for baseball mini game. Would love for that
-
- Cheater
- Posts: 34
- Joined: Thu Oct 21, 2021 6:46 am
- Reputation: 3
Re: [REQUEST] Persona 5 : The Phantom X
hmm there is probly something we can do like make it so enemies only defends and stuff
Re: [REQUEST] Persona 5 : The Phantom X
so far I couldn't find anything useful, I am not too expert on this thing xD
-
- What is cheating?
- Posts: 1
- Joined: Wed Jul 09, 2025 10:24 am
- Reputation: 0
Re: [REQUEST] Persona 5 : The Phantom X
following this. hopefully the gm/debug mode can be used soon or smth..
Re: [REQUEST] Persona 5 : The Phantom X
As I have a close friend who literally is unable to perform the rythm games. They have a disability, and unfortunely S*GA does not include any tools for accessability on this area.
We created a python-script bot that watches the game and prompts keypresses automatically.
It's essentially an overengineered autoclicker.
Code: Select all
import time
import cv2
import numpy as np
import sys
import mss
import win32gui
import threading
import msvcrt
import keyboard
print("Starting in 3 seconds... Remember to change the games resolution to 1280*720 and run in window mode.")
time.sleep(3)
print("Running. Press 1 to start/pause detection. Press 2 to quit.")
lanes = {
's': {
'coords_primary': (175, 505),
'coords_secondary': (138, 455),
'key': 's'
},
'd': {
'coords_primary': (379, 573),
'coords_secondary': (329, 538),
'key': 'd'
},
'f': {
'coords_primary': (579, 585),
'coords_secondary': (519, 572),
'key': 'f'
},
'j': {
'coords_primary': (776, 572),
'coords_secondary': (714, 582),
'key': 'j'
},
'k': {
'coords_primary': (962, 537),
'coords_secondary': (912, 565),
'key': 'k'
},
'l': {
'coords_primary': (1154, 452),
'coords_secondary': (1108, 495),
'key': 'l'
}
}
lane_states = {key: {'pressed': False} for key in lanes}
yellow_rgb = (249, 244, 42)
yellow_bgr = yellow_rgb[::-1]
yellow_hsv = cv2.cvtColor(np.uint8([[yellow_bgr]]), cv2.COLOR_BGR2HSV)[0][0]
h_y, s_y, v_y = yellow_hsv
yellow_lower = np.array([max(h_y - 9, 0), 160, 160])
yellow_upper = np.array([min(h_y + 9, 179), 255, 255])
green_rgb = (83, 220, 0)
green_bgr = green_rgb[::-1]
green_hsv = cv2.cvtColor(np.uint8([[green_bgr]]), cv2.COLOR_BGR2HSV)[0][0]
h_g, s_g, v_g = green_hsv
green_lower = np.array([max(h_g - 10, 0), 160, 160])
green_upper = np.array([min(h_g + 10, 179), 255, 255])
RADIUS = 9
detection_enabled = False
exit_flag = False
use_preview = input("Show detection preview window? (y/n): ").strip().lower() == 'y'
if use_preview:
cv2.namedWindow("Detection Preview", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Detection Preview", 1366, 768)
def get_window_rect(window_name="Persona5: The Phantom X"):
hwnd = win32gui.FindWindow(None, window_name)
if hwnd == 0:
return None
rect = win32gui.GetWindowRect(hwnd)
return rect # (left, top, right, bottom)
def cleanup_and_exit():
global exit_flag
exit_flag = True
print("Shutting down...")
# Release any keys still pressed
for key, state in lane_states.items():
if state['pressed']:
keyboard.release(lanes[key]['key'])
state['pressed'] = False
if use_preview:
cv2.destroyAllWindows()
sys.exit(0)
def key_listener():
global detection_enabled
while not exit_flag:
if msvcrt.kbhit():
key = msvcrt.getch()
if key == b'1':
detection_enabled = not detection_enabled
print("Detection", "enabled." if detection_enabled else "paused.")
elif key == b'2':
cleanup_and_exit()
time.sleep(0.05)
listener_thread = threading.Thread(target=key_listener, daemon=True)
listener_thread.start()
try:
with mss.mss() as sct:
while not exit_flag:
rect = get_window_rect()
if rect is None:
print("P5X window not found. Waiting...")
time.sleep(1)
continue
left, top, right, bottom = rect
width = right - left
height = bottom - top
capture_width = min(1366, width)
capture_height = min(768, height)
monitor = {
"top": top,
"left": left,
"width": capture_width,
"height": capture_height
}
screenshot = sct.grab(monitor)
frame = np.array(screenshot)
frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
if use_preview:
for data in lanes.values():
x1, y1 = data['coords_primary']
x2, y2 = data['coords_secondary']
if 0 <= x1 < capture_width and 0 <= y1 < capture_height:
cv2.circle(frame, (x1, y1), RADIUS, (255, 255, 255), 2)
if 0 <= x2 < capture_width and 0 <= y2 < capture_height:
cv2.circle(frame, (x2, y2), RADIUS, (255, 255, 255), 2)
if detection_enabled:
for key, data in lanes.items():
x1, y1 = data['coords_primary']
x2, y2 = data['coords_secondary']
lane_key = data['key']
state = lane_states[key]
def get_roi(hsv_img, x, y):
x_min = max(0, x - RADIUS)
x_max = min(hsv_img.shape[1], x + RADIUS)
y_min = max(0, y - RADIUS)
y_max = min(hsv_img.shape[0], y + RADIUS)
return hsv_img[y_min:y_max, x_min:x_max]
roi_primary = get_roi(hsv, x1, y1)
roi_secondary = get_roi(hsv, x2, y2)
yellow_mask_primary = cv2.inRange(roi_primary, yellow_lower, yellow_upper)
yellow_mask_secondary = cv2.inRange(roi_secondary, yellow_lower, yellow_upper)
green_mask_primary = cv2.inRange(roi_primary, green_lower, green_upper)
green_mask_secondary = cv2.inRange(roi_secondary, green_lower, green_upper)
note_detected = (cv2.countNonZero(yellow_mask_primary) > 100 or
cv2.countNonZero(yellow_mask_secondary) > 100 or
cv2.countNonZero(green_mask_primary) > 100 or
cv2.countNonZero(green_mask_secondary) > 100)
if note_detected and not state['pressed']:
keyboard.press(lane_key)
state['pressed'] = True
elif not note_detected and state['pressed']:
keyboard.release(lane_key)
state['pressed'] = False
if use_preview:
cv2.imshow("Detection Preview", frame)
if cv2.waitKey(1) & 0xFF == 27: # ESC key quits
cleanup_and_exit()
except KeyboardInterrupt:
cleanup_and_exit()
except Exception as e:
print(f"Error: {e}")
cleanup_and_exit()
# All Makt åt Tengil, vår befriare!
Re: [REQUEST] Persona 5 : The Phantom X
Hoping we get something good out of this at some point, especially with the new update and boss out.
Re: [REQUEST] Persona 5 : The Phantom X
Does it work for persona?Tengil wrote: ↑Fri Jul 11, 2025 12:28 amAs I have a close friend who literally is unable to perform the rythm games. They have a disability, and unfortunely S*GA does not include any tools for accessability on this area.
We created a python-script bot that watches the game and prompts keypresses automatically.
It's essentially an overengineered autoclicker.
Code: Select all
import time import cv2 import numpy as np import sys import mss import win32gui import threading import msvcrt import keyboard print("Starting in 3 seconds... Remember to change the games resolution to 1280*720 and run in window mode.") time.sleep(3) print("Running. Press 1 to start/pause detection. Press 2 to quit.") lanes = { 's': { 'coords_primary': (175, 505), 'coords_secondary': (138, 455), 'key': 's' }, 'd': { 'coords_primary': (379, 573), 'coords_secondary': (329, 538), 'key': 'd' }, 'f': { 'coords_primary': (579, 585), 'coords_secondary': (519, 572), 'key': 'f' }, 'j': { 'coords_primary': (776, 572), 'coords_secondary': (714, 582), 'key': 'j' }, 'k': { 'coords_primary': (962, 537), 'coords_secondary': (912, 565), 'key': 'k' }, 'l': { 'coords_primary': (1154, 452), 'coords_secondary': (1108, 495), 'key': 'l' } } lane_states = {key: {'pressed': False} for key in lanes} yellow_rgb = (249, 244, 42) yellow_bgr = yellow_rgb[::-1] yellow_hsv = cv2.cvtColor(np.uint8([[yellow_bgr]]), cv2.COLOR_BGR2HSV)[0][0] h_y, s_y, v_y = yellow_hsv yellow_lower = np.array([max(h_y - 9, 0), 160, 160]) yellow_upper = np.array([min(h_y + 9, 179), 255, 255]) green_rgb = (83, 220, 0) green_bgr = green_rgb[::-1] green_hsv = cv2.cvtColor(np.uint8([[green_bgr]]), cv2.COLOR_BGR2HSV)[0][0] h_g, s_g, v_g = green_hsv green_lower = np.array([max(h_g - 10, 0), 160, 160]) green_upper = np.array([min(h_g + 10, 179), 255, 255]) RADIUS = 9 detection_enabled = False exit_flag = False use_preview = input("Show detection preview window? (y/n): ").strip().lower() == 'y' if use_preview: cv2.namedWindow("Detection Preview", cv2.WINDOW_NORMAL) cv2.resizeWindow("Detection Preview", 1366, 768) def get_window_rect(window_name="Persona5: The Phantom X"): hwnd = win32gui.FindWindow(None, window_name) if hwnd == 0: return None rect = win32gui.GetWindowRect(hwnd) return rect # (left, top, right, bottom) def cleanup_and_exit(): global exit_flag exit_flag = True print("Shutting down...") # Release any keys still pressed for key, state in lane_states.items(): if state['pressed']: keyboard.release(lanes[key]['key']) state['pressed'] = False if use_preview: cv2.destroyAllWindows() sys.exit(0) def key_listener(): global detection_enabled while not exit_flag: if msvcrt.kbhit(): key = msvcrt.getch() if key == b'1': detection_enabled = not detection_enabled print("Detection", "enabled." if detection_enabled else "paused.") elif key == b'2': cleanup_and_exit() time.sleep(0.05) listener_thread = threading.Thread(target=key_listener, daemon=True) listener_thread.start() try: with mss.mss() as sct: while not exit_flag: rect = get_window_rect() if rect is None: print("P5X window not found. Waiting...") time.sleep(1) continue left, top, right, bottom = rect width = right - left height = bottom - top capture_width = min(1366, width) capture_height = min(768, height) monitor = { "top": top, "left": left, "width": capture_width, "height": capture_height } screenshot = sct.grab(monitor) frame = np.array(screenshot) frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) if use_preview: for data in lanes.values(): x1, y1 = data['coords_primary'] x2, y2 = data['coords_secondary'] if 0 <= x1 < capture_width and 0 <= y1 < capture_height: cv2.circle(frame, (x1, y1), RADIUS, (255, 255, 255), 2) if 0 <= x2 < capture_width and 0 <= y2 < capture_height: cv2.circle(frame, (x2, y2), RADIUS, (255, 255, 255), 2) if detection_enabled: for key, data in lanes.items(): x1, y1 = data['coords_primary'] x2, y2 = data['coords_secondary'] lane_key = data['key'] state = lane_states[key] def get_roi(hsv_img, x, y): x_min = max(0, x - RADIUS) x_max = min(hsv_img.shape[1], x + RADIUS) y_min = max(0, y - RADIUS) y_max = min(hsv_img.shape[0], y + RADIUS) return hsv_img[y_min:y_max, x_min:x_max] roi_primary = get_roi(hsv, x1, y1) roi_secondary = get_roi(hsv, x2, y2) yellow_mask_primary = cv2.inRange(roi_primary, yellow_lower, yellow_upper) yellow_mask_secondary = cv2.inRange(roi_secondary, yellow_lower, yellow_upper) green_mask_primary = cv2.inRange(roi_primary, green_lower, green_upper) green_mask_secondary = cv2.inRange(roi_secondary, green_lower, green_upper) note_detected = (cv2.countNonZero(yellow_mask_primary) > 100 or cv2.countNonZero(yellow_mask_secondary) > 100 or cv2.countNonZero(green_mask_primary) > 100 or cv2.countNonZero(green_mask_secondary) > 100) if note_detected and not state['pressed']: keyboard.press(lane_key) state['pressed'] = True elif not note_detected and state['pressed']: keyboard.release(lane_key) state['pressed'] = False if use_preview: cv2.imshow("Detection Preview", frame) if cv2.waitKey(1) & 0xFF == 27: # ESC key quits cleanup_and_exit() except KeyboardInterrupt: cleanup_and_exit() except Exception as e: print(f"Error: {e}") cleanup_and_exit() # All Makt åt Tengil, vår befriare!
Who is online
Users browsing this forum: AhrefsBot, Arhelay, DotBot, Rubyelf