def canAttackPlayer(owner, playerLocation): if playerLocation is None: return False meRenderable = owner.world.component_for_entity( owner.entity, system.graphics.renderable.Renderable) meOffensiveAttack = owner.world.component_for_entity( owner.entity, system.gamelogic.offensiveattack.OffensiveAttack) currentWeaponHitArea = meOffensiveAttack.getCurrentWeaponHitArea() if Config.showEnemyWeaponHitCollisionDetectionTargets: for hitlocation in currentWeaponHitArea.hitCd: messaging.add( type=MessageType.EmitTextureMinimal, data={ 'char': 'X', 'timeout': 0.2, 'coordinate': hitlocation, 'color': Color.grey } ) # only one of the hitlocations need to hit for hitLocation in currentWeaponHitArea.hitCd: canAttack = Utility.isPointInArea( hitLocation, playerLocation) if canAttack: return True return False
def on_enter(self): meEnemy = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.gamelogic.enemy.Enemy) meGroupId = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.groupid.GroupId) messaging.add( type=MessageType.EntityAttack, groupId=meGroupId.getId(), data=None ) # self.attackTimer.setTimer(meEnemy.enemyInfo.attackTime) # self.setTimer(meEnemy.enemyInfo.attackTime) self.stepsTodo = 30 self.attackMoveTimer.init() self.attackMoveTimer.setTimer(0.1) self.setTimer(3.0) # even though we attack multiple times (each step) # only send EntityAttack once (change animation) messaging.add( type=MessageType.EntityAttack, groupId=meGroupId.getId(), data={} )
def checkDead(self): for ent, (ai, enemy) in self.world.get_components(Ai, Enemy): # remove enemies which are completely dead if ai.brain.state.name == 'dead': # first, add it again to the cache renderable = self.world.component_for_entity(ent, Renderable) groupId = self.world.component_for_entity(ent, GroupId) attackable = self.world.component_for_entity(ent, Attackable) offensiveAttack = self.world.component_for_entity(ent, OffensiveAttack) enemyCached = EnemyCached() enemyCached.groupId = groupId enemyCached.renderable = renderable enemyCached.tenemy = enemy enemyCached.attackable = attackable enemyCached.offensiveAttack = offensiveAttack self.objectCache.addObject(enemyCached) # delete it logger.info("Remove Entity G: {}".format(ent)) self.world.delete_entity(ent) # message everyone that it is really dead now messaging.add( type = MessageType.EntityDead, groupId = None, data = {} )
def handleOnHit(self, hitLocations, direction, byPlayer, sourceRenderable): for entity, renderable in self.world.get_component(Renderable): if renderable == sourceRenderable: continue isPlayer = self.world.has_component(entity, Player) isEnemy = self.world.has_component(entity, Enemy) if renderable.isHitBy(hitLocations): particleLocations = renderable.getHitLocationsOf(hitLocations) if not isPlayer and not isEnemy: # its environment. allow pass else: # enemy can attack player, and vice-versa if not byPlayer ^ isPlayer: continue for particleLocation in particleLocations: messaging.add(type=MessageType.EmitMirageParticleEffect, data={ 'location': particleLocation, 'effectType': ParticleEffectType.impact, 'damage': 0, 'byPlayer': True, 'direction': direction, })
def doAttack(self, renderable, damage): # attack location = renderable.getLocation() #hitcd = copy.deepcopy(renderable.texture.getCurrentFrame()) frame = renderable.texture.getCurrentFrame() hitcd = Utility.getListFromTexture(frame) weaponHitArea = WeaponHitArea(hitcd, width=len(frame[0]), height=len(frame)) direction = Direction.none Utility.updateCoordinateListWithBase(weaponHitArea=weaponHitArea, loc=location, direction=direction) damage = 10 messaging.add(type=MessageType.AttackAt, data={ 'hitLocations': hitcd, 'damage': damage, 'byPlayer': False, 'direction': direction, 'knockback': False, 'stun': False, 'sourceRenderable': renderable, })
def chooseDestination(self): meRenderable = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.graphics.renderable.Renderable) # if true: go to a static point close to the current enemy position # if false: go to a point relative to the enemy # self.destIsPoint = random.choice([True, False]) # note that getLocation() will return a reference. we need to copy it here. playerEntity = EntityFinder.findPlayer(self.brain.owner.world) if not playerEntity: return playerRenderable = self.brain.owner.world.component_for_entity( playerEntity, system.graphics.renderable.Renderable) self.destCoord = AiHelper.pickDestAroundPlayer( playerRenderable, distanceX=meRenderable.texture.width, distanceY=meRenderable.texture.height) if Config.showEnemyWanderDest: messaging.add( type=MessageType.EmitTextureMinimal, data={ 'char': '.', 'timeout': self.timer, 'coordinate': self.destCoord, 'color': Color.grey } )
def restartScene(self): self.currentScene.leave() self.currentScene.init() self.startScene() if self.currentScene.isShowPlayer: messaging.add(type=MessageType.GameStart, data={})
def skillPort(self): meRenderable = self.esperData.world.component_for_entity( self.esperData.entity, system.graphics.renderable.Renderable) meGroupId = self.esperData.world.component_for_entity( self.esperData.entity, system.groupid.GroupId) moveX = 0 if meRenderable.direction is Direction.left: moveX = -self.data[SkillType.port]['distance'] if meRenderable.direction is Direction.right: moveX = self.data[SkillType.port]['distance'] # emit effect on old place locCenter = meRenderable.getLocationCenter() messaging.add( type=MessageType.EmitParticleEffect, data= { 'location': locCenter, 'effectType': ParticleEffectType.disappear, 'damage': 0, 'byPlayer': True, 'direction': Direction.none, } ) directmessaging.directMessaging.add( type = directmessaging.DirectMessageType.movePlayer, groupId = meGroupId.getId(), data = { 'x': moveX, 'y': 0, 'dontChangeDirection': False, 'whenMoved': "showAppearEffect", # emit effect on new place } )
def spawnEnemy(self, enemyCell): if enemyCell.spawnX % 2 != 0: logger.warning("Spawn enemy at uneven location!") messaging.add( type=MessageType.SpawnEnemy, data=enemyCell, )
def spawnPlayer(self): coordinates = Coordinates(24, 13) messaging.add( type=MessageType.SpawnPlayer, data={ 'coordinates': coordinates }, )
def adjustViewport(self, xoff): viewportChanged = self.viewport.adjustViewport(xoff) if viewportChanged: messaging.add( type=MessageType.ScreenMove, data={ 'x': xoff, }, )
def showBurst(self): messaging.add(type=MessageType.EmitParticleEffect, data={ 'location': Coordinates(10, 10), 'effectType': ParticleEffectType.hitBurst, 'damage': 0, 'byPlayer': True, 'direction': Direction.left, })
def moveRenderable(self, renderable, groupId, x: int = 0, y: int = 0, dontChangeDirection: bool = False, updateTexture: bool = True) -> bool: """Move this renderable in x/y direction, if map allows. Update direction too""" didMove = False didChangeDirection = False if x > 0: if (renderable.canMoveOutsideMap or renderable.coordinates.x + x < self.mapManager.getCurrentMapWidth()): renderable.coordinates.x += x didMove = True if (not dontChangeDirection and renderable.direction is not Direction.right): renderable.setDirection(Direction.right) didChangeDirection = True elif x < 0: if (renderable.canMoveOutsideMap or renderable.coordinates.x + x > 1): renderable.coordinates.x += x didMove = True if (not dontChangeDirection and renderable.direction is not Direction.left): renderable.setDirection(Direction.left) didChangeDirection = True if y > 0: if (renderable.canMoveOutsideMap or renderable.coordinates.y < Config.rows - renderable.texture.height - 1): renderable.coordinates.y += y didMove = True elif y < 0: if (renderable.canMoveOutsideMap or renderable.coordinates.y > Config.areaMoveable['miny'] - renderable.texture.height + 1): renderable.coordinates.y += y didMove = True if updateTexture: # notify texture manager messaging.add(groupId=groupId, type=MessageType.EntityMoved, data={ 'didChangeDirection': didChangeDirection, 'x': x, 'y': y, }) return didMove
def on_enter(self): self.canAttackTimer.setTimer(2.0) meGroupId = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.groupid.GroupId) messaging.add( type=MessageType.EntityStanding, groupId=meGroupId.getId(), data=None )
def updateRenderableDirection(self, renderable, direction, groupId): renderable.setDirection(direction) # notify texture manager messaging.add(groupId=groupId, type=MessageType.EntityMoved, data={ 'didChangeDirection': True, 'x': 0, 'y': 0, })
def makeStep(self, dt, adjustLife=True): if self.life <= 0: self.active = False return if self.fadeout: self.fadeoutSetColor() self.setChar() if self.speed > 0: xFloat = self.velocity['x'] * (dt * 100) + self.rx yFloat = self.velocity['y'] * (dt * 100) + self.ry xChange = int(round(xFloat)) yChange = int(round(yFloat)) # accumulate pos we could not handle yet changeRestX = xFloat - xChange - self.rx changeRestY = yFloat - yChange - self.ry self.rx += changeRestX self.ry += changeRestY # change pos self.x += xChange self.y += yChange if (self.damageEveryStep and self.damage > 0 and (xChange != 0 or yChange != 0)): # hitLocations = [Coordinates(self.x, self.y)] hitLocations = [] hitLocations.append(self) messaging.add( type=MessageType.AttackAt, data= { 'hitLocations': hitLocations, 'damage': self.damage, 'byPlayer': self.byPlayer, 'direction': Direction.none, 'knockback': False, 'stun': False, 'sourceRenderable': None, } ) if False: logging.info("Real change: X: {} Y: {}".format(xFloat, yFloat)) logging.info("Round change: X: {} Y: {}".format(xChange, yChange)) logging.info("Change Rest: X: {} Y: {}".format(changeRestX, changeRestY)) logging.info("New Rest: X: {} Y: {}".format(self.rx, self.ry)) logging.info("New Pos: X: {} Y: {}".format(self.x, self.y)) if adjustLife: self.life -= 1
def on_enter(self): meGroupId = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.groupid.GroupId) meEnemy = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.gamelogic.enemy.Enemy) messaging.add(type=MessageType.attackWindup, groupId=meGroupId.getId(), data=None) self.setTimer(meEnemy.enemyInfo.attackWindupTime)
def spawnDragon(self): coordinates = Coordinates(30, 7) enemyCell = EnemyCell(id=1, enemyType=EnemyType.dragon, spawnTime=None, spawnX=0, spawnLocation=coordinates, spawnDirection=Direction.left) messaging.add( type=MessageType.SpawnEnemy, data=enemyCell, )
def showBuckler(self): weaponData = fileOffenseLoader.weaponManager.getWeaponData( WeaponType.buckler) self.attackWithWeapon(weaponData, physics=True) location = self.getWeaponBaseLocation(weaponData) messaging.add( MessageType.Defense, data={ 'location': location, 'groupId': 0, # TODO: Real groupid here, not just player })
def createDamage(self, hitLocations, damage, byPlayer, direction): messaging.add( type=MessageType.AttackAt, data= { 'hitLocations': hitLocations, 'damage': damage, 'byPlayer': byPlayer, 'direction': direction, 'knockback': False, 'stun': False, 'sourceRenderable': None, } )
def startScene(self): self.viewport.reset() self.currentScene.enter() if self.currentScene.hasEnvironment: # Environment is current listing for screenmove messages, which # are only in maps (not intro etc.) messaging.add( type=MessageType.ScreenMove, data={ 'x': 0, }, )
def trySkill(self): if self.canSkillTimer.timeIsUp(): meRenderable = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.graphics.renderable.Renderable) locCenter = meRenderable.getLocationCenter() messaging.add(type=MessageType.EmitParticleEffect, data={ 'location': locCenter, 'effectType': ParticleEffectType.dragonExplosion, 'damage': 50, 'byPlayer': False, 'direction': Direction.none, }) self.canSkillTimer.reset()
def advance(self, dt): for ent, (meAttackable, meGroupId) in self.world.get_components(Attackable, GroupId): # advance timers meAttackable.advance(dt) # check if stun is finished if meAttackable.stunTimer.timeIsUp(): meAttackable.isStunned = False meAttackable.stunTimer.stop() # generate end-stun message (for animation) messaging.add(type=MessageType.EntityEndStun, groupId=meGroupId.getId(), data={})
def checkReceiveDamageMessages(self): for msg in directMessaging.getByType(DirectMessageType.receiveDamage, keep=True): sourceRenderable = msg.data['sourceRenderable'] destinationEntity = msg.data['destinationEntity'] if sourceRenderable is None: # not applicable continue if not self.world.has_entity(destinationEntity): # already gone continue if self.world.has_component(destinationEntity, Defense): defense = self.world.component_for_entity( destinationEntity, Defense) if not defense.isActive: continue destinationRenderable = self.world.component_for_entity( destinationEntity, Renderable) distanceDefense = Utility.distance( sourceRenderable.coordinates, defense.coordinates) distanceEnemy = Utility.distance( sourceRenderable.coordinates, destinationRenderable.coordinates) if distanceDefense['sum'] < distanceEnemy['sum']: msg.data['damage'] = 0 # msg.data['mitigated'] = True messaging.add( type=MessageType.EmitMirageParticleEffect, data={ 'location': destinationRenderable.getLocationTopCenter(), 'effectType': ParticleEffectType.floatingDamage, 'damage': 'Blocked', 'byPlayer': None, 'direction': Direction.none, })
def showDestAroundPlayer(self): playerEntity = EntityFinder.findPlayer(self.world) meRenderable = self.world.component_for_entity( playerEntity, system.graphics.renderable.Renderable) destCoord = AiHelper.pickDestAroundPlayer( meRenderable, distanceX=meRenderable.texture.width, distanceY=meRenderable.texture.height) messaging.add(type=MessageType.EmitTextureMinimal, data={ 'char': '.', 'timeout': 10.0, 'coordinate': destCoord, 'color': Color.grey })
def emitParticleEffect(self, loc, particleEffect): messaging.add(type=MessageType.EmitParticleEffect, data={ 'location': loc, 'effectType': particleEffect, 'damage': 0, 'byPlayer': True, 'direction': Direction.none, }) messaging.add(type=MessageType.EmitTextureMinimal, data={ 'char': 'X', 'timeout': 1, 'coordinate': loc, 'color': Color.grey })
def skillCleave(self): meRenderable = self.esperData.world.component_for_entity( self.esperData.entity, system.graphics.renderable.Renderable) locCenter = meRenderable.getLocationCenter() damage = fileOffenseLoader.skillManager.getSkillData(SkillType.cleave).damage particleEffectType = fileOffenseLoader.skillManager.getSkillData( SkillType.cleave).particleEffectType messaging.add( type=MessageType.EmitParticleEffect, data= { 'location': locCenter, 'effectType': particleEffectType, 'damage': damage, 'byPlayer': True, 'direction': meRenderable.direction, } )
def skillBlock(self): meRenderable = self.esperData.world.component_for_entity( self.esperData.entity, system.graphics.renderable.Renderable) locCenter = meRenderable.getAttackBaseLocation() locCenter.y -= 2 # FIXME base on skillBlock.yaml # damage = fileOffenseLoader.skillManager.getSkillData(SkillType.block).damage phenomenaType = fileOffenseLoader.skillManager.getSkillData( SkillType.block).phenomenatexture messaging.add( type=MessageType.EmitPhenomenaTexture, data={ 'phenomenaTextureType': phenomenaType, 'location': locCenter, 'staticLocation': False, 'direction': meRenderable.direction, 'physics': True, } )
def tryShooting(self): if self.attackingTimer.timeIsUp(): self.brain.pop() self.brain.push('standing') if self.cooldownTimer.timeIsUp(): meRenderable = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.graphics.renderable.Renderable) locCenter = meRenderable.getAttackBaseLocation() messaging.add(type=MessageType.EmitParticleEffect, data={ 'location': locCenter, 'effectType': ParticleEffectType.bullet, 'damage': 50, 'byPlayer': False, 'direction': meRenderable.getDirection(), }) self.cooldownTimer.reset()
def on_enter(self): self.cooldownTimer.setTimer(0.5) self.attackingTimer.setTimer(4.0) playerEntity = EntityFinder.findPlayer(self.brain.owner.world) if playerEntity is None: return meRenderable = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.graphics.renderable.Renderable) meGroupId = self.brain.owner.world.component_for_entity( self.brain.owner.entity, system.groupid.GroupId) self.turnIfNecessary(playerEntity, meRenderable, meGroupId) # attack messaging.add(type=MessageType.EntityAttack, groupId=meGroupId.getId(), data=None)