[Solved!] Editing a sprint script

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
amv2k9
Posts: 2178
Joined: Sun Jan 10, 2010 4:05 pm
Location: Southern California

[Solved!] Editing a sprint script

Post by amv2k9 »

I've been messing around with Project MSX again lately, and one of the things I've been implementing is a means to double tap directions to evade or sprint. I've used KeksDose's dodge script seen in Trailblazer and combined it with the sprint functionality of MSX, but I've run into a snag; when 'forward' is double tapped & then held, the sprint should continue until the key is released, but the sprint only ends once 'PlayerStamina' is depleted.

Code snippet:

Code: Select all

if((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=5)) // Double-tap forward for sprint.
{
 GiveInventory("SprintingPlayer",1);
 while((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=1))
 {
  Delay(1);
 }
 TakeInventory("SprintingPlayer",1);
 Delay(const:SD_DASHDELAY);
}
Full script:

Code: Select all

script "MSX Side Dodge" enter
{
 int dashinterval;
 int input;
 int oldInput;
 int taps;
 int tics;
 int last;
 int angle;
 int velX;
 int velY;
 int velZ;
 int player = PlayerNumber();
 while(GetActorProperty(0,APROP_HEALTH)>0)
 {
  dashinterval = GetUserCVar(player,"MSXA_DashInterval");
  if(dashinterval < 2)
  {
   Delay(const:1); 
   continue;
  }
  input = GetPlayerInput(-1,INPUT_BUTTONS);
  oldInput = GetPlayerInput(-1,INPUT_OLDBUTTONS);
  for(int i = 0; i < 4; i++)
  {
   if(IsButtonPressed(input,oldInput,settings[i][0]))
   {
    taps++;
    tics = dashinterval;
    if(taps == 2 && last == i)
    {
     taps = 0;
     angle = GetActorAngle(0) + settings[i][1];
     if((GetActorZ(0)-GetActorFloorZ(0)>0)&&(checkinventory("PlayerStamina")>=20))// In air, double tap any direction for air-dodge.
     {
      velX = FixedMul(cos(angle),SD_DASHSPEED);
      velY = FixedMul(sin(angle),SD_DASHSPEED);
      velZ = -GetActorVelZ(0) + SD_DASHJUMP;
      SetActorVelocity(0,velX,velY,velZ,true,false);
      ActivatorSound("player/powerevade",127);
      TakeInventory("PlayerStamina",20);
      FadeRange(20,255,0,0.3,0,0,0,0.0,0.5);
      Delay(const:SD_DASHDELAY);
     }
     else // On ground.
     {
      if((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=5)) // Double-tap forward for sprint.
      {
       GiveInventory("SprintingPlayer",1);
       while((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=1))
       {
        Delay(1);
       }
       TakeInventory("SprintingPlayer",1);
       Delay(const:SD_DASHDELAY);
      }
      else if((input & BT_BACK||BT_MOVELEFT||BT_MOVERIGHT)&&(CheckInventory("PlayerStamina")>=20))// Double-tap any direction except forward for dodge.
      {
       velX = FixedMul(cos(angle),SD_DASHSTRONG);
       velY = FixedMul(sin(angle),SD_DASHSTRONG);
       velZ = 0.0;
       SetActorVelocity(0,velX,velY,velZ,true,false);
       ActivatorSound("player/powerevade",127);
       TakeInventory("PlayerStamina",20);
       FadeRange(20,255,0,0.3,0,0,0,0.0,0.5);
       Delay(const:SD_DASHDELAY);
      }
     }
     while(GetActorVelZ(0) < 0.0)
     {
      Delay(const:1);
     }
    }
    last = i;
   }
  }
  if(tics)
  {
   tics--;
   if(!tics)
   {
    taps = 0;
   }
  }
  Delay(const:1);
 }
}
If this script could be made better in other ways, feel free to let me know, as I'm clearly in over my head :P
Last edited by amv2k9 on Mon May 08, 2017 4:13 pm, edited 1 time in total.
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Editing a sprint script

Post by Blue Shadow »

amv2k9 wrote:Code snippet:

Code: Select all

if((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=5)) // Double-tap forward for sprint.
{
 GiveInventory("SprintingPlayer",1);
 while((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=1))
 {
  Delay(1);
 }
 TakeInventory("SprintingPlayer",1);
 Delay(const:SD_DASHDELAY);
}
A problem I see here is that input isn't updated with player's current input every tic during the while loop. This means that input & BT_FORWARD will always be true in that loop. That leaves the stamina as the only part of the expression which could return false, and that's when the player runs out of stamina.
User avatar
amv2k9
Posts: 2178
Joined: Sun Jan 10, 2010 4:05 pm
Location: Southern California

Re: Editing a sprint script

Post by amv2k9 »

Blue Shadow wrote:...input isn't updated with player's current input every tic during the while loop. This means that input & BT_FORWARD will always be true in that loop...
So, assuming I'm understanding this correctly, should the following...

Code: Select all

while((input & BT_FORWARD)&&(CheckInventory("PlayerStamina")>=1))
...be changed to test either or both of the conditions every time, like...

Code: Select all

until(((input & BT_FORWARD)!=1)||(CheckInventory("PlayerStamina")<1))
I can't actually test at the moment.
User avatar
ramon.dexter
Posts: 1529
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: Editing a sprint script

Post by ramon.dexter »

Checking for input needs to be inside the while loop. You see, the while loop executes the check every tic (or other interval as in delay).

So, I am making it the following:

Code: Select all

while (true)
{
  if(checkAnything == true)
    {
the rest...
}
 
}
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Editing a sprint script

Post by Blue Shadow »

I wrote:A problem I see here is that input isn't updated with player's current input every tic during the while loop.
In other words, you need to keep updating input by calling GetPlayerInput() during that loop. Considering you're hitting delays here, player's actual input and what is stored in input could be different if it's not kept updated.
User avatar
amv2k9
Posts: 2178
Joined: Sun Jan 10, 2010 4:05 pm
Location: Southern California

Re: Editing a sprint script

Post by amv2k9 »

ramon.dexter wrote:...the while loop executes the check every tic (or other interval as in delay).
Blue Shadow wrote:...you need to keep updating input by calling GetPlayerInput() during that loop. ...player's actual input and what is stored in input could be different if it's not kept updated.
Okay, I think I understand it now. Thanks to both of you for your help!
User avatar
amv2k9
Posts: 2178
Joined: Sun Jan 10, 2010 4:05 pm
Location: Southern California

Re: Editing a sprint script

Post by amv2k9 »

...So I guess I didn't get it as well as I thought.

Code: Select all

while (true)
{
	if(((input & BT_FORWARD)==1)&&(CheckInventory("PlayerStamina")>=1)==true)
	{
		Delay(1);
	}
}
I tried to make it like the syntax in ramon.dexter's example, but it doesn't fix the problem; the player still sprints after you let go of forward. Not only that, it introduces another bug; once sprint ends after a loss of all 'PlayerStamina', you can't dash ever again.
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Editing a sprint script

Post by Blue Shadow »

Would this work?

Code: Select all

while(true)
{
    // Update the variable with player's current input.
    input = GetPlayerInput(-1, INPUT_BUTTONS);

    if(!((input & BT_FORWARD) && CheckInventory("PlayerStamina") >= 1))
    {
        // Either the player stopped pressing the key or they ran out of stamina, so exit the while-loop.
        break;
    }

    Delay(1);
}
User avatar
amv2k9
Posts: 2178
Joined: Sun Jan 10, 2010 4:05 pm
Location: Southern California

Re: Editing a sprint script

Post by amv2k9 »

Blue Shadow wrote:Would this work?
It does! Thank you, thank you, thank you for your help and patience. Now if I can just study this so I can avoid problems like this in the future...
Locked

Return to “Editing (Archive)”