from dataclasses import dataclass
from pybevy.prelude import *
@dataclass
class DealDamage(Message):
amount: int
@dataclass
class DamageReceived(Message):
@dataclass
class ArmorBlockedDamage(Message):
@resource
class DamageTimer(Resource):
def __init__(self):
self.timer: Timer = Timer(1.0, TimerMode.REPEATING)
def deal_damage_over_time(
time: Res[Time], state: ResMut[DamageTimer], deal_damage_writer: MessageWriter[DealDamage]
) -> None:
state.timer.tick(time.delta_secs())
if state.timer.just_finished():
deal_damage_writer.write(DealDamage(amount=10))
def apply_armor_to_damage(
dmg_reader: MessageReader[DealDamage],
dmg_writer: MessageWriter[DealDamage],
armor_writer: MessageWriter[ArmorBlockedDamage],
) -> None:
for message in dmg_reader:
reduced_amount = message.amount - 1
if reduced_amount <= 0:
armor_writer.write(ArmorBlockedDamage())
else:
dmg_writer.write(DealDamage(amount=reduced_amount))
def apply_damage_to_health(
deal_damage_reader: MessageReader[DealDamage],
damage_received_writer: MessageWriter[DamageReceived],
) -> None:
for deal_damage in deal_damage_reader:
print(f"Applying {deal_damage.amount} damage")
if deal_damage.amount > 0:
damage_received_writer.write(DamageReceived())
def play_damage_received_sound(damage_received_reader: MessageReader[DamageReceived]) -> None:
for _ in damage_received_reader:
print("Playing a sound.")
def play_damage_received_particle_effect(
damage_received_reader: MessageReader[DamageReceived],
) -> None:
for _ in damage_received_reader:
print("Playing particle effect.")
@entrypoint
def main(app: App) -> App:
return (
app.add_plugins(DefaultPlugins)
.add_message(DealDamage)
.add_message(ArmorBlockedDamage)
.add_message(DamageReceived)
.insert_resource(DamageTimer())
.add_systems(
Update,
(
deal_damage_over_time,
apply_armor_to_damage,
apply_damage_to_health,
),
)
.add_systems(
Update,
(
play_damage_received_sound,
play_damage_received_particle_effect,
),
)
)
if __name__ == "__main__":
main().run()