thanks
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
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Show posts Menuif ( nullifier_frobable_entity && ( frobable_entity == nullifier_frobable_entity ) ) { //a strange case
#define SUPERCOOL_TICK 0.1
object supercool_object { //any "object" is a sub object from "entity"
boolean IS_ON;
float thread_id;
void signalOn();
void signalOff();
void mainLoop();
void init(); // called by entity.cpp
void destroy(); //called by entity.cpp
}
void supercool_object::init() {
//called when the entity is spawned
IS_ON = false;
thread_id = thread mainLoop();
}
void supercool_object::destroy() {
// called when the entity is erased
float t_id;
if ( thread_id > 0 ) {
t_id = thread_id;
thread_id = 0;
sys.terminate( t_id );
}
}
void supercool_object::mainLoop() {
float t_id;
while( true ) {
/*
if ( "some situation that should de-enable forever the entity from such effect but not erase the entity from the map" ) {
if ( IS_ON ) {
IS_ON = false;
self.setShaderParm(SHADERPARM_FROB, IS_ON);
}
t_id = thread_id;
thread_id = 0;
sys.terminate( t_id );
}
*/
self.setShaderParm(SHADERPARM_FROB, IS_ON);
sys.wait( SUPERCOOL_TICK );
}
}
void supercool_object::signalOn() {
IS_ON = true;
}
void supercool_object::signalOff() {
IS_ON = false;
}
#define FROBBING_TICK 0.1;
object player : player_base {
supercool_object frobable_entity; //the type is a "supercool_object" type (so the file that defines that type has to come earlier in doom_main.script)
supercool_object last_frobable_entity; // those two variables won't be initiated until we first encounter a frobable object (can scriptobject variables be NULL? IDK )
supercool_object nullifier_frobable_entity; //since "NULL" is a "float" scriptobjects can't be nullified with "= NULL"
boolean FROBBING;
boolean testFrobable();
float frob_manager;
void frobUpdate();
(...)
}
boolean player::testFrobable() {
ent entity_to_check;
if ( frobable_entity ) {
last_frobable_entity = frobable_entity;
nullifier_frobable_entity = frobable_entity;
}
//check using whatever method if the entity the cursor is pointing to is frobable
//if not
FROBBING = false;
return false;
//if yes
frobable_entity = entity_to_check;
FROBBING = true;
if ( frob_manager == 0 ) { //only start the frobUpdate loop if it doesn't exist
frob_manager = thread frobUpdate();
}
return true;
}
void player::frobUpdate() {
float t_id, time_now, next_tick;
next_tick = 0;
while( true ) {
time_now = sys.getTime();
if ( time_now >= next_tick ) {
next_tick = time_now + FROBBING_TICK;
if ( ( nullifier_frobable_entity && ( frobable_entity == nullifier_frobable_entity ) ) { //a strange case
frobable_entity.callFunction( "signalOff" );
FROBBING = false;
}
if ( last_frobable_entity ) {
last_frobable_entity.callFunction( "signalOff" );
}
if ( FROBBING ) {
frobable_entity.callFunction( "signalON" );
} else {
t_id = frob_manager;
frob_manager = 0;
sys.terminate( t_id ); //the loop self kills itself if not frobbing anything
}
}
sys.wait( FROBBING_TICK ); //or it could be sys.waitFrame();
}
}
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
}
if ( ( command.flags & UCF_DOUBLE_TAP ) && ( waterLevel <= WATERLEVEL_FEET ) ) {
if ( command.rightmove > 0 ) {
PerformDodge( true );
} else if ( command.rightmove < 0 ) {
PerformDodge( false );
}
}
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;
}
}
}