Ghost enemy added, boss for level 10. Levels updated, probably still not final version, but getting close.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
"level_id": 10,
|
||||
"name": "Cursed Chapel",
|
||||
"description": "An old chapel looms before you, its stained glass windows glowing with an otherworldly light. The sound of organ music echoes from within, though the chapel has been abandoned for centuries.",
|
||||
"locked": true,
|
||||
"player_start": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
@@ -82,7 +83,7 @@
|
||||
"x_range": [110, 130],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -144,7 +145,7 @@
|
||||
"x_range": [200, 220],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 10,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"x_range": [240, 260],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -254,11 +255,26 @@
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [400, 415],
|
||||
"y": 0,
|
||||
"enemy_type": "ghost",
|
||||
"health": 16,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"vulnerability_duration": 2000,
|
||||
"invulnerability_duration": 5000,
|
||||
"speed_multiplier": 0.8,
|
||||
"attack_cooldown": 1200,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
}
|
||||
],
|
||||
"boundaries": {
|
||||
"left": 0,
|
||||
"right": 400
|
||||
"right": 420
|
||||
},
|
||||
"ambience": "Choir of Doom.ogg",
|
||||
"footstep_sound": "footstep_stone"
|
||||
|
@@ -36,7 +36,7 @@
|
||||
"x_range": [30, 45],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 10,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -104,7 +104,7 @@
|
||||
"x_range": [120, 135],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -160,7 +160,7 @@
|
||||
"x_range": [205, 220],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 10,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -216,7 +216,7 @@
|
||||
"x_range": [275, 290],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -275,7 +275,7 @@
|
||||
"x_range": [370, 385],
|
||||
"y": 0,
|
||||
"enemy_type": "witch",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 2,
|
||||
"attack_range": 1.5,
|
||||
"attack_pattern": {
|
||||
|
@@ -44,7 +44,7 @@
|
||||
"x_range": [75, 85],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 10,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -123,7 +123,7 @@
|
||||
"x_range": [185, 195],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -200,7 +200,7 @@
|
||||
"x_range": [305, 315],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 10,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -244,7 +244,7 @@
|
||||
"x_range": [385, 405],
|
||||
"y": 0,
|
||||
"enemy_type": "witch",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 2,
|
||||
"attack_range": 1.5,
|
||||
"attack_pattern": {
|
||||
|
@@ -263,7 +263,7 @@
|
||||
"y": 0,
|
||||
"type": "catapult",
|
||||
"fire_interval": 4000,
|
||||
"range": 45
|
||||
"range": 40
|
||||
},
|
||||
{
|
||||
"x": 410,
|
||||
@@ -286,7 +286,7 @@
|
||||
"y": 15,
|
||||
"type": "skull_storm",
|
||||
"damage": 4,
|
||||
"maximum_skulls": 4,
|
||||
"maximum_skulls": 5,
|
||||
"frequency": {
|
||||
"min": 1,
|
||||
"max": 3
|
||||
@@ -304,7 +304,29 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [405, 495],
|
||||
"x_range": [425, 445],
|
||||
"y": 0,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [425, 445],
|
||||
"y": 0,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [455, 495],
|
||||
"y": 0,
|
||||
"enemy_type": "witch",
|
||||
"health": 50,
|
||||
|
@@ -144,7 +144,7 @@
|
||||
"x_range": [101, 111],
|
||||
"y": 0,
|
||||
"enemy_type": "witch",
|
||||
"health": 3,
|
||||
"health": 6,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
@@ -195,13 +195,12 @@
|
||||
{
|
||||
"x_range": [146, 166],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"enemy_type": "goblin",
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
"type": "hunter",
|
||||
"turn_threshold": 5
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -248,6 +247,6 @@
|
||||
"left": 0,
|
||||
"right": 200
|
||||
},
|
||||
"ambience": "Wayward Ghouls.ogg",
|
||||
"ambience": "Dark Dust Dispatcher.ogg",
|
||||
"footstep_sound": "footstep_tall_grass"
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"level_id": 4,
|
||||
"name": "The Abandoned Church",
|
||||
"description": "The graves led you to a decrepit church. The holy ground offers no sanctuary - if anything, the undead seem stronger here.",
|
||||
"locked": true,
|
||||
"player_start": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
@@ -21,7 +22,18 @@
|
||||
"type": "coffin"
|
||||
},
|
||||
{
|
||||
"x_range": [20, 30],
|
||||
"x_range": [20, 25],
|
||||
"y": 0,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [25, 30],
|
||||
"y": 0,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
@@ -122,15 +134,11 @@
|
||||
"type": "coffin"
|
||||
},
|
||||
{
|
||||
"x_range": [120, 130],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 6,
|
||||
"damage": 2,
|
||||
"attack_range": 1.5,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
"x_range": [115, 118],
|
||||
"y": 3,
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x": 135,
|
||||
@@ -147,6 +155,13 @@
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x_range": [155, 160],
|
||||
"y": 3,
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x_range": [150, 170],
|
||||
"y": 12,
|
||||
@@ -168,13 +183,12 @@
|
||||
{
|
||||
"x_range": [175, 185],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 6,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1.5,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "hunter",
|
||||
"turn_threshold": 6
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -197,11 +211,44 @@
|
||||
"y": 3,
|
||||
"sound": "coffin",
|
||||
"type": "coffin"
|
||||
},
|
||||
{
|
||||
"x_range": [200, 207],
|
||||
"y": 0,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [208, 215],
|
||||
"y": 0,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [200, 215],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 6,
|
||||
"damage": 2,
|
||||
"attack_range": 1.5,
|
||||
"attack_pattern": {
|
||||
"type": "patrol"
|
||||
}
|
||||
}
|
||||
],
|
||||
"boundaries": {
|
||||
"left": 0,
|
||||
"right": 200
|
||||
"right": 220
|
||||
},
|
||||
"ambience": "Choir of Doom.ogg",
|
||||
"footstep_sound": "footstep_stone"
|
||||
|
@@ -22,6 +22,13 @@
|
||||
"static": true,
|
||||
"zombie_spawn_chance": 15
|
||||
},
|
||||
{
|
||||
"x_range": [15, 20],
|
||||
"y": 3,
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x_range": [20, 35],
|
||||
"y": 0,
|
||||
@@ -128,6 +135,13 @@
|
||||
"turn_threshold": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [130, 135],
|
||||
"y": 3,
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x": 140,
|
||||
"y": 3,
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"level_id": 6,
|
||||
"name": "The Webbed Crypts",
|
||||
"description": "The catacombs open into ancient crypts, their passages choked with massive cobwebs. Something skitters in the darkness above.",
|
||||
"locked": true,
|
||||
"player_start": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
@@ -31,6 +32,13 @@
|
||||
"turn_threshold": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"x_range": [25, 30],
|
||||
"y": 3,
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x": 30,
|
||||
"y": 3,
|
||||
@@ -73,13 +81,12 @@
|
||||
{
|
||||
"x_range": [70, 85],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"enemy_type": "goblin",
|
||||
"health": 4,
|
||||
"damage": 2,
|
||||
"attack_range": 1,
|
||||
"attack_pattern": {
|
||||
"type": "hunter",
|
||||
"turn_threshold": 4
|
||||
"type": "patrol"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -127,6 +134,13 @@
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x_range": [140, 145],
|
||||
"y": 3,
|
||||
"sound": "coin",
|
||||
"collectible": true,
|
||||
"static": true
|
||||
},
|
||||
{
|
||||
"x_range": [130, 145],
|
||||
"y": 0,
|
||||
@@ -149,7 +163,7 @@
|
||||
"x_range": [160, 180],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -184,11 +198,23 @@
|
||||
"sound": "coffin",
|
||||
"type": "coffin",
|
||||
"item": "extra_life"
|
||||
},
|
||||
{
|
||||
"x_range": [200, 215],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
"type": "hunter",
|
||||
"turn_threshold": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"boundaries": {
|
||||
"left": 0,
|
||||
"right": 200
|
||||
"right": 220
|
||||
},
|
||||
"ambience": "Escaping the Grave.ogg",
|
||||
"footstep_sound": "footstep_tall_grass"
|
||||
|
@@ -245,7 +245,7 @@
|
||||
"x_range": [230, 245],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 12,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
|
@@ -25,7 +25,7 @@
|
||||
"x_range": [20, 40],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -77,7 +77,7 @@
|
||||
"x_range": [90, 110],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -134,7 +134,7 @@
|
||||
"x_range": [155, 175],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -161,7 +161,7 @@
|
||||
"x_range": [200, 220],
|
||||
"y": 0,
|
||||
"enemy_type": "ghoul",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
|
@@ -23,7 +23,7 @@
|
||||
"x_range": [25, 45],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -144,7 +144,7 @@
|
||||
"x_range": [210, 230],
|
||||
"y": 0,
|
||||
"enemy_type": "boogie_man",
|
||||
"health": 10,
|
||||
"health": 8,
|
||||
"damage": 3,
|
||||
"attack_range": 2,
|
||||
"attack_pattern": {
|
||||
@@ -227,7 +227,7 @@
|
||||
"x_range": [340, 360],
|
||||
"y": 0,
|
||||
"enemy_type": "witch",
|
||||
"health": 8,
|
||||
"health": 6,
|
||||
"damage": 2,
|
||||
"attack_range": 1.5,
|
||||
"attack_pattern": {
|
||||
|
BIN
sounds/ambience/Dark Dust Dispatcher.ogg
(Stored with Git LFS)
Normal file
BIN
sounds/ambience/Dark Dust Dispatcher.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
sounds/ghost.ogg
(Stored with Git LFS)
Normal file
BIN
sounds/ghost.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
sounds/ghost_dies.ogg
(Stored with Git LFS)
Normal file
BIN
sounds/ghost_dies.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
sounds/ghost_is_vulnerable.ogg
(Stored with Git LFS)
Normal file
BIN
sounds/ghost_is_vulnerable.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
37
src/enemy.py
37
src/enemy.py
@@ -43,6 +43,20 @@ class Enemy(Object):
|
||||
self.damage = level.player.get_max_health() # Instant death
|
||||
self.health = 1 # Easy to kill
|
||||
self.attackCooldown = 1500 # Slower attack rate
|
||||
elif enemyType == "ghost":
|
||||
self.isVulnerable = False
|
||||
self.vulnerabilityTimer = 0
|
||||
self.vulnerabilityDuration = kwargs.get('vulnerability_duration', 3000) # Default 3 seconds
|
||||
self.invulnerabilityDuration = kwargs.get('invulnerability_duration', 5000) # Default 5 seconds
|
||||
self.movementSpeed *= kwargs.get('speed_multiplier', 0.8) # Default 80% speed
|
||||
self.health = kwargs.get('health', 3) # Default 3 HP
|
||||
self.damage = kwargs.get('damage', 2) # Default 2 damage
|
||||
self.attackRange = kwargs.get('attack_range', 1) # Use provided or default 1
|
||||
self.attackCooldown = kwargs.get('attack_cooldown', 1200) # Default 1.2 seconds
|
||||
self.attackPattern = kwargs.get('attack_pattern', {
|
||||
'type': 'hunter',
|
||||
'turn_threshold': 2
|
||||
})
|
||||
elif enemyType == "spider":
|
||||
speedMultiplier = kwargs.get('speed_multiplier', 2.0)
|
||||
self.movementSpeed *= speedMultiplier # Spiders are faster
|
||||
@@ -76,6 +90,25 @@ class Enemy(Object):
|
||||
if not self.isActive or self.health <= 0:
|
||||
return
|
||||
|
||||
# Ghost vulnerability state management
|
||||
if self.enemyType == "ghost":
|
||||
if self.isVulnerable and (currentTime - self.vulnerabilityTimer > self.vulnerabilityDuration):
|
||||
# Switch to invulnerable
|
||||
self.isVulnerable = False
|
||||
self.vulnerabilityTimer = currentTime
|
||||
# Change sound back to base ghost sound
|
||||
if self.channel:
|
||||
obj_stop(self.channel)
|
||||
self.channel = obj_play(self.sounds, "ghost", player.xPos, self.xPos)
|
||||
elif not self.isVulnerable and (currentTime - self.vulnerabilityTimer > self.invulnerabilityDuration):
|
||||
# Switch to vulnerable
|
||||
self.isVulnerable = True
|
||||
self.vulnerabilityTimer = currentTime
|
||||
# Change to vulnerable sound
|
||||
if self.channel:
|
||||
obj_stop(self.channel)
|
||||
self.channel = obj_play(self.sounds, "ghost_is_vulnerable", player.xPos, self.xPos)
|
||||
|
||||
# Check if player has entered territory
|
||||
if not self.hunting:
|
||||
if self.patrolStart <= player.xPos <= self.patrolEnd:
|
||||
@@ -142,6 +175,10 @@ class Enemy(Object):
|
||||
|
||||
def take_damage(self, amount):
|
||||
"""Handle enemy taking damage"""
|
||||
# Ghost can only take damage when vulnerable
|
||||
if self.enemyType == "ghost" and not self.isVulnerable:
|
||||
return
|
||||
|
||||
self.health -= amount
|
||||
if self.health <= 0:
|
||||
self.die()
|
||||
|
Reference in New Issue
Block a user