def do_dropoff(self): res = self.pickup.resource info(f'droped off {self.carrying} resources') self.dropoff.harveststore.dropoff(res, self.carrying) self.carrying = 0 self.dropoff = None
def write_variable(self, eid, var, op, val): info('write variable', eid, op, val) ent = self.entities.get(eid) if ent.has('variables'): if op == 'set': ent.variables[var] = int(val) elif op == 'add': ent.variables[var] += int(val)
def place_entity_near(self, eid, me): info('placing %d near %d' % (eid, me)) ent = self.entities.get(eid) meent = self.entities.get(me) x, y = meent.locator.pos() ent.locator.place(x + meent.locator.r, y)
def construct(self, name, *args, **kwargs): info('constructing {0}', name) cls = getcomponentclass(name) if _scopes[name] != 'dynamic': error('component {} cannot be runtime constructed (scope is {})', name, _scopes[name]) raise RuntimeError('dependency injection failed') inst = cls(*args, **kwargs) kwargs = get_inject_kwargs(inst, self.instances) trace('injecting {0}', inst.__class__.__name__) inst.inject(**kwargs) return inst
def complete_construction(self): info('entity %d completing constructions of %s' % (self.ent.eid, self.proto.name)) self.ent.locator.replace() em = self.ent.constructor.entitymanager em.destroy(self.construction_site.eid) building = em.create(self.proto) if self.oncomplete: self.oncomplete(building.eid) building.locator.place(*self.ent.locator.pos()) self.done() self.ent.actions.now(PostConstructAction(building))
def construct(name): info('constructing {0}', name) # find all the dependencies - transitive deps = set([name]) while 1: newdeps = set(deps) for c in deps: cls = getcomponentclass(c) for d in get_deps(cls): newdeps.add(d) if newdeps == deps: break deps = newdeps # construct the component classes components = {} for cname in deps: cls = getcomponentclass(cname) if _scopes[cname] != 'singleton': error( 'component {} cannot be constructed at global level ' '(scope is {})', cname, _scopes[cname]) raise RuntimeError('dependency injection failed') trace('creating {0}', cname) components[cname] = cls() # we expect that someone depends on this c = components['components'] c.instances = components # perform the injection for comp in list(components.values()): kwargs = get_inject_kwargs(comp, components) trace('injecting {0}', comp.__class__.__name__) comp.inject(**kwargs) info('done') return components[name]
def __del__(self): info('entity %r is being deleted' % self)
def ability(self, idx, add): info(f'trying to do ability {idx}') ''' Do the ability at idx for the currently selected entities ''' if not self.selection: # nothing selected warn('no selection') return # grab the ability - defined by the first entity in the selection ent = self.selection[0] if not ent.has('abilities'): # no abilities warn('entity has no abilities') return if not ent.ownedby(self.local.player): # should never happen, player doesn't own the entity warn('entity not owned by local player') return try: ability = ent.abilities[idx].ability except IndexError: error('index out of bounds') return # get the ents - non group abilities cannot be done by # multiple entities so we pick the first if not ability.group: entids = [ent.eid] else: entids = [e.eid for e in self.selection] # verify if there are any entities in the selection that can actually # do the ability right now # * do they have the same ability - for now we compare the protos # * enough resourcea # * cooldowns not active # NOTE this is a Game check, the Engine will check again when activating def check_ability(eid): e = self.engine.entities.get(eid) if not e.has('abilities'): error('entity has no abilities') return False try: ainst = e.abilities[idx] except IndexError: error('index out of bounds - entity doesn\'t havethis ability') return False if e.proto.epid != ent.proto.epid: warn('entity does not have ability {0}', ability.name) return False if ainst.cooldown > 0: warn('not ready - game checked it') return False if not ability.queue and ainst.wait > 0: warn('already doing this - game checked it') return False #if not ability.check_cost(e): # warn('cannot pay cost - game checked it') # return False return True entids = [eid for eid in entids if check_ability(eid)] if not entids: warn('no entities can do the ability now') self.gamelog.log('No units can do this ability right now') return # create the order order = AbilityOrder(entids, idx, add) # based on ability type we either issue an order # or enter a new mode if ability.type == ability.INSTANT: order.add = True # instants never interrupt the current action self.order(order) elif ability.type == ability.ACTIVITY: self.order(order) elif ability.type == ability.TARGETED: self.modes.push_mode('targetingmode', order, allowpos=False) elif ability.type == ability.BUILD: proto = ent.team.getproto(ability.proto) self.modes.push_mode('buildmode', order, proto) elif ability.type == ability.AREA_OF_EFFECT: self.modes.push_mode('targetingmode', order) elif ability.type == ability.STATIC: pass # do nothing else: raise RuntimeError('unknown ability type!')
def exit(self): info('exited targeting mode')
def enter(self): info('entered targeting mode')
def place_entity(self, eid, x, y): info('placing %d at (%d, %d)' % (eid, x, y)) ent = self.entities.get(eid) ent.locator.place(x, y)
def log(self, msg, *args): ''' Print a message to the console log ''' info(msg, *args)
def destroy(self, eid): info('destroying ', eid) self.entities.destroy(eid)
def handle_ready(self, msg): info('master got ready message: waiting={}', self.waiting) self.waiting -= 1 if self.waiting == 0: self.send_startgame() self.net.ongamestart.emit()
def _docreate(self, proto, eid=None): '''Create an entity from a proto - implementation method''' info('creating {0}', proto.name) if eid is None: eid = self.nextentid self.nextentid += 1 ent = Entity(eid, proto) self.newentities[eid] = ent # loop until the deps stop changing (when we find all the dependencies) deps = set(proto.components) while 1: newdeps = set(deps) for c in deps: if c[0] == '@': continue cls = getcomponentclass(c) for d in cls.depends: newdeps.add(d) if newdeps == deps: break deps = newdeps # construct the component classes for cname in deps: if cname[0] != '@': cls = getcomponentclass(cname) cls(ent) # TODO - tie this with the real global components globalcomponents = { 'sprites': self.eng.sprites, 'map': self.eng.map, 'datasrc': self.eng.datasrc, 'entitymanager': self, 'content': self.eng.content, 'pathfinder': self.eng.pathfinder, 'engine': self.eng, 'collisions': self.collisions, 'scripting': self.eng.scripting, 'team': proto.team } # perform the injection for cname in deps: if cname[0] != '@': cls = getcomponentclass(cname) comp = ent.components[cname] args = {} for c in cls.depends: if c[0] == '@': args[c[1:]] = globalcomponents[c[1:]] else: args[c] = ent.components[c] comp.inject(**args) # configure the new entity ent.configure() self.onentitycreated.emit(ent) return ent
def start(self): info('gamestate starting!') self.state = GameState.RUNNING