b8f124a1 |
from src import events
|
5f75058b |
import abc
|
ac4ad8e3 |
import collections
|
dff12016 |
from . import combat
|
5f75058b |
class Overlay(object):
|
dff12016 |
__metaclass__ = abc.ABCMeta
|
5f75058b |
char = abc.abstractproperty()
color = (0,0,0)
blocks = False
@property
def pos(self):
return self.x, self.y
def __init__(self, x,y, map):
|
df36dce5 |
super(Overlay, self).__init__()
|
b8f124a1 |
print self.handled_events
|
ac4ad8e3 |
self.events = collections.OrderedDict()
|
5f75058b |
self.x = x
self.y = y
self.map = map
|
ac4ad8e3 |
for key, value in self.handled_events.viewitems():
self.events.setdefault(key, []).extend(value)
|
86f3fea2 |
def draw(self):
self.map.add(self)
|
5f75058b |
|
ac4ad8e3 |
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):
|
df36dce5 |
for cb in self.events.get(event, []):
|
ac4ad8e3 |
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
|
b8f124a1 |
@staticmethod
def add_event(event, cb_name):
def _inner(cls):
if not hasattr(cls, 'handled_events'):
cls.handled_events = {}
for base in cls.bases:
if hasattr(base, 'handled_events'):
cls.handled_events.update(base.handled_events)
cls.handled_events.setdefault(event, []).append(getattr(cls, cb_name))
return cls
|
ac4ad8e3 |
return _inner
|
b8f124a1 |
def tick(self):
pass
|
ac4ad8e3 |
|
5f75058b |
|
b8f124a1 |
@Overlay.add_event('attacked', 'attacked_by')
@Overlay.add_event('bumped', 'bumped_by')
|
5f75058b |
class Actor(Overlay):
char = ord('@')
color = (255,0,0)
blocks = True
|
b8f124a1 |
handled_events = collections.OrderedDict()
|
5f75058b |
@property
def pos(self):
return self.x, self.y
def __init__(self, x,y, map, adventurer=None):
|
ac4ad8e3 |
super(Actor, self).__init__(x,y, map)
self.inventory = []
|
dff12016 |
if adventurer is None:
adventurer = combat.Adventurer.randomize()
self.adventurer = adventurer
|
b8f124a1 |
self.repeated_actions = {}
|
5f75058b |
|
b8f124a1 |
def add_repeated_action(self, time, action, *args, **kw):
print 'adding action', action, args, kw
self.repeated_actions.setdefault(time, []).append( (action, args, kw) )
def update_pos(self, dx,dy):
|
5f75058b |
self.x += dx
self.y += dy
|
b8f124a1 |
def move(self, dx, dy):
print 'moving'
self.map.move(self, dx,dy, self.update_pos)
|
5f75058b |
def tick(self):
|
86f3fea2 |
result = True
if self.adventurer.state >= 2:
result = False
self.char = ord('%')
self.blocks = False
|
b8f124a1 |
else:
|
df36dce5 |
self.act()
|
b8f124a1 |
ractions = {}
for nleft, actions in self.repeated_actions.items():
for (action,args,kwargs) in actions:
print action,args,kwargs
action(*args, **kwargs)
if nleft > 1:
ractions.setdefault(nleft-1, []).append( (action,args,kwargs) )
|
df36dce5 |
print ractions
|
b8f124a1 |
self.repeated_actions = ractions
|
86f3fea2 |
return result
|
5f75058b |
|
df36dce5 |
def act(self): pass
|
dff12016 |
def ishostile(self, other):
|
ac4ad8e3 |
return self.adventurer.state < 2 #TODO: implement factions
|
dff12016 |
|
5f75058b |
def bump(self, other):
print '%s bumped %s' % (type(self).__name__, type(other).__name__)
|
dff12016 |
if isinstance(other, Actor) and other.ishostile(self):
self.adventurer.attack(other.adventurer)
|
ac4ad8e3 |
other.trigger_event('attacked', self)
|
b8f124a1 |
def interact(self, other):
result = False
if isinstance(other, Object):
result = True
|
ac4ad8e3 |
self.pickup(other)
other.trigger_event('picked_up', self)
|
dff12016 |
|
ac4ad8e3 |
other.trigger_event('bumped', self)
|
b8f124a1 |
return result
def pickup(self, other):
self.inventory.append(other)
|
ac4ad8e3 |
|
dff12016 |
def attacked_by(self, other):
|
86f3fea2 |
if self.adventurer.skills.check('agility'):
|
dff12016 |
self.adventurer.attack(other.adventurer)
|
5f75058b |
def bumped_by(self, other):
print '%s was bumped by %s' % (type(self).__name__, type(other).__name__)
|
df36dce5 |
import random
class AIActor(Actor):
def act(self):
print 'wiggly %s' % self.adventurer.name
self.move(random.choice([-1,0,1]), random.choice([-1,0,1]))
|
b8f124a1 |
@Overlay.add_event('picked_up', 'picked_up_by')
@Overlay.add_event('bumped', 'bumped_by')
|
5f75058b |
class Object(Overlay):
|
ac4ad8e3 |
item = None
|
b8f124a1 |
handled_events = collections.OrderedDict()
|
ac4ad8e3 |
def picked_up_by(self, other):
|
b8f124a1 |
events.EventHandler().trigger_event('msg', 'picked up a %s' % self)
|
ac4ad8e3 |
self.map.remove(self)
|
b8f124a1 |
def bumped_by(self, other): pass
|
5f75058b |
|
ac4ad8e3 |
class Weapon(Object):
item = None
|
5f75058b |
class Potion(Object):
char = ord('!')
|
b8f124a1 |
def __str__(self): return 'potion'
|
ac4ad8e3 |
|
5f75058b |
class Scroll(Object):
char = ord('!')
|
ac4ad8e3 |
class Equipment(Object):
pass
|