Button use

As requested, here's a quick tutorial on converting buttons (the ones in game, not the ones on your keyboard) from things you push by moving against the, into buttons you puch by hitting a key on your keyboard. I'm going to be describing two ways how to do this, one of which uses a command which you bind to a key, and the other which uses Button_use (similar to Button_fire for your fire key, but which id never got round to using) both are fairly easy, but I prefer the first as I tend to use button_use for a secondary fire button (using the secondary fire tut on this site) The second method has the advantage that you don't have to keep hitting the key to have the effect occur


First of all we have to disable the touch function of the buttons so that they no longer trigger when you hit them. Open up g_func.c and scroll down to SP_func_button

Now that we are here, comment out the lines of code below, in that function. you could delete them, but i don't see much of a point. if you decide to go back to the old way of doing things it'll make your life easier

        else if (! ent->targetname)
               ent->touch = button_touch;

all this does is stop buttons from being activated by being pushed. Buttons that are activated by being shot will still work that way (i'll be adding checks so you cant activate them by command too)


Method 1

Now to the slightly trickier part. Anyone that's done the health station tut will notice similarities in the code. Thats because I'm almost lifting it straight from that tut

Open up g_cmds.c and go to the end of it. Change it to read like below

        else if (Q_stricmp(cmd, "usebutton") == 0)
               SCmd_use_button(ent);
        else    // anything that doesn't match a command will be a chat
               Cmd_Say_f (ent, false, true);

You'll need to bind a key to usebutton to be able to activate a button

Method 2

Sorry to say, but I havn't tested this method, but it should work without any problems. If you have a problem, email me and I'll see what I can do to fix it.

Open up p_client.c i'm using this file because it's good for effects you want to happen every 0.1 seconds. Go to the function Clientbeginserverframe and add the code below to it, just before the end }

        if (ent->client->buttons & BUTTON_USE)
        SCmd_use_button(ent);

Fairly simple isn't it? (all this does is check to see if the button is being pressed at the start of every server frame, and activates the map button if it is.) You'll need to bind a key to +use to be able to have it work.


Now the code below is the same for both methods, but where you put it is different. For method one, put it in g_cmds.c just after the #define lines at the top. For method two, put it in p_client.c just after the #defines at the top.

 
void button_use (edict_t *self, edict_t *other, edict_t *activator);
 
void SCmd_use_button(edict_t *ent)
{
        vec3_t  forward,end;
        trace_t tr;
        
 
        AngleVectors (ent->client->v_angle, forward, NULL, NULL);
        VectorMA (ent->s.origin, 40, forward, end);
        tr = gi.trace (ent->s.origin, NULL, NULL, end, ent, MASK_SHOT);
 
        if (Q_stricmp(tr.ent->classname,"func_button")==0)
               button_use(tr.ent,ent,ent);
}

At the moment the range of the button pressing is 40 quake units, modify the 40 in the VectorMA to change the range of the press. The button also must be directly in front of the player.


There we go, compile it and try it out :) If it doesn't work, email me with the compilation errors that occur and I'll see what I can do to help


Skunkworks Tutorials