TUTORIAL 12 - grappling hook

von Matt Ownby


Wie du vielleicht weisst, wurde der Code für den grappling hook bereits in Quake 3 eingearbeitet, die Idee wurde aber später wieder verworfen. Um den hook verfügbar zu machen, müssen wir also nur hier und da ein wenig "patchen" :evil: . Das folgende Tutorial beschreibt einen schnellen (sehr schnell sogar) Weg, den grappling hook zu reaktivieren.

1. Ändere g_client.c (in game)

In der Funktion ClientSpawn must du folgendes ergänzen:

    client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GAUNTLET );
    // start MATT
    client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GRAPPLING_HOOK);
    // end MATT

    client->ps.ammo[WP_GAUNTLET] = -1;
    client->ps.ammo[WP_GRAPPLING_HOOK] = -1;

Etwas weiter unten:

    // start MATT
    for ( i = WP_NUM_WEAPONS - 2 ; i > 0 ; i-- ) {
    // changed the -1 to a -2 so the grapple isn't selected by default
    // end MATT


    if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) {
    client->ps.weapon = i;
    break;
    }
    }

2. Ändere ui_controls2.c (in ui)
Füge an der nachfolgend gezeigten Stelle (etwa bei Zeile 100), diesen Wert für ID_WEAPON 10 ein. Das Feld g_bindings[] benutzt diese Werte als Indizes für die Steuerung aller MTYPE_ACTION's. Falls ihre Reihenfolge nicht mit der in g_bindings[] übereinstimmt, werden Fehler auftreten.
Die darauf folgenden Werte müssen je um eins erhöht werden, um sie wieder eindeutig zu machen.

    #define ID_CHAT3 32
    #define ID_CHAT4 33
    // start MATT
    #define ID_WEAPON10 34 // grappling hook

    // all others
    #define ID_FREELOOK 35
    #define ID_INVERTMOUSE 36
    #define ID_ALWAYSRUN 37
    #define ID_AUTOSWITCH 38
    #define ID_MOUSESPEED 39
    #define ID_JOYENABLE 40
    #define ID_JOYTHRESHOLD 41
    #define ID_SMOOTHMOUSE 42
    // end MATT

Darunter in controls_t

    menuaction_s bfg;
    // start MATT
    menuaction_s hook;
    // end MATT

    menuaction_s attack;

Darunter in g_bindings[] :

    {"messagemode4", "chat - attacker", ID_CHAT4, ANIM_CHAT, -1, -1, -1, -1},
    // start MATT
    {"weapon 10", "grappling hook", ID_WEAPON10, ANIM_WEAPON10, '0', -1, -1, -1},
    // stop MATT

    {(char*)NULL, (char*)NULL, 0, 0, -1, -1, -1, -1},

Weiter unten in *g_weapons_controls[] :

    (menucommon_s *)&s_controls.bfg,
    // start MATT
    (menucommon_s *)&s_controls.hook,
    // end MATT

    NULL,

Viieel weiter unten in Controls_MenuInit

    s_controls.bfg.generic.type = MTYPE_ACTION;
    s_controls.bfg.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
    s_controls.bfg.generic.callback = Controls_ActionEvent;
    s_controls.bfg.generic.ownerdraw = Controls_DrawKeyBinding;
    s_controls.bfg.generic.id = ID_WEAPON9;

    // start MATT
    s_controls.hook.generic.type = MTYPE_ACTION;
    s_controls.hook.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
    s_controls.hook.generic.callback = Controls_ActionEvent;
    s_controls.hook.generic.ownerdraw = Controls_DrawKeyBinding;
    s_controls.hook.generic.id = ID_WEAPON10;
    // end MATT


    s_controls.attack.generic.type = MTYPE_ACTION;
    s_controls.attack.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
    s_controls.attack.generic.callback = Controls_ActionEvent;
    s_controls.attack.generic.ownerdraw = Controls_DrawKeyBinding;
    s_controls.attack.generic.id = ID_ATTACK;

Tadaa, fertig.
Als kleines Bonbon: der Code funzt auch für CTF.

<< Tutorial 11 | | Tutorial 13 >>