Very hacky bullets.
[koperkapel.git] / koperkapel / weapons.py
1 """ Tools for dealing with weapons. """
2
3 from pygame.surface import Surface
4 from pygame.draw import circle
5 from pgzero.loaders import images, sounds
6 from .actors.animsurf import AnimatedSurfActor
7 from .util import safepath
8
9
10 class Weapon:
11     def __init__(self, name, damage, image_name=None, bullet_range=0,
12                  can_tape=True, frames=("_1",), sound=None):
13         self.name = name
14         self.image_name = image_name or name
15         self.frames = frames
16         self.damage = damage
17         self.bullet_range = bullet_range
18         self.can_tape = can_tape
19         self.sound = None
20         if sound:
21             self.sound = sounds.load(sound)
22
23     def play_sound(self):
24         if self.sound:
25             self.sound.play()
26
27     def assemble_bullet(self):
28         return BulletActor(self)
29
30
31 WEAPONS = [
32     Weapon("spit", damage=1, bullet_range=2, can_tape=False,
33            image_name="blank", frames=("",), sound="fire_spit"),
34     Weapon("butter_knife", damage=2),
35     Weapon("crowbar", damage=4),
36     Weapon("gun", damage=4, bullet_range=4, sound='gun_fire'),
37 ]
38
39 WEAPON_LOOKUP = {w.name: w for w in WEAPONS}
40
41
42 def weapon_by_name(weapon_name):
43     return WEAPON_LOOKUP[weapon_name]
44
45
46 class WeaponActor(AnimatedSurfActor):
47     def __init__(self, weapon, **kw):
48         super().__init__(**kw)
49         self.weapon = weapon
50
51
52 class BulletActor(AnimatedSurfActor):
53     def __init__(self, weapon, **kw):
54         radius = min(weapon.damage * 5, 32)
55         surf = Surface((radius * 2, radius * 2))
56         surf.convert_alpha()
57         surf.fill((255, 255, 255, 0))
58         circle(surf, (255, 0, 255, 32), (radius, radius), radius)
59         frames = [surf]
60         super().__init__(frames=frames, **kw)
61         self.weapon = weapon
62
63
64 class WeaponFactory:
65
66     def assemble_frame(self, suffix, weapon, tape):
67         surf = images.load(safepath("weapons/%s%s")
68                            % (weapon.image_name, suffix))
69         frame = surf.copy()
70         if tape:
71             tape_surf = images.load(safepath("weapons/tape"))
72             frame.blit(tape_surf, (0, 0))
73         return frame
74
75     def assemble(self, weapon_name, tape=False):
76         weapon = weapon_by_name(weapon_name)
77         tape = tape and weapon.can_tape
78         frames = [
79             self.assemble_frame(suffix, weapon, tape)
80             for suffix in weapon.frames]
81         return WeaponActor(weapon, frames=frames)
82
83
84 default_weapons = WeaponFactory()