This is an ai system for the generic commoners that occupy your towns/cities etc. It is not meant for anyone you meant to follow a specific behavior or schedule, though it can be used to do that. The goal is to provide an simple to implement, but relatively advanced AI for those "unimportant nameless npc" groups that fill out and add ambiance to game worlds. This ai allows your generic commoners to have schedules and carry out quasi realistic actions, automatically, and in as simple for a builder to implement manner as possible.
v1.2 New "generic" scripts trade the activity flexibility and location variability of my commoner ai for increased performance. Usage is even easier than the full ai, with many only requiring putting a heartbeat on the npc.
This system is based on:
Uncle FB's original NPC control code: Link It also includes additional activities provided by Lugaid of the Red Stripes from his Dana'an series Link and Link.
DannJ's Handy VFX Link has been integrated, since it handles a number of things there are activities for but not items to equip, such as books.
There is a demo module, as well as an erf plus the vfx used. And a readme on usage.
To greatly improve performance if you are using a lot of commoner ai npc's, in the script sh_npc_leg_oh, add the following at the beginning of the main() function.
if (GetAILevel(OBJECT_SELF) == AI_LEVEL_VERY_LOW)
{
return;
}
Then npc's will not run their routines if players are out of the area. This will be less realistic as players enter the area and then the npc's adjust to a new time.
additional credit:
kevL, who provided a superior waypoint selection function
kevL, Lugaid of the Red Stripes, and MasterChanger, for assistance with a looping bug. See:
Link _Knightmare, Kaldor Silverwand, Lugaid of the Red Stripes, and Shallina for code on selecting at random from objects with the same tag.
v1.21 demo module. Generics are shown in the test area. If you want to see the full ai, check the v1.0 demo module. The v1.21 demo module has all the full ai scripts, they're just not demonstrated.
astindextor: the npcs run the included heartbeat script, that's the only thing you have to do on the npcs. The rest is entirely area building, placing the ipoints and waypoints. _________________________ Shadow Thief: Crimmor and Path of Evil blog Link
I downloaded and imported the .ERF and I think I am following the instructions, but my commoners are just standing around doing nothing. I have no idea what I am doing wrong. I set the variables and I have waypoints for every action, and every Ipoint included. Im not clear on where the Ipoints should be, or if there is any specific location they should be? Do the commoners need to be placed on a waypoint of nay kind to get the thing rolling? I really want to get this working as it is one of the things i have dreamed of in the past, but I am god awful at scripting anything by myself.
Arvirago: I'm not the best coder, and there's probably some duplication because I welded two systems together. I relied on the community to provide some code sections, as indicated in the credits. _________________________ Shadow Thief: Crimmor and Path of Evil blog Link
When you are choosing a waypoint for the activity, you call kL_GetRandomObjectByTag() many times until you find one that is not in use (nWaypointInUse==0).
That could be inefficient if you have a lot of waypoints and almost all of them are already in use (specially because each call to that function checks all the waypoints again before choosing a random one).
As I'm not going to use the fMaxDistance, I will try to modify a little bit the kL_GetRandomObjectByTag() function:
1- Only counting waypoints once for each area.
2- Pick a random waypoint and search in order starting by that one.
2- Returning a non-used waypoint if instructed so by an optional argument.
Something like:
object kL_GetRandomObjectByTag(string sTag, int iOnlyUnused = 0) {
int iRandom, iCurrent; object oObject;
int iNumObjects = GetLocalInt(GetArea(OBJECT_SELF), sTag);
if (!iNumObjects) iNumObjects = GetNumberObjectsByTag(sTag);
iRandom = Random(iNumObjects) + 1;
if (iOnlyUnused) { // We have to find an object that is not used
for (iCurrent = iRandom; iCurrentiNumObjects) oObject = GetNearestObjectByTag(sTag, OBJECT_SELF, iCurrent-iNumObjects);
else oObject = GetNearestObjectByTag(sTag, OBJECT_SELF, iCurrent);
if (GetIsObjectValid(oObject) && !GetLocalInt(oObject, "nWaypointInUse")) return oObject;
}
} else {
oObject = GetNearestObjectByTag(sTag, OBJECT_SELF, iRandom);
if (GetIsObjectValid(oObject)) return oObject;
}
return OBJECT_INVALID;
}
That way if we have, say, 8 waypoints, and we randomly chose the 4th, we would check in order: 4, 5, 6, 7, 8, 1, 2 and 3, and stop when we find a valid one.
The function GetNumberObjectsByTag(sTag) just counts the objects with that tag like you do now.
That's the idea, I will check it now. Thanks for this great stuff. _________________________ Reino de Aldor
I downloaded yesterday and still examining. I started to translate to spanish and noticed a lot of doubled code, i.e. function TakeOrder() in sh_npc_include and sh_npc_bminc. _________________________ Reino de Aldor
jrscherzi: I just downloaded the erf and imported without issue. What kind of error did you get? _________________________ Shadow Thief: Crimmor and Path of Evil blog Link
I downloaded your demo, the pdf and the commoner ai erf. When I try to import the erf in my mod I get a runtime error and the toolset stops working. This sounds like a good idea, but I can't really tell at this point.
Posted by Rokene at 2012-09-07 22:40:26 Voted 10.00 on 09/07/12
This is a wonderful system. :) I was about to script something like this for my own PW but you saved a lot of time for doing this. Great system. :) _________________________ Shards of Vael - NWN2 RPPW Link
Posted by bealzebub at 2012-08-09 20:55:30 Voted 10.00 on 08/09/12
truly a masterpiece! Kamal, you're a great asset to the nwn2 community. Thanks for making my life easier.
Posted by Apep at 2012-08-05 02:13:43 Voted 10.00 on 08/05/12
Excellent stuff kamal, and of course the other folks that contributed! Very glad I checked it out, even though I'm not much of a toolseter anymore myself (not a real word). I don't have a lot to add except that I appreciate the extra effort you put into providing quality supporting documentation. It's a seemingly small touch, but it adds a lot in my opinion. _________________________ AP Magical Miscellanea Package (v1.5, over 750 items): Link
You must be Logged In to post comments in this section.
10 - A Masterpiece, Genuinely Groundbreaking 9 - Outstanding, a Must Have 8 - Excellent, Recommended to Anyone 7 - Very Good, Deserves a Look 6 - Good, Qualified Recommendation 5 - Fair, Solid yet Unremarkable 4 - Some Merit, Requires Improvements 3 - Poor Execution, Potential Unrealized 2 - Very Little Appeal 1 - Not Recommended to Anyone