Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #1  
Old 09-19-2010, 08:37 PM
Xanathol
Sarnak
 
Join Date: Oct 2009
Posts: 52
Default Find Nearest Object/Wall & Z value of floor @ point?

Forgive me as I am learning my way around the code - I couldn't find a function to identify the closest object / wall / whatever - is there one?

Reason: I am trying to implement the Shadow Knight AA Hate Step in the code. On live, this is an activatable AA that sends the SK forward x distance instantly; think Shadow Step, but always in the direction you are facing, for a fixed distance, unless you run into an object or wall, of course.

Right now, I have the code working for the spell ( no, the client didn't take care of this for me like it does with Shadow Step and yes, I added a break condition to the spell effect code switch ). The only problem is that I can go through walls and at the moment, I can't 'place' the character on the ground should the ground he is facing be lower than what he is on ( much less preventing him from going through a wall when the ground is slanted upwards ), since I don't know of a funciton to find the z value at a given point. So what I think I need is:

1. the ability to find objects / walls 'in the way' along a certain vector.
2. the ability to read the Z value of the map along said vector.

Anyone who knows the code that can point me to the functions I am looking for, if they exist?

Thanks!
Reply With Quote
  #2  
Old 09-20-2010, 05:58 AM
joligario's Avatar
joligario
Developer
 
Join Date: Mar 2003
Posts: 1,497
Default

I believe you are looking for the line of sight function. Check LoS to your point?
Reply With Quote
  #3  
Old 09-20-2010, 01:57 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

Defined in map.h/map.cpp
Code:
bool LineIntersectsZone(VERTEX start, VERTEX end, float step, VERTEX *result, FACE **on = NULL) const;
Will check if there are any obstacles in between the points defined by the start and end vertices, returning true if there is an obstacle.

I believe the result vertex is the point of collision, and the face 'on' is the triangle that was hit.

Code:
float Map::FindBestZ( NodeRef node_r, VERTEX p1, VERTEX *result, FACE **on) const
Given vertex p1, will return the 'best' Z value for that point. Basically it will cast a ray downwards from point p1 and if it intersects
something, then will return the Z of the face it intersected.

If it finds no ground beneath the given point, it will try again from 10 Z units higher up.

If you look in waypoints.cpp and pathing.cpp, you will find examples of both functions in use.
Reply With Quote
  #4  
Old 09-20-2010, 08:18 PM
Xanathol
Sarnak
 
Join Date: Oct 2009
Posts: 52
Default

Thank you both! I must have went right by those - will let you all know how it goes.

Thanks!
Reply With Quote
  #5  
Old 10-11-2010, 06:18 PM
Xanathol
Sarnak
 
Join Date: Oct 2009
Posts: 52
Default

Ok, so I gave it a few runs, tried to add in debug messages to figure out what was going wrong, but have to throw in the towel and see if you guys can spot what I am doing wrong here. Here is the sample code I wrote for the Hate Step effect ( recall - warps a character forward in the direction they are facing x distance; its an SK AA on live ).

Code:
			case SE_ShadowStepDirectional:
			{
				double look_heading = GetHeading();
				look_heading /= 256;
				look_heading *= 360;
				look_heading += 180;
				if(look_heading > 360)
					look_heading -= 360;

				// note: x and y are backwards
                                // the -8 is just a multiplier to increase the distance I arbitrarily picked, nothing more
				double new_x = ( spells[spell_id].base[i] * -8 ) * sin(double(look_heading * 0.017453289 ));
				double new_y = ( spells[spell_id].base[i] * -8 ) * cos(double(look_heading * 0.017453289 ));
				double new_z = GetZ( );

				// try to see if a zone wall is in the way
				VERTEX	start, end, result;
				FACE	*triangle	= NULL;

				start.x		= GetX( );
				start.y		= GetY( );
				start.z		= GetZ( );
				end.x		= GetX( ) + new_x;
				end.y		= GetY( ) + new_y;
				end.z		= GetZ( );

				bool	b = zone->zonemap->LineIntersectsZone( start, end, 1.0f, &result, &triangle );
				Message(15, "Debug: result is %s: %lf %lf %lf", ( b == true ? "true" : "false" ), result.x, result.y, result.z );
				if( b )
				{	// result should give us the point we hit
					Message(15, "Debug: intersect @ %lf %lf %lf", result.x, result.y, result.z );
					new_x	= result.x;
					new_y	= result.y;
				}
				else
				{	// otherwise, set new_* to values we wanted to use
					new_x	+= GetX( );
					new_y	+= GetY( );
					Message(15, "Debug: used2 x,y %lf %lf", new_x, new_y );
				}
				// now lets find the z-axis value
				VERTEX	org;
				org.x	= new_x;
				org.y	= new_y;
				org.z	= GetZ( );
				Message(15, "Debug: old z %lf", org.z );
				//new_z	= zone->zonemap->FindBestZ( MAP_ROOT_NODE, org, &result, &triangle );
				new_z	= org.z - zone->zonemap->FindClosestZ( org );
				Message(15, "Debug: new z %lf", new_z );

                                // I have no idea why, but I had to double the GetHeading return value for this function to work for me, hence the *2
				CastToClient()->MovePC( zone->GetZoneID(), zone->GetInstanceID(), new_x, new_y, new_z, GetHeading( ) *2, 0, PCStep );
				Message(15, "%s %s", GetName(), spells[spell_id].cast_on_other );
Thus far, I still go into / through walls and seem to always get returned a 0 from FindBestZ ( note - I've been testing int he Arena ), either implementation, while the 'real Z' shown by a #loc command can be vastly different, plus or minus.


I can paste in some of the logs too if that helps, but I figured it may be hard to envision in pure numbers when one is in a wall or not...

Anything stand out as to what I am doing wrong? Seems like a rather simple thing to implement but I put no limits as to what I can screw up!
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 12:27 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3