[Plugin] RNPC - Recordfree NPCs | Control NPCs without recording | DEV

I made new version of RNPC.

RNPC 0.3.2v
  • new function RNPC_PathFinderMovement for very smooth movement on calculated path (PathFinder Plugin).
  • new NPC speed RNPC_SPEED_FASTWALK - works only in RNPC_PathFinderMovement.
BUG:
When you use RNPC_SPEED_WALK in RNPC_PathFinderMovement NPC doesn't walk properly.

RNPC_PathFinderMovement
Code:
native RNPC_PathFinderMovement(Float:start_x, Float:start_y, Float:start_z, nodes_array[], nodes_array_size, Float:speed=RNPC_SPEED_RUN);
Parameters:
  • Float:start_x <- actual NPC X pos
  • Float:start_y <- actual NPC Y pos
  • Float:start_z <- actual NPC Z pos
  • nodes_array[] <- array with path nodes
  • nodes_array_size <- size of nodes_array
  • Float:speed <- NPC speed
NOTE:
This function uses built-in MapAndreas (so you must init it - look at example).

Example usage:
Code:
public OnFilterScriptInit()
{
	MapAndreas_Init(MAP_ANDREAS_MODE_NOBUFFER);
	for(new i; i < 50; i++)
	{
		new NPCNAME[MAX_PLAYER_NAME];
		format(NPCNAME, sizeof(NPCNAME), "(TEST)_%i", i);
		ConnectRNPC(NPCNAME);
	}
	PathFinder_Init(2.0);
}
CMD:onefollow(playerid, arg[])
{
	new Float:x, Float:y, Float:z;
	new Float:x1, Float:y1;
	GetPlayerPos(0, x, y, z); //NPC
	GetPlayerPos(playerid, x1, y1, z);
	PathFinder_FindWay(0, x, y, x1, y1);
	return 1;
}
public OnPathCalculated(routeid,success,nodes[],nodes_size)
{
	if(success)
	{
		RNPC_StopPlayback(routeid);
		new Float:x, Float:y, Float:z;
		RNPC_CreateBuild(routeid,PLAYER_RECORDING_TYPE_ONFOOT);
		
		//MOVE
		GetPlayerPos(routeid,x,y,z); //NPC
		RNPC_PathFinderMovement(x,y,z,nodes,nodes_size,RNPC_SPEED_RUN + (random(12) * 0.0001));
		//------------------------
		
		RNPC_FinishBuild();
		RNPC_StartBuildPlayback(routeid);
		
		return 1;
	}
}
Download:
https://dl.dropboxusercontent.com/u/...9/RNPC_032.zip

I'm going to work on RNPC.
Reply

Quote:
Originally Posted by pamdex
View Post
I made new version of RNPC.

RNPC 0.3.2v
  • new function RNPC_PathFinderMovement for very smooth movement on calculated path (PathFinder Plugin).
  • new NPC speed RNPC_SPEED_FASTWALK - works only in RNPC_PathFinderMovement.
BUG:
When you use RNPC_SPEED_WALK in RNPC_PathFinderMovement NPC doesn't walk properly.

RNPC_PathFinderMovement
Code:
native RNPC_PathFinderMovement(Float:start_x, Float:start_y, Float:start_z, nodes_array[], nodes_array_size, Float:speed=RNPC_SPEED_RUN);
Parameters:
  • Floattart_x <- actual NPC X pos
  • Floattart_y <- actual NPC Y pos
  • Floattart_z <- actual NPC Z pos
  • nodes_array[] <- array with path nodes
  • nodes_array_size <- size of nodes_array
  • Floatpeed <- NPC speed
NOTE:
This function uses built-in MapAndreas (so you must init it - look at example).

Example usage:
Code:
public OnFilterScriptInit()
{
	MapAndreas_Init(MAP_ANDREAS_MODE_NOBUFFER);
	for(new i; i < 50; i++)
	{
		new NPCNAME[MAX_PLAYER_NAME];
		format(NPCNAME, sizeof(NPCNAME), "(TEST)_%i", i);
		ConnectRNPC(NPCNAME);
	}
	PathFinder_Init(2.0);
}
CMD:onefollow(playerid, arg[])
{
	new Float:x, Float:y, Float:z;
	new Float:x1, Float:y1;
	GetPlayerPos(0, x, y, z); //NPC
	GetPlayerPos(playerid, x1, y1, z);
	PathFinder_FindWay(0, x, y, x1, y1);
	return 1;
}
public OnPathCalculated(routeid,success,nodes[],nodes_size)
{
	if(success)
	{
		RNPC_StopPlayback(routeid);
		new Float:x, Float:y, Float:z;
		RNPC_CreateBuild(routeid,PLAYER_RECORDING_TYPE_ONFOOT);
		
		//MOVE
		GetPlayerPos(routeid,x,y,z); //NPC
		RNPC_PathFinderMovement(x,y,z,nodes,nodes_size,RNPC_SPEED_RUN + (random(12) * 0.0001));
		//------------------------
		
		RNPC_FinishBuild();
		RNPC_StartBuildPlayback(routeid);
		
		return 1;
	}
}
Download:
https://dl.dropboxusercontent.com/u/...9/RNPC_032.zip

I'm going to work on RNPC.
Is great.
Reply

In OnGamemodeInit

Code:
MapAndreas_Init(MAP_ANDREAS_MODE_NOBUFFER);
	for(new i; i < 5; i++)
	{
		new NPCNAME[MAX_PLAYER_NAME];
		format(NPCNAME, sizeof(NPCNAME), "Zombie_%i", i);
		ConnectRNPC(NPCNAME);
	}
	PathFinder_Init(2.0);
And

Code:
	for(new i; i < 5; i++)
    {
        SetPlayerPos(i,1171.6742,-1084.2343,26.4909);
		SetPlayerSkin(i,162);
    }
And my NPC don't spawn , Why?
Reply

Quote:
Originally Posted by xeon_inside
View Post
In OnGamemodeInit

Code:
MapAndreas_Init(MAP_ANDREAS_MODE_NOBUFFER);
	for(new i; i < 5; i++)
	{
		new NPCNAME[MAX_PLAYER_NAME];
		format(NPCNAME, sizeof(NPCNAME), "Zombie_%i", i);
		ConnectRNPC(NPCNAME);
	}
	PathFinder_Init(2.0);
And

Code:
	for(new i; i < 5; i++)
    {
        SetPlayerPos(i,1171.6742,-1084.2343,26.4909);
		SetPlayerSkin(i,162);
    }
And my NPC don't spawn , Why?
Please slight delay.
Reply

There is some other things you should know.

- Sometimes connecting a lot of NPCs during server start-up will cause failed disconnections you need to check for this
- NPCs sometimes disconnect perhaps crash etc whatever the reason you need a loop that watches over NPCS and will reconnect them in case they disconnect (Don't rely on rnpc or a_rnpc connection functions they're bunk)
- I suggest pre-creating all your NPCS will make them easier to keep track of they should start at player slot 0
Reply

Quote:
Originally Posted by [uL]Pottus
View Post
There is some other things you should know.

- Sometimes connecting a lot of NPCs during server start-up will cause failed disconnections you need to check for this
- NPCs sometimes disconnect perhaps crash etc whatever the reason you need a loop that watches over NPCS and will reconnect them in case they disconnect (Don't rely on rnpc or a_rnpc connection functions they're bunk)
- I suggest pre-creating all your NPCS will make them easier to keep track of they should start at player slot 0
I'll keep that in mind, thanks! The two commands I made are just for pure testing. Planning on connecting the NPCs automatically as they'll be stored in a DB. How long delay should there at least be between the NPCs?
Reply

Well once one connects ex - OnPlayerConnect() is called then you can connect another.
Reply

Been thinking about this for a while now. Let's say I want to connect 4 NPCs after each other. They'd obviously need to start after the last one has been processed through OnPlayerConnect but I want to assign data to them as I load them (same way if a player connects to a server and it fetches that player's data from the database). How'd I do that? I thought about a multi-dimensional foreach or just a multi-dimensional array but I don't think that'd do the job. Anyhow I haven't got a clue on how I'd do it now when I wish to assign the NPCs data from my database.
Reply

Well you can group your NPCS with custom iterators I wouldn't recommend using a multi-dimensional custom iterator for this it will make things more difficult to read. You should make a new custom iterator for each new group of NPCS for instance some might be information NPCS others Zombies so it would be nice to have each grouped in their own iterator. Of course you want all your NPCS that you will be using connected when the script starts up I think dynamically creating them is a bad idea because you won't be able to control what player slots get taken up this can cause a lot of confusion. Lastly, don't rely on the A_RNPC include my experience with it proved that it was not very useful I ended up just writing my own system based off of RNPC.inc instead. Now if you need to detect when a zombie gets shot I can certainly help you with that when the time comes.
Reply

Any certain libaries needed for Linux Ubuntu? A NPC script doesn't seem to work on Linux Ubuntu...
Reply

This plugin for me, is better than the FCNPC.
But, why does not it work in version Linux?.
Reply

You guys probably forgot to put RNPC.amx in the npcmode folder
Reply

Quote:
Originally Posted by [uL]Pottus
View Post
You guys probably forgot to put RNPC.amx in the npcmode folder
Yes I put it, put everything as is that was in the unload; the plugin, the GM of example, the source...
Reply

Quote:
Originally Posted by EnzoMetlc
View Post
This plugin for me, is better than the FCNPC.
But, why does not it work in version Linux?.
Please give some more information what exactly isnt working. Do the bots crash? Do they not even connect? Are the bots not moving? Give as many information as possible, also the relevant parts of the server log might help.
Reply

Quote:
Originally Posted by Mauzen
View Post
Please give some more information what exactly isnt working. Do the bots crash? Do they not even connect? Are the bots not moving? Give as many information as possible, also the relevant parts of the server log might help.
It is as that it does not connect, they do not appear for any side of the map.
I have a command to bring the Npc's to the place of the player, the command works well, but the Npc's do not appear.

(At least, the plugin not me buguea the GM).

P/D: in windows the Npc's me work of marvel.
Reply

Usually it is one of these things when just linux doesnt work:
  • Make sure the npcmode "RNPC.amx" isnt "rnpc.amx". Linux is case sensitive.
  • Check the maxnpcs setting the server.cfg. People often forget to change this again in linux.
  • Try giving the NPC something to do as soon as they join, e.g. in OnPlayerConnect. Idle NPCs sometimes dont work as they should.
Reply

Now on having put the plugin in the list of the plugins (server.cfg), the 'server-samp.exe' is closed.
I have no mistake neither in the GM nor in the includes, what can be?


EDIT: Solved.
'
ConnectRNPC' is bug, it was what was not leaving me to open the 'samp-server.exe'.
Reply

When I put a command to control the Npc, it does it without problems... But on having put 2 commands to control it, the Npc remains bug.
It is created and everything, but it does not work.


(There does not appear the message of unknown command).
Reply

Hello, I tried to do a script like that:

pawn Code:
public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
{
    if(issuerid != INVALID_PLAYER_ID)
    {
        if(IsPlayerRNPC(playerid))
        {
            new string[20];
            new Float:Health;
            GetPlayerHealth(playerid, Health);
            SetPlayerHealth(playerid, Health-10);
            format(string, sizeof(string), "~w~RNPC HEALTH: ~r~%0.2f~w~.", Health);
            GameTextForPlayer(issuerid, string, 2000, 3);
        }
    }
    return 1;
}
But does not it work, how it should be the code really?.
Reply

You can't do NPC damage detection like that in fact no NPC to date that I know of can directly triggle OnPlayerTakeDamage() FCNPC will trigger OnPlayerGiveDamage() however. Anyways to do hit detection you need to get a little more creative fortunately for you I've written a few functions to take care of this problem.

This detects when a player shoots a weapon (Doesn't work for melee weapons)
pawn Code:
#include <YSI\y_hooks>

forward OnPlayerShoot(playerid,weaponid,ammo);

new OldAmmo[MAX_PLAYERS], OldWeap[MAX_PLAYERS];
new CurrAmmo[MAX_PLAYERS], CurrWeap[MAX_PLAYERS];

hook OnPlayerUpdate(playerid)
{
    // Get the current weapon and ammo
    CurrWeap[playerid] = GetPlayerWeapon(playerid);
    CurrAmmo[playerid] = GetPlayerAmmo(playerid);

    // Player still has old weapon does this weapon now have less ammo?
    if(CurrWeap[playerid] == OldWeap[playerid] && CurrAmmo[playerid] < OldAmmo[playerid])
    {
        CallLocalFunction( "OnPlayerShoot", "iii", playerid, CurrWeap[playerid], CurrAmmo[playerid]);
    }
   
    OldWeap[playerid] = CurrWeap[playerid];
    OldAmmo[playerid] = CurrAmmo[playerid];
    return 1;
}
Now we need some functions to detect when a player shoots a NPC, basically what you do is loop through all your NPCs every time a player shoots and if one is streamed in you check if there was a bullet collision. All you really need to know here is sx, sy, sz is your NPC position which is where the collision check sphere will be created fScale will scale your shooting vector the higher the value the further the collision detection will check and radius is your sphere size 1.0 is pretty good for NPCs.


pawn Code:
// Checks if a players bullet intersects a sphere
stock BulletCollisionSphere(playerid, weapon, Float:sx, Float:sy, Float:sz, Float:fScale = 30.0, Float:radius = 1.0)
{
    new
        Float:fP[3],
        Float:fV[3],
        Float:object[3],
        Float:sphere[3];

    sphere[0] = sx, sphere[1] = sy, sphere[2] = sz;

    GetPlayerCameraPos(playerid, fP[0], fP[1], fP[2]);
    GetPlayerCameraFrontVector(playerid, fV[0], fV[1], fV[2]);

    // Compensate (This is not perfect yet any ideas anyone?)
    if(weapon != 34 && weapon != 35 && weapon != 36)
    {
        new Float:FacingA;
        GetPlayerFacingAngle(playerid, FacingA);
        FacingA -= 90.0;
        if(FacingA < 0.0) FacingA += 360.0;
        else if(FacingA > 360.0) FacingA -= 360.0;

        fP[0] = (fP[0] + 0.6 * floatsin(-FacingA,degrees));
        fP[2] += 1.2;
    }

    object[0] = fP[0] + floatmul(fV[0], fScale);
    object[1] = fP[1] + floatmul(fV[1], fScale);
    object[2] = fP[2] + floatmul(fV[2], fScale);

    // Check if line intersects sphere
    if(RaySphere(fP, object, sphere, radius)) return 1;
    return 0;
}

// This checks to see if a line intersects a sphere
stock RaySphere(Float:p1[3],Float:p2[3],Float:sc[3],Float:r)
{
    new Float:a, Float:b, Float:c;
    new Float:bb4ac;
    new Float:dp[3];

    dp[0] = p2[0] - p1[0];
    dp[1] = p2[1] - p1[1];
    dp[2] = p2[2] - p1[2];
    a = dp[0] * dp[0] + dp[1] * dp[1] + dp[2] * dp[2];
    b = 2 * (dp[0] * (p1[0] - sc[0]) + dp[1] * (p1[1] - sc[1]) + dp[2] * (p1[2] - sc[2]));
    c = sc[0] * sc[0] + sc[1] * sc[1] + sc[2] * sc[2];
    c += p1[0] * p1[0] + p1[1] * p1[1] + p1[2] * p1[2];
    c -= 2 * (sc[0] * p1[0] + sc[1] * p1[1] + sc[2] * p1[2]);
    c -= r * r;
    bb4ac = b * b - 4 * a * c;
    if(bb4ac < 0) return 0;
    return 1;
}
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)