summaryrefslogtreecommitdiff
path: root/cheat_engine.py
blob: e385b749b1581f8bfa20010f4efb4cb41adf3fe3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
from typing import Callable, List

from config import Config
from menu import Menu


class Cheat:
    """A single cheat, to be assigned to a cheat engine"""

    def __init__(self, game, code: List[str], callback: Callable):
        """Initialise the cheat

        :param game: The game which the cheat belongs to
        :param code: A string of key codes to be pressed to activate the cheat
        :type code: List[str]
        :param callback: The function to be called when this cheat is activated
        :type callback: Callable
        """
        self.game = game
        self.code = code
        self.callback = callback
        self.position = 0

    def on_key(self, event):
        """Handle a key press event

        :param event: The event that is being handled
        """
        if self.position < len(self.code):
            next_key = self.code[self.position]
            if event.keysym == next_key:
                self.position += 1
                if self.position == len(self.code):
                    self.callback()
                    self.position = 0
            else:
                self.position = 0
        return False


class InvincibilityCheat(Cheat):
    """Cheat that makes the player invincible"""

    def __init__(self, game, code: List[str]):
        """Initialise the cheat

        :param game: The game which this belongs to
        :param code: The combination of characters for which to
                     activate this cheat
        :type code: List[str]
        """
        super().__init__(game, code, self.toggle)
        self.enabled = False
        self.damage_function = None

    def toggle(self):
        """Enable or disable this cheat"""
        self.enabled = not self.enabled
        if self.enabled:
            self.game.effect_player.splash_text("Godmode on")
            self.game.player.set_image(self.game.player.white_image)
            self.damage_function = self.game.player.damage
            self.game.player.damage = (lambda: None)
        else:
            self.game.effect_player.splash_text("Godmode off")
            self.game.player.set_image(
                self.game.texture_factory.get_image("ship"))
            self.game.player.damage = self.damage_function


class DevModeCheat(Cheat):
    """Cheat that enables 'dev mode' which:
       - enables spawning menu
       - key to remove all enemies
       - key to stop spawning outright
    """

    def __init__(self, game, code: List[str]):
        """Initialise the cheat

        :param game: The game which this belongs to
        :param code: The combination of characters which activate this cheat
        :type code: List[str]
        """
        super().__init__(game, code, self.toggle)
        self.enabled = Config.DEVMODE

        self.spawning_disabled = False
        self.spawn_menu = Menu(self.game, "Spawn Menu")
        for i in ("circle_boss",
                  "snake_boss",
                  "loop",
                  "orbital",
                  "rectangle",
                  "fleet"):
            self.spawn_menu.add_item(i, self.spawn_item(i))

    def toggle(self):
        """Toggle if this mode is enabled"""
        self.enabled = not self.enabled
        if self.enabled:
            self.game.effect_player.splash_text("devmode on")
        else:
            self.game.effect_player.splash_text("devmode off")

    def spawn_item(self, name):
        """Spawn a named item from the menu

        :param name: The name of the formation to spawn
        """
        return lambda: (
            self.spawn_menu.hide(),
            getattr(self.game.formation_spawner, f"spawn_{name}")()
        )

    def on_key(self, event):
        """Handle Key press events

        :param event: The key press event to handle
        """
        if self.enabled:
            if event.keysym == "n":
                self.game.formation_spawner.clear_all()
                self.game.formation_spawner.next_phase()

            if event.keysym == "c":
                self.game.formation_spawner.clear_all()

            if event.keysym == "k":
                if self.spawning_disabled:
                    self.game.effect_player.splash_text("spawning on")
                    self.spawning_disabled = False
                    self.game.formation_spawner.next_formation = 0
                else:
                    self.game.effect_player.splash_text("spawning off")
                    self.game.formation_spawner.clear_all()
                    self.game.formation_spawner.next_formation = -1

            if event.keysym == "m":
                self.spawn_menu.show()

        return super().on_key(event)


class CheatEngine:
    """Object which manages cheats"""

    def __init__(self, game):
        """Initialise the cheat engine

        :param game: The game which this belongs to
        """
        self.game = game
        self.cheats = []

    def add_cheat(self, cheat):
        """Register a cheat to the engine

        :param cheat: The cheat to be registered
        """
        self.game.inputs.add_keypress_handler(cheat.on_key)
        self.cheats.append(cheat)