Example #1
0
class AI:
    """
	Base class for all AIs.
	AI is a component and so must have owner.
	"""

    ais = enums.enum('base', 'player_control', 'basic_monster')

    def __init__(self, owner):
        self.owner = owner

    def get_type(self):
        """ 
		Returns the type of ai
		Used by Actor's act() to supply proper arguments
		children should redefine this
		"""
        return AI.ais.base

    def work(self):
        """
		Returns True if this Actor's turn is made.
		children should redefine this
		"""
        raise NotImplementedError("Subclass must implement abstract method")
Example #2
0
class Entity:
    """
	This is a generic game entity that can be assigned to map.
	It can't act on its own.
	Actors inherit from it (and items, projectiles will)
	"""

    types = enums.enum('Entity', 'Actor')

    def __init__(self, char, name, color, blocks):

        self.char = char
        self.color = color
        self.name = name

        # map-specific stuff
        # these are none, added when zone sets them
        self.x = None
        self.y = None
        self.zone = None
        # whether it blocks passage or not
        self.blocks = blocks

    def get_type(self):
        """
		Returns own type of entity in Entity.types.*
		Each child redefines this.
		"""
        #raise NotImplementedError("Subclass must implement abstract method")
        return Entity.types.Entity

    def set_zone(self, zone, x, y):
        """
		Sets entity's zone and positions the object at given coords.
		"""
        self.zone = zone
        self.x = x
        self.y = y
Example #3
0
try:
    from pervasive import PervasiveDisplay
except ImportError:
    # this will allow derived classes that do not depend on
    # PervasiveDisplay
    def PervasiveDisplay():
        return None


from PIL import Image, ImageFont, ImageDraw
from pil2epd import convert
from fontlist import FontList
from enums import enum

directions = enum(x=0, y=1)

char_width = 9.0
char_height = 18.0
line_width = 4.0


def chars_to_pixels(chars, direction=directions.x):
    if direction == directions.x:
        return chars * char_width
    elif direction == directions.y:
        return chars * char_height
    else:
        raise Exception("Direction must be x or y.")

Example #4
0
from enums import enum

keystates = enum(down=1, up=0, hold=2)

buckies = [
    "KEY_LEFTSHIFT", "KEY_RIGHTSHIFT", "KEY_LEFTCTRL", "KEY_RIGHTCTRL",
    "KEY_CAPSLOCK", "KEY_LEFTALT", "KEY_RIGHTALT"
]

alphabet = "abcdefghijklmnopqrstuvwxyz"
numeric_keys = "0123456789)!@#$%^&*("
char_keys = {
    "KEY_GRAVE": "`",
    "S-KEY_GRAVE": "~",
    "KEY_SPACE": " ",
    "KEY_MINUS": "-",
    "S-KEY_MINUS": "_",
    "KEY_EQUAL": "=",
    "S-KEY_EQUAL": "+",
    "KEY_SEMICOLON": ";",
    "S-KEY_SEMICOLON": ":",
    "KEY_APOSTROPHE": "'",
    "S-KEY_APOSTROPHE": '"',
    "KEY_COMMA": ",",
    "S-KEY_COMMA": "<",
    "KEY_DOT": ".",
    "S-KEY_DOT": ">",
    "KEY_SLASH": "/",
    "S-KEY_SLASH": "?",
    "KEY_LEFTBRACE": "[",
    "S-KEY_LEFTBRACE": "{",
Example #5
0
    def __str__(self):
        return '%s, errors: %s' % (self.response_code,
            ', '.join(str(e) for e in self.errors))

    @classmethod
    def server_error(cls, errors=()):
        return ServiceException(ResponseCode.SERVER_ERROR.name, errors)

    @classmethod
    def request_error(cls, errors=()):
        return ServiceException(ResponseCode.REQUEST_ERROR.name, errors)

class ServiceRequest(serializable.Serializable):
    pass

ResponseCode = enums.enum('SUCCESS', 'SERVER_ERROR', 'REQUEST_ERROR')

class ServiceResponse(serializable.Serializable):
    PUBLIC_FIELDS = serializable.fields('response_code',
        serializable.objlistf('errors', ServiceError))

    def __init__(self, response_code=None, errors=()):
        self.response_code = response_code
        self.errors = errors

class MethodDescriptor(object):
    def __init__(self, method_name, request_class, response_class):
        self.method_name = method_name
        self.request_class = request_class
        self.response_class = response_class
Example #6
0
class KeyHandler:
    """Handles Key through libtcode"""

    controls = enums.enum('none', 'other', 'exit', 'fullscreen')
    cheats = enums.enum('none', 'other', 'teleport', 'reveal_map')
    game = enums.enum('none', 'other', 'move_N', 'move_NE', 'move_E',
                      'move_SE', 'move_S', 'move_SW', 'move_W', 'move_NW',
                      'move_5')

    def __init__(self):
        pass

    def process_control_keys(self, key):
        """
		Checks if passed key corresponds to control action. if so, return control action const.
		"""
        if key.vk == libtcod.KEY_NONE:
            logger.log(logger.types.input, "key none")
            return KeyHandler.controls.none

        elif key.vk == libtcod.KEY_ESCAPE:
            logger.log(logger.types.input, "key escape")
            return KeyHandler.controls.exit

        elif key.vk == libtcod.KEY_ENTER and key.lalt:
            logger.log(logger.types.input, "key alt+enter")
            return KeyHandler.controls.fullscreen
        else:
            # some other key
            return KeyHandler.controls.other

    def process_cheat_keys(self, key):
        """
		Checks if passed key corresponds to cheat action. if so, returns cheat action const.
		"""
        if key.vk == libtcod.KEY_NONE:
            return KeyHandler.cheats.none

        elif key.vk == libtcod.KEY_1 and key.lctrl:
            return KeyHandler.cheats.teleport

        elif key.vk == libtcod.KEY_2 and key.lctrl:
            return KeyHandler.cheats.reveal_map

        else:
            return KeyHandler.cheats.other

    def process_game_key(self, key):
        """
		Checks if passed key corresponds to if passed key corresponds to any game action (that takes a turn). 
		If so, returns cheat action const.
		"""
        if libtcod.console_is_key_pressed(
                libtcod.KEY_UP) or libtcod.console_is_key_pressed(
                    libtcod.KEY_KP8):
            return KeyHandler.game.move_N

        elif libtcod.console_is_key_pressed(
                libtcod.KEY_DOWN) or libtcod.console_is_key_pressed(
                    libtcod.KEY_KP2):
            return KeyHandler.game.move_S

        elif libtcod.console_is_key_pressed(
                libtcod.KEY_LEFT) or libtcod.console_is_key_pressed(
                    libtcod.KEY_KP4):
            return KeyHandler.game.move_W

        elif libtcod.console_is_key_pressed(
                libtcod.KEY_RIGHT) or libtcod.console_is_key_pressed(
                    libtcod.KEY_KP6):
            return KeyHandler.game.move_E

        elif libtcod.console_is_key_pressed(libtcod.KEY_KP7):
            return KeyHandler.game.move_NW

        elif libtcod.console_is_key_pressed(libtcod.KEY_KP9):
            return KeyHandler.game.move_NE

        elif libtcod.console_is_key_pressed(libtcod.KEY_KP1):
            return KeyHandler.game.move_SW

        elif libtcod.console_is_key_pressed(libtcod.KEY_KP3):
            return KeyHandler.game.move_SE

        elif libtcod.console_is_key_pressed(
                libtcod.KEY_KP5) or libtcod.console_is_key_pressed(
                    libtcod.KEY_5):
            return KeyHandler.game.move_5

        elif key.vk == libtcod.KEY_NONE:
            return KeyHandler.game.none

        else:
            return KeyHandler.game.other

    def wait_for_key(self):
        """wait for a key and return it"""
        return libtcod.console_wait_for_keypress(True)
Example #7
0
SHOW_MOVEMENT = False
SHOW_LEVEL_GEN = False
SHOW_RENDERING = False
SHOW_COMBAT = True
SHOW_AI = False


# error log switch
VERBOSITY_ERROR = True

# game log switch
VERBOSITY_GAME = True

# suppressor based on message class

types = enums.enum('cheats', 'movement', 'level_gen', 'rendering', 'input', 'ai', 'combat')

# rendering - rendering-related stuff (consoles, e.t.c.)
# input - various keypresses (actions)
# cheats - cheat codes
# level_gen - level generation
# ai - ai related stuff
# movement - movement and collisions
# combat - getting and receiving damage



def log(subtype, message):
	"""Output debug log message of given type"""
	if VERBOSITY_DEBUG:
		if subtype == types.cheats and not SHOW_CHEATS:
Example #8
0
import math
from datetime import date, datetime
from threading import Thread

from paperui.key_events import ExclusiveKeyReader
from paperui.core import *
from enums import enum
from paperui.keyboard import KeyTranslator
from paperui.text_wrapper import TextWrapper

align = enum(left=-1, center=0, right=1)


def visible_text(text, writable_length, alignment=align.left):
    if len(text) < writable_length:
        if alignment == align.left:
            return text.ljust(writable_length)
        elif alignment == align.right:
            return text.rjust(writable_length)
        elif alignment == align.center:
            return text.center(writable_length)
    else:
        return text[0:writable_length]


class WidgetSanityError(Exception):
    pass


class Connectable(object):
    def __init__(self):
Example #9
0
class Actor(Entity):
    """
	An entity that can act, take turns and have stats dict.
	act() is called by engine each turn
	ai component must be passed as a constant: entities.AI.ais.basic_monster

	* ai - ai to use
	* design - design to use (hardcoded for now, later can be loaded)
	* stats['hp'] - stats are a dict
	"""

    designs = enums.enum('orc', 'troll', 'player')

    def __init__(self, char, name, color, blocks, ai, design):

        # call Entity's constructor class to setup the child
        Entity.__init__(self, char, name, color, blocks)

        # setup ai (it is a component, so will need an owner)
        if ai == AI.ais.player_control:
            # this ai just asks player for input
            self.ai = PlayerControl(owner=self)
            logger.log(logger.types.ai,
                       "player_control ai assigned to " + self.name)

        elif ai == AI.ais.basic_monster:
            self.ai = BasicMonster(owner=self)
            logger.log(logger.types.ai,
                       "basic_monster ai assigned to " + self.name)

        else:
            logger.error("Can't pick an ai for an actor")

        # setup stats based on design, hardcoded (later take from data files)
        if design == Actor.designs.player:
            self.stats = dict(max_hp=30, hp=30, defense=2, power=5)
        elif design == Actor.designs.orc:
            self.stats = dict(max_hp=10, hp=10, defense=2, power=5)
        elif design == Actor.designs.troll:
            self.stats = dict(max_hp=16, hp=16, defense=1, power=4)
        else:
            logger.error("Can't pick design for an actor")

    def get_type(self):
        """	
		Returns own type of entity in Entity.types.*. 
		For now is used by main to call actor's act().
		"""
        return Entity.types.Actor

    def act(self, act_data):
        """
		This method is called each turn for all actors in the map.
		For now it only gets ai to work based on its type.
		
		act_data - dict containing all the stuff
		"""

        # for now we only need to call an ai properly
        ai_type = self.ai.get_type()

        if ai_type == AI.ais.player_control:
            # no inbound params for player
            result = self.ai.work(player_action=act_data['player_action'])

        elif ai_type == AI.ais.basic_monster:
            # we need to feed player and fov_map to it
            result = self.ai.work(player=act_data['player'],
                                  fov_map=act_data['fov_map'])

        else:
            logger.error('Unknown ai type')
            # skip its turn just in case
            result = True

        # true if turn was made, false if not
        return result

    def move(self, dx, dy):
        """move by the given amount"""
        # check if blocked by wall or entity
        if not self.zone.is_blocked(self.x + dx, self.y + dy):
            # not blocked, move there
            self.x += dx
            self.y += dy
            logger.log(logger.types.movement, self.name + " moved to " + str(
                (self.x, self.y)))
        else:
            # tile is blocked, let's try to bump into object!
            entity = self.zone.entity_at(self.x + dx, self.y + dy)
            if not entity is None:
                #it is an entity
                self.bump(entity)
            else:
                #it is a wall
                logger.log(logger.types.movement,
                           'The ' + self.name + ' bumps into a wall. Ugh.')
                pass

    def step_towards(self, target_x, target_y):
        """
		Moves one tile towards target coords
		"""
        #vector from this object to the target, and distance
        dx = target_x - self.x
        dy = target_y - self.y
        distance = math.sqrt(dx**2 + dy**2)

        #normalize it to length 1 (preserving direction), then round it and
        #convert to integer so the movement is restricted to the map grid
        dx = int(round(dx / distance))
        dy = int(round(dy / distance))
        self.move(dx, dy)

    def distance_to(self, other):
        """	Returns distance to another object """
        dx = other.x - self.x
        dy = other.y - self.y
        return math.sqrt(dx**2 + dy**2)

    def bump(self, ent):
        """bumps into an entity (this gets called for entities only, not for walls)"""
        # this should check for factions )
        # FIXME: attacking should be handled inside player! here only spontaneous collisions!
        # works only for actors.
        logger.log(logger.types.movement,
                   "Bump called for " + self.name + " and " + ent.name)

        if (ent.get_type() == Entity.types.Actor):
            # if player, attack any monster
            if (self.ai.get_type()
                    == AI.ais.player_control) and (ent.ai.get_type()
                                                   == AI.ais.basic_monster):
                self.attack(ent)

    def take_damage(self, damage):
        """apply damage if possible"""
        if damage > 0:
            self.stats['hp'] -= damage
            logger.log(
                logger.types.combat, self.name + ' now has ' +
                str(self.stats['hp']) + ' hp of ' + str(self.stats['max_hp']))

    def attack(self, target):
        """
		attack another actor
		convert to send_damage eventually
		"""
        #a simple formula for attack damage
        damage = self.stats['power'] - target.stats['defense']

        if damage > 0:
            #make the target take some damage
            logger.game(self.name.capitalize() + ' attacks ' + target.name +
                        ' for ' + str(damage) + ' hit points.')
            target.take_damage(damage)
        else:
            logger.game(self.name.capitalize() + ' attacks ' + target.name +
                        ' but it has no effect!')
Example #10
0
SHOW_CHEATS = True
SHOW_MOVEMENT = False
SHOW_LEVEL_GEN = False
SHOW_RENDERING = False
SHOW_COMBAT = True
SHOW_AI = False

# error log switch
VERBOSITY_ERROR = True

# game log switch
VERBOSITY_GAME = True

# suppressor based on message class

types = enums.enum('cheats', 'movement', 'level_gen', 'rendering', 'input',
                   'ai', 'combat')

# rendering - rendering-related stuff (consoles, e.t.c.)
# input - various keypresses (actions)
# cheats - cheat codes
# level_gen - level generation
# ai - ai related stuff
# movement - movement and collisions
# combat - getting and receiving damage


def log(subtype, message):
    """Output debug log message of given type"""
    if VERBOSITY_DEBUG:
        if subtype == types.cheats and not SHOW_CHEATS:
            return
Example #11
0
from PIL import Image, ImageFont, ImageDraw
from enums import enum
from paperui import ui
from paperui.core import *
from threading import Thread
import math

orientations = enum(landscape=0, portrait=1)


class Line(object):
    def __init__(self, text, size):
        self.text = text
        self.size = size


class Page(list):
    def __init__(self, size):
        list.__init__(self)
        self.size = size
        if self.size[0] < self.size[1]:
            self.orientation = orientations.portrait
        else:
            self.orientation = orientations.landscape

    def to_image(self, font, margin):
        image = Image.new("1", self.size, 1)
        drawer = ImageDraw.Draw(image)

        x, y = margin, 0