Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion Features/esp.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from Process.offsets import Offsets
from Process.memory_interface import MemoryInterface
from Features import worldesp
from Features import radar as radar_module

# Add current directory to path for vischeck.pyd
current_dir = os.path.dirname(os.path.abspath(__file__))
Expand Down Expand Up @@ -1658,6 +1659,10 @@ def point_in_box(px, py, pos, w, h):
map_status_dragging = False
map_status_drag_offset = [0, 0]

# Radar draggable globals
radar_dragging = False
radar_drag_offset = [0, 0]

def calculate_speed(vel):
return math.sqrt(vel['x']**2 + vel['y']**2 + vel['z']**2)

Expand Down Expand Up @@ -2382,7 +2387,17 @@ def handle_local_info_drag():
local_info_dragging, local_info_box_pos, local_info_drag_offset, box_width, 24
)


def handle_radar_drag():
global radar_dragging, radar_drag_offset
if not getattr(Config, "radar_enabled", False):
return
radar_size = getattr(Config, "radar_size", 200)
radar_pos = [getattr(Config, "radar_x", 20), getattr(Config, "radar_y", 20)]
radar_dragging, radar_drag_offset = handle_dragging(
radar_dragging, radar_pos, radar_drag_offset, radar_size, radar_size
)
Config.radar_x = radar_pos[0]
Config.radar_y = radar_pos[1]

# Error tracking for stability
consecutive_errors = 0
Expand Down Expand Up @@ -2773,6 +2788,16 @@ def handle_local_info_drag():
overlay.end_scene()
continue

# --- Radar ---
try:
if getattr(cfg, "radar_enabled", False) and local_pos:
handle_radar_drag()
local_yaw = read_float(handle, base + Offsets.dwViewAngles + 4)
radar_module.draw_radar(overlay, local_pos, local_team, local_yaw, entities)
radar_module.draw_radar_label(overlay)
except Exception as e:
print(f"[Radar Error] {e}")

# ESP status tracking
current_time = time.time()
if current_time - last_esp_status_time > 10: # Every 10 seconds
Expand Down
185 changes: 185 additions & 0 deletions Features/radar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
"""
2D Radar for CS2 - Integrated with ESP overlay
Draws on the same overlay as ESP for correct screen positioning
"""
import math
from Process.config import Config
from Process.offsets import Offsets

# Radar state
_radar_cache = {
'players': [],
'local_pos': None,
'local_team': None,
'local_yaw': None,
'last_update': 0
}

def world_to_radar(world_pos, local_pos, local_yaw, radar_size, radar_range):
"""Convert world coordinates to radar coordinates"""
dx = world_pos[0] - local_pos[0]
dy = world_pos[1] - local_pos[1]

# Rotate based on local player's yaw (add 90° to align forward with up)
yaw_rad = math.radians(-local_yaw + 90)
cos_yaw = math.cos(yaw_rad)
sin_yaw = math.sin(yaw_rad)

# Rotate coordinates so forward = up on radar
rotated_x = dx * cos_yaw - dy * sin_yaw
rotated_y = dx * sin_yaw + dy * cos_yaw

# Scale to radar (forward = up, so negate Y)
scale = radar_size / (2 * radar_range)
radar_x = rotated_x * scale + radar_size // 2
radar_y = -rotated_y * scale + radar_size // 2

return int(radar_x), int(radar_y)

def update_radar_cache(entities, local_pos, local_team, local_yaw):
"""Update radar player cache from ESP entities"""
global _radar_cache

players = []
for ent in entities:
if ent.hp <= 0:
continue
players.append({
'pos': (ent.pos.x, ent.pos.y, ent.pos.z),
'team': ent.team,
'is_enemy': ent.team != local_team
})

_radar_cache['players'] = players
_radar_cache['local_pos'] = (local_pos.x, local_pos.y, local_pos.z) if local_pos else None
_radar_cache['local_team'] = local_team
_radar_cache['local_yaw'] = local_yaw

def draw_radar(overlay, local_pos, local_team, local_yaw, entities=None):
"""Draw 2D radar on ESP overlay"""
if not getattr(Config, "radar_enabled", False):
return

# Update cache if entities provided
if entities is not None and local_pos is not None:
try:
update_radar_cache(entities, local_pos, local_team, local_yaw)
except Exception as e:
print(f"[Radar] Cache update error: {e}")
return

cache = _radar_cache
if not cache['local_pos']:
return

# Radar settings
radar_size = getattr(Config, "radar_size", 200)
radar_range = getattr(Config, "radar_range", 1500)
radar_x = getattr(Config, "radar_x", 20)
radar_y = getattr(Config, "radar_y", 20)
show_team = getattr(Config, "radar_show_team", True)
show_background = getattr(Config, "radar_show_background", True)
radar_shape = getattr(Config, "radar_shape", "square")
is_circle = radar_shape == "circle"

# Colors (RGB only, no alpha for GDI)
bg_color = getattr(Config, "radar_bg_color", (20, 20, 20))[:3]
border_color = getattr(Config, "radar_border_color", (100, 100, 100))[:3]
enemy_color = getattr(Config, "radar_color_enemy", (255, 50, 50))[:3]
team_color = getattr(Config, "radar_color_team", (50, 150, 255))[:3]
local_color = (0, 255, 0) # Green for local player

center_x = radar_x + radar_size // 2
center_y = radar_y + radar_size // 2

try:
# Draw radar background based on shape (only if enabled)
if show_background:
if is_circle:
overlay.draw_circle(center_x, center_y, radar_size // 2, border_color)
for r in range(radar_size // 2 - 1, 0, -2):
overlay.draw_circle(center_x, center_y, r, bg_color)
else:
overlay.draw_filled_rect(radar_x, radar_y, radar_size, radar_size, bg_color)
overlay.draw_box(radar_x, radar_y, radar_size, radar_size, border_color)

# Draw crosshairs
line_color = (60, 60, 60)
if is_circle:
half = radar_size // 2 - 5
overlay.draw_line(center_x - half, center_y, center_x + half, center_y, line_color)
overlay.draw_line(center_x, center_y - half, center_x, center_y + half, line_color)
else:
overlay.draw_line(radar_x, center_y, radar_x + radar_size, center_y, line_color)
overlay.draw_line(center_x, radar_y, center_x, radar_y + radar_size, line_color)

# Draw local player dot (center)
overlay.draw_filled_rect(center_x - 3, center_y - 3, 6, 6, local_color)

# Draw direction indicator (small triangle pointing up)
overlay.draw_line(center_x, center_y - 8, center_x - 4, center_y - 2, local_color)
overlay.draw_line(center_x, center_y - 8, center_x + 4, center_y - 2, local_color)
except Exception as e:
print(f"[Radar] Draw background error: {e}")
return

# Draw players
local_pos_tuple = cache['local_pos']
local_yaw_val = cache['local_yaw'] or 0
radius = radar_size // 2

for player in cache['players']:
# Skip teammates if not showing team
if not player['is_enemy'] and not show_team:
continue

# Convert world position to radar position
px, py = world_to_radar(
player['pos'], local_pos_tuple, local_yaw_val,
radar_size, radar_range
)

# Check if point is within radar bounds
if is_circle:
# For circle, check distance from center
dist = math.sqrt((px - radius)**2 + (py - radius)**2)
if dist > radius - 2:
continue
else:
# For square, check bounds
if px < 0 or px > radar_size or py < 0 or py > radar_size:
continue

# Choose color based on team
color = enemy_color if player['is_enemy'] else team_color

# Draw player dot
dot_x = radar_x + px
dot_y = radar_y + py
dot_size = 5
overlay.draw_filled_rect(dot_x - dot_size//2, dot_y - dot_size//2, dot_size, dot_size, color)

def draw_radar_label(overlay):
"""Draw radar label"""
if not getattr(Config, "radar_enabled", False):
return

radar_x = getattr(Config, "radar_x", 20)
radar_y = getattr(Config, "radar_y", 20)
radar_size = getattr(Config, "radar_size", 200)

# Draw "RADAR" label above
# overlay.draw_text("RADAR", radar_x + radar_size // 2, radar_y - 16, (200, 200, 200), 12, centered=True)


# Legacy class for backwards compatibility (if GFusion.py imports it)
class CS2RadarManager:
"""Legacy wrapper - radar now integrated into ESP"""
def __init__(self, shared_config=None):
self.shared_config = shared_config
print("[Radar] Radar is now integrated into ESP overlay")

def run(self):
"""No-op - radar runs through ESP now"""
print("[Radar] Radar draws through ESP overlay - no separate thread needed")
pass
77 changes: 77 additions & 0 deletions GFusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from Features.bhop import BHopProcess
from Features.fov import FOVChanger
from Features.glow import CS2GlowManager
from Features.radar import CS2RadarManager
from Features.triggerbot import TriggerBot
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
Expand Down Expand Up @@ -900,6 +901,15 @@ def run_glow():
except Exception as e:
logger.exception(f"Glow crashed: {e}", category="Glow")

def run_radar():
global radar_manager
logger.info("Starting radar", category="Radar")
try:
radar_manager = CS2RadarManager(cfg)
radar_manager.run()
except Exception as e:
logger.exception(f"Radar crashed: {e}", category="Radar")

def run_triggerbot():
global triggerbot_instance
logger.info("Starting triggerbot", category="Triggerbot")
Expand Down Expand Up @@ -988,6 +998,18 @@ def start_glow_thread():
except Exception as e:
logger.error(f"Failed to start glow thread: {e}", category="Threading", exc_info=True)

def start_radar_thread():
global radar_thread
try:
if radar_thread is None or not radar_thread.is_alive():
Config.radar_stop = False
Config.radar_enabled = True
radar_thread = threading.Thread(target=run_radar, daemon=True, name="RadarThread")
radar_thread.start()
logger.info("Radar thread started", category="Threading")
except Exception as e:
logger.error(f"Failed to start radar thread: {e}", category="Threading", exc_info=True)

def start_toggle_listener(main_window):
def _toggle_menu():
"""Runs on the Qt (GUI) thread via signal."""
Expand Down Expand Up @@ -1150,6 +1172,17 @@ def stop_glow_thread():
except Exception as e:
logger.error(f"Failed to stop glow: {e}", category="Threading", exc_info=True)

def stop_radar_thread():
global radar_thread, radar_manager
try:
Config.radar_enabled = False
Config.radar_stop = True
radar_thread = None
radar_manager = None
logger.info("Radar stop signal sent", category="Threading")
except Exception as e:
logger.error(f"Failed to stop radar: {e}", category="Threading", exc_info=True)

def stop_triggerbot_thread():
try:
cfg.triggerbot_enabled = False
Expand Down Expand Up @@ -3128,6 +3161,46 @@ def set_panic():
colors_layout.addLayout(color_grid)
layout.addWidget(colors_group)

# === 2D Radar ===
radar_group = self.create_group_box("2D Radar")
radar_layout = QVBoxLayout(radar_group)
radar_layout.setSpacing(4)

r_row1 = QHBoxLayout()
self.add_checkbox(r_row1, "Enable Radar", "radar_enabled")
self.add_checkbox(r_row1, "Show Team", "radar_show_team")
self.add_checkbox(r_row1, "Show Background", "radar_show_background")
radar_layout.addLayout(r_row1)

self.add_slider(radar_layout, "Size", "radar_size", 100, 400)
self.add_slider(radar_layout, "Range", "radar_range", 500, 5000)

shape_row = QHBoxLayout()
shape_lbl = QLabel("Shape:")
shape_lbl.setStyleSheet("color: #f5f5f7;")
shape_row.addWidget(shape_lbl)
shape_combo = QComboBox()
shape_combo.addItems(["square", "circle"])
shape_combo.setCurrentText(getattr(Config, "radar_shape", "square"))
shape_combo.setStyleSheet("QComboBox { background: #2d2d30; color: #f5f5f7; border: 1px solid #3e3e42; padding: 4px; }")
shape_combo.currentTextChanged.connect(lambda t: setattr(Config, "radar_shape", t))
shape_row.addWidget(shape_combo)
shape_row.addStretch()
radar_layout.addLayout(shape_row)

drag_hint = QLabel("💡 Drag radar in-game to reposition")
drag_hint.setStyleSheet("color: #888; font-size: 10px;")
radar_layout.addWidget(drag_hint)

r_color_grid = QGridLayout()
self.add_color_picker_to_grid(r_color_grid, 0, 0, "Background", "radar_bg_color", (20, 20, 20))
self.add_color_picker_to_grid(r_color_grid, 0, 1, "Border", "radar_border_color", (100, 100, 100))
self.add_color_picker_to_grid(r_color_grid, 1, 0, "Enemy", "radar_color_enemy", (255, 50, 50))
self.add_color_picker_to_grid(r_color_grid, 1, 1, "Team", "radar_color_team", (50, 150, 255))
radar_layout.addLayout(r_color_grid)
radar_layout.addStretch()
layout.addWidget(radar_group)

layout.addStretch()
scroll.setWidget(content)
main_layout = QVBoxLayout(self)
Expand Down Expand Up @@ -4952,6 +5025,10 @@ def refresh_ui(self):

glow_manager = None

radar_thread = None

radar_manager = None

triggerbot_thread = None

triggerbot_instance = None
Expand Down
Loading