Beispiel #1
0
void Gameplay::calc_active()
{
    if (!malo) return;

    // Wo ist die Maus auf dem Land?
    int mx = map.get_mouse_x();
    int my = map.get_mouse_y();

    const bool mouse_on_panel = hardware.get_my() > map.get_screen_yl();

    // Remedies the bug: displays "N nothings" after level restart
    pan.stats.set_tarcnt(0);

    // Spawn interval buttons
    if (cs.tribes.size() == 1) {
        Tribe& tribe = cs.tribes[0];

        int cur = pan.spawnint_cur .get_spawnint();

        if (cur == tribe.spawnint_slow)
            ;
        else if (pan.spawnint_slow.get_execute_right())
            pan.spawnint_cur.set_spawnint(tribe.spawnint_slow);
        else if (pan.spawnint_slow.get_execute_left())
            pan.spawnint_cur.set_spawnint(cur + 1);

        if (cur == tribe.spawnint_fast)
            ;
        else if (pan.spawnint_cur .get_execute_right())
            pan.spawnint_cur.set_spawnint(tribe.spawnint_fast);
        else if (pan.spawnint_cur.get_execute_left())
            pan.spawnint_cur.set_spawnint(cur - 1);
    }

    // Selection of skills in the panel aren't checked here anymore.
    // They aren't replay data, so that check went into gamepl_c.cpp.

    // Atombombe
    if (pan.get_nuke_doubleclicked()) {
        // set_on() kommt zwar auch im Update, aber wenn wir das
        // hier immer machen, sieht es besser aus. Gleiches gilt fuer
        // den Sound, ist wie beim normalen Anklicken.
        pan.nuke_single.set_on();
        pan.nuke_multi .set_on();
        pan.pause      .set_off();
        Replay::Data data = new_replay_data();
        data.action       = Replay::NUKE;
        replay.add(data);
        Network::send_replay_data(data);
        effect.add_sound(cs.update + 1, *trlo, 0, Sound::NUKE);
        Sound::play_loud(Sound::NUKE);
    }



    ///////////////////////////////////////
    // End of: check things in the panel //
    // Now: mouse on the playing field   //
    ///////////////////////////////////////



    // mouse on the playing field, lixes are selectable
    if (! mouse_on_panel && trlo) {
        // Bestimmte Richtung anwählen?
        bool only_dir_l = false;
        bool only_dir_r = false;
        if (  key[useR->key_force_left]
         && ! key[useR->key_force_right]) {
            only_dir_l = true;
            mouse_cursor.set_x_frame(1);
        }
        else if (! key[useR->key_force_left]
         &&        key[useR->key_force_right]) {
            only_dir_r = true;
            mouse_cursor.set_x_frame(2);
        }
        // Decide which lix the cursor points at
        // Die Liste der Lixen wird durchlaufen und die Priorität jeder
        // Lix errechnet. Wird eine höhere Priorität als die derzeitig
        // höchste gefunden, wechselt LixIt target. Bei gleicher Prioritaet
        // haben Lixen, die naeher am Mauscursor liegen, Vorrang! Mit rechter
        // Maustaste (selectable in the options) waehlt man dagegen die letzte
        // Lix mit der niedrigsten Priorität. Auch hier haben naeher liegende
        // Lixen Vorrang.
        LixIt  target = trlo->lixvec.end(); // Klickbar mit Prioritaet
        LixIt  tarinf = trlo->lixvec.end(); // Nicht unb. klickbar mit Prior.
        int    tarcnt = 0; // Anzahl Lixen unter Cursor
        int    target_priority = 0;
        int    target_prio_min = 100000; // if (< target_prio) => tooltip
        int    tarinf_priority = 0;
        double target_hypot = 1000;
        double tarinf_hypot = 1000;
        bool   tooltip_l_elig = false; // if both true => tooltip
        bool   tooltip_r_elig = false; // is there a l/r walker considered?

        // Bei Zoom diese Variablen veraendern
        int zoom   = map.get_zoom();
        int mmld_x = mouse_max_lix_distance_x - mouse_cursor_offset/2*zoom;
        int mmld_u = mouse_max_lix_distance_u - mouse_cursor_offset/2*zoom;
        int mmld_d = mouse_max_lix_distance_d - mouse_cursor_offset/2*zoom;

        // find current skill of the local player via the GUI
        GameplayPanel::SkBIt skill_visible = pan.skill.begin();
        while (skill_visible != pan.skill.end()
            && (! skill_visible->get_on()
                // panel has reordered skills. trlo and the replay don't
                || trlo->skills.find(skill_visible->get_skill()) ==
                   trlo->skills.end()
                || trlo->skills[skill_visible->get_skill()] == 0
                || skill_visible->get_number() == 0))
            ++skill_visible;

        if (skill_visible != pan.skill.end())
            for (LixIt i =  --trlo->lixvec.end();
                       i != --trlo->lixvec.begin(); --i)
        {
            // (skill_visible) is now a skill with (trlo has != 0 of it).
            // In particular, it appears in trlo->skills as a key.

            if (   map.distance_x(i->get_ex(), mx) <=  mmld_x
                && map.distance_x(i->get_ex(), mx) >= -mmld_x
                && map.distance_y(i->get_ey(), my) <=  mmld_d
                && map.distance_y(i->get_ey(), my) >= -mmld_u
            ) {
                // Hypot geht von (ex|ey+etwas) aus
                // true = Beachte persoenliche Einschraenkungen wie !MultBuild
                int priority
                    = i->get_priority(skill_visible->get_skill(), true);

                // Invert priority if a corresponding mouse button is held
                if ((hardware.get_mrh() && useR->prioinv_right)
                 || (hardware.get_mmh() && useR->prioinv_middle)
                 ||  hardware.key_hold(useR->key_priority)) {
                    priority = 100000 - priority;
                }
                double hypot = map.hypot(mx, my, i->get_ex(),
                                          i->get_ey() + ((mmld_d - mmld_u)/2)
                                          );
                if (priority > 0 && priority < 100000) {
// This is horrible code. 9 indentation levels imply a severe problem,
// we should use more functions. Will fix this in the D port.

// Die Anforderungen den offenen Mauscursur
// und das Schreiben des Strings auf die Info...
++tarcnt;
if (priority >  tarinf_priority
 ||(priority == tarinf_priority && hypot < tarinf_hypot)) {
    tarinf = i;
    tarinf_priority = priority;
    tarinf_hypot    = hypot;
}
// ...sind geringer als die für Anklick-Inbetrachtnahme!
if (priority > 1 && priority < 99999) {
    if (!(only_dir_l && i->get_dir() ==  1)
     && !(only_dir_r && i->get_dir() == -1)) {
        // consider this clickable and eligible for tooltip
        if  (priority >  target_priority
         || (priority == target_priority && hypot < target_hypot)) {
            if (target_priority != 0
             && target_priority < priority)
                pan.suggest_tooltip_priority();
            target          = i;
            target_priority = priority;
            target_hypot    = hypot;
            if (priority < target_prio_min)
                target_prio_min = priority;
        }
        else if (priority <  target_prio_min
             || (priority == target_prio_min && hypot >= target_hypot)) {
            if (target_prio_min != 100000
             && target_prio_min > priority)
                pan.suggest_tooltip_priority();
            target_prio_min = priority;
        }
    }
    if (i->get_dir() ==  1) tooltip_r_elig = true;
    if (i->get_dir() == -1) tooltip_l_elig = true;
    if (tooltip_r_elig && tooltip_l_elig)
        pan.suggest_tooltip_force_dir();
}
                }
            }
        }

        // Auswertung von tarinf
        if (tarinf != trlo->lixvec.end()) {
            mouse_cursor.set_y_frame(1);
        }
        pan.stats.set_tarinf(tarinf == trlo->lixvec.end() ? 0 : &*tarinf);
        pan.stats.set_tarcnt(tarcnt);

        // tooltips for queuing builders/platformers
        if (target != trlo->lixvec.end()
         && skill_visible->get_number() != 0) {
            if (target->get_ac() == LixEn::BUILDER
             && skill_visible->get_skill() == LixEn::BUILDER)
                pan.suggest_tooltip_builders();
            else if (target->get_ac() == LixEn::PLATFORMER
             && skill_visible->get_skill() == LixEn::PLATFORMER)
                pan.suggest_tooltip_platformers();
        }

        // Resolving target
        // target == trlo->lixvec.end() if there was nobody under the cursor,
        // or if skill_visible is somehow pan.skill.end(), shouldn't happen
        // we're also checking the displayed number, look at comment about the
        // visible number due to eye candy/making button seem more responsive
        if (target != trlo->lixvec.end() && hardware.get_ml()) {
            if (skill_visible->get_number() != 0) {

                const int lem_id = target - trlo->lixvec.begin();

                // put sound into effect manager, so that it's not played
                // again when the next update is computed
                Sound::Id snd = Lixxie::get_ac_func(skill_visible
                                ->get_skill()).sound_assign;
                effect.add_sound(cs.update + 1, *trlo, lem_id, snd);

                effect.add_arrow_but_dont_draw_it_now(cs.update + 1, *trlo,
                    lem_id); // so framestepping doesn't draw it again

                // Die sichtbare Zahl hinabsetzen geschieht nur fuer's Auge,
                // in Wirklichkeit geschieht dies erst beim Update. Das Augen-
                // spielzeug verabreichen wir allerdings nur, wenn nicht z.B.
                // zweimal auf dieselbe Lix mit derselben Faehigkeit
                // geklickt wurde.
                if (!replay.get_on_update_lix_clicked(
                    cs.update + 1, lem_id, skill_visible->get_skill())
                    && skill_visible->get_number() != LixEn::infinity
                ) {
                    skill_visible->set_number(skill_visible->get_number() - 1);
                    Sound::play_loud(snd);
                }
                Replay::Data data = new_replay_data();
                data.action       = only_dir_l ? Replay::ASSIGN_LEFT
                                  : only_dir_r ? Replay::ASSIGN_RIGHT
                                  : Replay::ASSIGN;
                data.skill        = skill_visible->get_skill();
                data.what         = lem_id;
                replay.add(data);
                Network::send_replay_data(data);

                // Assign shouldn't disable pause. Nonetheless, we advance
                // one frame, to provide feedback. See Gameplay.calc_self()
                // and think about why we can safely do it here
                if (pan.pause.get_on())
                    update();
            }
            else {
                Sound::play_loud(Sound::PANEL_EMPTY);
            }
        }
        else if (hardware.get_ml() && pan.pause.get_on())
            update();
    }
    // end of: mouse in the playing field, no aiming

}
Beispiel #2
0
void Gameplay::calc_active()
{
    if (!malo) return;

    // Wo ist die Maus auf dem Land?
    int mx = map.get_mouse_x();
    int my = map.get_mouse_y();

    const bool mouse_on_panel = hardware.get_my() > map.get_screen_yl();

    // Remedies the bug: displays "N nothings" after level restart
    pan.stats.set_tarcnt(0);

    // Panels ueberpruefen. Zuerst Singleplayer-Panels.
    if (cs.tribes.size() == 1) {
        // Plus und Minus werden nicht auf "clicked" geprueft, sondern aktiv,
        // wenn gehalten. Dennoch benutzen wir Button::clicked(), um Halten
        // zu ermoeglichen.
        // Doppelklicks auf F1 oder F2 werden leider nicht erkannt, im Gegen-
        // satz zu Doppelklicks auf F12 fuer die Nuke. Das liegt daran, dass
        // die Tasten nach etwas gedrueckt gehaltener Zeit immer wieder
        // key_once() ausloesen und es somit auch beim Gedrueckthalten unbe-
        // absichtigt zur Max-/Min-Einstellung kaeme.
        // Dies aendert nur die angezeigte Zahl. Die Ratenaenderung wird erst,
        // wenn ein Update ansteht, zum Replay geschickt. Das spart Ballast,
        // da alle bis auf die letzte Aenderung pro Update egal sind.
        // Modulo 2 rechnen wir bei den Help::timer_ticks, weil Frank die
        // Aenderung der Rate auch bei 60 /sec zu rasant war.
        bool minus_clicked = pan.rate_minus.get_clicked()
                          || hardware.key_release(useR->key_rate_minus);
        bool plus_clicked  = pan.rate_plus .get_clicked()
                          || hardware.key_release(useR->key_rate_plus);
        if (hardware.key_hold(useR->key_rate_minus)) pan.rate_minus.set_down();
        if (hardware.key_hold(useR->key_rate_plus))  pan.rate_plus.set_down();
        if (pan.rate_minus.get_down() || minus_clicked) {
            // Doppelklick?
            if (minus_clicked && Help::timer_ticks - timer_tick_last_F1
             <= hardware.doubleclick_speed) {
                pan.rate_cur.set_number(trlo->spawnint_slow);
            }
            else if (minus_clicked) timer_tick_last_F1 = Help::timer_ticks;
            else {
                // Normales Halten
                if (pan.rate_cur.get_number() < trlo->spawnint_slow) {
                    if (Help::timer_ticks % 3 == 0)
                     pan.rate_cur.set_number(pan.rate_cur.get_number() + 1);
                }
                else pan.rate_minus.set_down(false);
            }
        }
        // Plus
        if (pan.rate_plus.get_down() || plus_clicked) {
            if (plus_clicked && Help::timer_ticks - timer_tick_last_F2
             <= hardware.doubleclick_speed) {
                pan.rate_cur.set_number(trlo->spawnint_fast);
            }
            else if (plus_clicked) timer_tick_last_F2 = Help::timer_ticks;
            else {
                if (pan.rate_cur.get_number() > trlo->spawnint_fast) {
                    if (Help::timer_ticks % 3 == 0)
                     pan.rate_cur.set_number(pan.rate_cur.get_number() - 1);
                }
                else pan.rate_plus.set_down(false);
            }
        }
    }

    // Check skill buttons
    if (malo) {
        // This starts at the next button and breaks immediately if one is
        // pressed. This enables a hotkey to cycle through its skills.
        // We don't read malo->skill_sel, this is only updated after a
        // gameplay physics update. Switching skills is nicer when paused
        // if we use the following variable instead.
        size_t current_button = malo->skill_sel;
        if (current_button >= pan.skill.size()) current_button = 0;
        for (size_t i = 0; i < pan.skill.size(); ++i)
         if (pan.skill[i].get_on()) {
            current_button = i;
            break;
        }
        // This next if makes that an overloaded hotkey will select the skill
        // that's more to the left always, unless a skill with the same
        // hotkey is already selected. If the if wasn't there, sometimes the
        // first hit of a new skillkey would select a different than the
        // leftmost occurence, based on where the skills are.
        if (!pan.skill[current_button].get_clicked())
            current_button = gloB->skill_max - 1;

        // Scan for hotkey presses of empty/nonpresent skills
        // if this is still false later, iterate over nonpresent skills
        // and play the empty-skill sound if a key for them was pressed
        bool some_panel_action = false;

        for (size_t j = 0; j < pan.skill.size(); ++j) {
            size_t i = (current_button + j + 1) % pan.skill.size();
            if (pan.skill[i].get_number() != 0
             && pan.skill[i].get_clicked()
             && !pan.skill[i].get_on()) {
                // Dies wird zwar auch beim naechsten Update erledigt, aber
                // so sieht der Button viel antwortfreudiger aus!
                pan.set_skill_on(i);
                // Das hier ist das eigentlich Wichtige
                Replay::Data data = new_replay_data();
                data.action       = Replay::SKILL;
                data.what         = i;
                replay.add(data);
                Network::send_replay_data(data);
                // Jetzt schon den Klang abspielen, dafuer beim Update nicht.
                // Es wird also der Effekt gesichert und zusaetzlich manuell
                // der Effekt vorgemerkt, falls jemand in der Pause wechselt.
                effect.add_sound(cs.update + 1, *trlo, i, Sound::PANEL);
                Sound::play_loud(Sound::PANEL);
                // Don't check any more buttons, see comment before the loop.
                some_panel_action = true;
                break;
            }
        }


        if (! some_panel_action) {
            // check for empty clicked panel icons
            for (size_t i = 0; i < pan.skill.size(); ++i)
             if (pan.skill[i].get_clicked()
             &&  pan.skill[i].get_skill() != LixEn::NOTHING) {
                if (! pan.skill[i].get_on()) {
                    if (hardware.get_ml()) {
                        Sound::play_loud(Sound::PANEL_EMPTY);
                    }
                    // else play no sound -- we're holding the mouse button
                    // over a wrong skill, that's not notify-necessary, but
                    // leave open the possibility to play a sound later
                }
                // we've clicked on an activated skill, that's all good,
                // never play a sound even if a hotkey was used
                else some_panel_action = true;
            }
            // check for hotkeys of present/nonpresent skills:
            // if the hotkey is of an available skill, we wouldn't have ended
            // up in this if (! some_panel_action)
            if (! some_panel_action)
             for (size_t i = 0; i < LixEn::AC_MAX; ++i) {
                const int key = useR->key_skill[i];
                if (key != 0 && hardware.key_once(key))
                 Sound::play_loud(Sound::PANEL_EMPTY);
            }

        }
    }
    // Restliche Buttons in der normalen Calculate-Funktion

    // Atombombe
    if (pan.get_nuke_doubleclicked()) {
        // set_on() kommt zwar auch im Update, aber wenn wir das
        // hier immer machen, sieht es besser aus. Gleiches gilt fuer
        // den Sound, ist wie beim normalen Anklicken.
        pan.nuke_single.set_on();
        pan.nuke_multi .set_on();
        pan.pause      .set_off();
        Replay::Data data = new_replay_data();
        data.action       = Replay::NUKE;
        replay.add(data);
        Network::send_replay_data(data);
        effect.add_sound(cs.update + 1, *trlo, 0, Sound::NUKE);
        Sound::play_loud(Sound::NUKE);
    }



    ///////////////////////////////////////
    // End of: check things in the panel //
    // Now: mouse on the playing field   //
    ///////////////////////////////////////



    // mouse on the playing field, lixes are selectable
    if (!mouse_on_panel && malo->aiming != 2 && trlo) {
        // Bestimmte Richtung anwählen?
        bool only_dir_l = false;
        bool only_dir_r = false;
        if (  key[useR->key_force_left]
         && ! key[useR->key_force_right]) {
            only_dir_l = true;
            mouse_cursor.set_x_frame(1);
        }
        else if (! key[useR->key_force_left]
         &&        key[useR->key_force_right]) {
            only_dir_r = true;
            mouse_cursor.set_x_frame(2);
        }
        // Decide which lix the cursor points at
        // Die Liste der Lixen wird durchlaufen und die Priorität jeder
        // Lix errechnet. Wird eine höhere Priorität als die derzeitig
        // höchste gefunden, wechselt LixIt target. Bei gleicher Prioritaet
        // haben Lixen, die naeher am Mauscursor liegen, Vorrang! Mit rechter
        // Maustaste (selectable in the options) waehlt man dagegen die letzte
        // Lix mit der niedrigsten Priorität. Auch hier haben naeher liegende
        // Lixen Vorrang.
        LixIt  target = trlo->lixvec.end(); // Klickbar mit Prioritaet
        LixIt  tarinf = trlo->lixvec.end(); // Nicht unb. klickbar mit Prior.
        int    tarcnt = 0; // Anzahl Lixen unter Cursor
        int    target_priority = 0;
        int    tarinf_priority = 0;
        double target_hypot = 1000;
        double tarinf_hypot = 1000;

        // Bei Zoom diese Variablen veraendern
        int zoom   = map.get_zoom();
        int mmld_x = mouse_max_lix_distance_x - mouse_cursor_offset/2*zoom;
        int mmld_u = mouse_max_lix_distance_u - mouse_cursor_offset/2*zoom;
        int mmld_d = mouse_max_lix_distance_d - mouse_cursor_offset/2*zoom;

        // trlo->skill_sel wird erst beim naechsten Update gesetzt.
        // Also suchen wir manuell, welche Faehigkeit der Spieler durch
        // Anklicken gewaehlt hat.
        int skill_visible;
        for (skill_visible = 0; skill_visible < gloB->skill_max
         && ( !pan.skill[skill_visible].get_on()
          || trlo->skill[skill_visible].nr == 0
          ||   pan.skill[skill_visible].get_number() == 0); ++skill_visible);

        // Dies fuer den Notfall, um sinniges Cursoroeffnen zu produzieren
        if (skill_visible == gloB->skill_max) {
            skill_visible = malo->skill_sel;
        }

        for (LixIt i = --trlo->lixvec.end(); i != --trlo->lixvec.begin();
         --i) {
            if (map.distance_x(i->get_ex(), mx) <=  mmld_x
             && map.distance_x(i->get_ex(), mx) >= -mmld_x
             && map.distance_y(i->get_ey(), my) <=  mmld_d
             && map.distance_y(i->get_ey(), my) >= -mmld_u) {

                // Hypot geht von (ex|ey+etwas) aus
                // true = Beachte persoenliche Einschraenkungen wie !MultBuild
                int priority = i->get_priority(
                 trlo->skill[skill_visible].ac, true);

                // Invert priority if a corresponding mouse button is held
                if ((hardware.get_mrh() && useR->prioinv_right)
                 || (hardware.get_mmh() && useR->prioinv_middle)
                 ||  hardware.key_hold(useR->key_priority)) {
                    priority = 100000 - priority;
                }
                double hypot = map.hypot(mx, my, i->get_ex(),
                                          i->get_ey() + ((mmld_d - mmld_u)/2)
                                          );
                if (priority > 0 && priority < 100000) {
                    // Die Anforderungen den offenen Mauscursur
                    // und das Schreiben des Strings auf die Info...
                    ++tarcnt;
                    if (priority >  tarinf_priority
                     ||(priority == tarinf_priority && hypot < tarinf_hypot)) {
                        tarinf = i;
                        tarinf_priority = priority;
                        tarinf_hypot    = hypot;
                    }
                    // ...sind geringer als die für Anklick-Inbetrachtnahme!
                    if ((priority > 1 && priority < 99999)
                     && (priority >  target_priority
                     || (priority == target_priority && hypot < target_hypot))
                     && !(only_dir_l && i->get_dir() ==  1)
                     && !(only_dir_r && i->get_dir() == -1)) {
                        target          = i;
                        target_priority = priority;
                        target_hypot    = hypot;
                    }
                }
            }
        }

        // Auswertung von tarinf
        if (tarinf != trlo->lixvec.end()) {
            mouse_cursor.set_y_frame(1);
        }
        pan.stats.set_tarinf(tarinf == trlo->lixvec.end() ? 0 : &*tarinf);
        pan.stats.set_tarcnt(tarcnt);

        // Auswertung von target
        // Wir kontrollieren auch die angezeigte Zahl, siehe Kommentar zur
        // sichtbaren Zahl wegen Schokolade fuer's Auge
        if (target != trlo->lixvec.end() && hardware.get_ml()) {

            if (pan.skill[skill_visible].get_number() != 0) {
                // assign
                const int lem_id = target - trlo->lixvec.begin();
                pan.pause.set_off();

                Replay::Data data = new_replay_data();
                data.action       = only_dir_l ? Replay::ASSIGN_LEFT
                                  : only_dir_r ? Replay::ASSIGN_RIGHT
                                  : Replay::ASSIGN;
                data.what         = lem_id;
                replay.add(data);
                Network::send_replay_data(data);

                // Die sichtbare Zahl hinabsetzen geschieht nur fuer's Auge,
                // in Wirklichkeit geschieht dies erst beim Update. Das Augen-
                // spielzeug verabreichen wir allerdings nur, wenn nicht z.B.
                // zweimal auf dieselbe Lix mit derselben Faehigkeit
                // geklickt wurde. Den unwahrscheinlichen Fall, dass man
                // zweimal mit beide Male anwendbaren Faehigkeiten auf dieselbe
                // Lix geklickt hat, koennen wir vernachlaessigen - dann
                // erscheint die Nummernaenderung eben erst beim kommenden Upd.
                // Auch der Sound (s.u.) wird dann nicht gespielt.
                if (!replay.get_on_update_lix_clicked(cs.update + 1, lem_id)
                 && pan.skill[skill_visible].get_number() != LixEn::infinity) {
                    pan.skill[skill_visible].set_number(
                    pan.skill[skill_visible].get_number() - 1);
                }
                // Sound in der Effektliste speichern, damit er nicht beim Upd.
                // nochmal ertoent, und dazu wird er hier nochmals gespielt,
                // damit wir sicher gehen, dass er beim Klick kommt.
                Sound::Id snd = Lixxie::get_ac_func(pan.skill[skill_visible]
                                .get_skill()).sound_assign;
                effect.add_sound(cs.update + 1, *trlo, lem_id, snd);
                Sound::play_loud(snd);
            }
            else {
                Sound::play_loud(Sound::PANEL_EMPTY);
            }
        }

    }
    // Ende von: Maus im Spielfeld ohne Zielen

    // Zielen
    else if (malo->aiming == 2) {
        // Hingucken der Lixen wird im Update der Lixen erledigt. Hier
        // geht es nur darum, einen Klick und dessen Koordinaten zu
        // registrieren. Es wird entsprechend auch ein Netzwerkpaket versandt.
        if (hardware.get_ml() && !pan.pause.is_mouse_here())
         for (LixIt lem = trlo->lixvec.begin();
         lem != trlo->lixvec.end(); ++lem) if (lem->get_aiming()) {
            pan.pause.set_off();
            // Klick sauber vormerken fuers naechste Update und verschicken.
            Replay::Data data = new_replay_data();
            data.action       = Replay::AIM;
            data.what         = (my * level.initial * map.get_xl())
                              + (mx * level.initial)
                              + lem - trlo->lixvec.begin(); // siehe replay.h
            replay.add(data);
            Network::send_replay_data(data);

            // Gegen zweimaliges Schiessen pro Update
            malo->aiming = 1;

            // Sound in der Effektliste speichern, damit er nicht beim Update
            // nochmal ertoent, und zusatzlich wird er hier nochmals gespielt,
            // damit wir sicher gehen, dass er auf jeden Fall beim Klick kommt.
            Sound::play_loud(lem->get_sound_aim());
            effect.add_sound(cs.update + 1, *trlo, lem - trlo->lixvec.begin(),
                                                   lem->get_sound_aim());
            break;
        }
    }
    // end of: aiming

}