## Maintain verticality while dashing in mid-air

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

### Maintain verticality while dashing in mid-air

As the subject reads, I'm attempting to implement a dash mechanic that keeps the player in mid-air while using the dash function, sort of how it is in Doom Eternal.

You'll see in the code provided that I'm using the dash function from "Project MSX" in conjunction with nashmove; this is so the player decelerates in a controlled manner rather than flying from one point to the next. The reason I point this out is I'd like this effect to also be applied while in mid-air, however, if there is a better way to achieve this then I am certainly open to suggestions!

Still, the main thing I'm trying to figure out is how to keep the player's vertical position while dashing and any pointers would be greatly appreciated.

Code: Select all
`// ACS#library "dash"#include "zcommon.acs"//Player-Evade taken from MagSigmaX's Project MSXfunction void evade_start(int angle, int dir){   int force = 40;//45;   faderange (255, 255, 255, 0.3, 0, 0, 0, 0.0, 0.5);   ThrustThing(angle+dir, force, 0, 0);   GiveInventory("EvadeCheck",1);   GiveInventory("Decelerate",1);}script "Player-Evade" enter {   int angle=0, input=0, oldinput=0;   int heldTime=0, force = 100, sdel=25;   SetPlayerProperty(0, OFF, PROP_FROZEN);       while (true) {        delay(1);        angle = GetActorAngle(0) >> 8;      input = GetPlayerInput(-1, INPUT_BUTTONS);      oldinput = GetPlayerInput(-1, INPUT_OLDBUTTONS);      TakeInventory("Decelerate",1);            if ((oldinput & BT_FORWARD && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 0)) {                                       evade_start(angle, 0);                ActivatorSound("player/powerevade",127);               SetFont("dash2");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               ACS_Execute(3808, 0);               }            else if((oldinput & BT_BACK && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 0)){               evade_start(angle, 128);               ActivatorSound("player/powerevade",127);               SetFont("dash2");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               ACS_Execute(3808, 0);            }            else if((oldinput & BT_MOVELEFT && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 0)){               evade_start(angle, 64);               ActivatorSound("player/powerevade",127);               SetFont("dash2");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               ACS_Execute(3808, 0);            }            else if((oldinput & BT_MOVERIGHT && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 0)){               evade_start(angle, 192);               ActivatorSound("player/powerevade",127);               SetFont("dash2");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               ACS_Execute(3808, 0);            }            else if ((oldinput & BT_FORWARD && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 1 && checkinventory("EvadeHold") == 0)) {                                       evade_start(angle, 0);                ActivatorSound("player/powerevade",127);               SetFont("dash3");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               }            else if((oldinput & BT_BACK && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 1 && checkinventory("EvadeHold") == 0)){               evade_start(angle, 128);               ActivatorSound("player/powerevade",127);               SetFont("dash3");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);            }            else if((oldinput & BT_MOVELEFT && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 1 && checkinventory("EvadeHold") == 0)){               evade_start(angle, 64);               ActivatorSound("player/powerevade",127);               SetFont("dash3");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);            }            else if((oldinput & BT_MOVERIGHT && oldinput & BT_USER3 && checkinventory("EvadeCheck") == 1 && checkinventory("EvadeHold") == 0)){               evade_start(angle, 192);               ActivatorSound("player/powerevade",127);               SetFont("dash3");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);            }            else if(checkinventory("EvadeCheck") == 2){               SetFont("dash3");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               SetFont("dash3");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               ActivatorSound("player/evaderdy",75);               TakeInventory("EvadeCheck",2);               TakeInventory("EvadeHold",1);            }            else if(checkinventory("EvadeCheck") == 0){               SetFont("dash1");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);            }            else if(checkinventory("EvadeCheck") == 1 && checkinventory("EvadeHold") == 1){               SetFont("dash2");               HudMessage(s:"A"; 1,95,CR_UNTRANSLATED, 0.015, 0.885, 9.0, 0.8, 3.7);               delay(sdel);               ActivatorSound("player/evaderdy",75);               TakeInventory("EvadeCheck",1);               TakeInventory("EvadeHold",1);            }        } }script 3808 (void) NET CLIENTSIDE {   delay(10);   GiveInventory("EvadeHold",1);   }function int CheckPlayerOnGround (void) {   int onground;   if (GetActorZ(0) == GetActorFloorZ(0) || GetActorVelZ(0) == 0) {      onground = 1; // On ground.   }   else {      onground = 0; // In air.   }   return onground;}script "Script_NoSlideSetup" ENTER{   int speeddec = 0.80;//0.85;   while( true )   {      // Stop script from trying to run off wit meh goodies!      delay(1);      if(checkinventory("Decelerate")==1)      {         // Anti-Ice : no sliding.          // Check if player isnt walking and if the player is on the ground         if( !( GetPlayerInput(-1,MODINPUT_BUTTONS) & BT_FORWARD ) && !( GetPlayerInput(-1,MODINPUT_BUTTONS) & BT_BACK ) &&             !( GetPlayerInput(-1,MODINPUT_BUTTONS) & BT_MOVELEFT ) && !( GetPlayerInput(-1,MODINPUT_BUTTONS) & BT_MOVERIGHT )/* &&            CheckPlayerOnGround()*/)         {            // Decrease player speed gradually, but at a faster rate than friction.            SetActorVelocity(0, FixedMul(GetActorVelX(0), speeddec), FixedMul(GetActorVelY(0), speeddec), GetActorVelZ(0), false, true);         }      }   }}   `

BROS_ETT_311
I've got somethin' and it goes thumpin' like this

Joined: 03 Nov 2017

### Re: Maintain verticality while dashing in mid-air

The first idea I had is to set the player's Z velocity to 0, which I don't know if it's possible in ACS without stopping all other velocity with Thing_Stop.
And then setting flight to the player using SetPlayerProperty.
Untested:
Code: Select all
`function void evade_start(int angle, int dir){   SetPlayerProperty(0,1,PROP_FLY);   Thing_Stop(0);   int force = 40;//45;   (....) `

However setting flight off might be tricky, since I don't know where exactly the dash ends.
So instead you can give the player a custom PowerFlight powerup with a limited time.
So the flight is taken away at the same time the player dash ends.

This is untested, so I'm not entirely sure if this will work though.
Maybe flight isn't the best option here and SetActorFlag with +NOGRAVITY should be used.
Jarewill

Joined: 21 Jul 2019

### Re: Maintain verticality while dashing in mid-air

Thanks so much!! That definitely pointed me in the right direction. At first I was actually considering the gravity property, but upon further testing I noticed the player would start sinking while in air...which made sense. What I ended up using was a combination of FLY and FREEZE, which resulted in exactly what I was aiming for.

Here's my end result for reference:
Code: Select all
`function void evade_start(int angle, int dir){   int force = 40;//45;   faderange (255, 255, 255, 0.3, 0, 0, 0, 0.0, 0.5);   ThrustThing(angle+dir, force, 0, 0);   GiveInventory("EvadeCheck",1);   GiveInventory("Decelerate",1);   SetPlayerProperty(0,1,PROP_FLY);   SetPlayerProperty(0, ON, PROP_FROZEN);   ACS_NamedExecute("Evade-Over", 0);//This references the script below}`

Code: Select all
`   script "Evade-Over" (void) NET CLIENTSIDE {   delay(8);   SetPlayerProperty(0,0,PROP_FLY);   SetPlayerProperty(0, OFF, PROP_FROZEN);   }`
You do not have the required permissions to view the files attached to this post.

BROS_ETT_311
I've got somethin' and it goes thumpin' like this

Joined: 03 Nov 2017