Example #1
0
void assclk_platformer(Lixxie& l)
{
    if (l.get_ac() == LixEn::PLATFORMER) {
        l.set_queue(l.get_queue() + 1);
    }
    else l.become(LixEn::PLATFORMER);
}
Example #2
0
void assclk_builder(Lixxie& l)
{
    if (l.get_ac() == LixEn::BUILDER) {
        l.set_queue(l.get_queue() + 1);
    }
    else l.become(LixEn::BUILDER);
}
Example #3
0
void update_shrugger(Lixxie& l, const UpdateArgs& ua)
{
    ua.suppress_unused_variable_warning();

    if (l.is_last_frame()) l.become(LixEn::WALKER);
    else l.next_frame();
}
Example #4
0
void update_splatter(Lixxie& l, const UpdateArgs& ua)
{
    ua.suppress_unused_variable_warning();

    if (l.is_last_frame()) l.become(LixEn::NOTHING);
    else l.next_frame();
}
Example #5
0
void update_drowner(Lixxie& l, const UpdateArgs& ua)
{
    // Make it look more nicely
    // if (!l.is_solid(0, 6)) l.move_down(1);
    if (l.get_frame() < drowner_steep_frame && !l.is_solid(8, 0))
        l.move_ahead();

    update_splatter(l, ua);
}
Example #6
0
void update_burner(Lixxie& l, const UpdateArgs& ua)
{
    // Nach unten bewegen, wenn kein Boden da ist und wir die Animation
    // noch nicht zu weit abgeschritten haben
    for (int i = 0; i < 5 - l.get_frame(); ++i)
     if (!l.is_solid()) l.move_down(1);

    update_splatter(l, ua);
}
Example #7
0
void become_drowner(Lixxie& l)
{
    int drowner_frame = 0;
    if (l.get_ac() == LixEn::TUMBLER
        && l.get_frame() > tumbler_frame_steep_drown) {
        drowner_frame = drowner_steep_frame;
    }
    l.become_default(LixEn::DROWNER);
    l.set_frame(drowner_frame);
}
Example #8
0
void become_platformer(Lixxie& l)
{
    const bool continue_on_same_height
        = (l.get_ac() == LixEn::SHRUGGER2
        && l.get_frame() < platformer_standing_up_frame);

    l.become_default(LixEn::PLATFORMER);
    l.set_special_x(12);
    l.set_frame(continue_on_same_height ? 16 : 0);
}
Example #9
0
void update_ascender(Lixxie& l, const UpdateArgs& ua)
{
    ua.suppress_unused_variable_warning();

    // normally, move up once, but not on the last frame
    if (l.get_frame() != 5) l.move_up();

    if (l.is_last_frame()) l.become(LixEn::WALKER);
    else l.next_frame();
}
Example #10
0
void become_ascender(Lixxie& l)
{
    l.become_default(LixEn::ASCENDER);

    // determine the height to step up. Seek a floor pixel with air above it.
    int swh = 0;
    while (swh < 26 && ! (l.is_solid(0, 2 - swh) && ! l.is_solid(0, 1 - swh)))
        ++swh;
    int frame = 5; // this is the last frame
    switch (swh) {
        case 0:  case 1:
        case 2:  case 3:  frame = 5; break;
        case 4:  case 5:  frame = 4; break;
        case 6:  case 7:  frame = 3; break;
        case 8:  case 9:  frame = 2; break;
        case 10: case 11: frame = 1; break;
        default:          frame = 0; break;
    }
    int swh_wanted = 10 - frame * 2;
    l.set_frame(frame);

    // Move up, [check for even cliff,] move down again
    l.move_up(swh);
    // This was in earlier versions to look good, but the community frowned
    // on it for inconsistency; and sometimes the skipped x-pixels have indeed
    // yielded problems.
    // if (! l.is_solid(2, 0) && ! l.is_solid(2, 1)) l.move_ahead();
    l.move_down(swh_wanted);
}
Example #11
0
void update_exiter(Lixxie& l, const UpdateArgs& ua)
{
    ua.suppress_unused_variable_warning();

    int x = l.get_special_x();
    if (x < 0) {
        l.set_x(l.get_x() + 1);
        ++x;
    }
    else if (x > 0 && x < 1000) {
        l.set_x(l.get_x() - 1);
        --x;
    }
    l.set_special_x(x);

    if (!l.is_last_frame()) l.next_frame();
    else l.set_special_x(1000);
}
Example #12
0
File: jumper.cpp Project: Lucki/Lix
void become_jumper(Lixxie& l)
{
    l.become_default(LixEn::JUMPER);
    if (l.get_runner()) {
        l.set_special_x(  8); // X-speed
        l.set_special_y(-12); // Y-speed
        l.set_frame(12);
    }
    else {
        l.set_special_x( 6); // X-speed
        l.set_special_y(-8); // Y-speed
    }

    for (int i = -4; i > -16; --i)
     if (l.is_solid(0, i)) {
        l.become(LixEn::STUNNER);
        return;
    }
}
Example #13
0
static bool platformer_is_solid(Lixxie& l, int x, int y)
{
    // If the pixel is solid, return false nontheless if there is free air
    // over the pixel
    bool b = l.is_solid(x, y);
    if (b && l.is_solid(x + 2, y) && l.is_solid(x + 4, y)) return true;
    for (int i = 0; i > -3; --i)
        b = b && (l.is_solid(x+2, y-2)
               || l.is_solid(x, y-2)
               || l.is_solid(x-2, y-2));
    return b;
}
Example #14
0
// Hilfsfunktion
void set_frame_after_aiming(Lixxie& l, const UpdateArgs& ua)
{
    const double pi = std::acos(-1.0);
    const int    x  = (ua.aim_x - l.get_ex()) * l.get_dir();
    const int    y  =  ua.aim_y - l.get_ey();
    // Fuer (0, 0) einfach nix machen, Lix soll wie vorher schauen
    if (x != 0 || y != 0) {
        // Den Winkel so ausrechnen, als sei (0, 1) der Nullwinkel,
        // nicht (1, 0), wie es normal waere. Alles gedreht.
        // atan2 nimmt die Dinger in der Reihenfolge 1. y, 2. x.
        double angle = std::atan2(-x, -y) * 180 / pi;
        if      (angle >  99) l.set_frame(frame_aiming_first +  0);
        else if (angle >  80) l.set_frame(frame_aiming_first +  1);
        else if (angle >  60) l.set_frame(frame_aiming_first +  2);
        else if (angle >  30) l.set_frame(frame_aiming_first +  3);
        else if (angle >  10) l.set_frame(frame_aiming_first +  4);
        else if (angle > -10) l.set_frame(frame_aiming_first +  5);
        else if (angle > -30) l.set_frame(frame_aiming_first +  6);
        else if (angle > -60) l.set_frame(frame_aiming_first +  7);
        else if (angle > -80) l.set_frame(frame_aiming_first +  8);
        else if (angle > -99) l.set_frame(frame_aiming_first +  9);
        else                  l.set_frame(frame_aiming_first + 10);
    }
}
Example #15
0
void update_roper(Lixxie& l, const UpdateArgs& ua)
{
    // Normales Update, einmal pro Tick
    if (!ua.aim_c) {
        if (l.get_frame() < frame_aiming_first) {
            l.next_frame();
        }
        // Nagel fertig in der Erde, aber vor Haken abschiessen
        else if (l.get_special_x() == 0) {
            set_frame_after_aiming(l, ua);

            // Wenn man zu lange wartet, weiterlaufen, einfach
            l.set_special_y(l.get_special_y() + 1);
            if (l.get_special_y() > Lixxie::updates_roper_before)
             l.become(LixEn::WALKER);
        }
        // Haken wurde schon abgeschossen, warten, ehe man weiterlaeuft
        else {
            l.set_special_y(l.get_special_y() + 1);
            if (l.get_special_y() > Lixxie::updates_roper_after)
             l.become(LixEn::WALKER);
        }
    }

    // Zusaetzliches Update pro Tick, wenn zum Zielen per Klick aufgefordert
    // wurde: Dies wird vor dem normalen Update ausgefuehrt.
    else {
        // Nagel in den Boden hauen: Zwar Maus in Beschlag nehmen durch
        // special_x == 0, aber nix machen. Weiter die Klicks aufsaugen.
        if (l.get_frame() < frame_aiming_first);

        // Zielen, aber noch nicht abgeschossen: Nun abschiessen
        else if (l.get_special_x() == 0) {
            l.set_special_x(1);
            l.set_special_y(0);
            set_frame_after_aiming(l, ua);
        }
    }
}
Example #16
0
void update_faller(Lixxie& l, const UpdateArgs& ua)
{
    for (int i = 0; i <= l.get_special_y() && l.get_ac() == LixEn::FALLER;++i){
        // a bit kludgy, we can't do such a thing for flingers etc, since
        // they might be nonconstant.
        if (l.get_foot_encounters() & Lookup::bit_trampoline) {
            // stop falling, so the trampoline can be used
            break;
        }
        else if (l.is_solid(0, i+2)) {
            l.move_down(i);
            l.set_special_x(l.get_special_x() + i);

            // Schirm in letzter Sekunde?
            if (l.get_special_x() > Lixxie::distance_safe_fall
             && !l.get_floater()) {
                l.become(LixEn::SPLATTER);
                l.play_sound(ua, Sound::SPLAT);
                // Nicht explodieren lassen, das täte er bei 76 :-)
                if (l.get_updates_since_bomb() == 75)
                 l.set_updates_since_bomb(0);
            }
            else if ((l.get_special_x() <= 9 && l.get_frame() < 1)
             ||       l.get_special_x() == 0) {
                l.become(LixEn::WALKER);
                if (l.get_runner()) l.set_frame(6);
                else                l.set_frame(8);
            }
            else if (l.get_frame() < 2) {
                l.become(LixEn::WALKER);
                l.set_frame(0);
            }
            else if (l.get_frame() < 3) {
                l.become(LixEn::LANDER);
                l.set_frame(1);
            }
            else {
                l.become(LixEn::LANDER);
                // use the regular frame 0
            }
        }
    }

    if (l.get_ac() == LixEn::FALLER) {
        l.set_special_x(l.get_special_x() + l.get_special_y());
        l.move_down(l.get_special_y());

        if (l.get_special_y() < 8) l.set_special_y(l.get_special_y() + 1);

        // The last two frames alternate, the first frames are just the
        // initial frames of falling.
        if (l.is_last_frame()) l.set_frame(l.get_frame() - 1);
        else l.next_frame();

        if (l.get_floater()
         && l.get_special_x() >= Lixxie::distance_float) {
            const int sy = l.get_special_y();
            l.become(LixEn::FLOATER);
            l.set_special_y(sy);
        }
    }
}
Example #17
0
void become_faller(Lixxie& l)
{
    l.become_default(LixEn::FALLER);
    l.set_special_y(4);
}
Example #18
0
void update_builder(Lixxie& l, const UpdateArgs& ua)
{
    switch (l.get_frame()) {

    // Bau-Frame
    case 7:
        // don't glitch up through steel, but still get killed by top of
        // screen: first see whether trapped, then make brick. For the magic
        // number 13, see walker.cpp, it's because they can ascend 12 pixels.
        l.set_special_y(l.solid_wall_height(2) >= 13);

        l.set_special_x(l.get_special_x() - 1);
        l.draw_brick   (-2, 0, 9, 1);
        if (l.get_special_x() < 3 && l.get_queue() <= 0)
            l.play_sound_if_trlo(ua, Sound::BRICK);

        l.move_up();
        break;

    // Zwei Fortbewegungs-Frames
    case 11:
        // Kollision mit Landschaft? Dann umdrehen!
        // Kopf und Fuß werden geprüft hierfür.
        // +6|-18 statt +2|-16: Die Lix soll wissen, wo's hin geht.
        // +6|-1 ist die Koordinate über dem Stein, nicht -2, da sonst
        // in seltenen Fällen (Lix in dünner Horizontalen) nicht
        // bis zu dieser Ebene hochgebaut wird.

        // Die zweite Abfrage in der Und-Klammer dient dazu, Treppen
        // auch auf anderen Treppen bauen zu können.
        // Last line is Horus bug prevention.

        // Note that the lix has already moved up and the image has its
        // feet below the regular position, inside the newly placed brick.
        //
        //   XX - the effective coordinate of the checking Lixxie. She has
        //        already moved up from inside the brick, but not yet walked
        //        forward.
        //   11 - numbers denote the checks in the corresp. code line below
        //
        //
        //
        //                   33  22  11
        //
        //               XX
        //           44  44  34  24  11
        //           ()()()()()()()()()()()()
        //           ()()()()()()()()()()()()
        //   [][][][][][][][][][][][]
        //   [][][][][][][][][][][][]
        //
        // lines 1, 2, 3, don't build through walls
        if ((l.is_solid(6, 1) && l.is_solid(6, -2))
         || (l.is_solid(4, 1) && l.is_solid(4, -2))
         || (l.is_solid(2, 1) && l.is_solid(2, -2))
         // line 4, don't allow building through long, 2px-thin horiz. beams
         || (l.is_solid(4, 1) && l.is_solid(2, 1) && l.is_solid(0,  1)
                                                  && l.is_solid(-2, 1))
         // hit head
         ||  l.is_solid(6, -16)
         ||  l.is_solid(4, -16)
        ) {
            // Ueberfluessige Faehigkeitsbenutzngen an den Spieler
            // zurueckgeben, passiert nur bei Option "multiple Builders".
            // Wird von l.assign() erledigt.
            // See top comment for the check of special_y.
            l.turn();
            if (l.get_special_y() == 1) l.move_down();
            l.become(LixEn::WALKER);
        }
        break;

    case 12:
    case 13:
        l.move_ahead();
        break;

    // Klötze zählen und ggf. zum Shrugger werden.
    case 15:
        if (l.get_special_x() <= 0) {
            if (l.get_queue() <= 0) l.become(LixEn::SHRUGGER);
            else {
                l.set_queue    (l.get_queue()     -  1);
                l.set_special_x(l.get_special_x() + 12);
            }
        }
        break;
    }

    if (l.get_ac() == LixEn::BUILDER) l.next_frame();
}
Example #19
0
void become_builder(Lixxie& l)
{
    l.become_default(LixEn::BUILDER);
    l.set_special_x(12);
    l.set_frame(6);
}
Example #20
0
void update_platformer(Lixxie& l, const UpdateArgs& ua)
{
    // Der Platformer hat zwei Zyklen. Im ersten Zyklus baut der den
    // Stein oberhalb der Laufhoehe, im allen nachfolgenden Zyklen weiter
    // unten.
    switch (l.get_frame()) {

    // Bauen
    case  1:
    case 17:
        l.set_special_x(l.get_special_x() - 1);
        if (l.get_frame() == 1) l.draw_brick(0, 0, 7, 1);
        else                    l.draw_brick(4, 2, 9, 3);
        if (l.get_special_x() < 3 && l.get_queue() <= 0)
            l.play_sound_if_trlo(ua, Sound::BRICK);
        break;

    case  4:
        // Sinnvolle Steinverlegung wie bei Frame 25 pruefen:
        // Kompletten naechsen Stein vorausplanen, bei Kollision NICHT drehen.
        if (platformer_is_solid(l, 6, -1)
         && platformer_is_solid(l, 8, -1) && platformer_is_solid(l, 10, -1)) {
            l.become(LixEn::WALKER);
        }
        break;

    case  6:
        if (! l.is_solid(0, -2)) l.move_up();
        else {
            l.become(LixEn::SHRUGGER2);
            l.set_frame(platformer_standing_up_frame);
        }
        // faellt durch

    case  7:
    case 21:
    case 22:
    case 23:
        // 2, 1 statt 2, 0, weil wir direkt ueber dem Boden pruefen wollen,
        // ob da ein Pixel ist. Sonst laufen die Walker durch.
        if (! platformer_is_solid(l, 2, 1)) l.move_ahead();
        else {
            l.become(LixEn::SHRUGGER2);
            l.set_frame(platformer_standing_up_frame);
        }
        break;

    case 25: // durchaus auch das letzte Frame
        // Kann noch ein Stein verlegt werden?
        if (l.get_special_x() <= 0) {
            if (l.get_queue() <= 0) {
                l.become(LixEn::SHRUGGER2);
                l.set_special_y(2); // Bei Klick 2 tiefer anfng. = weiterbauen
            }
            else {
                l.set_queue    (l.get_queue()     -  1);
                l.set_special_x(l.get_special_x() + 12);
            }
        }
        else if (platformer_is_solid(l, 2, 1)
         &&      platformer_is_solid(l, 4, 1)
         &&      platformer_is_solid(l, 6, 1)) {
            l.become(LixEn::SHRUGGER2);
            l.set_frame(platformer_standing_up_frame);
        }
        break;
    }

    if (l.get_ac() == LixEn::PLATFORMER) {
        if (l.is_last_frame()) l.set_frame(10);
        else                   l.next_frame();
    }
}
Example #21
0
void become_exiter(Lixxie& l)
{
    l.become_default(LixEn::EXITER);
    l.set_updates_since_bomb(0);
}
Example #22
0
File: jumper.cpp Project: Lucki/Lix
void update_jumper(Lixxie& l, const UpdateArgs& ua)
{
    if (l.get_special_x() % 2 == 1) {
        if (l.get_special_x() > 0) l.set_special_x(l.get_special_x() + 1);
        else                       l.set_special_x(l.get_special_x() - 1);
    }
    const int       sgn = l.get_special_y() >= 0 ? 1 : -1; // sgn(Y-Spd.)
    const unsigned  abs = l.get_special_y() / sgn;         // |Y-Spd.|
    const unsigned& spe = l.get_special_x();               // X-Spd.
    // Das Signum ist auch fuer 0 gleich +1, das macht im Code allerdings
    // nix, weil in dem Fall null Schleifendurchlaeufe passieren oder
    // mit null multipliziert wird.

    // Schrittweise schraeg vorruecken und jedes Mal auf
    // Kollision mit der Landschaft testen.
    // Die groessere Laenge wird pixelweise abgearbeitet.
    for (unsigned i = 0; i < (abs >= spe ? abs : spe); ++i) {
        // 2 * (... / 2) sorgt fuer das Einhalten der geraden X-Zahlen.
        // Es wird jeweils geguckt, ob der Zaehler i weit genug vor-
        // geschritten ist, damit in die kurze Richtung ein
        // Schritt stattfinden kann - wenn nicht, ist das Argument
        // von move_ahead stets 0. In die lange Richtung geht's immer.
        const int old_ex = l.get_ex();
        const int old_ey = l.get_ey();
        const Lookup::LoNr old_enc_foot = l.get_foot_encounters();
        const Lookup::LoNr old_enc_body = l.get_body_encounters();

        if (abs >= spe) {
            l.move_ahead(2 * ((i+1)*spe/2 / abs - i*spe/2 / abs));
            l.move_down(sgn);
        }
        else {
            l.move_down(sgn * ((i+1)*abs/spe - i*abs/spe));
            l.move_ahead(i%2 * 2);
        }

        int coll = jumper_and_tumbler_collision(l);
        if (coll == 0) {
            // nothing hit, proceed with next step for this frame
        }
        else if (coll == 1) {
            // we hit something, but don't have to reset anything. Stop motion.
            break;
        }
        else if (coll == 2) {
            // We hit something, reset encounters and check again at position.
            l.set_foot_encounters(old_enc_foot);
            l.set_body_encounters(old_enc_body);
            l.set_ey(l.get_ey()); // re-check encounters at current position
            break;
        }
        else if (coll == 3) {
            // Like coll == 2, but also reset position.
            l.set_foot_encounters(old_enc_foot);
            l.set_body_encounters(old_enc_body);
            l.set_ex(old_ex);
            l.set_ey(old_ey);
            // Do this for completely immobilizied tumblers
            if (l.is_solid(0, 0)) l.become(LixEn::STUNNER);
            break;
        }
        // end checking return val of collision
    }
    // end of motion

    // Wenn nicht beim Bewegen irgendwo angestossen...
    if (l.get_ac() == LixEn::JUMPER
     || l.get_ac() == LixEn::TUMBLER) {
        const int sp_y = l.get_special_y();
        if      (sp_y <= 12) l.set_special_y(sp_y + 2);
        else if (sp_y <  64) l.set_special_y(sp_y + 1);

        if (l.get_ac() == LixEn::TUMBLER
         && (l.get_foot_encounters() & Lookup::bit_trampoline)
         && l.get_special_y() > 0) {
            // don't use the tumbler frame selection that is used onwards here,
            // but take a nicer frame
            l.set_frame(std::max(0, l.get_frame() - 4));
        }
        else if (l.get_special_y() > 14) {
            if (l.get_floater()) {
                const int sx = l.get_special_x();
                const int sy = l.get_special_y();
                l.become(LixEn::FLOATER);
                l.set_special_x(sx);
                l.set_special_y(sy);
            }
            else if (l.get_ac() == LixEn::JUMPER)  {
                l.set_ac(LixEn::TUMBLER);
                l.set_frame(3); // override autoframechoice for 1 frame now
            }
            else { // we're already a tumbler
                tumbler_frame_selection(l);
            }
        }
        else if (l.get_ac() == LixEn::TUMBLER) {
            tumbler_frame_selection(l);
        }
        else {
            // we are a jumper
            if (l.is_last_frame()) {
                if (l.get_runner()) l.set_frame(12);
                else                l.set_frame(l.get_frame() - 1);
            }
            else l.next_frame();
        }
    }

    switch (l.get_ac()) {
        case LixEn::STUNNER:  l.play_sound(ua, Sound::OUCH);  break;
        case LixEn::SPLATTER: l.play_sound(ua, Sound::SPLAT); break;
        case LixEn::CLIMBER:  l.play_sound(ua, Sound::CLIMBER); break;
        default: break;
    }
}