EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=590)
-   -   Find Nearest Object/Wall & Z value of floor @ point? (https://www.eqemulator.org/forums/showthread.php?t=32152)

Xanathol 09-19-2010 08:37 PM

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!

joligario 09-20-2010 05:58 AM

I believe you are looking for the line of sight function. Check LoS to your point?

Derision 09-20-2010 01:57 PM

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.

Xanathol 09-20-2010 08:18 PM

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

Thanks!

Xanathol 10-11-2010 06:18 PM

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! :grin:


All times are GMT -4. The time now is 11:01 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.