News:

One Minute Game Review by The Happy Friar: https://ugetube.com/@OneMinteGameReviews
Also on Rumble: https://rumble.com/c/c-1115371

idTech 4 (aka Doom 3 tech) Discord Server! https://discord.gg/9wtCGHa

Main Menu

Attempting to code in a double tap feature

Started by BielBdeLuna, September 05, 2016, 07:39:53 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

BielBdeLuna

I'm working as the coder for I guess it's an unannounced mod, and I was tasked on adding a feature from the fragging free mod, the dodge activated by double tapping the left or the right keys on the keyboard. in FF they did it within doom3 script (which is always a fall-back option) I thouth on implementing it via c++, and so I have it implemented in c++:

void idPhysics_Player::PerformDodge( bool dodge_right ) {
const float DODGE_POWER = 550.0f;
const float DODGE_HEIGHT = 300.0f;

idPlayer* player = static_cast<idPlayer*>(self);

idVec3 current_vel = GetLinearVelocity();
idVec3 push;
idAngles viewangles = idAngles( player->viewAngles[0], player->viewAngles[1], player->viewAngles[2] );
viewangles[2] = 0.0f;

idVec3 viewangles_to_right;
viewangles.ToVectors( NULL, &viewangles_to_right ); // viewangles to right...
idVec3 dodgedir = viewangles_to_right;
if ( !dodge_right ) {
dodgedir = -dodgedir;
}
//idVec3 normaldir = viewangles.ToForward();

push = dodgedir * DODGE_POWER;
push[2] = DODGE_HEIGHT;

player->StartSound("snd_jump_small", SND_CHANNEL_VOICE, 0, false, NULL);

current_vel += push;

SetLinearVelocity( current_vel );

command.flags ^= UCF_DOUBLE_TAP; //revert the flag so the player can go back to double tap again

}


the way to perform the dodge is the added code in idPhysics_Player::WalkMove:

               if ( ( command.flags & UCF_DOUBLE_TAP ) && ( waterLevel <= WATERLEVEL_FEET ) ) {
if ( command.rightmove > 0 ) {
PerformDodge( true );
} else if ( command.rightmove < 0 ) {
PerformDodge( false );
}
}


so it all moves around that flag: UCF_DOUBLE_TAP
if we have a direction (left or right) and we have the flag on, then on that tick we're double tapping (in the end of PerformDodge I lower the flag)

I did it this way, because I thought that recreating every button and key just for the double tapping would create more problems that become any solution. the flag system has flaws, it can only handle a single double tap at the time, so it fails to recognize more than one double tap (that is double tapping two or three keys at the time). but for testing should be fine.

my problem comes on how to activate this flag, my system doesn't seem to work:

void idUsercmdGenLocal::DoubleTap( void ) {
// the double tap feature for left / right keys, TODO generalize with a method that serves all keys and buttons
// only serves a single dobule tap motion

//if ( ( idUsercmdGenLocal::in_doubleTap.getBool() ) && ( cmd.flags && !UCF_DOUBLE_TAP ) ) {
if ( cmd.flags & !UCF_DOUBLE_TAP ) {
int cur_time = Sys_Milliseconds()

if ( !ButtonState( UB_RIGHT ) && !ButtonState( UB_LEFT ) ) {
last_key = selected_key;
selected_key = -2;
double_tap_time = cur_time + 750; // let not last more than that time before making the next tap
} else {
//pressing the two keys always waste the chance!
last_key = -1;
selected_key = -2;
double_tap_time = 0;
next_double_tap_chance_time = 0;
common->Printf( "pressed both" );
}

if ( ButtonState( UB_RIGHT ) && !ButtonState( UB_LEFT ) ) {
if ( selected_key == UB_LEFT ) {
last_key = -1;
}
selected_key = UB_RIGHT;+
common->Printf( "pressed right" );
} else if ( ButtonState( UB_LEFT ) && !ButtonState( UB_RIGHT ) ) {
if ( selected_key == UB_RIGHT ) {
last_key = -1;
}
selected_key = UB_LEFT;
common->Printf( "pressed left" );
}

if ( ( selected_key == last_key ) && ( cur_time < double_tap_time ) && ( cur_time >= next_double_tap_chance_time ) ) {
cmd.flags ^= UCF_DOUBLE_TAP;
common->Printf( "double Tap" );
next_double_tap_chance_time = cur_time + 1500;
}
}
}


this code is called from idUsercmdGenLocal::MakeCurrent when creating the command of the frame.

it seems that ButtonState( UB_LEFT ) and ButtonState( UB_RIGHT ) doesn't react as those buttons are pressed, can someone help me solve this, is there any way to make it even more general purpose?

double tapping is a three part situation, you first tap, then you stop tapping ,and then you tap again, I'm using two int variables to keep the key that was tap in the beginning, and a timer to know if we are legit when it comes to double tapping, it's I think a very heavy handed way to keep track of it all but it's just testing code. any idea why it doesn't work?

Ivan_the_B

I'm still working in Fragging Free from time to time and I'm planning to move the dodge logic to c++ soon.
As starting point have a look at my double-jump implementation in Hardqore2 mod. Sources are on moddb.
It should be very similar.