git.fiddlerwoaroof.com
Raw Blame History
import abc
import collections
from . import combat

class Overlay(object):
	__metaclass__ = abc.ABCMeta

	char = abc.abstractproperty()
	color = (0,0,0)
	blocks = False

	@property
	def pos(self):
		return self.x, self.y
	def __init__(self, x,y, map):
		self.events = collections.OrderedDict()
		self.x = x
		self.y = y
		self.map = map
		for key, value in self.handled_events.viewitems():
			self.events.setdefault(key, []).extend(value)

	def draw(self):
		self.map.add(self)

	def register_event(self, event, cb):
		'''register a callback for an event

		if the callback returns a false value besides None, execution will end after that event'''
		self.events.setdefault(event, []).append(cb)

	def trigger_event(self, event, *args, **kw):
		if event not in self.events:
			raise ValueError('%r has no event %r' % (self, event))

		for cb in self.events[event]:
			result = cb(self, *args, **kw)
			result = result is None or result # if the event returns a false value besides None, break
			if result == False: break

	handled_events = collections.OrderedDict()
	@classmethod
	def handle_event(cls, event):
		def _inner(cb):
			cls.handled_events.setdefault(event, []).append(cb)
			return cb
		return _inner



class Actor(Overlay):
	char = ord('@')
	color = (255,0,0)
	blocks = True

	@property
	def pos(self):
		return self.x, self.y

	def __init__(self, x,y, map, adventurer=None):
		super(Actor, self).__init__(x,y, map)
		self.inventory = []
		if adventurer is None:
			adventurer = combat.Adventurer.randomize()
		self.adventurer = adventurer

	def move(self, dx, dy):
		dx, dy = self.map.move(self, dx,dy)
		self.x += dx
		self.y += dy

	def tick(self):
		result = True
		if self.adventurer.state >= 2:
			result = False
			self.char = ord('%')
			self.blocks = False
		return result

	def ishostile(self, other):
		return self.adventurer.state < 2 #TODO: implement factions

	def bump(self, other):
		print '%s bumped %s' % (type(self).__name__, type(other).__name__)
		if isinstance(other, Actor) and other.ishostile(self):
			self.adventurer.attack(other.adventurer)
			other.trigger_event('attacked', self)
		elif isinstance(other, Object):
			self.pickup(other)
			other.trigger_event('picked_up', self)

		other.trigger_event('bumped', self)

	@Overlay.handle_event('attacked')
	def attacked_by(self, other):
		if self.adventurer.skills.check('agility'):
			self.adventurer.attack(other.adventurer)

	@Overlay.handle_event('bumped')
	def bumped_by(self, other):
		print '%s was bumped by %s' % (type(self).__name__, type(other).__name__)

class Object(Overlay):
	item = None
	@Overlay.handle_event('picked_up')
	def picked_up_by(self, other):
		self.map.remove(self)

class Weapon(Object):
	item = None

class Potion(Object):
	char = ord('!')

class Scroll(Object):
	char = ord('!')

class Equipment(Object):
	pass