Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign up[DONE] Carrion monster spawning #23774
Conversation
acidia
added some commits
May 17, 2018
BevapDin
reviewed
May 19, 2018
| it = i_rem( pnt, it ); | ||
| } else { | ||
| ++it; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| template <typename Item> | ||
| void map::rotten_item_spawn( Item &item, const tripoint &pnt ) |
This comment has been minimized.
This comment has been minimized.
BevapDin
May 19, 2018
Contributor
Why is this a function template? I guess it's because item is not really an item, but an iterator into a std::list<item> (which explains why it's dereferenced on every access even through it is a reference).
Change the function to take an actual item reference (and make it a reference to a const item as the function does not modify the item) and call it as rotten_item_spawn( *it, ... ).
BevapDin
reviewed
May 19, 2018
| @@ -6726,13 +6727,38 @@ void map::remove_rotten_items( Container &items, const tripoint &pnt ) | |||
| const tripoint abs_pnt = getabs( pnt ); | |||
| for( auto it = items.begin(); it != items.end(); ) { | |||
| if( has_rotten_away( *it, abs_pnt ) ) { | |||
| //If the item that is rotting is a food item, see if we can spawn a monster | |||
This comment has been minimized.
This comment has been minimized.
BevapDin
May 19, 2018
Contributor
Why do you feel the need to repeat the code as comment. "if the item ... is a food item" is the same as if(it->is_comestible()) {.
BevapDin
reviewed
May 19, 2018
| @@ -166,6 +166,11 @@ struct islot_comestible | |||
| int get_calories() const { | |||
| return nutr * kcal_per_nutr; | |||
| } | |||
| /** The monster group that is drawn from when the item rots away */ | |||
| std::string rot_spawn = "null"; | |||
This comment has been minimized.
This comment has been minimized.
BevapDin
May 19, 2018
Contributor
Please change this to be of mongroup_id type. It's not a simple string, it's the id of an monster group. Don't create the mongroup_id when calling MonsterGroupManager::GetResultFromGroup because the compiler complains there. Create it as soon as possible.
Also would be nice to add a consitency check for this id in "item_factory.cpp" (so an invalid id is reported when the game loads, not when the id is actually used). For this it would be nice to use mongroup_id::NULL_ID() instead of "null" as the default value (which is "GROUP_NULL"), also for consistency with other monster group related code.
BevapDin
reviewed
May 19, 2018
| chance *= get_option<int>( "CARRION_SPAWNRATE" )/100; | ||
| if (rng(0, 100) < chance){ | ||
| MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup(mongroup_id(mgroup)); | ||
| if( g->critter_at( pnt ) == nullptr ) { |
This comment has been minimized.
This comment has been minimized.
BevapDin
May 19, 2018
Contributor
This should probably be checked first as all the other stuff is pointless when this turns out to be false.
Also consider using early returns instead of that many levels of intendation,e g.
if( some_is_wrong ) {
return;
}
do_something();
if( some_else_is_wrong ) {
return;
}
do_something_more();Instead of
if( !some_is_wrong ) {
do_something();
if( !some_else_is_wrong ) {
do_something_more();
}
}
BevapDin
reviewed
May 19, 2018
| std::string mgroup = comest->rot_spawn; | ||
| if ( mgroup != "null" ) { | ||
| int chance = comest->rot_spawn_chance; | ||
| chance *= get_option<int>( "CARRION_SPAWNRATE" )/100; |
This comment has been minimized.
This comment has been minimized.
BevapDin
May 19, 2018
Contributor
Those two lines can be combined into one. In fact, they should be because currently any value of "CARRION_SPAWNRATE" below 100 will set the chance to 0: get_option<int> returns an int and 100 is an int as well, so the division is done as integer division (e.g. 80/100 == 0) and the multiplication is only done after that.
I suggest this: const int chance = ( rot_spawn_chance * get_option ) / 100;
BevapDin
reviewed
May 19, 2018
| if( jo.has_string( "rot_spawn" ) ) { | ||
| slot.rot_spawn = jo.get_string( "rot_spawn" ); | ||
| } | ||
| if( jo.has_string( "rot_spawn_chance" ) ) { |
This comment has been minimized.
This comment has been minimized.
BevapDin
May 19, 2018
Contributor
If you use assign to load the value, you don't need to check for existance of that member. assign will handle that case on its own (and do nothing).
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Have you considered extending it to make human meat resurrect into zombies? |
acidia
added some commits
May 19, 2018
This comment has been minimized.
This comment has been minimized.
|
I figured human meat wouldn't become zombies but making human corpses rot into zombies makes sense. Corpses are handled differently from comestibles, I think all corpses inherit from a single json item, so you'd be changing the creature entry instead of the item. Certainly possible but isn't worth the work with so few NPCs generally. |
This comment has been minimized.
This comment has been minimized.
|
Could you please describe what monsters you've added, what features they have etc? |
This comment has been minimized.
This comment has been minimized.
|
@acidia Other than that I really like this idea, even as actual way to hunt - drawing carrion beasts to prepared corpse, hiding and then, for example, shooting down vultures for their own meat, bones and feathers. |
This comment has been minimized.
This comment has been minimized.
|
Sure, general thoughts on monsters: Roaches are already in and they aren't that bad., They typically allow combat with the player immediately so a roach infestation isn't something a brave melee survivor can't deal with in an hour. I'm thinking about giving these guys a food damaging attack so if you trow all of your perishable and non-perishable food in a shed you might find it all gone if you let things rot. The main spawn for clean rotting meat/veg. Plague nymph/skittering/vector animals nasty enough to think it was a good idea to start eating zombie meat. Think of them as post threshold mutants since they are still kinda roaches. These guys are bad because they avoid combat with the player until you are either too weak to fight or they grow to become vectors and can bring the fight to you. In combat they are faster than normal roach and will have an extremely infectious bite but have about half the HP. Game play wise, see about these guys eating grass/trees/crops with their special to turn infested areas into wasteland. If infestations truly become something the player can't deal with, in a bad way, we can always make temps below 0 drop their move to 1/4. Main spawn for tainted meat. Triffid Sprig, the "favorable" spawn for intentional carrion farming. Little guys that obviously turn into triffids eventually. My thoughts were setting them on roughly a 1yr life cycle from sprouting->young triffid->triffid. Goal would be to not have adult triffids reproduce but instead have their seeds dispersed into the wind... making favorable "planting"/carrion conditions the best way to get them. Easy for you to kill, or the other carrion spawns. You might have to use small batches of carrion or their preferred carrion to ensure you actual keep them. Minor spawn for clean meat. Chicken chick, like chicken but smaller and less capable. Currently it takes a year (2x rot time) for bird eggs to start hatching but that should probably be halved. Spawns from wild eggs at the moment because I didn't want to make a shit ton of baby animals in the engine change PR. |
BevapDin
reviewed
May 20, 2018
| @@ -14,6 +14,7 @@ | |||
| #include "damage.h" | |||
| #include "translations.h" | |||
| #include "calendar.h" | |||
| #include "mongroup.h" | |||
This comment has been minimized.
This comment has been minimized.
BevapDin
May 20, 2018
Contributor
This is not needed. A forward declaration of MonsterGroup and the typedef of mongroup_id is enough (see "map.h" for how it's done).
ZhilkinSerg
added
[JSON]
Spawn
[C++]
Monsters
labels
May 21, 2018
This comment has been minimized.
This comment has been minimized.
|
I was thinking about it and would like to ask - shouldn't spawn of such scavengers be limited by certain storage methods? I'd reckon spawning of such things in buildings should be considerably smaller in comaprison with the chance of some scavenger being drawn to food rotting outside. Also, if the food is stored somewhere (locker, crate, other furniture or containers) it should prevent spawn of such creatures in general. |
This comment has been minimized.
This comment has been minimized.
|
Rotting stuff in container will bring roaches regardless of the fact that it's in a container. |
This comment has been minimized.
This comment has been minimized.
|
It was already handled well enough for me (I don't know how to quote code) but starting at line 6704 of map.cpp has
So if the container is airtight you won't have to worry about monster spawning because items won't rot away (the stank doesn't escape). Setting it per location would be a bit of a nightmare given how many different overmap and terrain tiles we have. It would be possible to add a multiplier on say t_grass then x2 as likely to spawn carrion but defining all of those is way more than what I need at the moment. |
acidia
changed the title
[TESTING] Carrion monster spawning
[DONE] Carrion monster spawning
May 24, 2018
This comment has been minimized.
This comment has been minimized.
|
I'm happy enough after a few hours of wilderness play. I'll push a different PR json update for wild eggs shortly, just so things make sense. Chickens will always produce chicken eggs, but a white/brown wild bird egg could be a chicken egg or it could be a turkey/pheasant/duck egg. Eggs shouldn't be immediately obvious who they belong to nor should some chicks... a wild brown chick could be a quail/pheasant, a duckling could be a duck/goose/swan. It'll add some mystery till it grows up. Balance wise, butchering large numbers of enemies will leave enough tainted meat that carrion spawns are noticeable without altering game-play much yet. It leaves the question of what should be done with pulped corpses, which will never re-spawn into the same creature but should be huge attractions for carrion feeders? I don't want to define a specific carrion spawn group for each monster but zombie dogs spawning on a dead squirrel makes sense while deep in a lab on a pulped zombie corpse doesn't make sense, dogs aren't "vermin" at any point so they shouldn't be everywhere. Should all pulped corpses spawn from a minor to greater jabberwock type corpse amalgamation group? |
acidia
referenced this pull request
May 25, 2018
Merged
[DONE] Carrion monster growing and reproduction #23833
This comment has been minimized.
This comment has been minimized.
|
Probably some sort of checks and limits should be introduced, since as things are it seems they may easily spiral out of control. Kill a bunch of things -> lots of scavengers appear -> kill them -> even more things are now dead drawing in even more scavengers. At some point scavengers may become bigger threat than whatever they were scavenging on. Possibly some way of flagging the overmap tile when scavengers are called in once so it will not call in further attention till a few days pass could help here. Also, a thing for further consideration - we certainly require more non-hostile scavengers. Black or even more regular rats, vultures etc rather than hordes of dogs and oversized roaches. |
This comment has been minimized.
This comment has been minimized.
|
I don't think we'll need any checks until we get a bit more play testing, rotting meat is running about a 15% chance of spawning a tiny vermin (~1 meat) creature so we do have decreasing total biomass in the short term. Vermin will of course grow and breed quickly so you might see total biomass size repopulate in 1-2 seasons, if you visit occasionally, don't clean house, and monster infighting doesn't purge populations. Of course, leaving a giant trail of rotten mutating corpses behind you can and should create a bigger problem than you originally had if you don't deal with it. Fire is the simplest way of cleansing your battle ground. Certainly going to add more scavengers, I think I had crows spawn on low chances on clean vegetables rotting in the demo jsons. I didn't add rats simply because I didn't think they would utilize the breeding mechanics. Not that they don't breed but I think anything other than an adult rat would be too small to notice. Been trying to keep the carrion spawn group distribution in favor of once species otherwise they will immediately kill each other when they spawn. 5 baby roaches vs 5 young triffids might mean you only see 2 wounded young triffids when you approach. Instead of 3 baby roaches vs 7 young triffids where you find 6 wounded young triffids when you approach. I'd say increasing variety should follow a diversity of different spawn groups instead of diluting spawning in one group. |
This comment has been minimized.
This comment has been minimized.
|
Not my call, that is the linter reformatting everything... |
Clyybber
approved these changes
May 27, 2018
|
This is great! I would only keep those json entries multiline. |
| "price": 20, | ||
| "calories": 0.95 | ||
| }, | ||
| "proportional": { "price": 20, "calories": 0.95 }, |
This comment has been minimized.
This comment has been minimized.
Clyybber
May 27, 2018
Contributor
I guess its a bit more readable if ywe would keep all these entries multiline.
This comment has been minimized.
This comment has been minimized.
acidia
May 27, 2018
Author
Contributor
I agree but I'm not sure how to go about changing the linter.
This comment has been minimized.
This comment has been minimized.
Clyybber
May 27, 2018
Contributor
Yeah, thats a thing for a different PR. I will try to look into it.
acidia
added some commits
May 27, 2018
This comment has been minimized.
This comment has been minimized.
|
Added a rotting spawn check when plants grow. This lets me use carrion spawns to spawn locusts or other nuisances any time a plant growth check is made. Seeds don't rot normally so it will only occur for plant growth. Spawning monsters doesn't hurt the plant, the monsters should do that themselves. Probably leave all spawn chances at 1% since it makes the check for each growth stage (three times). |
acidia commentedMay 19, 2018
Fairly straightforward, when a comestible rots away it has a small chance of spawning a creature.
Food (currently just meat, tainted meat, wild vegetables, eggs, and a couple others) has two new stats:
"rot_spawn": "GROUP_CARRION_INFECTED",
"rot_spawn_chance": 15,
Name the monster group that is spawning and set the spawn rate (default to 10% if not listed). There is also a world spawn chance that is defaulted to 100%. The two numbers are multiplied to generate the overall chance that a monster will spawn. So if there is a monster that has a 200% spawning rate it will still spawn 100% of the time at 50% global carrion spawns.
The issue emerged with the factories in #23748, where a giant factory full of rotting food was still a nice place to visit a week into the cataclysm. The monsters spawning are generally vermin that don't pose a threat but I'll see about getting a more general maturation than what we currently have so plague nymphs (infected meat eating roaches)->plague vectors/giant roaches which we can make damage food items they step on.
For wilderness runs, this gives static bases something to manage. Bird eggs can be let to rot to try your chances of spawning a chick (takes a year currently and runs ~60% chance) or triffid farming if you figure out what triffid sprigs like spawning on.