Hosting and domain costs until October 2024 have been generously sponsored by dumptruck_ds. Thank you!

Difference between revisions of "Editing Impulses"

From Quake Wiki

(Created page with " Details of the quake-c interface with a human Posted by numbersix on Jun 14th, 2014 - Intermediate Server Side Coding Quake-c has three distinct ways to know what a human p...")
 
(reformatting to wiki standards. are there missing links in this page?)
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
 +
The following is taken from a post by '''numbersix''' on June 14, 2014.
 +
== Original Post ==
 +
Quake-c has three distinct ways to know what a human player wants.
  
Details of the quake-c interface with a human
 
 
Posted by numbersix on Jun 14th, 2014 - Intermediate Server Side Coding
 
 
Quake-c has three distinct ways to know what a human player wants.
 
  
 
1. mouse directional movement (interpreted movement of the mouse, typically across the x-y plane of the monitor with a cursor, but used differently in FPS games)
 
1. mouse directional movement (interpreted movement of the mouse, typically across the x-y plane of the monitor with a cursor, but used differently in FPS games)
 
+
// defs.qc
// defs.qc
+
.vector angles;
.vector angles;
 
 
 
 
2. button press on the mouse
 
2. button press on the mouse
 
+
// defs.qc
// defs.qc
+
.float button0; // fire
.float button0; // fire
+
.float button1; // use
.float button1; // use
+
.float button2; // jump
.float button2; // jump
+
// Cataboligne - 9.30.11 - extended mouse button support from darkplaces (... and possibly other engines)
 
+
// some mice have a lot of buttons now: Cyborggaming.com (yes, I already have one...it is very nice)
// Cataboligne - 9.30.11 - extended mouse button support from darkplaces (... and possibly other engines)
+
.float button3, button4, button5, button6, button7, button8, button9, button10, button11, button12, button13, button14, button15, button16;
// some mice have a lot of buttons now: Cyborggaming.com (yes, I already have one...it is very nice)
 
 
 
.float button3, button4, button5, button6, button7, button8, button9, button10, button11, button12, button13, button14, button15, button16;
 
 
 
 
3. impulse command
 
3. impulse command
 
+
// defs.qc
// defs.qc
+
.float impulse; // weapon changes
.float impulse; // weapon changes
 
 
 
 
Impulse is a console command - "impulse {number}" where {number} is an integer value 1 - 255.
 
Impulse is a console command - "impulse {number}" where {number} is an integer value 1 - 255.
 
+
impulse 2; // select weapon slot 2 - shotgun<
impulse 2; // select weapon slot 2 - shotgun
+
Of course, having to pull down the console to issue commands would be an extreme challenge in game control, so a number of shortcut possibilities are used. The most common type is another console command called bind - "bind {keypress} {command sequence}"
 
+
// typical weapon slot key bindings
Of course, having to pull down the console to issue commands would be an extreme challenge in game control, so a number of shortcut possibilities are used.
+
// note that keys can be bound to multiple commands - either by a semicolon separated list or with aliases
The most common type is another console command called bind - "bind {keypress} {command sequence}"
+
 
+
// typical weapon slot key bindings
+
bind "1" "impulse 1"
// note that keys can be bound to multiple commands - either by a semicolon separated list or with aliases
+
bind "2" "impulse 2"
 
+
bind "3" "impulse 3"
bind "1" "impulse 1"
+
bind "4" "impulse 4"
bind "2" "impulse 2"
+
bind "5" "impulse 5"
bind "3" "impulse 3"
+
bind "6" "impulse 6"
bind "4" "impulse 4"
+
bind "7" "impulse 7"
bind "5" "impulse 5"
+
bind "6" "impulse 6"
 
bind "7" "impulse 7"
 
 
 
 
When the indicated key is pressed, the assigned command is entered directly in the console.
 
When the indicated key is pressed, the assigned command is entered directly in the console.
 
+
=== Usage in code ===
Usage in code.
+
==== Mouse movement ====
 
 
Mouse movement:
 
 
 
 
The mouse directional interpretation is assigned by the engine to the player entity vector ".angles".
 
The mouse directional interpretation is assigned by the engine to the player entity vector ".angles".
 
The player entity is set by the engine from a reserved list of entity slots (usually 1 - 16) upon player network connect.
 
The player entity is set by the engine from a reserved list of entity slots (usually 1 - 16) upon player network connect.
 
(Debugging hint: for singleplayer and the player hosting a "-listen" server [ not a "-dedicated" server ] this will always be entity 1.)
 
(Debugging hint: for singleplayer and the player hosting a "-listen" server [ not a "-dedicated" server ] this will always be entity 1.)
  
How is mouse movement interpreted by the engine?
 
  
Movement up and down (often thought of as the y plane on your monitor) is interpreted as a scalar rate and used to change angles_x referred to as "pitch".
+
==== How is mouse movement interpreted by the engine? ====
(Debugging hint - pitch is reversed from expectations and limited - this is NOT a viewpoint angle - looking up has positive angles_x and looking down has negative angles_x, with a range of 30 to -30. So when the player looks straight up - 90 degrees from viewpoint of 0 degrees or straight ahead, the value of angles_x is 30.)
+
Movement up and down (often thought of as the y plane on your monitor) is interpreted as a scalar rate and used to change angles_x referred to as "pitch". (Debugging hint - pitch is reversed from expectations and limited - this is NOT a viewpoint angle - looking up has positive angles_x and looking down has negative angles_x, with a range of 30 to -30. So when the player looks straight up - 90 degrees from viewpoint of 0 degrees or straight ahead, the value of angles_x is 30.) This causes player viewpoint to move up and down - from pointing straight up to pointing straight down. Additionally any model assigned to the player entity will be adjusted by using the angles_x value as an actual angle. What this means is when a player looks up, the model will "tilt" back at angles_x degrees. When the player looks down the model will "tilt" forward at angles_x degrees .
  
This causes player viewpoint to move up and down - from pointing straight up to pointing straight down. Additionally any model assigned to the player entity will be adjusted by using the angles_x value as an actual angle. What this means is when a player looks up, the model will "tilt" back at angles_x degrees. When the player looks down the model will "tilt" forward at angles_x degrees .
 
  
 
As if this usage of pitch was not already confusing enough - for a visual understanding this video segment demonstrates first pitch (up-down), then yaw (side to side) and then faster pitch / faster yaw:
 
As if this usage of pitch was not already confusing enough - for a visual understanding this video segment demonstrates first pitch (up-down), then yaw (side to side) and then faster pitch / faster yaw:
Line 68: Line 50:
 
fig 1. pitch and yaw
 
fig 1. pitch and yaw
  
Movement from side to side (often thought of as the x plane on your monitor ) is interpreted as a scalar rate and used to change angles_y referred to as "yaw".
 
This is an actual facing angle that represents the players view offset from angle 0. Any model assigned to the player entity will be rotated to the same angle.
 
  
The ".angles" vector values are modified by a rate - the faster you move the mouse the faster they change. This degree of rate control is the primary reason some keyboard + mouse users despise console controls. (Even the silly little analog sticks that attempt to do the same thing.)
+
Movement from side to side (often thought of as the x plane on your monitor ) is interpreted as a scalar rate and used to change angles_y referred to as "yaw". This is an actual facing angle that represents the players view offset from angle 0. Any model assigned to the player entity will be rotated to the same angle. The ".angles" vector values are modified by a rate - the faster you move the mouse the faster they change. This degree of rate control is the primary reason some keyboard + mouse users despise console controls. (Even the silly little analog sticks that attempt to do the same thing.)
  
 
You can also assign pitch and yaw angles in quake-c. This code fragment forces the engine to change the viewpoint to the assigned value:
 
You can also assign pitch and yaw angles in quake-c. This code fragment forces the engine to change the viewpoint to the assigned value:
 
+
<nowiki>// teleporters use this to point the player in the proper direction
// teleporters use this to point the player in the proper direction
 
 
// self must be the player entity - often it will be other in the case of touch with trigger entities
 
// self must be the player entity - often it will be other in the case of touch with trigger entities
  
self.fixangle = TRUE; // turn this way immediately
 
 
Mouse buttons:
 
  
The button values are read by the engine from the OS drivers and the floats defined above are assigned the set values.
+
self.fixangle = TRUE; // turn this way immediately</nowiki>
 
+
==== Mouse buttons ====
For each mouse button pressed, the corresponding .button{n} value is set to 1 - if that button is not pressed it is 0.
+
The button values are read by the engine from the OS drivers and the floats defined above are assigned the set values. For each mouse button pressed, the corresponding .button{n} value is set to 1 - if that button is not pressed it is 0. While all mouse button presses could be seen per frame - you can only see one impulse value in quake-c per frame! The mouse button values can be read anywhere in the code until they are zeroed. This is typically done in functions called from PlayerPreThink() and PlayerPostThink() ( per frame code: Moddb.com )
 
 
While all mouse button presses could be seen per frame - you can only see one impulse value in quake-c per frame!
 
 
 
The mouse button values can be read anywhere in the code until they are zeroed. This is typically done in functions called from PlayerPreThink() and PlayerPostThink() ( per frame code: Moddb.com )
 
 
 
Impulse commands:
 
  
 +
=== Impulse commands ===
 
The float ".impulse" is assigned the value of an impulse command by the engine when one is entered in the console by that player - either directly, by key binding or alias.
 
The float ".impulse" is assigned the value of an impulse command by the engine when one is entered in the console by that player - either directly, by key binding or alias.
  
 
Impulse commands are handled in client.qc and weapons.qc.
 
Impulse commands are handled in client.qc and weapons.qc.
 
Found in PlayerPostThink() covered here: Moddb.com
 
Found in PlayerPostThink() covered here: Moddb.com
 +
// do weapon stuff - after intermission and dead checks
  
// do weapon stuff - after intermission and dead checks
 
 
W_WeaponFrame ();
 
 
// in weapons.qc
 
void () W_WeaponFrame =
 
{
 
if (time < self.attack_finished)
 
return;
 
 
if (self.impulse)
 
ImpulseCommands(); // also in weapons.qc
 
};
 
 
void () ImpulseCommands =
 
{
 
// weapons are changed 1 - 7
 
// cycle weapons (using key press or mousewheel / buttons) are done
 
  
// *** any mod impulses should be checked and dealt with here
+
W_WeaponFrame ();
  
// *** sample code - this is an example only!
 
  
if (self.impulse == 66)
+
// in weapons.qc
bprint("developer: Impulse 66 detected !\n");
+
 +
void () W_WeaponFrame =
 +
{
 +
if (time < self.attack_finished)
 +
return;
  
if (self.button6)
+
if (self.impulse)
{
+
ImpulseCommands(); // also in weapons.qc
bprint("developer: Mouse button #6 detected !\n");
+
};
bprint(" player facing angle: ");
+
bprint(ftos(self.angles_y));
+
void () ImpulseCommands =
bprint(" - pitch: ");
+
{
bprint(ftos(self.angles_x));
+
// weapons are changed 1 - 7
bprint(" - pitch view angle: ");
+
// cycle weapons (using key press or mousewheel / buttons) are done
bprint(ftos(self.angles_x * -3)); // correct for sign, estimate true view angle
+
bprint("\n");
+
// *** any mod impulses should be checked and dealt with here
}
 
// *** end sample code
 
  
// MUST be cleared for next impulse and so command is not repeated
+
// *** sample code - this is an example only!
self.impulse = 0;
 
};
 
  
Your best opportunity to handle impulse commands is in this function *** before the value is zeroed.
+
if (self.impulse == 66)
 +
bprint("developer: Impulse 66 detected !\n");
  
Player interface is done in the per frame code segment via PlayerPreThink() and PlayerPostThink() ( per frame code: Moddb.com ) to interpret commands as quickly as possible.
+
if (self.button6)
 +
{
 +
bprint("developer: Mouse button #6 detected !\n");
 +
bprint(" player facing angle: ");
 +
bprint(ftos(self.angles_y));
 +
bprint(" - pitch: ");
 +
bprint(ftos(self.angles_x));
 +
bprint(" - pitch view angle: ");
 +
bprint(ftos(self.angles_x * -3)); // correct for sign, estimate true view angle
 +
bprint("\n");
 +
}
 +
// *** end sample code
 +
 +
// MUST be cleared for next impulse and so command is not repeated
 +
self.impulse = 0;
 +
};
 +
Your best opportunity to handle impulse commands is in this function *** before the value is zeroed. Player interface is done in the per frame code segment via PlayerPreThink() and PlayerPostThink() ( per frame code: Moddb.com ) to interpret commands as quickly as possible.
  
 
New impulses can be added for: bots, admin control, alternate weapon modes, grapple hooks, dropping runes or items, and many other exciting details.
 
New impulses can be added for: bots, admin control, alternate weapon modes, grapple hooks, dropping runes or items, and many other exciting details.
  
 
Good luck adding new impulses to your mods!
 
Good luck adding new impulses to your mods!

Latest revision as of 20:08, 16 December 2020

The following is taken from a post by numbersix on June 14, 2014.

Original Post[edit]

Quake-c has three distinct ways to know what a human player wants.


1. mouse directional movement (interpreted movement of the mouse, typically across the x-y plane of the monitor with a cursor, but used differently in FPS games)

// defs.qc
.vector angles;

2. button press on the mouse

// defs.qc
.float button0; // fire
.float button1; // use
.float button2; // jump
// Cataboligne - 9.30.11 - extended mouse button support from darkplaces (... and possibly other engines)
// some mice have a lot of buttons now: Cyborggaming.com (yes, I already have one...it is very nice)
.float button3, button4, button5, button6, button7, button8, button9, button10, button11, button12, button13, button14, button15, button16;

3. impulse command

// defs.qc
.float impulse; // weapon changes

Impulse is a console command - "impulse {number}" where {number} is an integer value 1 - 255.

impulse 2; // select weapon slot 2 - shotgun<

Of course, having to pull down the console to issue commands would be an extreme challenge in game control, so a number of shortcut possibilities are used. The most common type is another console command called bind - "bind {keypress} {command sequence}"

// typical weapon slot key bindings
// note that keys can be bound to multiple commands - either by a semicolon separated list or with aliases


bind "1" "impulse 1"
bind "2" "impulse 2"
bind "3" "impulse 3"
bind "4" "impulse 4"
bind "5" "impulse 5"
bind "6" "impulse 6"
bind "7" "impulse 7"

When the indicated key is pressed, the assigned command is entered directly in the console.

Usage in code[edit]

Mouse movement[edit]

The mouse directional interpretation is assigned by the engine to the player entity vector ".angles". The player entity is set by the engine from a reserved list of entity slots (usually 1 - 16) upon player network connect. (Debugging hint: for singleplayer and the player hosting a "-listen" server [ not a "-dedicated" server ] this will always be entity 1.)


How is mouse movement interpreted by the engine?[edit]

Movement up and down (often thought of as the y plane on your monitor) is interpreted as a scalar rate and used to change angles_x referred to as "pitch". (Debugging hint - pitch is reversed from expectations and limited - this is NOT a viewpoint angle - looking up has positive angles_x and looking down has negative angles_x, with a range of 30 to -30. So when the player looks straight up - 90 degrees from viewpoint of 0 degrees or straight ahead, the value of angles_x is 30.) This causes player viewpoint to move up and down - from pointing straight up to pointing straight down. Additionally any model assigned to the player entity will be adjusted by using the angles_x value as an actual angle. What this means is when a player looks up, the model will "tilt" back at angles_x degrees. When the player looks down the model will "tilt" forward at angles_x degrees .


As if this usage of pitch was not already confusing enough - for a visual understanding this video segment demonstrates first pitch (up-down), then yaw (side to side) and then faster pitch / faster yaw:


fig 1. pitch and yaw


Movement from side to side (often thought of as the x plane on your monitor ) is interpreted as a scalar rate and used to change angles_y referred to as "yaw". This is an actual facing angle that represents the players view offset from angle 0. Any model assigned to the player entity will be rotated to the same angle. The ".angles" vector values are modified by a rate - the faster you move the mouse the faster they change. This degree of rate control is the primary reason some keyboard + mouse users despise console controls. (Even the silly little analog sticks that attempt to do the same thing.)

You can also assign pitch and yaw angles in quake-c. This code fragment forces the engine to change the viewpoint to the assigned value: // teleporters use this to point the player in the proper direction // self must be the player entity - often it will be other in the case of touch with trigger entities self.fixangle = TRUE; // turn this way immediately

Mouse buttons[edit]

The button values are read by the engine from the OS drivers and the floats defined above are assigned the set values. For each mouse button pressed, the corresponding .button{n} value is set to 1 - if that button is not pressed it is 0. While all mouse button presses could be seen per frame - you can only see one impulse value in quake-c per frame! The mouse button values can be read anywhere in the code until they are zeroed. This is typically done in functions called from PlayerPreThink() and PlayerPostThink() ( per frame code: Moddb.com )

Impulse commands[edit]

The float ".impulse" is assigned the value of an impulse command by the engine when one is entered in the console by that player - either directly, by key binding or alias.

Impulse commands are handled in client.qc and weapons.qc. Found in PlayerPostThink() covered here: Moddb.com

// do weapon stuff - after intermission and dead checks


W_WeaponFrame ();


// in weapons.qc

void () W_WeaponFrame =
{
if (time < self.attack_finished)
return;
if (self.impulse)
ImpulseCommands(); // also in weapons.qc 
};

void () ImpulseCommands =
{
// weapons are changed 1 - 7
// cycle weapons (using key press or mousewheel / buttons) are done

// *** any mod impulses should be checked and dealt with here
// *** sample code - this is an example only!
if (self.impulse == 66)
bprint("developer: Impulse 66 detected !\n");
if (self.button6)
{
bprint("developer: Mouse button #6 detected !\n");
bprint(" player facing angle: ");
bprint(ftos(self.angles_y));
bprint(" - pitch: ");
bprint(ftos(self.angles_x));
bprint(" - pitch view angle: ");
bprint(ftos(self.angles_x * -3)); // correct for sign, estimate true view angle
bprint("\n");
}
// *** end sample code

// MUST be cleared for next impulse and so command is not repeated
self.impulse = 0;
};

Your best opportunity to handle impulse commands is in this function *** before the value is zeroed. Player interface is done in the per frame code segment via PlayerPreThink() and PlayerPostThink() ( per frame code: Moddb.com ) to interpret commands as quickly as possible.

New impulses can be added for: bots, admin control, alternate weapon modes, grapple hooks, dropping runes or items, and many other exciting details.

Good luck adding new impulses to your mods!