Weapons now do different things. Shovels fill in graves, broom gives a speed and jump bonus and nunchucks just thwack things real hard and have best reach.

This commit is contained in:
Storm Dragon
2025-09-07 13:20:49 -04:00
parent cf3f27d9b8
commit 56a78aa4ff
6 changed files with 88 additions and 16 deletions

View File

@@ -16,6 +16,7 @@ class GraveObject(Object):
)
self.graveItem = item
self.isCollected = False # Renamed to match style of isHazard, isStatic etc
self.isFilled = False # Track if grave has been filled with shovel
self.sounds = sounds
def collect_grave_item(self, player):
@@ -28,11 +29,38 @@ class GraveObject(Object):
if not self.graveItem or self.isCollected:
return False
# Collect the item if player is ducking
if player.isDucking:
# Collect the item if player is ducking, walking (not running), and wielding shovel
if (player.isDucking and not player.isRunning and
player.currentWeapon and player.currentWeapon.name == "rusty_shovel"):
self.isCollected = True # Mark as collected when collection succeeds
return True
return False
def can_fill_grave(self, player):
"""Check if grave can be filled with shovel.
Returns:
bool: True if grave can be filled, False otherwise
"""
# Can only fill empty graves (no item) that haven't been filled yet
if self.graveItem or self.isFilled:
return False
# Must be ducking, walking (not running), and wielding shovel
return (player.isDucking and not player.isRunning and
player.currentWeapon and player.currentWeapon.name == "rusty_shovel")
def fill_grave(self, player):
"""Fill the grave with dirt using shovel.
Returns:
bool: True if grave was filled successfully
"""
if self.can_fill_grave(player):
self.isFilled = True
self.isHazard = False # No longer a hazard once filled
return True
return False

View File

@@ -417,9 +417,10 @@ class Level:
if obj.isHazard and not self.player.isJumping:
if isinstance(obj, GraveObject):
can_collect = obj.collect_grave_item(self.player)
can_fill = obj.can_fill_grave(self.player)
if can_collect:
# Successfully collected item while ducking
# Successfully collected item while ducking with shovel
play_sound(self.sounds[f'get_{obj.graveItem}'])
self.player.stats.update_stat('Items collected', 1)
# Create PowerUp to handle the item effect
@@ -434,6 +435,16 @@ class Level:
obj.channel = None
obj.isActive = False # Mark the grave as inactive after collection
continue
elif can_fill and obj.fill_grave(self.player):
# Successfully filled empty grave with shovel
play_sound(self.sounds.get('shovel_dig', obj.soundName)) # Use dig sound if available
self.player.stats.update_stat('Graves filled', 1)
# Stop grave's current audio channel
if obj.channel:
obj_stop(obj.channel)
obj.channel = None
obj.isActive = False # Mark grave as inactive after filling
continue
elif not self.player.isInvincible:
# Kill player for normal graves or non-ducking collision
play_sound(self.sounds[obj.soundName])

View File

@@ -158,15 +158,23 @@ class Player:
def get_step_distance(self):
"""Get step distance based on current speed"""
weaponBonus = self.currentWeapon.speedBonus if self.currentWeapon else 1.0
totalMultiplier = weaponBonus
if self.isRunning or self.isJumping:
return self.baseStepDistance / self.runMultiplier
return self.baseStepDistance
totalMultiplier *= self.runMultiplier
return self.baseStepDistance / totalMultiplier
def get_step_interval(self):
"""Get minimum time between steps based on current speed"""
weaponBonus = self.currentWeapon.speedBonus if self.currentWeapon else 1.0
totalMultiplier = weaponBonus
if self.isRunning or self.isJumping:
return self.baseStepInterval / self.runMultiplier
return self.baseStepInterval
totalMultiplier *= self.runMultiplier
return self.baseStepInterval / totalMultiplier
def get_health(self):
"""Get current health"""
@@ -181,10 +189,18 @@ class Player:
self._health = self._maxHealth
def get_current_speed(self):
"""Calculate current speed based on state"""
"""Calculate current speed based on state and weapon"""
baseSpeed = self.moveSpeed
if self.isJumping or self.isRunning: return baseSpeed * self.runMultiplier
return baseSpeed
weaponBonus = self.currentWeapon.speedBonus if self.currentWeapon else 1.0
if self.isJumping or self.isRunning:
return baseSpeed * self.runMultiplier * weaponBonus
return baseSpeed * weaponBonus
def get_current_jump_duration(self):
"""Calculate current jump duration based on weapon bonus"""
weaponBonus = self.currentWeapon.jumpDurationBonus if self.currentWeapon else 1.0
return int(self.jumpDuration * weaponBonus)
def set_footstep_sound(self, soundName):
"""Set the current footstep sound"""
@@ -269,7 +285,7 @@ class Player:
for weapon in self.weapons:
if weapon.name == targetWeaponName:
self.equip_weapon(weapon)
speak(f"Switched to {weapon.name.replace('_', ' ')}")
speak(weapon.name.replace('_', ' '))
return True
# Weapon not found in inventory

View File

@@ -100,7 +100,9 @@ class SaveManager:
'range': weapon.range,
'attackSound': weapon.attackSound,
'hitSound': weapon.hitSound,
'attackDuration': weapon.attackDuration
'attackDuration': weapon.attackDuration,
'speedBonus': getattr(weapon, 'speedBonus', 1.0),
'jumpDurationBonus': getattr(weapon, 'jumpDurationBonus', 1.0)
})
return serialized
@@ -109,13 +111,24 @@ class SaveManager:
from src.weapon import Weapon
weapons = []
for data in weapon_data:
# Handle backward compatibility for old saves
speedBonus = data.get('speedBonus', 1.0)
jumpDurationBonus = data.get('jumpDurationBonus', 1.0)
# For old saves, restore proper bonuses for specific weapons
if data['name'] == 'witch_broom' and speedBonus == 1.0:
speedBonus = 1.17
jumpDurationBonus = 1.25
weapon = Weapon(
name=data['name'],
damage=data['damage'],
range=data['range'],
attackSound=data['attackSound'],
hitSound=data['hitSound'],
attackDuration=data['attackDuration']
attackDuration=data['attackDuration'],
speedBonus=speedBonus,
jumpDurationBonus=jumpDurationBonus
)
weapons.append(weapon)
return weapons

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
class Weapon:
def __init__(self, name, damage, range, attackSound, hitSound, cooldown=500, attackDuration=200):
def __init__(self, name, damage, range, attackSound, hitSound, cooldown=500, attackDuration=200, speedBonus=1.0, jumpDurationBonus=1.0):
self.name = name
self.damage = damage
self.range = range # Range in tiles
@@ -9,6 +9,8 @@ class Weapon:
self.hitSound = hitSound
self.cooldown = cooldown # Milliseconds between attacks
self.attackDuration = attackDuration # Milliseconds the attack is active
self.speedBonus = speedBonus # Speed multiplier when wielding this weapon
self.jumpDurationBonus = jumpDurationBonus # Jump duration multiplier when wielding this weapon
self.lastAttackTime = 0
self.hitEnemies = set()
@@ -35,7 +37,9 @@ class Weapon:
attackSound="player_broom_attack",
hitSound="player_broom_hit",
cooldown=500,
attackDuration=200
attackDuration=200,
speedBonus=1.17, # 17% speed bonus when wielding the broom
jumpDurationBonus=1.25 # 25% longer jump duration for better traversal
)
def can_attack(self, currentTime):

View File

@@ -242,7 +242,7 @@ class WickedQuest:
play_sound(self.sounds['jump'])
# Check if jump should end
if player.isJumping and currentTime - player.jumpStartTime >= player.jumpDuration:
if player.isJumping and currentTime - player.jumpStartTime >= player.get_current_jump_duration():
player.isJumping = False
play_sound(self.sounds[player.footstepSound]) # Landing sound
# Reset step distance tracking after landing