Working towards Animal Instincts in NPCs
This is a divergent view from eqlive. Purists should skip this thread. I'm hashing it out here because, I don't quite have access to the tools I need to do any development work. It'll be ultimately up to the base maintainers if they want to include this.Regardless, I plan on putting in a flag to turn such experiments on/off.
The goal is to put in place some instincts for the critters that walk about the face of norrath. For example, a hungry wolf will attack, while a full wolf may not. Secondly, I've always viewed a zone as a kind of fishbowl and I'd like to make my fish do stupid tricks. The first part of this is going to introduce hunger code for NPCs. It is a rather primative instinct. Either you are hungry or you aren't. And there are thresholds, such as being stuffed full makes you cranky, and not eating enough makes you cranky, but eating just the right amount makes you (generally) healthy, wealthy, and wise. I'm thinking a simple struct, a struct so I can easily expand it later, might look like Code:
NPC With 0 being equilibrium. Now if you're hungry (hunger < 0), then you need food. I'm thinking that if you give the item (check Consume_Struct), then you are hungry. Next, we need a command in (i think client.cpp) that processes the command #Hungry? If an NPC is Hungry, it tells you as much. If not, then not. (need pseudo code script ;) Code:
//isnpc check and stuff Now, over time the NPC will go hungry. So, their hunger should be increased (which actually decreases the Hunger value). At some point, this should probably work off the existing eat-food timer, but for testing I want all my NPCs to starve. Which brings in the second command for client.cpp: #StrikeFamineInZone which causes all the npcs hunger to drop to -100. This doesn't classify itself as an instinct quite yet, and I'm fearful of putting in any kind of silly check such as (if Hungry, go find food!) as all the NPCs will flock to the first available food source... rather, instead, I have two ideas I'm kicking around. The first goes back to the healthy, wealthy, and wise argument. If an NPC is fed well, we'll say 0 < hunger < 50, then a. their wisdom score goes up (perhaps skills too, but last I checked these were hardcoded at 252 with a big TODO flocked next to it). b. their strength score goes up (or maybe minimum damage) c. they get extra cash ( a few silver or something small) Alternatively, I'd just like to tint the npcs a different color. However, I don't know if the client supports this. |
Odd. Must have caught a cookie in my login there. Ooopsie.
I don't suppose someone could clear my ScotchTape account, could they? --MV |
Woot. 2.6 was released today! :-)
Aside from accepting gifts from players, the above was trivial to implement. So now comes necessarily phase 1+, then 2. In phase 1+ I need to: 1. Move the above instinct core code into 2.6 2. get that working 3. Move on to phase 2 Phase::2 Being hungry is only part of it. Animals fall into three different categories. You either eat meat, eat vegies, or eat both. Eating meat means you have a tendency to eat N/PCs. Eating vegies makes you hungry and docile. Maybe if item population in the zone (item droppings) work, then sprinkling vegies about the area to have NPCs go after them. (Smells like I'm cooking part 2) If you eat both, then you're moody, but are prone to eat the N/PC. Alright, so omnivore might be a bit more complicated to do right now, so we'll just deal with the core two: carni and herbi -vores. I'm going to add in the animal instinct struct a member possible values (0,-1,1) that designates whether I am a carnivore (0), herbivore (-1), or omnivore (1). So (1) isn't going to be used for a bit, but it will be used so a bool won't work. Carnivore: When a NPC "eats" a PC, it calls NPC::Eat() and increments by the level of the PC. If it is another NPC, then perhaps the same. Now what I find interesting is that I'm going to try to aggro against NPCs. Cannibalistic goblins. Oh yeah! Potential problem: what happens if zone aggros against one another and the entire place goes nuts? So maybe only eat your fellow if you are below, say -50. I don't think the attack code currently allows for NPCs to attack one another. I might have to modify this. Herbivore: Sprinkling items about the zone, such as vegies, is necessary for this to work. Once that is possible, sprinkle the items about the zone and have the various NPCs path to their location. Nothing fancy here, just slowly move the NPC in the direction of the item. e.g., set NPC eventual destination == item location. They only need one, and no two NPCs should get the same item (prevention of another problem). Omnivore: Does both. Can't do this without the first two, so looks like I'll save this until later. That's a good start for the game plan tonight (hoping), if not, then sometime this week. :) --MV |
I love the idea !
I would set a true false value in the variables table though AnimalAI 0/1 though.. Some people might not want their animals all following instinctual pattens. Plus, Im thinking that running the AI on all the zone animals might be a bit CPU intensive, especially in big zones like the karanas. While you are emulating natural patterns.. You could even put sleep code in... If they are asleep, you have a random chance of wakening them if you come within a certain radius, but if you sneak by, you get an attack bonus, or you can just run by them without agro'ing. (sleep would lower their agro radius to 0 in essence). |
it should be 0 to 3.
zero no animial effect ( ie: rock golems ) one veggie eater two meat eater three both |
man this is an awesome idea! good work and good luck. Instincts opens the world to so many kewl possibilities.
|
Quote:
4 - rocks |
good idea would be to have npc animals eat each other too, following some kind of food chain, don't know if you said that but I missed it...
also: If an animal with rabies bites another one, it gets rabies... ect... |
Make a new database field, food chain level, where a creature will attack anything else with a lower food chain number but ignore, stay away from anything with a higher one.
It might be fun watching a bunch of animals chasing each other around south karana, but it would lead to very erratic behavior as everything started running from one another and never stopped to eat.. It'd look like the playground at mcdonalds... |
well if something bigger wasn't hungry it could ignore it or if something was a jerk it would kill anything it saw that was lower on the food chain, IE a giant would smash a bunny into goo if it saw it :D or something to that effect.
|
ahh thats very good idea!
maybe 2 variables.or a table.. if its veggie eater some plants is uneatable ( like high level plants like trents) or meat eater ie: wolf dont try to eat bear. |
doh didnt see previous suggestion sorry heh
|
Yeah, I've got no idea how you'd do it, but those hunting animals should eventually give up the chase too. Could you imagine trying to camp a spawn that won't stop chasing a ribbit that it can't catch...
|
I decided against using an integer to represent what kind of thing a mob is (meat/vegie, etc.) and so settled on using boolean on whether
1. do you eat meat T/F 2. do you eat vegies T/F Which pretty much get the vast majority of cases I could think of and since they're in the struct, it wouldn't take much to expand it later. There was also the issue of expressing whether a mob is a meat or is a vegie. 1. i am meat T/F 2. i am vegie T/F Same kind of thing, as described above, is happening here. before I sat down to code this, the integer idea seemed like the way to go. Then i started looking at the chaos I'd have to deal with and decided some boolean checks would get the job done and be easier to put in place. And, as a bonus, might conserve on resources more than a sint8 (or whatever). If my theory holds true, these simpler pieces, when and once assembled, will create a nifty illusion. Still a little while to go though :-) todo/notes: mobs have properties of animalinstincts, but not methods like npcs if the player doesn't have a target selected, then the npc can't eat (so if a player unselects target before death, then npc can't feast on body) ::Starve() needs done (just reverse of Eat but w/o having to do -'s) need to think about what kind of benefits should fall onto a mob for having good health. For example, maybe if you aren't hungry then your stun timer doesn't last as long. And if you are hungry, then it lasts longer. Phase 3 will consist of a few things that I pushed aside in p2. Namely, messing around with players giving npcs items and having that translate to food for the npc. Note to self: OP_Click_Give. Anyhow, here's the bulk of phase 2 (I expect to amend this later), which is more proof of concept groundwork: Code:
|
Quote:
hrm. I assumed that such a check was already in there. However, looking quickly through npc.cpp, suggests that I might be wrong. Blimey. I'll have to take a peek at that tomorrow. --MV |
All times are GMT -4. The time now is 10:16 PM. |
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.