Fixing player animation for walls

Discuss programming in the QuakeC language.
Post Reply
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Fixing player animation for walls

Post by Cobalt »

Has there been a fix for this? The animation continues (player_run) even if we are moving and hit a wall. This probably is ok for underwater, but on land it would look better making player_stand activate.

I researched it a little and velocity_x and velocity_y are active so the qc will trigger the animations.

I remember thinking that .th_blocked would be the trigger called for this scenario, but was told its only for movetype_push.
Dr. Shadowborg
InsideQC Staff
Posts: 1120
Joined: Sat Oct 16, 2004 3:34 pm

Re: Fixing player animation for walls

Post by Dr. Shadowborg »

vlen(self.velocity) > 0 check perhaps? (add FL_ONGROUND check, for falling if you don't want quakeguy to pretend he's Luigi :P)
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Re: Fixing player animation for walls

Post by Cobalt »

Yea I determined vlen was about 27 or so when you keep running into the wall. Also you are FL_ONGROUND even as you impact the side of a wall in any way.

In DP there is a .movement vector which is active when you press a key to move. Maybe somehow that could be used with velocity.

Im also experimenting with some new code I call: Pctbbox () , which right now only works on the bottom rectangle of the player box. I merely pick the corners at absmin, plus the 4 points from the center to the extreme x and y edges, in total (8) coordinates, (plus a 2 quake units fudge factor). I check if they are in solid pointcontents, and determine a % score. Right now its to pick a "landing" animation when the player lands on a ledge , and its nearly working.

So if I can do the same thing for the l -r sides and f-r sides, with some checks we would know if he was touching a wall thats stopping his movement. Looks like any wall higher than a step stops him from moving.

Dr. Shadowborg wrote:vlen(self.velocity) > 0 check perhaps? (add FL_ONGROUND check, for falling if you don't want quakeguy to pretend he's Luigi :P)
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: Fixing player animation for walls

Post by gnounc »

Image
PrimalLove
Posts: 14
Joined: Sun Oct 19, 2014 2:37 am

Re: Fixing player animation for walls

Post by PrimalLove »

@Cobalt This simple method can work but it may not be good for all situations.

Code: Select all


.float blockplayer;

// In case you do not hve this defined (A suggestion by Spike and included in gnounc qc clean source)
void makevectors2(vector ang) = 
{
	ang_x *= -1;
	makevectors(ang);
};

// Place this in PostThink somewhere. 
void Wall_Check()
{
	makevectors2 (self.angles); 
	vector start = self.origin + '0 0 16';
	v_forward_z = 0;
	normalize(v_forward);
	vector end = start + v_forward*24;
	traceline (start, end, TRUE, self); // Don't worry about monsters unless you want them to block movement too :s
	if(trace_fraction < 1)
		self.blockplayer = 1;
	else	
		self.blockplayer = 0;

        if(self.blockplayer)
	{
		self.velocity = self.velocity * 0;
		self.origin = self.oldorigin;
	}
}

//in Player.qc

void()	player_stand1 =[	$axstnd1,	player_stand1	]
{
	self.weaponframe=0;

	if ((self.velocity_x || self.velocity_y) && !self.blockplayer)
	{
		self.walkframe=0;
		player_run();
		return;
	}

void()	player_run =[	$rockrun1,	player_run	]
{
	self.weaponframe=0;

	if ((!self.velocity_x && !self.velocity_y) || self.blockplayer)
	{
		self.walkframe=0;
		player_stand1();
		return;
	}


This will basically do what you want. Animations will stop while your are against a wall and you will need to physically turn your character to start moving again. This will only assume going forward of course. You could use something like a tracebox to take care of all sides or multiple tracelines. Depends on how far you want to go with this. But this example will work. Might also get you stuck in some locations... :s
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Re: Fixing player animation for walls

Post by Cobalt »

Ok thanks PL. I used your logic conditions on the player stand and run functions which check a new function Blocked () which returns a score based on measurements from knee level to points about 2 Q units all around the bbox sides and corners. If any one of those are in solid, we are blocked. The score system allows for some leeway so you can tell "how" much blocked but thats for future dev.

This is what I have working so far, but I have worked in some solid hard coded values for vlen of velocity based in my mods paramaters which allow for sprinting via button8. Not sure if these values would fit in other mods, but probably ok to start with. Im not too keen on using vlen of velocity as a means to further detect/ perfect the condtition where if we are facing a wall and hitting it at a slight angle, we need to animate because there is a slight velocity depending on the mouse angle / direction we are facing the wall. The other alternative is use dotproduct I guess, but that seems perhaps a more complex forumla.

Code: Select all


// In player_stand funct
if ((self.velocity_x || self.velocity_y) && !Blocked (self))
	{
		self.walkframe = 0;
		player_run ();
		return;
	}


// In player_run func, added waterlevel condition
if ((!self.velocity_x && !self.velocity_y) || (Blocked (self) && !self.waterlevel))
	{
		self.walkframe = 0;
		player_stand1 ();
		return;
	}



float(entity head) Blocked =
{

if (!head.health || head.waterlevel) return 0;
if (!head.button8 && vlen(head.velocity) >= 28) return 0;

local float score;
local vector here;
here = head.origin - '0 0 10';


   if (head.flags & FL_CLIENT) 
{	

if (pointcontents (here + '18 0 0') == CONTENT_SOLID) 
score = score + 1; // Front at knee level

if (pointcontents (here + '-18 0 0') == CONTENT_SOLID) score = score + 1; // back at knee level


if (pointcontents (here + '18 18 0') == CONTENT_SOLID) 
score = score + 1; // Front side at knee level
if (pointcontents (here + '18 -18 0') == CONTENT_SOLID) 
score = score + 1; // Front side knee level

if (pointcontents (here + '-18 18 0') == CONTENT_SOLID) 
score = score + 1; // back side at knee level
if (pointcontents (here + '-18 -18 0') == CONTENT_SOLID) 
score = score + 1; // back side at knee level

if (pointcontents (here + '0 18 0') == CONTENT_SOLID) 	
score = score + 1; // side at knee level
if (pointcontents (here + '0 -18 0') == CONTENT_SOLID) 
score = score + 1; // side at knee level

}
     
     
	 if (score)
	 {
	 if (head.button8 && vlen(head.velocity) > 44.5) // For condition when sprinting into a wall and having mild velocity
		  return 0;		 
		  
	return 1;
	}
        return FALSE;    // Entity is not  blocked.
};



PrimalLove wrote:@Cobalt This simple method can work but it may not be good for all situations.
Post Reply