Add Fireball Scoll, completing part 8
This commit is contained in:
parent
621d4780e8
commit
a1e6125c34
@ -8,7 +8,7 @@ import components.ai
|
||||
import components.inventory
|
||||
from components.base_component import BaseComponent
|
||||
from exceptions import Impossible
|
||||
from input_handlers import SingleRangedAttackHandler
|
||||
from input_handlers import AreaRangedAttackHandler, SingleRangedAttackHandler
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from entity import Actor, Item
|
||||
@ -94,6 +94,45 @@ class HealingConsumable(Consumable):
|
||||
raise Impossible(f"Your health is already full.")
|
||||
|
||||
|
||||
class FireballDamageConsumable(Consumable):
|
||||
def __init__(self, damage: int, radius: int):
|
||||
self.damage = damage
|
||||
self.radius = radius
|
||||
|
||||
def get_action(self, consumer: Actor) -> Optional[actions.Action]:
|
||||
self.engine.message_log.add_message(
|
||||
"Select a target location.",
|
||||
color.needs_target
|
||||
)
|
||||
self.engine.event_handler = AreaRangedAttackHandler(
|
||||
self.engine,
|
||||
self.radius,
|
||||
lambda xy: actions.ItemAction(consumer, self.parent, xy),
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
def activate(self, action: actions.ItemAction) -> None:
|
||||
target_xy = action.target_xy
|
||||
|
||||
if not self.engine.game_map.visible[target_xy]:
|
||||
raise Impossible("You cannot target an area that you cannot see.")
|
||||
|
||||
targets_hit = False
|
||||
for actor in self.engine.game_map.actors:
|
||||
if actor.distance(*target_xy) <= self.radius:
|
||||
self.engine.message_log.add_message(
|
||||
f"The {actor.name} is engulfed in a fiery explosion, taking {self.damage} damage!"
|
||||
)
|
||||
actor.fighter.take_damage(self.damage)
|
||||
targets_hit = True
|
||||
|
||||
if not targets_hit:
|
||||
raise Impossible("There are no targets in the radius.")
|
||||
|
||||
self.consume()
|
||||
|
||||
|
||||
class LightningDamageConsumable(Consumable):
|
||||
def __init__(self, damage: int, maximum_range: int):
|
||||
self.damage = damage
|
||||
|
@ -36,6 +36,12 @@ confusion_scroll = Item(
|
||||
name="Confusion Scroll",
|
||||
consumable=consumable.ConfusionConsumable(number_of_turns=10),
|
||||
)
|
||||
fireball_scroll = Item(
|
||||
char="~",
|
||||
color=(255, 0, 0),
|
||||
name="Fireball Scroll",
|
||||
consumable=consumable.FireballDamageConsumable(damage=12, radius=3),
|
||||
)
|
||||
health_potion = Item(
|
||||
char="!",
|
||||
color=(127, 0, 255),
|
||||
|
@ -310,6 +310,43 @@ class SingleRangedAttackHandler(SelectIndexHandler):
|
||||
return self.callback((x, y))
|
||||
|
||||
|
||||
class AreaRangedAttackHandler(SelectIndexHandler):
|
||||
"""
|
||||
Handles targeting an area within a given radius.
|
||||
Any entity within the area will be affected.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
engine: Engine,
|
||||
radius: int,
|
||||
callback: Callable[[Tuple[int, int]], Optional[Action]]
|
||||
):
|
||||
super().__init__(engine)
|
||||
|
||||
self.radius = radius
|
||||
self.callback = callback
|
||||
|
||||
def on_render(self, console: tcod.Console) -> None:
|
||||
"""Highlight the tile under the cursor."""
|
||||
super().on_render(console)
|
||||
|
||||
x, y = self.engine.mouse_location
|
||||
|
||||
# Draw a rectangle around the targeted area, so the player can see the affected tiles.
|
||||
console.draw_frame(
|
||||
x=x - self.radius - 1,
|
||||
y=y - self.radius - 1,
|
||||
width=self.radius ** 2,
|
||||
height=self.radius ** 2,
|
||||
fg=color.red,
|
||||
clear=False,
|
||||
)
|
||||
|
||||
def on_index_selected(self, x: int, y: int) -> Optional[Action]:
|
||||
return self.callback((x, y))
|
||||
|
||||
|
||||
class MainGameEventHandler(EventHandler):
|
||||
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
||||
action: Optional[Action] = None
|
||||
|
@ -70,6 +70,8 @@ def place_entities(
|
||||
|
||||
if item_chance < 0.7:
|
||||
entity_factories.health_potion.spawn(dungeon, x, y)
|
||||
elif item_chance < 0.8:
|
||||
entity_factories.fireball_scroll.spawn(dungeon, x, y)
|
||||
elif item_chance < 0.9:
|
||||
entity_factories.confusion_scroll.spawn(dungeon, x, y)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user