void Hero::DamagedMobilityState::enter() {
    hero.isStunned = true;
    hero.invincibilityTimer = 1.4667f;
    hero.stopShooting();
    hero.chooseAnimation();

    // If we're facing left, move right, if right, move left.
    if(hero.getDirection() == Directions::Left) {
        horizontalVelocity.setX(NESNumber(0x00, 0x80).toFloat());
    } else {
        horizontalVelocity.setX(-(NESNumber(0x00, 0x80).toFloat()));
    }

    // Special case for sliding and climbing:
    // * If damaged mid-slide there is no knockback
    // * If damaged while climbing there is no knockback
    if(hero.isSliding || hero.isClimbing) {
        horizontalVelocity.setX(0.0f);
    }

    // Ensure we get knocked back
    hero.body.setGravitated(true);
    hero.body.setApplyHorizontalVelocity(true);

    // Make sure we start falling immediately
    hero.setVelocityY(0.0f);

    // Make sure animations will play (like when you're on a ladder)
    hero.getAnimatedSprite()->unpause();

    if(auto events = hero.getEventBus().lock()) {
        events->triggerEvent(EventDataPtr(new EntityDamageEventData(hero.getId(), 0.0f)));
    }
}
Beispiel #2
0
    NESNumber NESNumber::fromFloat(const float& f) {
        int high = static_cast<int>(f);
        float frac = std::abs(f - high);
        unsigned char low = static_cast<unsigned char>(frac * 256.0f);

        return NESNumber(high, low);
    }
Beispiel #3
0
 NESNumber NESNumber::fromInt(const int& i) {
     return NESNumber(i, 0);
 }
Beispiel #4
0
 NESNumber NESNumber::operator-() const {
     return NESNumber(-getHigh(), getLow());
 }
Beispiel #5
0
    Hero::Hero(int id, std::shared_ptr<Room> room)
        : Entity(id, room)
        , isDecelerating(false)
        , isStanding(false)
        , isWalking(false)
        , isSliding(false)
        , isInTunnel(false)
        , isJumping(false)
        , isFalling(false)
        , isAirborn(false)
        , isClimbing(false)
        , isTouchingLadderTop(false)
        , isFullyAccelerated(false)
        , isShooting(false)
        , isTeleporting(false)
        , isMorphing(false)
        , isStunned(false)
        , isInvincible(false)
        , isUnderWater(false)
        , wasUnderWaterLastFrame(false)
        , climbableRegion(0, 0, 0, 0)
        , actionController(nullptr)
        , mobilityState(nullptr)
        , nextMobilityState(nullptr)
        , temporaryMobilityState(nullptr)
        , shootingState(nullptr)
        , nextShootingState(nullptr) 
    {
        setDeathType(EntityDeathType::Hero);

        body.setGravitated(true);
        body.setHasWorldCollision(true);

        body.setCollisionCallback(std::bind(&Entity::handleCollision, this, std::placeholders::_1, std::placeholders::_2));
        body.setLandingCallback([this](Movable& movable, CollisionInfo& collisionInfo) {
            if(actionController->shouldMoveRight() || actionController->shouldMoveLeft()) {
                this->isFullyAccelerated = true;
            }

            this->isJumping = false;
            this->isFalling = false;
            this->isAirborn = false;

            if(auto events = this->getEventBus().lock()) {
                events->triggerEvent(EventDataPtr(new EntityStateChangeEventData(getId(), "landed")));
            }

#ifdef HIKARI_DEBUG_HERO_PHYSICS
            this->countAscendingFrames = 0;
            this->countDecendingFrames = 0;
#endif // HIKARI_DEBUG_HERO_PHYSICS
        });

        invincibilityTimer = 0;
        blinkTimer = 0;
        isBlinking = false;
        isVisible = true;

        walkVelocity = Vector2<float>(NESNumber(0x01, 0x4C).toFloat(), 0.0f);
        climbVelocity = Vector2<float>(walkVelocity.getY(), walkVelocity.getX()); // Climbs at same speed as he walks
        jumpVelocity = Vector2<float>(0.0f, -(NESNumber(0x04, 0xA5) + NESNumber(0, 0x40) + NESNumber(0, 0x40)).toFloat());
        suddenFallVelocity = Vector2<float>(0.0f, NESNumber(0, 0x80).toFloat());
        slideVelocity = Vector2<float>(NESNumber(0x02, 0x80).toFloat(), 0.0f);
        hurtVelocity = Vector2<float>();

        accelerationDelay = 0;
        accelerationDelayThreshold = 6;
#ifdef HIKARI_DEBUG_HERO_PHYSICS
        this->countAscendingFrames = 0;
        this->countDecendingFrames = 0;
#endif // HIKARI_DEBUG_HERO_PHYSICS

        isFullyAccelerated = false;

        setFaction(Factions::Hero);

        changeMobilityState(std::unique_ptr<MobilityState>(new IdleMobilityState(*this)));
        changeShootingState(std::unique_ptr<ShootingState>(new NotShootingState(*this)));

        getAnimatedSprite()->setUsePalette(true);
        getAnimatedSprite()->setUseSharedPalette(true);
    }