Raised This Month: $51 Target: $400
 12% 

A* Pathfinding API


Post New Thread Reply   
 
Thread Tools Display Modes
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 07-21-2014 , 17:44   Re: A* Pathfinding API
Reply With Quote #31

Quote:
Originally Posted by yokomo View Post
Impressive, so this can be set auto way point to NPC right? can someone create a simple plugin that can make a npc move on itself? Because this is too advance for me
You can always make NPC wander around on its own, and that is not really what you would use this for. This can be used, for instance, if you are creating DotA mod and you want to create Courier. Courier should pathfind from base to specific player to give him items it carries, wherever he is on the map. That is just one use for it, but there are plenty more.
klippy is offline
meTaLiCroSS
Gaze Upon My Hat
Join Date: Feb 2009
Location: Viņa del Mar, Chile
Old 07-22-2014 , 22:01   Re: A* Pathfinding API
Reply With Quote #32

@Black Rose

PHP Code:
                engfunc(EngFunc_TraceLinev1v2gData[WorkerIndex][_Ignore], gData[WorkerIndex][_IgnoreID], hTrace);

                
get_tr2(hTraceTR_flFractiontrFraction);
                
free_tr2(hTrace); 
You're freeing an empty trace handle

By the way, it won't do anything bad

PHP Code:
static cell AMX_NATIVE_CALL free_tr2(AMX *amxcell *params)
{
    
TraceResult *tr reinterpret_cast<TraceResult *>(params[1]);
    if (!
tr)
    {
        return 
0;
    }

    
g_FreeTRs.push(tr);

    return 
1;

You can create a new handler, or just using 0 for using the global trace handle
__________________
Quote:
Originally Posted by joropito View Post
You're right Metalicross
meTaLiCroSS is offline
fireattack
Senior Member
Join Date: Jul 2008
Old 12-18-2014 , 01:18   Re: A* Pathfinding API
Reply With Quote #33

https://www.youtube.com/watch?v=qQWV...Wt8s9amaq5FrYg

Nice work, but did this today and that was eating CPU like a boss, still searching a good way to A* pathfind a lot of monsters at the same time.
fireattack is offline
AGoodGuy
Member
Join Date: Sep 2014
Old 02-16-2015 , 16:18   Re: A* Pathfinding API
Reply With Quote #34

First, i want to say thank you Black Rose, you making is awesome for NPC moding!

I'm newbie in coding, i try to using your function to make my NPC to find object, but i can't understand how to do this.

Full code of NPC(base code from 1 NPC tut in alliedmod(:

PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <engine>
#include <hamsandwich>


//Boolean of when NPC spawned 
new boolg_NpcSpawn[256]; 
//Boolean to check if NPC is alive or not 
new boolg_NpcDead[256]; 
//Classname for our NPC 
new const g_NpcClassName[] = "ent_npc"
//Constant model for NPC 
new const g_NpcModel[] = "models/barney.mdl"

//List of sounds our NPC will emit when damaged 
new const g_NpcSoundPain[][] =  

    
"barney/ba_pain1.wav"
    
"barney/ba_pain2.wav"
    
"barney/ba_pain3.wav" 


//Sounds when killed 
new const g_NpcSoundDeath[][] = 

    
"barney/ba_die1.wav"
    
"barney/ba_die2.wav"
    
"barney/ba_die3.wav" 


//Sounds when we knife our flesh NPC
new const g_NpcSoundKnifeHit[][] = 
{
    
"weapons/knife_hit1.wav",
    
"weapons/knife_hit2.wav",
    
"weapons/knife_hit3.wav",
    
"weapons/knife_hit4.wav"
}

new const 
g_NpcSoundKnifeStab[] = "weapons/knife_stab.wav";

//List of idle animations 
new const NPC_IdleAnimations[] = { 012311121821396365 };

//Sprites for blood when our NPC is damaged
new spr_blood_dropspr_blood_spray

//Player cooldown for using our NPC 
new Floatg_Cooldown[32];

//Boolean to check if we knifed our NPC
new boolg_Hit[32];

public 
plugin_init()
{
    
register_plugin("NPC Plugin""1.1""Mazza");
    
register_clcmd("say /npc""ClCmd_NPC");
    
    
register_event("HLTV""Event_NewRound""a""1=0""2=0");
        
    
RegisterHam(Ham_TakeDamage"info_target""npc_TakeDamage");
    
RegisterHam(Ham_Killed"info_target""npc_Killed");
    
RegisterHam(Ham_Think"info_target""npc_Think");
    
RegisterHam(Ham_TraceAttack"info_target""npc_TraceAttack");
    
RegisterHam(Ham_ObjectCaps"player""npc_ObjectCaps");
    
    
register_forward(FM_EmitSound"npc_EmitSound"); 
}

public 
plugin_precache()
{
    
spr_blood_drop precache_model("sprites/blood.spr")
    
spr_blood_spray precache_model("sprites/bloodspray.spr")
    
    new 
i;
    for(
sizeof g_NpcSoundPain i++)
        
precache_sound(g_NpcSoundPain[i]);
    for(
sizeof g_NpcSoundDeath i++)
        
precache_sound(g_NpcSoundDeath[i]);

    
precache_model(g_NpcModel)
}

public 
plugin_cfg()
{
    
Load_Npc()
}

public 
ClCmd_NPC(id)
{
    
//Create a new menu
    
new menu menu_create("NPC: Main Menu""Menu_Handler");
    
    
//Add some items to the newly created menu
    
menu_additem(menu"Create NPC""1");
    
menu_additem(menu"Delete NPC""2");
    
menu_additem(menu"Save current NPC locations""3");
    
menu_additem(menu"Delete all NPC""4");
    
    
//Let the menu have an 'Exit' option
    
menu_setprop(menuMPROP_EXITMEXIT_ALL);
    
    
//Display our menu
    
menu_display(idmenu);
}

public 
Menu_Handler(idmenuitem)
{
    
//If user chose to exit menu we will destroy our menu
    
if(item == MENU_EXIT)
    {
        
menu_destroy(menu);
        return 
PLUGIN_HANDLED;
    }
    
    new 
info[6], szName[64];
    new 
accesscallback;
    
    
menu_item_getinfo(menuitemaccessinfocharsmax(info), szNamecharsmax(szName), callback);
    
    new 
key str_to_num(info);
    
    switch(
key)
    {
        case 
1:
        {
            
//Create our NPC
            
Create_Npc(id);
        }
        case 
2:
        {
            
//Remove our NPC by the users aim
            
new iEntbodyszClassname[32];
            
get_user_aiming(idiEntbody);
            
            if (
is_valid_ent(iEnt)) 
            {
                
entity_get_string(iEntEV_SZ_classnameszClassnamecharsmax(szClassname));
                
                if (
equal(szClassnameg_NpcClassName)) 
                {
                    
remove_entity(iEnt);
                }
                
            }
        }
        case 
3:
        {
            
//Save the current locations of all the NPCs
            
Save_Npc();
            
            
client_print(idprint_chat"[AMXX] NPC origin saved succesfully");
        }
        case 
4:
        {
            
//Remove all NPCs from the map
            
remove_entity_name(g_NpcClassName);
            
            
client_print(idprint_chat"[AMXX] ALL NPC origin removed");
        }
    }
    
    
//Keep the menu displayed when we choose an option
    
menu_display(idmenu);
    
    return 
PLUGIN_HANDLED;
}

public 
npc_TakeDamage(iEntinflictorattackerFloat:damagebits)
{
    
//Make sure we only catch our NPC by checking the classname
    
new className[32];
    
entity_get_string(iEntEV_SZ_classnameclassNamecharsmax(className))
    
    if(!
equali(classNameg_NpcClassName))
        return;
        
    
//Play a random animation when damanged
    
Util_PlayAnimation(iEntrandom_num(1317), 1.25);

    
//Make our NPC say something when it is damaged
    //NOTE: Interestingly... Our NPC mouth (which is a controller) moves!! That saves us some work!!
    
emit_sound(iEntCHAN_VOICEg_NpcSoundPain[random(sizeof g_NpcSoundPain)],  VOL_NORMATTN_NORM0PITCH_NORM)
    
    
g_Hit[attacker] = true;
}

public 
npc_Killed(iEnt)
{
    new 
className[32];
    
entity_get_string(iEntEV_SZ_classnameclassNamecharsmax(className))
    
    if(!
equali(classNameg_NpcClassName))
        return 
HAM_IGNORED;

    
//Player a death animation once our NPC is killed
    
Util_PlayAnimation(iEntrandom_num(2530))

    
//Because our NPC may look like it is laying down. 
    //The bounding box size is still there and it is impossible to change it so we will make the solid of our NPC to nothing
    
entity_set_int(iEntEV_INT_solidSOLID_NOT);

    
//The voice of the NPC when it is dead
    
emit_sound(iEntCHAN_VOICEg_NpcSoundDeath[random(sizeof g_NpcSoundDeath)],  VOL_NORMATTN_NORM0PITCH_NORM)

    
//Our NPC is dead so it shouldn't take any damage and play any animations
    
entity_set_float(iEntEV_FL_takedamage0.0);
    
//Our death boolean should now be true!!
    
g_NpcDead[iEnt] = true;
        
    
//The most important part of this forward!! We have to block the death forward.
    
return HAM_SUPERCEDE
}

public 
npc_Think(iEnt)
{
    if(!
is_valid_ent(iEnt))
        return;
    
    static 
className[32];
    
entity_get_string(iEntEV_SZ_classnameclassNamecharsmax(className))
    
    if(!
equali(classNameg_NpcClassName))
        return;
    
    
//We can remove our NPC here if we wanted to but I left this blank as I personally like it when there is a NPC coprse laying around
    
if(g_NpcDead[iEnt])
    {
        return;
    }
        
    
//Our NPC just spawned
    
if(g_NpcSpawn[iEnt])
    {
        static 
Floatmins[3], Floatmaxs[3];
        
pev(iEntpev_absminmins);
        
pev(iEntpev_absmaxmaxs);

        
//Draw a box which is the size of the bounding NPC
        
message_begin(MSG_BROADCASTSVC_TEMPENTITY)
        
write_byte(TE_BOX)
        
engfunc(EngFunc_WriteCoordmins[0])
        
engfunc(EngFunc_WriteCoordmins[1])
        
engfunc(EngFunc_WriteCoordmins[2])
        
engfunc(EngFunc_WriteCoordmaxs[0])
        
engfunc(EngFunc_WriteCoordmaxs[1])
        
engfunc(EngFunc_WriteCoordmaxs[2])
        
write_short(100)
        
write_byte(random_num(25255))
        
write_byte(random_num(25255))
        
write_byte(random_num(25255))
        
message_end();
        
        
//Our NPC spawn boolean is now set to false
        
g_NpcSpawn[iEnt] = false;
    }
    
    
//Choose a random idle animation
    
Util_PlayAnimation(iEntNPC_IdleAnimations[random(sizeof NPC_IdleAnimations)]);

    
//Make our NPC think every so often
    
entity_set_float(iEntEV_FL_nextthinkget_gametime() + random_float(5.010.0));
}

public 
npc_TraceAttack(iEntattackerFloatdamageFloatdirection[3], tracedamageBits)
{
    if(!
is_valid_ent(iEnt))
        return;
    
    new 
className[32];
    
entity_get_string(iEntEV_SZ_classnameclassNamecharsmax(className))
    
    if(!
equali(classNameg_NpcClassName))
        return;
        
    
//Retrieve the end of the trace
    
new Floatend[3]
    
get_tr2(traceTR_vecEndPosend);
    
    
//This message will draw blood sprites at the end of the trace
    
message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
    
write_byte(TE_BLOODSPRITE)
    
engfunc(EngFunc_WriteCoordend[0])
    
engfunc(EngFunc_WriteCoordend[1])
    
engfunc(EngFunc_WriteCoordend[2])
    
write_short(spr_blood_spray)
    
write_short(spr_blood_drop)
    
write_byte(247// color index
    
write_byte(random_num(15)) // size
    
message_end()
}

public 
npc_ObjectCaps(id)
{
    
//Make sure player is alive
    
if(!is_user_alive(id))
        return;

    
//Check when player presses +USE key
    
if(get_user_button(id) & IN_USE)
    {        
        
//Check cooldown of player when using our NPC
        
static Floatgametime gametime get_gametime();
        if(
gametime 1.0 g_Cooldown[id])
        {
            
//Get the classname of whatever ent we are looking at
            
static iTargetiBodyszAimingEnt[32];
            
get_user_aiming(idiTargetiBody75);
            
entity_get_string(iTargetEV_SZ_classnameszAimingEntcharsmax(szAimingEnt));
            
            
//Make sure our aim is looking at a NPC
            
if(equali(szAimingEntg_NpcClassName))
            {
                
//Do more fancy stuff here such as opening a menu
                //But for this tutorial I will only display a message to prove it works
                
client_print(idprint_chat"Hello");
            }
            
            
//Set players cooldown to the current gametime
            
g_Cooldown[id] = gametime;
        }
    }
}

public 
npc_EmitSound(idchannelsample[], Float:volumeFloat:attnflagpitch)
{
    
//Make sure player is alive
    
if(!is_user_connected(id))
        return 
FMRES_SUPERCEDE;

    
//Catch the current button player is pressing
    
new iButton get_user_button(id);
                    
    
//If the player knifed the NPC
    
if(g_Hit[id])
    {    
        
//Catch the string and make sure its a knife 
        
if (sample[0] == 'w' && sample[1] == 'e' && sample[8] == 'k' && sample[9] == 'n')
        {
            
//Catch the file of _hitwall1.wav or _slash1.wav/_slash2.wav
            
if(sample[17] == 's' || sample[17] == 'w')
            {
                
//If player is slashing then play the knife hit sound
                
if(iButton IN_ATTACK)
                {
                    
emit_sound(idCHAN_WEAPONg_NpcSoundKnifeHit[random(sizeof g_NpcSoundKnifeHit)], volumeattnflagpitch);
                }
                
//If player is tabbing then play the stab sound
                
else if(iButton IN_ATTACK2)
                {
                    
emit_sound(id,CHAN_WEAPONg_NpcSoundKnifeStabvolumeattnflagpitch);
                }

                
//Reset our boolean as player is not hitting NPC anymore
                
g_Hit[id] = false;
                
                
//Block any further sounds to be played
                
return FMRES_SUPERCEDE
            
}
        }
    }
    
    return 
FMRES_IGNORED
}

public 
Event_NewRound()
{
    new 
iEnt = -1;
    
    
//Scan and find all of the NPC classnames
    
while( ( iEnt find_ent_by_class(iEntg_NpcClassName) ) )
    {
        
//If we find a NPC which is dead...
        
if(g_NpcDead[iEnt])
        {
            
//Reset the solid box
            
entity_set_int(iEntEV_INT_solidSOLID_BBOX);
            
//Make our NPC able to take damage again
            
entity_set_float(iEntEV_FL_takedamage1.0);
            
//Make our NPC instanstly think
            
entity_set_float(iEntEV_FL_nextthinkget_gametime() + 0.01);
            
            
//Reset the NPC boolean to false
            
g_NpcDead[iEnt] = false;
        }    
        
        
//Reset the health of our NPC
        
entity_set_float(iEntEV_FL_health250.0);
    }
}

Create_Npc(idFloat:flOrigin[3]= { 0.00.00.0 }, Float:flAngle[3]= { 0.00.00.0 } )
{
    
//Create an entity using type 'info_target'
    
new iEnt create_entity("info_target");
    
    
//Set our entity to have a classname so we can filter it out later
    
entity_set_string(iEntEV_SZ_classnameg_NpcClassName);
        
    
//If a player called this function
    
if(id)
    {
        
//Retrieve the player's origin
        
entity_get_vector(idEV_VEC_originflOrigin);
        
//Set the origin of the NPC to the current players location
        
entity_set_origin(iEntflOrigin);
        
//Increase the Z-Axis by 80 and set our player to that location so they won't be stuck
        
flOrigin[2] += 80.0;
        
entity_set_origin(idflOrigin);
        
        
//Retrieve the player's  angle
        
entity_get_vector(idEV_VEC_anglesflAngle);
        
//Make sure the pitch is zeroed out
        
flAngle[0] = 0.0;
        
//Set our NPC angle based on the player's angle
        
entity_set_vector(iEntEV_VEC_anglesflAngle);
    }
    
//If we are reading from a file
    
else 
    {
        
//Set the origin and angle based on the values of the parameters
        
entity_set_origin(iEntflOrigin);
        
entity_set_vector(iEntEV_VEC_anglesflAngle);
    }

    
//Set our NPC to take damange and how much health it has
    
entity_set_float(iEntEV_FL_takedamage1.0);
    
entity_set_float(iEntEV_FL_health250.0);

    
//Set a model for our NPC
    
entity_set_model(iEntg_NpcModel);
    
//Set a movetype for our NPC
    
entity_set_int(iEntEV_INT_movetypeMOVETYPE_PUSHSTEP);
    
//Set a solid for our NPC
    
entity_set_int(iEntEV_INT_solidSOLID_BBOX);
    
    
    
//Create a bounding box for oru NPC
    
new Floatmins[3] = {-12.0, -12.00.0 }
    new 
Floatmaxs[3] = { 12.012.075.0 }

    
entity_set_size(iEntminsmaxs);
    
    
//Controllers for our NPC. First controller is head. Set it so it looks infront of itself
    
entity_set_byte(iEnt,EV_BYTE_controller1,125);
    
// entity_set_byte(ent,EV_BYTE_controller2,125);
    // entity_set_byte(ent,EV_BYTE_controller3,125);
    // entity_set_byte(ent,EV_BYTE_controller4,125);
    
    //Drop our NPC to the floor
    
drop_to_floor(iEnt);
    
    
// set_rendering( ent, kRenderFxDistort, 0, 0, 0, kRenderTransAdd, 127 );
    
    //We just spawned our NPC so it should not be dead
    
g_NpcSpawn[iEnt] = true;
    
g_NpcDead[iEnt] = false;
    
    
//Make it instantly think
    
entity_set_float(iEntEV_FL_nextthinkget_gametime() + 0.01)
}

Load_Npc()
{
    
//Get the correct filepath and mapname
    
new szConfigDir[256], szFile[256], szNpcDir[256];
    
    
get_configsdir(szConfigDircharsmax(szConfigDir));
    
    new 
szMapName[32];
    
get_mapname(szMapNamecharsmax(szMapName));
    
    
formatex(szNpcDircharsmax(szNpcDir),"%s/NPC"szConfigDir);
    
formatex(szFilecharsmax(szFile),  "%s/%s.cfg"szNpcDirszMapName);
        
    
//If the filepath does not exist then we will make one
    
if(!dir_exists(szNpcDir))
    {
        
mkdir(szNpcDir);
    }
    
    
//If the map config file does not exist we will make one
    
if(!file_exists(szFile))
    {
        
write_file(szFile"");
    }
    
    
//Variables to store when reading our file
    
new szFileOrigin[3][32]
    new 
sOrigin[128], sAngle[128];
    new 
Float:fOrigin[3], Float:fAngles[3];
    new 
iLineiLengthsBuffer[256];
    
    
//When we are reading our file...
    
while(read_file(szFileiLine++, sBuffercharsmax(sBuffer), iLength))
    {
        
//Move to next line if the line is commented
        
if((sBuffer[0]== ';') || !iLength)
            continue;
        
        
//Split our line so we have origin and angle. The split is the vertical bar character
        
strtok(sBuffersOrigincharsmax(sOrigin), sAnglecharsmax(sAngle), '|'0);
                
        
//Store the X, Y and Z axis to our variables made earlier
        
parse(sOriginszFileOrigin[0], charsmax(szFileOrigin[]), szFileOrigin[1], charsmax(szFileOrigin[]), szFileOrigin[2], charsmax(szFileOrigin[]));
        
        
fOrigin[0] = str_to_float(szFileOrigin[0]);
        
fOrigin[1] = str_to_float(szFileOrigin[1]);
        
fOrigin[2] = str_to_float(szFileOrigin[2]);
                
        
//Store the yawn angle
        
fAngles[1] = str_to_float(sAngle[1]);
        
        
//Create our NPC
        
Create_Npc(0fOriginfAngles)
        
        
//Keep reading the file until the end
    
}
}

Save_Npc()
{
    
//Variables
    
new szConfigsDir[256], szFile[256], szNpcDir[256];
    
    
//Get the configs directory.
    
get_configsdir(szConfigsDircharsmax(szConfigsDir));
    
    
//Get the current map name
    
new szMapName[32];
    
get_mapname(szMapNamecharsmax(szMapName));
    
    
//Format 'szNpcDir' to ../configs/NPC
    
formatex(szNpcDircharsmax(szNpcDir),"%s/NPC"szConfigsDir);
    
//Format 'szFile to ../configs/NPC/mapname.cfg
    
formatex(szFilecharsmax(szFile), "%s/%s.cfg"szNpcDirszMapName);
        
    
//If there is already a .cfg for the current map. Delete it
    
if(file_exists(szFile))
        
delete_file(szFile);
    
    
//Variables
    
new iEnt = -1Float:fEntOrigin[3], Float:fEntAngles[3];
    new 
sBuffer[256];
    
    
//Scan and find all of my custom ents
    
while( ( iEnt find_ent_by_class(iEntg_NpcClassName) ) )
    {
        
//Get the entities' origin and angle
        
entity_get_vector(iEntEV_VEC_originfEntOrigin);
        
entity_get_vector(iEntEV_VEC_anglesfEntAngles);
        
        
//Format the line of one custom ent.
        
formatex(sBuffercharsmax(sBuffer), "%d %d %d | %d"floatround(fEntOrigin[0]), floatround(fEntOrigin[1]), floatround(fEntOrigin[2]), floatround(fEntAngles[1]));
        
        
//Finally write to the mapname.cfg file and move on to the next line
        
write_file(szFilesBuffer, -1);
        
        
//We are currentlying looping to find all custom ents on the map. If found another ent. Do the above till there is none.
    
}
    
}

stock Util_PlayAnimation(indexsequenceFloatframerate 1.0)
{
    
entity_set_float(indexEV_FL_animtimeget_gametime());
    
entity_set_float(indexEV_FL_framerate,  framerate);
    
entity_set_float(indexEV_FL_frame0.0);
    
entity_set_int(indexEV_INT_sequencesequence);


I want to ask, how to use your function:
PHP Code:
native AStarThreaded(Float:Start[3], Float:Goal[3], Handler[], StepSize 30Ignore IGNORE_MONSTERSIgnoreID 0GroundDistance 35Heuristic 50, ...); 
or

PHP Code:
native Array:AStar(Float:Start[3], Float:Goal[3], StepSize 30Ignore IGNORE_MONSTERSIgnoreID 0GroundDistance 35Heuristic 50, ...); 
to make NPC move to target with this code:

PHP Code:
public hook_ent(entvictimFloat:speed)
{
    static 
Float:fl_Velocity[3]
    static 
Float:VicOrigin[3], Float:EntOrigin[3]

    
pev(entpev_originEntOrigin)
    
pev(victimpev_originVicOrigin)
    
    static 
Float:distance_f
    distance_f 
get_distance_f(EntOriginVicOrigin)

    if (
distance_f 60.0)
    {
        new 
Float:fl_Time distance_f speed

        fl_Velocity
[0] = (VicOrigin[0] - EntOrigin[0]) / fl_Time
        fl_Velocity
[1] = (VicOrigin[1] - EntOrigin[1]) / fl_Time
        fl_Velocity
[2] = 0.0 //(VicOrigin[2] - EntOrigin[2]) / fl_Time
    
} else
    {
        
fl_Velocity[0] = 0.0
        fl_Velocity
[1] = 0.0
        fl_Velocity
[2] = 0.0
    
}

    
entity_set_vector(entEV_VEC_velocityfl_Velocity)

Anyone know, please help me. Thank so much!

Edit:

If you don't have time, please post some example with entity, to caculator and move entity from A-origin to B-origin, may be it's simple and understand than your example in 1st post. Very thanks!
__________________
Without Passion Life Is Nothing

Quote:
“If you can't fly then run, if you can't run then walk, if you can't walk then crawl, but whatever you do, you have to keep moving forward.”― Martin Luther King Jr.

Last edited by AGoodGuy; 02-16-2015 at 16:21.
AGoodGuy is offline
Xalus
Veteran Member
Join Date: Dec 2009
Location: Belgium
Old 09-03-2015 , 14:46   Re: A* Pathfinding API
Reply With Quote #35

Hey,
I got some issues with the pathfinding, for some reason it always returns Invalid_array.

AMX Mod X 1.8.2
Compiled: Feb 14 2013, 00:55:00

AStarThreaded returns a normal Index, but in the forward I get an empty array?

PHP Code:
if(!fm_can_see(entityid))
            {
                new 
Float:flOrigin[2][3];
                
pev(entitypev_originflOrigin[0]);
                
pev(idpev_originflOrigin[1]);
                
                
set_pev(entitypev_activeACTIVE_PATH)
                
                new 
intIndex;
                if( (
intIndex AStarThreaded(flOrigin[0], flOrigin[1], "AStar_Pathdone"30IGNORE_MONSTERSentity3550)) == -1)
                {
                    
set_pev(entitypev_activeACTIVE_ATTACK)
                    
set_pev(entitypev_targetidget_enemy(entityid));
                    
set_pev(entitypev_nextthinkget_gametime() + 0.1)
                    
                    return;
                }

                
client_print(0print_chat"Path finder activated, hide fucker!");
                
                
g_arrayPathentity[intIndex] = entity;
                
                return;
            } 
PHP Code:
public AStar_Pathdone(Index, Array:hPathFloat:DistanceNodesAddedNodesValidatedNodesCleared) {

    if(
hPath == Invalid_Array
    
|| !pev_valid(g_arrayPathentity[Index]) 
    || 
pev(g_arrayPathentity[Index], pev_active) != ACTIVE_PATH)
    {
        
client_print(0print_chat"Pathfinding failed. (Reason: %s)", (hPath == Invalid_Array) ? "INVALID ARRAY" : !pev_valid(g_arrayPathentity[Index]) ? "INVALID ENTITY" "NOT FUCKING PATH RUNNING"); 
__________________
Retired.
Xalus is offline
folycs
Junior Member
Join Date: Jan 2011
Old 11-23-2015 , 11:36   Re: A* Pathfinding API
Reply With Quote #36

How can use this with MM ? Any example ?
__________________
folycs is offline
folycs
Junior Member
Join Date: Jan 2011
Old 02-08-2016 , 15:25   Re: A* Pathfinding API
Reply With Quote #37

BUMP....

how can get monster mod follow the path?


some like this ->
https://www.youtube.com/watch?v=qQWV...Wt8s9amaq5FrYg
__________________

Last edited by folycs; 02-08-2016 at 15:27. Reason: suck
folycs is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 02-15-2016 , 10:39   Re: A* Pathfinding API
Reply With Quote #38

It's really not an issue related to this API. The points are all there, accessable. The issue is to move the monsters. I don't know if monster mod has an integrated way of moving the monsters by supplying a point to move to. If so, easily done. I could even take a look at it myself. If it doesn't have that you have to try your way forward using the regular natives to move entities and play animations. I would look into some kind of bot.

On a side note. This is really experimental and should be unapproved for the following reasons:
* I would like it to be a module for speed reasons. This is just not good enough to use in multiple plugins and for serious mods. I'm not experienced enough in C(#/++) for now.
* It still doesn't always give a correct path. I had problems using the various trace functions and I haven't figured it out yet. Possibly making it a module would create new options.

This however doesn't mean it's completely useless. I do encourage the use of it for testing purposes and to find better ways to do things. Possibly small, fun-style, unimportant plugins.
__________________

Last edited by Black Rose; 02-15-2016 at 11:11.
Black Rose is offline
Baws
Veteran Member
Join Date: Oct 2012
Old 02-15-2016 , 12:30   Re: A* Pathfinding API
Reply With Quote #39

Quote:
Originally Posted by Black Rose View Post
It's really not an issue related to this API. The points are all there, accessable. The issue is to move the monsters. I don't know if monster mod has an integrated way of moving the monsters by supplying a point to move to. If so, easily done. I could even take a look at it myself. If it doesn't have that you have to try your way forward using the regular natives to move entities and play animations. I would look into some kind of bot.

On a side note. This is really experimental and should be unapproved for the following reasons:
* I would like it to be a module for speed reasons. This is just not good enough to use in multiple plugins and for serious mods. I'm not experienced enough in C(#/++) for now.
* It still doesn't always give a correct path. I had problems using the various trace functions and I haven't figured it out yet. Possibly making it a module would create new options.

This however doesn't mean it's completely useless. I do encourage the use of it for testing purposes and to find better ways to do things. Possibly small, fun-style, unimportant plugins.
Give this man Plugin Approver already.
__________________
Like my clean plugins and work?
Baws is offline
Old 10-12-2016, 20:30
Hedgehog Fog
This message has been deleted by Hedgehog Fog.
VoivoDpl
Junior Member
Join Date: Apr 2017
Old 04-18-2017 , 17:21   Re: A* Pathfinding API
Reply With Quote #40

Can someone attach all the code that is needed to test the functions ?

Threaded pathfinding doesn't work for me. Gives:

Quote:
Start: -1596, 722, -53. End: -1292, -622, 10. Distance: 1380 units.
Execution time: 1ms (0 nodes, 1 validated, 0 successful)
VoivoDpl is offline
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 03:01.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode