Example #1
0
class SceneLogo(SceneBase):
    def __init__(self, viewport, world):
        super().__init__(world=world, viewport=viewport)

        # teh logo
        coordinates = Coordinates(2, 5)
        textureLogo = PhenomenaTexture(phenomenaType=PhenomenaType.intro)
        self.renderableLogo = Renderable(
            texture=textureLogo,
            viewport=self.viewport,
            coordinates=coordinates,
            active=True,
        )

        self.anyKeyFinishesScene = True

        self.timer = Timer(3)
        self.sceneFinished = False
        self.name = "Scene0 - Logo"

    def enter(self):
        self.addRenderable(self.renderableLogo)

    def sceneIsFinished(self):
        if self.timer.timeIsUp():
            return True
        else:
            return False

    def advance(self, dt):
        self.timer.advance(dt)
Example #2
0
class DragonStateChase(StateChase):
    def __init__(self, brain):
        super().__init__(brain)
        self.canSkillTimer = Timer()

    def on_enter(self):
        super().on_enter()
        self.canSkillTimer.setTimer(3.0)

    def process(self, dt):
        super().process(dt)
        self.canSkillTimer.advance(dt)

    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()
Example #3
0
class RamboStateStanding(State):
    name = "standing"

    def __init__(self, brain):
        super().__init__(brain)
        self.canAttackTimer = Timer()


    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 process(self, dt):
        self.canAttackTimer.advance(dt)
        self.tryAttack()


    def tryAttack(self):
        if self.canAttackTimer.timeIsUp():
            self.brain.pop()
            self.brain.push("attacking")
Example #4
0
class Player():
    def __init__(self):
        self.name = 'Player'
        self.points = 0
        self.isPlayer = True
        self.isAttacking = False
        self.isAlive = True

        self.attackTimer = Timer(0.0)

    def advance(self, deltaTime: float):
        self.attackTimer.advance(deltaTime)

        if self.attackTimer.timeIsUp():
            self.isAttacking = False
            self.attackTimer.setActive(False)

    def setAttacking(self, attackTime: float):
        self.isAttacking = True

        self.attackTimer.setTimer(attackTime)
        self.attackTimer.start()

    def setAlive(self, alive):
        self.isAlive = alive

    def __repr__(self):
        return "Player"
Example #5
0
class Defense():
    def __init__(self):
        self.coordinates = None
        self.timer = Timer(1.0)
        self.isActive = False

    def advance(self, dt):
        self.timer.advance(dt)

        if self.timer.timeIsUp():
            self.isActive = False
Example #6
0
class Texture(object):
    def __init__(self, type, width=0, height=0, name=''):
        self.type = type
        self.width: int = width
        self.height: int = height
        self.active: bool = True
        self.name = name

        # color related
        self.overwriteColorTimer = Timer(0.25, active=False)
        self.overwriteColor = None

    def init(self):
        pass

    def draw(self, viewport):
        pass

    def advance(self, deltaTime: float):
        # reset overwrite color
        if self.overwriteColorTimer.timeIsUp():
            self.overwriteColor = None
            self.overwriteColorTimer.stop()
        self.overwriteColorTimer.advance(deltaTime)

    def setOverwriteColorFor(self, time: float, color: Color):
        if self.overwriteColorTimer.isActive():
            logger.debug("{} Color already active on new set color".format(
                self.name))

        self.overwriteColor = color
        self.overwriteColorTimer.setTimer(time)
        self.overwriteColorTimer.reset()

    def advanceStep(self):
        pass

    def setActive(self, active: bool):
        self.active = active

    def isActive(self) -> bool:
        return self.active

    def setName(self, name: str):
        self.name = name

    def __repr__(self):
        return self.name
Example #7
0
class DamageStat(object):
    def __init__(self):
        self.damage = 100
        self.dmgTimer = Timer(1.0)


    def addDamage(self, damage):
        self.damage += damage


    def process(self, dt):
        self.dmgTimer.advance(dt)
        if self.dmgTimer.timeIsUp():
            self.dmg -= 10
            self.dmgTimer.reset()


    def getDamageStat(self):
        return self.damage
Example #8
0
class StateAttack(State):
    name = "attack"

    def __init__(self, brain):
        State.__init__(self, brain)
        self.attackTimer = Timer(instant=True)


    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)

        self.attackTimer.setTimer(meEnemy.enemyInfo.attackTime)
        self.setTimer(meEnemy.enemyInfo.attackStateTime)

        messaging.add(
            type=MessageType.EntityAttack,
            groupId=meGroupId.getId(),
            data=None
        )


    def process(self, dt):
        self.attackTimer.advance(dt)

        if self.attackTimer.timeIsUp():
            logger.info(self.name + " I'm attacking, via offensiveattack!")
            self.attackTimer.reset()
            offensiveAttack = self.brain.owner.world.component_for_entity(
                self.brain.owner.entity, OffensiveAttack)
            offensiveAttack.attack()

        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")
Example #9
0
class StateChase(State):
    name = "chase"

    def __init__(self, brain):
        State.__init__(self, brain)
        meEnemy = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.enemy.Enemy)

        # basically move speed
        self.lastInputTimer = Timer(meEnemy.enemyInfo.chaseStepDelay,
                                    instant=True)

        # try attacking when timer is finished
        self.canAttackTimer = Timer()

        # we need to know player location, or we could just handle on every new
        # PlayerLocation message
        self.lastKnownPlayerPosition = None

    def on_enter(self):
        meEnemy = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.enemy.Enemy)

        stateTimeRnd = random.randrange(-100 * meEnemy.enemyInfo.chaseTimeRnd,
                                        100 * meEnemy.enemyInfo.chaseTimeRnd)
        self.setTimer(meEnemy.enemyInfo.chaseTime + (stateTimeRnd / 100))

        self.canAttackTimer.setTimer(meEnemy.enemyInfo.enemyCanAttackPeriod)
        self.canAttackTimer.reset()

        if not Config.allowEnemyAttacking:
            self.canAttackTimer.setActive(False)

    def tryAttacking(self):
        if self.canAttackTimer.timeIsUp():
            logger.debug("{}: Check if i can attack player".format(self.name))
            if self.canAttackPlayer():
                if (EntityFinder.numEnemiesInState(self.brain.owner.world,
                                                   'attack') <
                        Config.maxEnemiesInStateAttacking):
                    self.brain.pop()
                    self.brain.push("attackwindup")

            self.canAttackTimer.reset()

    def tryMoving(self):
        # only move if we can not hit him (even on cooldown)
        # this is quiet... taxing. and not really necessary?
        # if not self.canAttackPlayer():

        if True:
            # movement speed, and direction
            if self.lastInputTimer.timeIsUp():
                self.getInputChase()
                self.lastInputTimer.reset()

    def trySkill(self):
        # stickfigure has no skills
        pass

    def process(self, dt):
        meAttackable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.attackable.Attackable)

        if meAttackable.isStunned:
            return

        self.lastInputTimer.advance(dt)
        self.canAttackTimer.advance(dt)

        # update player position if new location
        self.checkForNewPlayerPosition()

        self.tryAttacking()
        # note that if we want to attack, as identified a few lines above,
        # we will be in state attackWindup, and not reach here
        self.trySkill()
        self.tryMoving()

        # switch to wander if exhausted
        if self.timeIsUp():
            logger.debug("{}: Too long chasing, switching to wander".format(
                self.owner))
            self.brain.pop()
            self.brain.push("wander")

    def checkForNewPlayerPosition(self):
        # check if there are any new player position messages
        for message in messaging.getByType(MessageType.PlayerLocation):
            self.lastKnownPlayerPosition = message.data

    def canAttackPlayer(self):
        if self.lastKnownPlayerPosition is None:
            # we may not yet have received a location.
            # find it directly via player entity
            # this is every time we go into chase state
            playerEntity = EntityFinder.findPlayer(self.brain.owner.world)
            # player not spawned
            if playerEntity is not None:
                playerRenderable = self.brain.owner.world.component_for_entity(
                    playerEntity, system.graphics.renderable.Renderable)
                self.lastKnownPlayerPosition = playerRenderable.getLocationAndSize(
                )

        canAttack = AiHelper.canAttackPlayer(self.brain.owner,
                                             self.lastKnownPlayerPosition)

        return canAttack

    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,
                },
            )
Example #10
0
class StateAttack(State):
    name = "attack"

    def __init__(self, brain):
        State.__init__(self, brain)
        self.attackMoveTimer = Timer()  # Timer(0.5, instant=False) # windup and cooldown


    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 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")
Example #11
0
class SceneProcessor(esper.Processor):
    def __init__(self, viewport, sceneManager):
        super().__init__()
        self.viewport = viewport
        self.sceneManager = sceneManager
        self.xCenter = Config.columns / 2 - 5
        self.state = State.start
        self.screenMoveTimer = Timer(0.1)
        self.lastKnownPlayerPos = None
        self.gameoverTimer = Timer(3.0,
                                   active=False)  # show gameover for this long

    def setState(self, state):
        logging.debug("Set to state: {}".format(state))
        self.state = state

    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)

    def adjustViewport(self, xoff):
        viewportChanged = self.viewport.adjustViewport(xoff)
        if viewportChanged:
            messaging.add(
                type=MessageType.ScreenMove,
                data={
                    'x': xoff,
                },
            )

    def killAllEnemies(self):
        for _, ai in self.world.get_component(system.gamelogic.ai.Ai):
            ai.brain.pop()
            ai.brain.push('dead')

    def numEnemiesAlive(self) -> int:
        count = 0
        for _, ai in self.world.get_component(system.gamelogic.ai.Ai):
            if ai.brain.state.name != 'dead' and ai.brain.state.name != 'dying':
                count += 1

        return count

    def numEnemiesVisible(self) -> int:
        count = 0
        for _, (ai, renderable) in self.world.get_components(
                system.gamelogic.ai.Ai, system.graphics.renderable.Renderable):
            if (ai.brain.state.name != 'dead'
                    and ai.brain.state.name != 'dying'
                    and renderable.coordinates.x > self.viewport.getx()
                    and renderable.coordinates.x < self.viewport.getRightX()):
                count += 1

        return count

    def enemiesLeftOfChar(self, playerX):
        for _, (ai, renderable) in self.world.get_components(
                system.gamelogic.ai.Ai, system.graphics.renderable.Renderable):
            if (ai.brain.state.name != 'dead'
                    and ai.brain.state.name != 'dying'
                    and renderable.coordinates.x < playerX):
                return True

        return False
Example #12
0
class SceneIntro(SceneBase):
    def __init__(self, viewport, world):
        super().__init__(world=world, viewport=viewport)

        self.textureEmiter = TextureEmiter(viewport=viewport, world=world)
        renderableCache.init(viewport=viewport)

        textureCopter = PhenomenaTexture(
            phenomenaType=PhenomenaType.roflcopter,
            name="Scene1 chopper")
        self.copterSpawn = Coordinates(13, -1 * textureCopter.height)
        renderableCopter = Renderable(
            texture=textureCopter,
            viewport=self.viewport,
            coordinates=self.copterSpawn,
            active=True,
        )

        texturePlayer = CharacterTexture(
            characterAnimationType=CharacterAnimationType.standing,
            characterTextureType=CharacterTextureType.player,
            name='Scene1 Player')
        coordinates = Coordinates(24, 13)
        renderablePlayer = Renderable(
            texture=texturePlayer,
            viewport=self.viewport,
            coordinates=coordinates,
            active=True,
        )

        textureEnemy = CharacterTexture(
            characterAnimationType=CharacterAnimationType.standing,
            characterTextureType=CharacterTextureType.player,
            name='Scene1 Enemy')
        coordinates = Coordinates(Config.columns, 13)
        renderableEnemy = Renderable(
            texture=textureEnemy,
            viewport=self.viewport,
            coordinates=coordinates,
            active=True,
        )

        self.renderableCopter = renderableCopter
        self.renderablePlayer = renderablePlayer
        self.renderableEnemy = renderableEnemy

        self.myTimer = Timer(0.5)
        self.state = IntroSceneState.wait1
        self.name = "Scene1 - Intro Animation"
        self.anyKeyFinishesScene = True

        self.init()


    def advance(self, dt):
        self.myTimer.advance(dt)
        self.handleState()


    def enter(self):
        self.addRenderable(self.renderableCopter)


    def sceneIsFinished(self) -> bool:
        if self.state is IntroSceneState.done:
            return True
        else:
            return False


    def handleState(self):
        # interactive, aka a hack, but it works
        if (self.state is IntroSceneState.wait1
                or self.state is IntroSceneState.flydown
                or self.state is IntroSceneState.drop
                or self.state is IntroSceneState.flyup):

            c1, a1 = ColorPalette.getColorByColor(Color.blue)
            c2, a2 = ColorPalette.getColorByColor(Color.brightblue)
            self.viewport.addstr(5, 40,  "N Key Rollover", c1, a1)
            self.viewport.addstr(6, 40,  "Escape from Hong Kong", c2, a2)

            c3, a3 = ColorPalette.getColorByColor(Color.cyan)
            self.viewport.addstr(8, 40,  "Moving: arrow keys, shift to strafe", c3, a3)
            self.viewport.addstr(9, 40,  "Select attack: 1 2 3 4", c3, a3)
            self.viewport.addstr(10, 40, "Attack       : space", c3, a3)
            self.viewport.addstr(11, 40, "Skills       : q w e r", c3, a3)
            self.viewport.addstr(12, 40, "Heal, Port   : f g", c3, a3)

        # state
        if self.state is IntroSceneState.wait1:
            # for next scene: Flydown
            if self.myTimer.timeIsUp():
                self.state = IntroSceneState.flydown
                self.myTimer.setTimer(0.1)
                self.renderableCopter.setActive(True)
                logger.debug("Scene: Go to State: Flydown")

        elif self.state is IntroSceneState.flydown:
            if self.myTimer.timeIsUp():
                self.myTimer.reset()
                self.renderableCopter.coordinates.y += 1

            # for next scene: Drop
            if self.renderableCopter.coordinates.y == 8:
                self.myTimer.setTimer(0.1)
                logger.debug("Scene: Go to State: Drop")
                self.addRenderable(self.renderablePlayer)
                self.state = IntroSceneState.drop

        elif self.state is IntroSceneState.drop:
            # for next scene: Flyup
            if self.myTimer.timeIsUp():
                self.myTimer.reset()
                self.renderableCopter.coordinates.y -= 1

            if self.renderableCopter.coordinates.y == self.copterSpawn.y:
                self.myTimer.setTimer(0.1)
                self.addRenderable(self.renderableEnemy)
                self.renderableEnemy.texture.changeAnimation(
                    CharacterAnimationType.walking, direction=Direction.left)
                self.state = IntroSceneState.spawnenemy
                self.isShowMap = True
                logger.info("Scene: Go to State: SpawnEnemy")

        elif self.state is IntroSceneState.spawnenemy:
            if self.myTimer.timeIsUp():
                self.myTimer.reset()
                self.renderableEnemy.coordinates.x -= 1
                self.renderableEnemy.advanceStep()

            if (self.renderableEnemy.coordinates.x
                    == self.renderablePlayer.coordinates.x + 15):
                self.renderableEnemy.texture.changeAnimation(
                    CharacterAnimationType.standing, direction=Direction.none)
                self.myTimer.setTimer(2.0)
                self.state = IntroSceneState.speakenemy
                self.textureEmiter.showSpeechBubble(
                    'The princess is in another castle...',
                    time=3.0,
                    parentRenderable=self.renderableEnemy
                )

        elif self.state is IntroSceneState.speakenemy:
            if self.myTimer.timeIsUp():

                self.state = IntroSceneState.leaveenemy
                self.renderableEnemy.texture.changeAnimation(
                    CharacterAnimationType.walking, direction=Direction.right)
                self.myTimer.setTimer(0.1)

        elif self.state is IntroSceneState.leaveenemy:
            if self.myTimer.timeIsUp():
                self.myTimer.reset()
                self.renderableEnemy.advanceStep()
                self.renderableEnemy.coordinates.x += 1

            if (self.renderableEnemy.coordinates.x
                    == Config.columns):
                self.state = IntroSceneState.done


        elif self.state is IntroSceneState.done:
            pass
Example #13
0
class StateWander(State):
    name = "wander"

    def __init__(self, brain):
        State.__init__(self, brain)
        meEnemy = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.enemy.Enemy)
        self.lastInputTimer = Timer(meEnemy.enemyInfo.wanderStepDelay, instant=True)
        self.destCoord = Coordinates()
        self.destIsPoint = False


    def on_enter(self):
        meEnemy = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.enemy.Enemy)

        stateTimeRnd = random.randrange(
            -100 * meEnemy.enemyInfo.wanderTimeRnd,
            100 * meEnemy.enemyInfo.wanderTimeRnd)
        self.setTimer(meEnemy.enemyInfo.wanderTime + (stateTimeRnd / 100))
        self.chooseDestination()


    def process(self, dt):
        meRenderable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.graphics.renderable.Renderable)
        meAttackable = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.attackable.Attackable)
        meEnemy = self.brain.owner.world.component_for_entity(
            self.brain.owner.entity, system.gamelogic.enemy.Enemy)

        if meAttackable.isStunned:
            return

        self.lastInputTimer.advance(dt)

        if self.lastInputTimer.timeIsUp():
            self.getInputWander()
            self.lastInputTimer.reset()

        if self.timeIsUp():
            if (EntityFinder.numEnemiesInState(self.brain.owner.world, 'chase')
                    < Config.maxEnemiesInStateChase):
                logger.info("{}: Too long wandering, chase again a bit".format(
                    self.owner))
                self.brain.pop()
                self.brain.push("chase")

        elif Utility.isIdentical(meRenderable.getLocation(), self.destCoord):
            # No reset of wander state atm, just a new location
            self.chooseDestination()

        else:
            # check if player is close
            for message in messaging.getByType(MessageType.PlayerLocation):
                distance = Utility.distance(
                    message.data,
                    meRenderable.getLocation())

                if distance['sum'] < meEnemy.enemyInfo.wanderAttackDistance:
                    logger.info("{}: Player is close, chasing".format(self.owner))
                    self.brain.pop()
                    self.brain.push("chase")


    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,
            },
        )


    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
                }
            )
Example #14
0
class RamboStateAttacking(State):
    name = "attacking"

    def __init__(self, brain):
        super().__init__(brain)
        self.cooldownTimer = Timer()
        self.attackingTimer = Timer()

    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)

    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,
                },
            )

    def process(self, dt):
        self.cooldownTimer.advance(dt)
        self.attackingTimer.advance(dt)
        self.tryShooting()

    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()
Example #15
0
class InputProcessor(esper.Processor):
    def __init__(self):
        super().__init__()
        self.movementTimer = Timer(1.0 / Config.movementKeysPerSec,
                                   instant=True)
        self.keyCache = []

    def process(self, deltaTime):
        self.handleKeyboardInput()
        self.advance(deltaTime)

    def advance(self, deltaTime):
        self.movementTimer.advance(deltaTime)

    def handleKeyboardInput(self):
        playerEntity = EntityFinder.findPlayer(self.world)
        if playerEntity is None:
            return

        player = self.world.component_for_entity(
            playerEntity, system.gamelogic.player.Player)
        renderable = self.world.component_for_entity(
            playerEntity, system.graphics.renderable.Renderable)
        attackable = self.world.component_for_entity(
            playerEntity, system.gamelogic.attackable.Attackable)

        # return if we cannot handle key, but cache it first
        if attackable.isStunned or player.isAttacking:
            for message in messaging.getByType(MessageType.PlayerKeypress):
                # store a few movement commands
                if len(self.keyCache) >= 1:
                    del (self.keyCache[0])

                self.keyCache.append(message)

            return

        if not player.isAlive:
            return

        didMove = False
        for message in self.keyCache:
            # identical to bottom loop atm
            apm.tick(message.data['time'])
            didMoveTmp = self.handleKeyPress(message.data['key'], player,
                                             renderable, playerEntity)
            if didMoveTmp:
                didMove = True
        self.keyCache.clear()

        for message in messaging.getByType(MessageType.PlayerKeypress):
            apm.tick(message.data['time'])
            didMoveTmp = self.handleKeyPress(message.data['key'], player,
                                             renderable, playerEntity)
            if didMoveTmp:
                didMove = True

        # to allow diagonal movement, we allow multiple movement keys per input
        # cycle, without resetting the timer.
        if didMove:
            self.movementTimer.reset()

    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
Example #16
0
class DamageProcessor(esper.Processor):
    def __init__(self):
        super().__init__()
        self.dmgTimer = Timer(1.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)