Update combat_system.py
parent
69bc45ad83
commit
e7b8d48b0c
133
combat_system.py
133
combat_system.py
|
|
@ -1,55 +1,116 @@
|
||||||
# combat_system.py
|
# combat_system.py
|
||||||
import random
|
import random
|
||||||
|
import pygame
|
||||||
from settings import *
|
from settings import *
|
||||||
from items import get_item, ITEMS, WEAPON_STATS
|
from items import WEAPON_STATS
|
||||||
|
|
||||||
|
|
||||||
class CombatSystem:
|
class CombatSystem:
|
||||||
def __init__(self, weapon_manager):
|
def __init__(self, weapon_manager=None):
|
||||||
self.weapon_manager = weapon_manager
|
self.weapon_manager = weapon_manager
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# SAFE VECTOR HANDLING
|
||||||
|
# ==========================================================
|
||||||
|
def _safe_vec(self, obj):
|
||||||
|
"""Ensure we always get a usable Vector2"""
|
||||||
|
try:
|
||||||
|
if isinstance(obj, pygame.Vector2):
|
||||||
|
return obj
|
||||||
|
if hasattr(obj, "x") and hasattr(obj, "y"):
|
||||||
|
return pygame.Vector2(obj.x, obj.y)
|
||||||
|
if isinstance(obj, (list, tuple)) and len(obj) >= 2:
|
||||||
|
return pygame.Vector2(obj[0], obj[1])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return pygame.Vector2(0, 0)
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# PLAYER ATTACK
|
||||||
|
# ==========================================================
|
||||||
def player_attack(self, player, enemies):
|
def player_attack(self, player, enemies):
|
||||||
"""
|
try:
|
||||||
Handles player attack on enemies using the currently equipped weapon.
|
if not player or not enemies:
|
||||||
"""
|
return
|
||||||
# Get weapon ID from weapon manager
|
|
||||||
weapon_id = self.weapon_manager.get_current_weapon()
|
|
||||||
if weapon_id is None:
|
|
||||||
print("DEBUG: No weapon equipped")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Get weapon stats
|
# Get weapon safely
|
||||||
damage = WEAPON_STATS.get(weapon_id, {}).get("damage", 1)
|
weapon_id = None
|
||||||
attack_range = WEAPON_STATS.get(weapon_id, {}).get("range", 50)
|
if self.weapon_manager and hasattr(self.weapon_manager, "get_current_weapon"):
|
||||||
|
weapon_id = self.weapon_manager.get_current_weapon()
|
||||||
|
|
||||||
player_pos = player.pos
|
# Default weapon if none
|
||||||
|
weapon_data = WEAPON_STATS.get(weapon_id, {})
|
||||||
|
damage = weapon_data.get("damage", 5)
|
||||||
|
attack_range = weapon_data.get("range", 60)
|
||||||
|
|
||||||
# Attack enemies within range
|
player_pos = self._safe_vec(getattr(player, "pos", (0, 0)))
|
||||||
for enemy in enemies:
|
|
||||||
if not getattr(enemy, "alive", True):
|
|
||||||
continue # Skip dead enemies
|
|
||||||
|
|
||||||
enemy_pos = enemy.pos
|
for enemy in enemies:
|
||||||
distance = (enemy_pos - player_pos).length()
|
if not enemy:
|
||||||
if distance <= attack_range:
|
continue
|
||||||
enemy.health -= damage
|
|
||||||
print(f"DEBUG: {enemy.name if hasattr(enemy,'name') else 'Enemy'} took {damage} damage! (HP left: {enemy.health})")
|
|
||||||
if enemy.health <= 0:
|
|
||||||
enemy.alive = False
|
|
||||||
print(f"DEBUG: {enemy.name if hasattr(enemy,'name') else 'Enemy'} has been defeated!")
|
|
||||||
|
|
||||||
|
if hasattr(enemy, "alive") and not enemy.alive:
|
||||||
|
continue
|
||||||
|
|
||||||
|
enemy_pos = self._safe_vec(getattr(enemy, "pos", (0, 0)))
|
||||||
|
distance = (enemy_pos - player_pos).length()
|
||||||
|
|
||||||
|
if distance <= attack_range:
|
||||||
|
direction = 1 if enemy_pos.x > player_pos.x else -1
|
||||||
|
|
||||||
|
# Use proper damage method if exists
|
||||||
|
if hasattr(enemy, "take_damage"):
|
||||||
|
enemy.take_damage(damage, direction)
|
||||||
|
else:
|
||||||
|
# Fallback
|
||||||
|
if hasattr(enemy, "health"):
|
||||||
|
enemy.health -= damage
|
||||||
|
if enemy.health <= 0 and hasattr(enemy, "alive"):
|
||||||
|
enemy.alive = False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("CombatSystem.player_attack ERROR:", e)
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# ENEMY ATTACK
|
||||||
|
# ==========================================================
|
||||||
def enemy_attack(self, enemy, player):
|
def enemy_attack(self, enemy, player):
|
||||||
"""
|
try:
|
||||||
Handles enemy attack on player.
|
if not enemy or not player:
|
||||||
"""
|
return
|
||||||
if not getattr(enemy, "alive", True):
|
|
||||||
return
|
|
||||||
|
|
||||||
# Ensure enemy has attack properties
|
if hasattr(enemy, "alive") and not enemy.alive:
|
||||||
attack_range = getattr(enemy, "attack_range", 50)
|
return
|
||||||
attack_damage = getattr(enemy, "attack_damage", ENEMY_ATTACK_DAMAGE)
|
|
||||||
|
|
||||||
distance = (enemy.pos - player.pos).length()
|
enemy_pos = self._safe_vec(getattr(enemy, "pos", (0, 0)))
|
||||||
if distance <= attack_range:
|
player_pos = self._safe_vec(getattr(player, "pos", (0, 0)))
|
||||||
|
|
||||||
|
attack_range = getattr(enemy, "attack_range", 50)
|
||||||
|
attack_damage = getattr(enemy, "attack_damage", ENEMY_ATTACK_DAMAGE)
|
||||||
|
|
||||||
|
distance = (enemy_pos - player_pos).length()
|
||||||
|
|
||||||
|
if distance <= attack_range:
|
||||||
|
direction = 1 if player_pos.x > enemy_pos.x else -1
|
||||||
|
|
||||||
|
if hasattr(player, "take_damage"):
|
||||||
|
player.take_damage(attack_damage, direction)
|
||||||
|
else:
|
||||||
|
if hasattr(player, "health"):
|
||||||
|
player.health -= attack_damage
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("CombatSystem.enemy_attack ERROR:", e)
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# UPDATE
|
||||||
|
# ==========================================================
|
||||||
|
def update(self, dt):
|
||||||
|
# Keep safe even if dt is weird
|
||||||
|
try:
|
||||||
|
dt = float(dt)
|
||||||
|
except:
|
||||||
|
dt = 0
|
||||||
player.health -= attack_damage
|
player.health -= attack_damage
|
||||||
print(f"DEBUG: Player took {attack_damage} damage! (HP left: {player.health})")
|
print(f"DEBUG: Player took {attack_damage} damage! (HP left: {player.health})")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue