Esempio n. 1
0
    def process_action(self, action):
        """Process this Action by executing its phase sequence within a
        list of prefixes.

        The necessary arguments for each phase are pulled from the provided
        keyword arguments. The return value accumulates the method return
        values into a list like so:

                ["believe", "can", "do"] x ["touch", "get", "drop"]

            =   ["believe_touch", "can_touch", "do_touch",
                "believe_get", "can_get", "do_get",
                "believe_drop", "can_drop", "do_drop"]

        If any function returns False, processing will stop, meaning that the
        return value has variable length."""
        debug.log("ACT: %s" % action.__class__.get_name())

        ctx = action.context
        # ctx.set_active(action.__class__)

        # This is a generator, so we can check the Context object for a
        # different list of phases between go-arounds.
        for phase in action.get_phases():
            phase.context = ctx

            result = self.process_phase(phase)
            ctx.append_result(action.__class__, result)
            outcome, cause = ctx.parse_result(result)
            if outcome is False:
                break

        return ctx.parse_results(action.__class__)
Esempio n. 2
0
 def react(self):
     key = kernel.input.pop()
     if key:
         command = Command(key, self.keybindings.get(key, False))
         if command:
             debug.log("{} received command: {}".format(self, command))
             self.push(command)
             return command
Esempio n. 3
0
 def input(self, command):
     """Recurse through children trying their keyin functions until you've
     done your own."""
     debug.log("{} received command: {}.".format(self, command))
     for child in reversed(self.children):
         if child.input(command) is False or child.blocking is True:
             return False
     return self.process(command)
Esempio n. 4
0
 def react(self):
     """Get key codes from the display. If there is one, push it to the keyin service."""
     event = self.display.input()
     if event is not -1:
         # TODO: Handle mice.
         key_name = self.key_name(event)
         debug.log("Input event: `{}` => `{}`".format(event, key_name))
         if key_name == "Ctrl+c":
             assert False, "Keyboard interrupt!"
         self.push(key_name)
Esempio n. 5
0
    def _act(self):
        if not self.turn():
            debug.die("%s tried to act when not the acting actor in queue %s." % (self, Queue))
        if self.controlled:
            debug.die("Player-controlled actor %s tried to hit AI code." % self.appearance())

        # If we don't have a target, try to find a new one.
        if not self.pathing.target and not self.pathing.retarget():
            # wander aimlessly
            return self.do(random.choice(dirs))

        # Repath if our current target isn't correct
        if self.pathing.target:
            if self.pathing.target.coords != self.pathing.destination:
                self.pathing.destination = self.pathing.target.coords
                if isinstance(self.pathing.destination, tuple):
                    debug.die([self, self.pathing.destination, self.pathing.target])
                self.pathing.repath()

            # Calculate the distance to the target.
            self.pathing.distance = self.distance(self.pathing.target)
        else:
            if isinstance(self.pathing.destination, tuple):
                debug.die([self, self.pathing.destination, self.pathing.target])
            self.pathing.repath()

        # TODO: If within attack range, do so.
        # if self.preferred_reach(self.distance) is True:
        #     return self.do(sub(self.target.coords, self.coords))

        # If we've successfully pathed, follow it.
        if self.pathing.path:
            debug.log("%s had a path." % self.appearance())
            next_step = self.pathing.path.pop()
            next_dir = next_step - self.coords
            # # HACK, fixes stuff like teleporting
            # if dir not in dirs:
            #     self.path.append(pos)
            #     dir = CC
            if self.map.cell(next_step).can_block(self, next_dir):
                # TODO: Randomize choice here
                for alt_dir in arc(next_dir)[1:]: # We already checked the first one
                    alt_next = self.coords + alt_dir
                    # Prefer unoccupied cells, but accept sharing.

                    if not self.map.cell(alt_pos).occupied():
                        next_dir = alt_dir
                        break
                    elif self.map.cell(alt_pos).blocked(alt_dir) is False:
                        next_dir = alt_dir

            self.do(next_dir)
Esempio n. 6
0
    def launch(self, package_choice):
        """Spawn the selected module's main.Game as a child Component and then
        launch it."""
        # TODO: Handle multiple game folders
        # TODO: Permit class names other than 'main'
        package_name, package_info = package_choice # e.g., hellmouth, Hellmouth, <description>, <version>
        game_module = __import__('src.games.%s.main' % package_name, globals(), locals(), ['main'])
        game_class = game_module.main

        debug.log("In launch")
        # Spawn the game as a child Component, and then launch it.
        self.game = self.spawn(game_class())
        self.game.launch()
        debug.log("Launched the game!")
Esempio n. 7
0
    def react(self):
        """Loop drawing, keyin, and event processing through this Component and
        into its children. If still alive, perform a Game loop."""

        # Input tree.
        command = kernel.command.pop()
        if command:
            self.input(command)

        # The RootComponent dies if it has no children.
        if not self.children:
            self.alive = False

        if self.alive and self.game:
            debug.log("Acting game: {}".format(self.game))
            self.game.loop()
Esempio n. 8
0
    def process_phase(self, phase):
        """Process a Phase object.

        Returns an outcome and a cause, based on the Context's parsing.
        """
        ctx = phase.context
        ctx.set_active(phase)
        debug.log("PHASE: %s" % phase.name)

        # TODO: 7DRL
        ctx.require_arguments(phase.required_arguments)
        # arguments = {}
        # for argument in phase.required_arguments:
        #     arguments[phase.aliases.get(argument, argument)] = ctx.get_argument(argument)

        arguments = {}
        for argument in phase.required_arguments:
            send = ctx.get_argument(argument)
            send_as = phase.aliases.get(argument, argument)
            arguments[send_as] = send

        is_method = getattr(ctx.agent, "is" + "_" + phase.name, None)
        if is_method:
            is_result = is_method(**arguments)
            outcome, cause = ctx.parse_result(is_result)
            if outcome:
                debug.log("***PHASE SATISFIED***: %s (%s)" % ("is" + "_" + phase.name, outcome))
                return True, "done"

        # TODO: Rewrite this entire section, augh
        could_result = getattr(ctx.agent, "could" + "_" + phase.name)()
        outcome, cause = ctx.parse_result(could_result)
        debug.log("METHOD: %s (%s)" % ("could" + "_" + phase.name, outcome))
        if not outcome: return False, "could" + "_" + phase.name

        can_result = getattr(ctx.agent, "can" + "_" + phase.name)(**arguments)
        outcome, cause = ctx.parse_result(can_result)
        debug.log("METHOD: %s (%s)" % ("can" + "_" + phase.name, outcome))
        if not outcome: return False, "can" + "_" + phase.name

        result = getattr(ctx.agent, "do" + "_" + phase.name)(**arguments)
        outcome, cause = ctx.parse_result(result)
        debug.log("METHOD: %s (%s)" % ("do" + "_" + phase.name, outcome))
        ctx.append_result(phase.__class__, result)
        return outcome, cause
Esempio n. 9
0
    def process_command(self, command):
        """Process a Command object by attempting to process each of its Actions in sequence.

        Returns an outcome and a cause, based on the Context's parsing.
        """
        ctx = command.context
        # ctx.set_active(command.__class__)
        debug.log("CMD: %s." % command.__class__.get_name())

        # This is a generator, so we can check the Context object for a
        # different list of actions between go-arounds.

        for action_class in command.get_actions(ctx):
            action = action_class(command)

            result = self.process_action(action)
            ctx.append_result(command.__class__, result)
            outcome, cause = ctx.parse_result(result)
            if outcome is False:
                break

        return ctx.parse_results(command.__class__)
Esempio n. 10
0
    def process_event(self, event, context):
        """Find the first Command matching an event, instantiate it, and process it."""

        if not self.turn():
            debug.die("Event %s by %s; should be acting: %s; queue: %s" % (event, self.appearance(), Queue.get_acting().appearance(), [a.appearance() for a in Queue.queue]))

        if event not in ["Up", "Down"]:
            debug.log("EVENT: %s" % event)

        for command_class, command_arguments in context.get_commands():
            for command_event in command_class.get_events():
                if event != command_event:
                    continue

                command = command_class(context)
                context.update_arguments(**command_arguments)

                result = self.process_command(command)
                outcome, cause = context.parse_result(result)
                if outcome is True:
                    debug.log("(+): %s" % cause)
                    Log.add("(+): %s" % cause)
                else:
                    debug.log("(-): %s" % cause)
                    Log.add("(-): %s" % cause)

                # TODO: Something else to decide this
                self.end_turn()

                # TODO: Instead return whether the event was consumed.
                return outcome, cause

        if event not in ["Up", "Down"]:
            debug.log("( ): %s" % event)
            Log.add("( ): %s" % event)
        # TODO: Instead return whether the event was consumed.
        return False
Esempio n. 11
0
    def retarget(self):
        target = self.owner.call("Faction", "get_target").get_result()
        if target:
            self.target = target
            self.destination = self.target.coords
            debug.log("%s retargeted to %s." % (self.owner.appearance(), self.target.appearance()))
            return True

        destination = self.owner.call("Faction", "get_destination").get_result()
        if destination:
            self.destination = destination
            debug.log("%s found no target but instead a destination." % self.owner.appearance())
            return True

        # Move somewhere random.
        debug.log("%s failed to retarget." % self.owner.appearance())
        self.destination = random.choice([h for h in Hexagon.area(self.owner.coords, 10)])
        return True
Esempio n. 12
0
from src.lib.util import debug
from src.lib.util.define import *
from src.lib.util import system

debug.log("Completed all imports.")

# Import and initialize the Unicursal kernel.
from src.lib.core.kernel import kernel

debug.log("Kernel initialization complete.")

# Set a bitmask for game-wide display modes.
displayflags = {
    "silent" : 0b1,
    "curses" : 0b10,
    "unicode" : 0b100,
    "256" : 0b1000,
}

# Set up a dictionary of game settings.
# TODO: Have the kernel parse this.
arguments = {}

# Add a folder with default configurations.
arguments["configuration"] = 'src/lib/data/configuration'

# Default to displaying with curses
arguments["displaymode"] = displayflags["curses"]

# Default to launching Meat Arena
# TODO: If not provided, always get a game launcher
Esempio n. 13
0
 def run(self):
     """Run an instance of the main application loop."""
     # Allow services to react to the loop.
     for service in kernel.loop:
         debug.log("Acting service: {}".format(service))
         service.react()
Esempio n. 14
0
 def act(self):
     debug.log("%s started turn." % self.appearance())
     self._act()
     debug.log("%s ended turn." % self.appearance())
     self.end_turn()
Esempio n. 15
0
 def repath(self):
     debug.log("%s repathed." % self.owner.appearance())
     self.astar = AStar(self.owner, self.owner.map)
     self.path = self.astar.path(self.owner.coords, self.destination)
Esempio n. 16
0
 def draw(self, display):
     for text, color in self.get_controller().values("Status", "get_view_data", self):
         debug.log("text: %s, color: %s" % (text, color))
         display.line(self, text, color)
     return True
Esempio n. 17
0
 def pop(self):
     if self.queue:
         command = self.queue.pop()
         debug.log("{} popped: {}".format(self, command))
         return command
Esempio n. 18
0
 def __exit__(self, exception_type, exception_val, trace):
     """Tell the display to stop using curses."""
     debug.log("{}: {}".format(exception_type, exception_val))
     self.display.reset_mode()
     del self.display
Esempio n. 19
0
 def push(self, value):
     debug.log("{} pushed: {}".format(self, value))
     self.queue.append(value)