Skip to content

Commit 56ea888

Browse files
committed
added new enemies to the game
1 parent f654803 commit 56ea888

File tree

3 files changed

+128
-7
lines changed

3 files changed

+128
-7
lines changed

components/ai.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,83 @@ def perform(self) -> None:
112112

113113
# The actor will either try to move or attack in the chosen random direction.
114114
# Its possible the actor will just bump into the wall, wasting a turn.
115-
return BumpAction(self.entity, direction_x, direction_y,).perform()
115+
return BumpAction(self.entity, direction_x, direction_y,).perform()
116+
117+
118+
class SpawnerEnemy(BaseAI):
119+
"""
120+
A spawner enemy will spawn a new enemy (of the selected type) in a random location around it self. while trying to get distanced from the player.
121+
"""
122+
123+
def __init__(
124+
self, entity: Actor
125+
):
126+
super().__init__(entity)
127+
128+
self.is_setup = False
129+
130+
def setup(self,spawned_entity: Actor, spawn_rate: int):
131+
self.spawned_entity = spawned_entity
132+
self.spawn_rate = spawn_rate
133+
self.spawn_timer = 0
134+
self.is_setup = True
135+
136+
def perform(self) -> None:
137+
# Do not perform if this AI is not setup or the spawner is not visible.
138+
if not self.is_setup or not self.engine.game_map.visible[self.entity.x, self.entity.y]:
139+
return WaitAction(self.entity).perform()
140+
141+
142+
143+
# If the spawn timer is greater than the spawn rate, spawn a new enemy.
144+
if self.spawn_timer >= self.spawn_rate:
145+
# Reset the spawn timer.
146+
self.spawn_timer = 0
147+
148+
# Get a random location near the spawner.
149+
x = self.entity.x + random.randint(-3, 3)
150+
y = self.entity.y + random.randint(-3, 3)
151+
152+
tries = 0
153+
while not self.engine.game_map.in_bounds(x, y) or not self.engine.game_map.get_blocking_entity_at_location(x, y):
154+
x = self.entity.x + random.randint(-3, 3)
155+
y = self.entity.y + random.randint(-3, 3)
156+
tries += 1
157+
if tries > 10:
158+
return WaitAction(self.entity).perform() # If the spawner is not able to find a valid location, it will wait.
159+
160+
# Spawn the new enemy.
161+
self.spawned_entity.spawn(self.engine.game_map, x, y)
162+
# Add a message to the message log.
163+
self.engine.message_log.add_message(
164+
f"The {self.entity.name} spawned a new {self.spawned_entity.name}!"
165+
)
166+
167+
# Get the distance between the player and the spawner.
168+
distance = self.entity.distance(self.engine.player.x, self.engine.player.y)
169+
170+
# If the distance is less than 5, move away from the player.
171+
if distance < 5:
172+
# Get the direction to the player.
173+
direction_x = self.engine.player.x - self.entity.x
174+
direction_y = self.engine.player.y - self.entity.y
175+
176+
# Normalize the direction.
177+
direction_x = max(min(direction_x, 1), -1)
178+
direction_y = max(min(direction_y, 1), -1)
179+
180+
# Round the direction.
181+
direction_x = -round(direction_x)
182+
direction_y = -round(direction_y)
183+
184+
# Move the spawner in the direction of the player.
185+
return MovementAction(
186+
self.entity, direction_x, direction_y,
187+
).perform()
188+
189+
190+
# Add 1 to the spawn timer.
191+
self.spawn_timer += 1
192+
193+
# Return a wait action.
194+
return WaitAction(self.entity).perform()

entity_factories.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from components.ai import HostileEnemy
1+
from components.ai import HostileEnemy, SpawnerEnemy
22
from components import consumable, equippable
33
from components.fighter import Fighter
44
from components.inventory import Inventory
@@ -18,7 +18,7 @@
1818
equipment=Equipment(),
1919
)
2020

21-
smile_mold = Actor(
21+
slime_mold = Actor(
2222
char="m",
2323
color=(255, 80, 80),
2424
name="Slime Mold",
@@ -40,14 +40,55 @@
4040
level=Level(xp_given=100),
4141
equipment=Equipment(),
4242
)
43+
hunter_humanoid = Actor(
44+
char="h",
45+
color=(244, 227, 210),
46+
name="Hunter Humanoid",
47+
ai_cls=HostileEnemy,
48+
fighter=Fighter(hp=20, base_defense=2, base_power=7),
49+
inventory=Inventory(capacity=0),
50+
level=Level(xp_given=150),
51+
equipment=Equipment(),
52+
inspect_message="It's a mutated human, probably due to being exposed to irradiated places. It's now a reckless hunter, with sharp claws and skinny body, it wants to eat fresh flesh."
53+
)
54+
acid_mold = Actor(
55+
char="m",
56+
color=(0, 204, 102),
57+
name="Acid Mold",
58+
ai_cls=HostileEnemy,
59+
fighter=Fighter(hp=19, base_defense=1, base_power=6),
60+
inventory=Inventory(capacity=0),
61+
level=Level(xp_given=50),
62+
equipment=Equipment(),
63+
inspect_message="It's a slime mold, but it's acidic. Don't touch it! It's pains to the touch."
64+
)
65+
mama_mold = Actor(
66+
char="M",
67+
color=(0, 204, 102),
68+
name="Mama Mold",
69+
ai_cls=SpawnerEnemy,
70+
fighter=Fighter(hp=30, base_defense=1, base_power=0),
71+
inventory=Inventory(capacity=0),
72+
level=Level(xp_given=200),
73+
equipment=Equipment(),
74+
inspect_message="It's a big slime mold. It's trying to reproduce, and use its offspring to defend itself from you."
75+
)
76+
mama_mold.ai.setup(acid_mold, 10)
4377

4478
healing_gel = Item(
4579
char="!",
4680
color=(102, 255, 102),
4781
name="Healing Gel",
48-
consumable=consumable.HealingConsumable(amount=4),
82+
consumable=consumable.HealingConsumable(amount=7),
4983
inspect_message="A Small, green-glowing piece of smile. It has a some-what apple taste.",
5084
)
85+
XL_healing_gel = Item(
86+
char="!",
87+
color=(0, 255, 0),
88+
name="XL Healing Gel",
89+
consumable=consumable.HealingConsumable(amount=18),
90+
inspect_message="A Extra Large healing Gel. Don't choke while gobbling it up!",
91+
)
5192
taser = Item(
5293
char="~",
5394
color=(255, 255, 0),

procgen.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,17 @@
2525

2626
item_chances: Dict[int, List[Tuple[Entity, int]]] = {
2727
0: [(entity_factories.healing_gel, 35)],
28-
2: [(entity_factories.stun_gun, 10), (entity_factories.old_kinfe, 5), (entity_factories.iron_chest_plate, 5)],
28+
2: [(entity_factories.stun_gun, 10), (entity_factories.old_kinfe, 5), (entity_factories.iron_chest_plate, 5), (entity_factories.XL_healing_gel, 5)],
2929
4: [(entity_factories.taser, 25), (entity_factories.sharp_kinfe, 15)],
3030
6: [(entity_factories.fireball_gun, 25), (entity_factories.steel_chest_plate, 12)],
3131
}
3232

3333
enemy_chances: Dict[int, List[Tuple[Entity, int]]] = {
34-
0: [(entity_factories.smile_mold, 80)],
34+
0: [(entity_factories.slime_mold, 80)],
3535
3: [(entity_factories.rusty_automaton, 15)],
3636
5: [(entity_factories.rusty_automaton, 30)],
37-
7: [(entity_factories.rusty_automaton, 60)],
37+
6:[(entity_factories.hunter_humanoid, 40), (entity_factories.acid_mold, 40)],
38+
7: [(entity_factories.rusty_automaton, 60), (entity_factories.mama_mold, 40)],
3839
}
3940

4041
def get_max_value_for_floor(

0 commit comments

Comments
 (0)