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

Thanks for r39 my long time query error was this ! "UPDATE `"#mHouse_Table"` SET `Renter_Username` = 'Nobody' WHERE `ID` = %d 5"

the 5 at the end!

Edit: .. wow did I just post in the wrong forum thread... nvm me. Please delete
Reply

Quote:
Originally Posted by Kar
View Post
Thanks for r39 my long time query error was this ! "UPDATE `"#mHouse_Table"` SET `Renter_Username` = 'Nobody' WHERE `ID` = %d 5"

the 5 at the end!

Edit: .. wow did I just pot in the wrong forum thread...
unfortunately.. YES.
Reply

Mauzen, you can add:

pawn Code:
forward RNPC_OnStopMove(rnpcid);
?
Reply

Quote:
Originally Posted by EnzoMetlc
View Post
Mauzen, you can add:

pawn Code:
forward RNPC_OnStopMove(rnpcid);
?
Okay Ill add that. I already added a response code for stopped playback in my current dev version, so adding a callback is just one more line. Actually less work than writing these sentences was


Quote:
Originally Posted by [D]ry[D]esert
View Post
Oh right, I forgot about that. They are part of some other Visual C runtime or developement package. I had them uploaded before i started releasing non-debug .dlls. Ill give it some more investigation later to find out what package exactly is required, downloading single dlls is such a dirty manner.
Reply

Heres the new update! Due to the major feature updates I decided to make it 0.4, even though I had other stuff planned for 0.4.

In short, 0.4 makes NPCs killable.

Slightly longer, heres a list of all changes:
  • Added serversided health management for NPCs, with correct handling of NPC deaths
  • Correctly synced OnRNPCPlaybackStopped
  • Fixed a major memory leak bug that messed up NPC control in timers (that one was also fixed in the 0.3.4 package earlier today)
  • New callbacks added
    • OnRNPCDeath(npcid, killerid, reason)
    • OnRNPCVehicleHit(npcid, driverid, vehicleid, times)
  • New functions added
    • RNPC_PauseRecordingPlayback(npcid) / RNPC_ResumeRecordingPlayback(npcid)
    • RNPC_ToggleVehicleCollisionCheck(npcid,enable)
    • RNPC_SetShootable(npcid,enable)
    • SetRNPCHealth(npcid, Float:health, issuer=INVALID_PLAYER_ID, reason=53) / Float:GetRNPCHealth(npcid)
    • IsVehicleOnPlayer(playerid, vehicleid)
    • RespawnRNPC(npcid)
And in long:
This update finally brings in a feature that I originally didnt even want to add. NPCs now got a working equivalent of health, they can be damaged, shot, hit by vehicles, and killed. But just if you want them to.
In order to stick with RNPCs aim of maximum customizability I had to make some tricky decisions. But after all im quite happy with the result. You can turn on/off automatic weapon and vehicle damage. So either you enable it (default: disabled) and accept what I thought would be good damage values (GTA standard damage), or you keep it disabled, and instead use the new and old callbacks to handle damage on your own way.
Same about the stuff that happens when a NPC dies or gets hit by a car. Dead NPCs respawn automatically after 4 seconds, play a random one of the 4 default death-fall animations, and OnPlayerDeath is called to treat NPC kills like normal player kills. If you dont like that, return 1 in OnRNPCDeath to skip those default actions. Anyways, dead NPCs will ignore playback requests, so there is no chance a dead NPC is accidentally moving.
If a NPC is hit by a car, and collision detection is actually turned on for him, he will pause the playback, get (160*vehicle_velocity) damage, and 1 damage for every 100ms the vehicle is still standing on top of them. After 2200ms he will resume the playback, thats about the time until he stands up. Again, if you dont like those damage values, return 1 in OnRNPCVehicleHit to skip the damage.


Performance
I did a quick performance test for this version, and managed to fire a minigun into a bulk of 330 NPCs running after me, without noticeable server lag. Then the client crashed. There was no big server lag, though the client lagged like hell, probably because the NPCs run through each other, and I guess 330 intersecting player models are too much for the GTA engine.
Those NPCs had the vehicle collision check turned off though. That collision check is the first thing that actually makes use of a concept I thought of quite a while ago: it uses the NPC scripts to calculate stuff in an own process without lagging the server. Each NPC with the detection turned on runs a timer that checks for occupied vehicles nearby. If there is one, the NPC reports that to the server for a closer check (NPC scripts miss some functions that are needed for the exact check, so this has to be done by the server). That way the checks can run in a fast 100ms interval without lagging the server. Anyways, if there are many players in vehicles, driving through many NPCs, there are going to be thousands of vehicle reports coming from the NPCs every second, and this got good potential to lag the server, even though the exact collision check isnt very complex.
It is very hard to give a general suggestion for how many NPCs should have collision enabled, this greatly depends on the server. Best thing is to try it, maybe do a stress test with many players and many NPCs.

Known new bugs and things to consider
  • NPCs sometimes will stop vehicles on hit, like driving against a wall. This especially happens when driving into a group of NPCs. Its a SA-MP thing, and theres nothing RNPC could do against it.
  • NPCs killed by a vehicle will stand up after dying. I had to decide for this, or to apply a manual animation, but the latter one would block vehicles and make driving over npcs really annoying. So I rather picked the "ugly" option.
  • The minimum collision range for vehicles is 6.0 (can be changed in the RNPC npc script). Vehicles longer than that wont trigger OnRNPCVehicleHit, until the rammed NPC gets into that range. I picked that value as a good mean, there are just a few vehicles longer than that (mostly planes), but it improves performance.
  • Dead NPCs might keep moving. This is a very rare "bug" caused by asynchronism. Dead NPCs normally ignore playback requests, but only after they stopped their last playback (they stop automatically when dying). This is a 5-10ms timeframe, so it happens very rarely for NPCs moved in a timer. A good and very simple fix for this is to check if a NPC is dead (rnpcData[npcid][RNPC_DEAD]) before moving NPCs in timers.

So much to the new version. I hope with that new mid-level damage management RNPC got one step closer to becoming an easy NPC solution.
For detailled description of all new functions check the RNPC wiki page (Edit: it is updated now)
The download link is on the first page. Additionally theres a pastebin link for a very basic "zombie npc" include that allows easy testing of the new damage management.

I know this might sound difficult in some points. Feel free to ask if anything of this is too confusing.
Have fun!

(damn those release posts get longer every version, no wonder there arent many people using it if they need to read a 100000 word text before )
Reply

Nice, going to give it a try now I will let you know if there is any issues.

@Edit - Looks legit now thanks for fixing that issue!
I can't really test the death features because my system has a similar implementation already with applying animations to simulate death. I also use a custom rnpc.inc the way the RNPC include functions now is simply not compatible with how I have things set up.
Reply

Quote:
Originally Posted by [uL]Pottus
View Post
Nice, going to give it a try now I will let you know if there is any issues.

@Edit - Looks legit now thanks for fixing that issue!
I can't really test the death features because my system has a similar implementation already with applying animations to simulate death. I also use a custom rnpc.inc the way the RNPC include functions now is simply not compatible with how I have things set up.
You might want to switch to the new death system anyways, or at least adapt the way it works. I dont know how exactly you handle that, but the new system has some great general advantages compared to the 0.3 branch
0.4 now has a clean and fully synced playback stop. OnRNPCPlaybackStopped is called when the NPC finally finished resetting his state. And that way applying death animations and handling NPC reactions in general works much more seamless. (Health goes below 0 -> Stop NPC and mark as dead -> wait for completed stop -> handle death).
Reply

Quote:
Originally Posted by Mauzen
View Post
You might want to switch to the new death system anyways, or at least adapt the way it works. I dont know how exactly you handle that, but the new system has some great general advantages compared to the 0.3 branch
0.4 now has a clean and fully synced playback stop. OnRNPCPlaybackStopped is called when the NPC finally finished resetting his state. And that way applying death animations and handling NPC reactions in general works much more seamless. (Health goes below 0 -> Stop NPC and mark as dead -> wait for completed stop -> handle death).
I really can't use any of that new code at all looking it over unfortunately I'm sure other people will find it useful though!
Reply

Hey Mauzen, nice update I'll test this version.

Now, I'm trying know how to make a PathFinder (not %100 functional), the code work well, but I don't know how to find a free path. This is the code:

pawn Code:
stock GetFreePath(playerid, &Float:fX, &Float:fY) // 'fX' and 'fY' would be the free positions.
{
    new Float:Pos[3], Float:Z, Float:Angle;

    GetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);
    GetPlayerFacingAngle(playerid, Angle);

    Pos[0] += (5.0 * floatsin(-Angle, degrees)); // Check if to 5 mtrs. there a free path
    Pos[1] += (5.0 * floatcos(-Angle, degrees));

    MapAndreas_FindZ_For2DCoord(Pos[0], Pos[1], Z);

    if((Z - Pos[2]) > 5.0)
    {
        for(new Float:i = Angle; i < 360; i += 6.0) // Search per the NPC angle if there a free path.
        {
            GetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);
            Pos[0] += (5.0 * floatsin(-i, degrees));
            Pos[1] += (5.0 * floatcos(-i, degrees));

            MapAndreas_FindZ_For2DCoord(Pos[0], Pos[1], Z);

            if((Z-Pos[2]) < 5.0)
            {
                fX = Pos[0];
                fZ = Pos[1];
                break;
            }
        }
    }
    return 1;
}

I know that the code is bad, I need help
Reply

Mauzen. let's just say I FUCKING LOVE YOU NO HOMO.

I'll be there 3pm.
Reply

Quote:
Originally Posted by Kitten
View Post
Mauzen. let's just say I FUCKING LOVE YOU NO HOMO.

I'll be there 3pm.
He lives too far but you can always come and bunk with me baby!
Reply

Quote:
Originally Posted by EnzoMetlc
View Post
Hey Mauzen, nice update I'll test this version.

Now, I'm trying know how to make a PathFinder (not %100 functional), the code work well, but I don't know how to find a free path. This is the code:
Pathfinding is a tricky thing. It could work the way you try it, but after all it will get pretty complicated and slow. By means of efficiency nothing can keep up with the established algorithms (dijkstra/A* mostly). Pamdex already did an RNPC update with working pathfinding: http://forum.sa-mp.com/showpost.php?...&postcount=572
Though as I didnt test it myself, this wasnt considered in the new versions yet. You could try that version, but its based on 0.3.1 and back then, sync and functionality was much worse than in the current versions. But Ill focus on integrating pamdex updates soon, and if it works out well the next update will finally contain his nice work.
Anyways, youll need, pamdex's plugin: https://sampforum.blast.hk/showthread.php?tid=427227
Basically, you would just have to create a build that follows the calculated nodes in OnPathCalculated, similar to this: http://forum.sa-mp.com/showpost.php?...&postcount=716 example I made for the GPS plugin. And finally I found out pamdex provided full code for moving RNPCs with his plugin, it should still work with RNPC 0.4: http://forum.sa-mp.com/showpost.php?...3&postcount=37

Quote:
Originally Posted by Kitten
View Post
Mauzen. let's just say I FUCKING LOVE YOU NO HOMO.

I'll be there 3pm.
Cant wait to see you!
Reply

@UP
Finally, I have a lot of time... Current version of the Pathfinder Plugin is working but it has some bugs.

Mauzen if you want to add support for the Pathfinder Plugin wait for the new version (I'm working hard on it).
Reply

Quote:
Originally Posted by pamdex
View Post
@UP
Finally, I have a lot of time... Current version of the Pathfinder Plugin is working but it has some bugs.

Mauzen if you want to add support for the Pathfinder Plugin wait for the new version (I'm working hard on it).
Great to hear that. Okay Ill wait for it then before experimenting with pathfinding.
Reply

Quote:
Originally Posted by pamdex
View Post
@UP
Finally, I have a lot of time... Current version of the Pathfinder Plugin is working but it has some bugs.

Mauzen if you want to add support for the Pathfinder Plugin wait for the new version (I'm working hard on it).
Always seemed to fucked up for me when there was a lot of NPCs.
Reply

Quote:
Originally Posted by [uL]Pottus
View Post
Always seemed to fucked up for me when there was a lot of NPCs.
Using NOBUFFER mode is slow. Especially on virtual servers with limited hdd i/o. And calculating the path requires many z coordinates. I guess this could be the reason for the problems.
I understand this is a logical measure to avoid loading the same data into memory twice. But maybe there should be an option to buffer it in full mode. Would be even greater if there was some way for plugins to communicate with each other, so they can share mapandreas, but I havent seen that yet, and got no idea how this could be done myself.

Whatever, that should go to the correct plugin thread

RNPC Dev: I just restructured the plugin so last build data for every NPC is stored. That way you dont need to set the weapon, special actions, animations etc again and again for every single build, and setters work outside the build mode, affecting the next build.
This is the next step for controlling NPCs in realtime, but thats still gonna take a while. (My plan actually is to rewrite recordings when something like the weapon or the keys (aiming) get changed, and restart them from the last moment, so recording can practically be modified during the playback. There wouldnt be a big difference to FCNPC then, by means of handling and possiblities. Im still not sure if this will work well, but chances are pretty good)
Just a side note, I wont release a next version that fast, theres more stuff to do for 0.4.1, and that "plan" will take even longer, I was following that idea since the very first versions
Reply

Mauzen, can you add the ability to apply animations without a build? I'm using rnpc for my zombies, I almost got them perfected until I seen how dumb it looked when a zombies comes up and you lose health... Please :P
Reply

Quote:
Originally Posted by Crayder
View Post
Mauzen, can you add the ability to apply animations without a build? I'm using rnpc for my zombies, I almost got them perfected until I seen how dumb it looked when a zombies comes up and you lose health... Please :P
Ill give animations a closer look soon. The changes in the next version might already be enough to make animations work correctly, but I still need to test several things.
Edit: The next update allows editing each NPCs last created build. That way it will be possible to control certain things during the playback in realtime (e.g. the played animation, the keys etc), without the need for a new build. Right now Im thinking about a way to provide this in a good way. I dont really want to add another bunch of new natives for that, so after all people had no idea when to use which function.

What would everyone think about an "edit"-mode in addition to the build mode?
pawn Code:
RNPC_EditBuild(npcid, PLAYER_RECORDING_TYPE_ONFOOT);
RNPC_SetKeys(4, npcid, EDIT_MODE_OR); // keys |= newkeys
RNPC_FinishEdit(true);  // jump to the currently played time for realtime update, save file, and play it back

// That one could be shortened with a macro again then to
RNPC_SetKeys_RT(4, npcid, EDIT_MODE_OR);
The RNPC_Setter would be useable anywhere then, in build mode (affects current and future builds), in edit mode (affects current build in realtime), and anywhere else (affects future builds only). That would be the least confusing way IMO. But it would also harm the code readability due to all those extra conditions.
Reply

Hey, Mauzen! Do you know how I could make the vehicles a bit less jiggery when following node paths? I wrote a script which makes an NPC recording from the NPC's current pos to a pos in LV (using GamerZ's Plugin) and it works really well, however, I have problems with the car movement. It is not as smooth as I would like it to be and I often find the car stuck in the ground when I am going from node to node. I would suppose this is due to the altitude differences and because a smooth interpolation does not exist yet.

How could I possibly make the experience a bit smoother?
Reply

Give us this way "RNPC_SetKeys_RT(4, npcid, EDIT_MODE_OR);" but don't keep that _RT extension, lol.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)