Ejemplo n.º 1
0
    def getInputChase(self):
        meGroupId = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.groupid.GroupId)
        meRenderable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.graphics.renderable.Renderable)

        if not Config.allowEnemyMovement:
            return

        moveX, moveY, dontChangeDirection = AiHelper.getAttackVectorToPlayer(
            self.owner, meRenderable)

        # only move if we really move a character
        if moveX != 0 or moveY != 0:
            directMessaging.add(
                groupId=meGroupId.getId(),
                type=DirectMessageType.moveEnemy,
                data={
                    'x': moveX,
                    'y': moveY,
                    'dontChangeDirection': dontChangeDirection,
                    'updateTexture': True,
                    'force': False,
                },
            )
Ejemplo n.º 2
0
    def turnIfNecessary(self, playerEntity, meRenderable, meGroupId):
        playerRenderable = self.brain.owner.world.component_for_entity(
            playerEntity, system.graphics.renderable.Renderable)
        x, y = AiHelper.getVectorToPlayer(source=meRenderable.coordinates,
                                          dest=playerRenderable.getLocation())

        if x > 0:
            playerDir = Direction.right
            cx = 1
        else:
            playerDir = Direction.left
            cx = -1

        if playerDir is not meRenderable.getDirection():
            directMessaging.add(
                groupId=meGroupId.getId(),
                type=DirectMessageType.moveEnemy,
                data={
                    'x': cx,
                    'y': 0,
                    'dontChangeDirection': False,
                    'updateTexture': False,
                    'force': False,
                },
            )
Ejemplo n.º 3
0
    def process(self, dt):
        self.dmgTimer.advance(dt)
        if self.dmgTimer.timeIsUp():
            damageStat.addDamage(-10)
            self.dmgTimer.reset()

        damageSumPlayer = 0
        for msg in messaging.getByType(MessageType.AttackAt):
            for entity, (meAtk, groupId, renderable) in self.world.get_components(
                Attackable, GroupId, Renderable
            ):
                hitLocations = msg.data['hitLocations']
                damage = msg.data['damage']
                byPlayer = msg.data['byPlayer']
                direction = msg.data['direction']
                knockback = msg.data['knockback']
                stun = msg.data['stun']

                if 'sourceRenderable' in msg.data:
                    sourceRenderable = msg.data['sourceRenderable']
                else:
                    sourceRenderable = None

                if renderable.isHitBy(hitLocations):
                    directMessaging.add(
                        groupId=groupId.id,
                        type=DirectMessageType.receiveDamage,
                        data={
                            'damage': damage,
                            'byPlayer': byPlayer,
                            'direction': direction,
                            'knockback': knockback,
                            'stun': stun,

                            'sourceRenderable': sourceRenderable,
                            'destinationEntity': entity,
                            'hitLocations': hitLocations,
                        }
                    )

                    if byPlayer:
                        damageSumPlayer += damage

        # check if we should announce our awesomeness
        if damageSumPlayer > Config.announceDamage:
            # find player
            for ent, (groupId, player) in self.world.get_components(
                GroupId, Player
            ):
                directMessaging.add(
                    groupId = groupId.getId(),
                    type = DirectMessageType.activateSpeechBubble,
                    data = {
                        'text': 'Cowabunga!',
                        'time': 1.0,
                    }
                )

        damageStat.addDamage(damageSumPlayer)
Ejemplo n.º 4
0
    def process(self, dt):
        self.attackMoveTimer.advance(dt)

        # check if we got stunned
        meAttackable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.attackable.Attackable)
        if meAttackable.isStunned:
            self.brain.pop()
            self.brain.push("chase")

        # check if we should do one attack step
        if self.attackMoveTimer.timeIsUp():
            logger.info("{}: I'm attacking, step {}".format(self.owner, self.stepsTodo))

            if self.stepsTodo > 0:
                self.attackMoveTimer.reset()
                self.stepsTodo -= 1

                meRenderable = self.brain.owner.world.component_for_entity(
                    self.brain.owner.entity, Renderable)
                meGroupId = self.brain.owner.world.component_for_entity(
                    self.brain.owner.entity, system.groupid.GroupId)

                if self.stepsTodo % 2 == 0:
                    offensiveAttack = self.brain.owner.world.component_for_entity(
                        self.brain.owner.entity, OffensiveAttack)
                    offensiveAttack.attack()

                if meRenderable.direction is Direction.left:
                    x = -1
                else:
                    x = 1
                directMessaging.add(
                    groupId = meGroupId.getId(),
                    type = DirectMessageType.moveEnemy,
                    data = {
                        'x': x,
                        'y': 0,
                        'dontChangeDirection': False,
                        'updateTexture': False,
                        'force': True
                    },
                )
            else:
                self.attackMoveTimer.stop()

        if self.timeIsUp():
            # too long attacking. lets switch to chasing
            logger.info("{}: Too long attacking, switch to chasing".format(
                self.owner))
            self.brain.pop()
            self.brain.push("chase")
Ejemplo n.º 5
0
    def advance(self, dt):
        self.time += dt

        if len(self.speechBubbles) > 0:
            speechEntry = self.speechBubbles[0]
            if self.time > speechEntry['timeSpawn']:
                playerEnt = EntityFinder.findPlayer(self.world)
                playerGroupId = self.world.component_for_entity(
                    playerEnt, system.groupid.GroupId)

                directMessaging.add(
                    groupId = playerGroupId.getId(),
                    type = DirectMessageType.activateSpeechBubble,
                    data = {
                        'text': speechEntry['text'],
                        'time': speechEntry['timeShow'],
                        'waitTime': 0,
                    }
                )
                self.speechBubbles.pop(0)
Ejemplo n.º 6
0
    def getInputWander(self):
        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)

        if not Config.allowEnemyMovement:
            return

        x, y = AiHelper.getVectorToPlayer(
            source=meRenderable.coordinates, dest=self.destCoord)

        directMessaging.add(
            groupId = meGroupId.getId(),
            type = DirectMessageType.moveEnemy,
            data = {
                'x': x,
                'y': y,
                'dontChangeDirection': False,
                'updateTexture': True,
                'force': False,
            },
        )
Ejemplo n.º 7
0
    def process(self, dt):
        self.screenMoveTimer.advance(dt)
        self.gameoverTimer.advance(dt)

        for message in messaging.getByType(MessageType.Gameover):
            self.gameoverTimer.reset()
            self.gameoverTimer.start()
            self.setState(State.gameover)
            messaging.add(type=MessageType.EmitPhenomenaTexture,
                          data={
                              'phenomenaTextureType': PhenomenaType.gameover,
                              'location': Coordinates(10, 10),
                              'staticLocation': True,
                              'direction': Direction.right,
                              'physics': False,
                          })

        if self.state is State.gameover:
            for message in messaging.getByType(MessageType.PlayerKeypress):
                if self.gameoverTimer.timeIsUp():
                    messaging.add(type=MessageType.ClearRenderables, data={})

                    self.setState(State.start)
        elif self.state is State.start:
            self.sceneManager.restartScene()
            self.setState(State.brawl)

        for message in messaging.getByType(MessageType.EntityDying):
            # if no enemies are alive, we want to go to the next akt
            if self.numEnemiesAlive() == 0:
                self.screenMoveTimer.start()

                if self.state is not State.gameover:
                    self.setState(State.pushToNextScene)
            break

        for message in messaging.getByType(MessageType.PlayerLocation):
            self.lastKnownPlayerPos = message.data

            if self.state is State.pushToNextScene:
                # if suddenly enemies appear, let the player free
                if self.numEnemiesVisible() > 0:
                    self.setState(State.brawl)

            if self.state is State.brawl:
                if (self.numEnemiesVisible() == 0 and
                        not self.enemiesLeftOfChar(self.lastKnownPlayerPos.x)):
                    self.screenMoveTimer.start()
                    self.setState(State.pushToEnemies)

            if self.state is State.pushToEnemies:
                if self.numEnemiesVisible() > 0:
                    self.setState(State.brawl)

            playerScreenCoords = self.viewport.getScreenCoords(message.data)

            # adjust viewport on move
            if self.state is State.pushToNextScene:
                # screen follows player
                # player is left side of screen (screen pushes player right)
                if playerScreenCoords.x != 10:
                    distance = int(playerScreenCoords.x - 10)
                    if distance < 0:
                        self.adjustViewport(-1)
                        self.screenMoveTimer.reset()
                    elif distance > 0:
                        self.adjustViewport(1)
                        self.screenMoveTimer.reset()

            elif self.state is State.pushToEnemies:
                # screen follows player
                # player is middle of the screen
                if playerScreenCoords.x != self.xCenter:
                    distance = int(playerScreenCoords.x - self.xCenter)
                    if distance < 0:
                        self.adjustViewport(-1)
                        self.screenMoveTimer.reset()
                    elif distance > 0:
                        self.adjustViewport(1)
                        self.screenMoveTimer.reset()

            elif self.state is State.brawl:
                if not self.enemiesLeftOfChar(self.lastKnownPlayerPos.x):
                    # player can move freely
                    # coming close to left/right of the screen will move it
                    if playerScreenCoords.x >= Config.moveBorderRight:
                        distance = playerScreenCoords.x - Config.moveBorderRight
                        self.adjustViewport(distance)
                    if playerScreenCoords.x <= Config.moveBorderLeft:
                        distance = playerScreenCoords.x - Config.moveBorderLeft
                        self.adjustViewport(distance)
            # /adjust viewport on move

            # let the scene decide if we need more enemies
            self.sceneManager.currentScene.handlePosition(
                message.data, self.viewport.getx(), self.numEnemiesAlive())

        for message in messaging.getByType(MessageType.PlayerKeypress):
            key = message.data['key']
            self.sceneManager.handlePlayerKeyPress(key)

            if key == ord('k'):
                logger.info("Scene: Kill All Enemies")
                self.killAllEnemies()

            if key == ord('n'):
                logger.info("Scene: Go to next part")
                self.killAllEnemies()
                enemyCell = self.sceneManager.currentScene.getNextEnemy()

                playerEntity = EntityFinder.findPlayer(self.world)
                meGroupId = self.world.component_for_entity(
                    playerEntity, system.groupid.GroupId)
                renderable = self.world.component_for_entity(
                    playerEntity, system.graphics.renderable.Renderable)

                distX = enemyCell.spawnX - renderable.coordinates.x

                directMessaging.add(
                    groupId=meGroupId.getId(),
                    type=DirectMessageType.movePlayer,
                    data={
                        'x': distX,
                        'y': 0,
                        'dontChangeDirection': False,
                        'whenMoved': None,
                    },
                )

        # move screen animation
        if self.screenMoveTimer.timeIsUp(
        ) and self.lastKnownPlayerPos is not None:
            playerScreenCoords = self.viewport.getScreenCoords(
                self.lastKnownPlayerPos)

            if self.state is State.pushToNextScene:
                # screen follows player
                # player is left side of screen (screen pushes player right)
                if playerScreenCoords.x != 10:
                    distance = int(playerScreenCoords.x - 10)
                    if distance < 0:
                        self.adjustViewport(-1)
                        self.screenMoveTimer.reset()
                    elif distance > 0:
                        self.adjustViewport(1)
                        self.screenMoveTimer.reset()

                else:
                    self.screenMoveTimer.stop()

            elif self.state is State.pushToEnemies:
                # screen follows player
                # player is middle of the screen
                if playerScreenCoords.x != self.xCenter:
                    distance = int(playerScreenCoords.x - self.xCenter)
                    if distance < 0:
                        self.adjustViewport(-1)
                        self.screenMoveTimer.reset()
                    elif distance > 0:
                        self.adjustViewport(1)
                        self.screenMoveTimer.reset()
                else:
                    self.screenMoveTimer.stop()

        self.sceneManager.advance(dt)
Ejemplo n.º 8
0
    def moveEnemy(self):
        for msg in directMessaging.getByType(DirectMessageType.moveEnemy):
            entity = EntityFinder.findCharacterByGroupId(
                self.world, msg.groupId)
            if entity is None:
                # May be already deleted?
                continue

            meRenderable = self.world.component_for_entity(
                entity, system.graphics.renderable.Renderable)

            # these are the actual x/y position change we will use to move
            x = msg.data['x']
            y = msg.data['y']

            # turning on the spot
            if meRenderable.direction is Direction.left and x > 0:
                self.updateRenderableDirection(meRenderable, Direction.right,
                                               msg.groupId)
                continue
            if meRenderable.direction is Direction.right and x < 0:
                self.updateRenderableDirection(meRenderable, Direction.left,
                                               msg.groupId)
                continue

            meRenderable.storeCoords()
            meRenderable.changeLocationFromStored(x, y)

            if msg.data['force']:
                canMove = True

                # push player out of the way, if there
                isDestEmpty = EntityFinder.isDestinationEmpty(
                    self.world, meRenderable)
                if not isDestEmpty:
                    if EntityFinder.isDestinationWithPlayer(
                            self.world, meRenderable):
                        directMessaging.add(
                            groupId=0,
                            type=DirectMessageType.movePlayer,
                            data={
                                'x': x,
                                'y': 0,
                                'dontChangeDirection': True,
                                'whenMoved': None,
                            },
                        )

            else:
                canMove = EntityFinder.isDestinationEmpty(
                    self.world, meRenderable)

                if not canMove:
                    # seems we cannot move in the chose direction.
                    # if there are two components in the coordinates, just try one of
                    # them
                    if x != 0 and y != 0:
                        # try x. yes this is ugly, but fast
                        x = msg.data['x']
                        y = 0
                        meRenderable.changeLocationFromStored(x, y)
                        canMove = EntityFinder.isDestinationEmpty(
                            self.world, meRenderable)

                        if not canMove:
                            # try y... ugh
                            x = 0
                            y = msg.data['y']
                            meRenderable.changeLocationFromStored(x, y)
                            canMove = EntityFinder.isDestinationEmpty(
                                self.world, meRenderable)

                # check if we are stuck
                if not canMove:
                    meRenderable.restoreCoords()

                    isStuck = not EntityFinder.isDestinationEmpty(
                        self.world, meRenderable)
                    if isStuck:
                        logger.info(
                            "{}: Overlaps, force way out".format(meRenderable))
                        # force our way out of here. do intended path
                        x = msg.data['x']
                        y = msg.data['y']
                        canMove = True
                    else:
                        # not stuck, just wait until we are free,
                        # as another enemy most likely blocks our way
                        logger.info(
                            "{}: Does not overlap, wait until moving".format(
                                meRenderable))
                        pass

            meRenderable.restoreCoords()

            if canMove:
                self.moveRenderable(meRenderable, msg.groupId, x, y,
                                    msg.data['dontChangeDirection'],
                                    msg.data['updateTexture'])
Ejemplo n.º 9
0
    def checkReceiveDamage(self):
        healthUpdated = False

        for msg in directMessaging.getByType(DirectMessageType.receiveDamage):
            entity = EntityFinder.findAttackableByGroupId(
                self.world, msg.groupId)
            if entity is None:
                # May be already deleted?
                continue

            meRenderable = self.world.component_for_entity(entity, Renderable)
            meAttackable = self.world.component_for_entity(entity, Attackable)
            meGroupId = self.world.component_for_entity(entity, GroupId)

            damage = msg.data['damage']
            byPlayer = msg.data['byPlayer']
            direction = msg.data['direction']
            knockback = msg.data['knockback']
            stun = msg.data['stun']
            isPlayer = self.world.has_component(entity, Player)

            # enemy can attack player, and vice-versa
            if not byPlayer ^ isPlayer:
                continue

            if damage == 0:
                continue

            # change health
            meAttackable.adjustHealth(-1 * damage)
            healthUpdated = True
            logger.info("{} got {} damage, new health: {}".format(
                meRenderable, damage, meAttackable.getHealth()))

            # gfx: show floating damage numbers
            if Config.showEnemyDamageNumbers:
                messaging.add(type=MessageType.EmitMirageParticleEffect,
                              data={
                                  'location':
                                  meRenderable.getLocationTopCenter(),
                                  'effectType':
                                  ParticleEffectType.floatingDamage,
                                  'damage': damage,
                                  'byPlayer': byPlayer,
                                  'direction': Direction.none,
                              })

            # gfx: emit on-hit particles
            if Config.showBurstOnImpact:
                if damage > Config.showBurstOnImpactDamage:
                    messaging.add(
                        type=MessageType.EmitMirageParticleEffect,
                        data={
                            'location':
                            meRenderable.getAttackBaseLocationInverted(),
                            'effectType':
                            ParticleEffectType.hitBurst,
                            'damage':
                            0,
                            'byPlayer':
                            byPlayer,
                            'direction':
                            direction,
                        })

            # no stun, knockdown, knockback, or new color if there is no health left
            # (animations may overwrite each other)
            if meAttackable.getHealth() <= 0.0:
                continue

            # gfx: set texture color
            healthPercentage = meAttackable.getHealthPercentage()
            if healthPercentage > 0.5:
                meRenderable.texture.setOverwriteColorFor(
                    Config.overwriteColorTime,
                    ColorPalette.getColorByColor(Color.yellow))
            else:
                meRenderable.texture.setOverwriteColorFor(
                    Config.overwriteColorTime,
                    ColorPalette.getColorByColor(Color.red))

            # handle: stun
            if stun and meAttackable.isStunnable():
                stunTime = meAttackable.stunTime
                meAttackable.stunTimer.setTimer(timerValue=stunTime)
                meAttackable.stunTimer.start()
                meAttackable.isStunned = True
                meAttackable.addStun(stunTime=stunTime)

                # handle: knockdown
                if random.random() < meAttackable.knockdownChance:
                    messaging.add(
                        type=MessageType.EntityKnockdown,
                        data={},
                        groupId=meGroupId.getId(),
                    )
                else:
                    messaging.add(
                        type=MessageType.EntityStun,
                        data={
                            'timerValue': stunTime,
                        },
                        groupId=meGroupId.getId(),
                    )

                # no additional effects
                continue

            # handle: knockback
            if knockback and random.random() < meAttackable.knockbackChance:
                if direction is Direction.left:
                    x = -2
                else:
                    x = 2

                if isPlayer:
                    directMessaging.add(
                        groupId=meGroupId.getId(),
                        type=DirectMessageType.movePlayer,
                        data={
                            'x': x,
                            'y': 0,
                            'dontChangeDirection': True,
                            'whenMoved': "showOnKnockback",
                        },
                    )
                else:
                    directMessaging.add(
                        groupId=meGroupId.getId(),
                        type=DirectMessageType.moveEnemy,
                        data={
                            'x': x,
                            'y': 0,
                            'dontChangeDirection': True,
                            'updateTexture': False,
                            'force': True,
                        },
                    )

                # no additional effects
                continue

        return healthUpdated
Ejemplo n.º 10
0
    def handleKeyPress(self, key, player, playerRenderable, playerEntity):
        didMove = False
        x = 0
        y = 0

        if self.movementTimer.timeIsUp():
            dontChangeDirection = False

            if key == Screen.KEY_LEFT:
                if Config.xDoubleStep:
                    x = -2
                else:
                    x = -1
                didMove = True

            elif key == Screen.KEY_RIGHT:
                if Config.xDoubleStep:
                    x = 2
                else:
                    x = 1
                didMove = True

            if key == 393:  # shift left
                dontChangeDirection = True
                if Config.xDoubleStep:
                    x = -2
                else:
                    x = -1
                didMove = True

            elif key == Screen.KEY_RIGHT:
                if Config.xDoubleStep:
                    x = 2
                else:
                    x = 1
                didMove = True

            if key == 402:  # shift right
                dontChangeDirection = True
                if Config.xDoubleStep:
                    x = 2
                else:
                    x = 1
                didMove = True

            elif key == Screen.KEY_UP:
                y = -1
                didMove = True

            elif key == Screen.KEY_DOWN:
                y = 1
                didMove = True

        meGroupId = self.world.component_for_entity(playerEntity,
                                                    system.groupid.GroupId)

        if didMove:
            directMessaging.add(
                groupId=meGroupId.getId(),
                type=DirectMessageType.movePlayer,
                data={
                    'x': x,
                    'y': y,
                    'dontChangeDirection': dontChangeDirection,
                    'whenMoved': None,
                },
            )

        return didMove