Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Egglaying #21261

Closed
wants to merge 35 commits into from

Conversation

Projects
None yet
10 participants
@AlecWhite
Copy link
Contributor

commented Jun 17, 2017

This PR makes monster lay eggs:

  • Added EGGLAYING flag to monster.
  • Added egglaid effect of 2 days max duration.
  • Monsters with the EGGLAYING flag will lay an egg every 2 days.
  • Chickens now lay eggs.
  • Added òn_idle() method and called it in move().
  • òn_idle() method defaults to stumble() when the monster can't do any special action.
  • EGGLAYING monsters will only lay eggs on furniture with the NEST flag.
  • Added lay_egg attack and add it to chickens.
  • Added animal box and its recipe.
  • Added NEST flag for furniture
  • Animal box is used the same way as pet carrier but they are craftable.
  • Added makeshift nest and its recipe.

As always I tried to be as less invasive as possible, and due to my little knowledge of how things work I opted to do it the easiest way.

Will work on a poultry farm soon.

@Coolthulhu

This comment has been minimized.

Copy link
Contributor

commented Jun 17, 2017

I'd leave that for much later.
Egg laying will not work as nicely as milking - the result will be chickens laying fresh eggs when you pass by and random eggs littering the landscape.

For proper egg laying, the animals should have an AI that directs them into their nest before laying eggs and more "conscious" egg laying.
Not to mention that there is still no way to herd chickens properly.

data/json/effects.json Outdated
"type": "effect_type",
"id": "laidegg",
"name": [ "Laid an egg" ],
"desc": [ "This creature has laid an egg recently" ],

This comment has been minimized.

Copy link
@BrettDong

BrettDong Jun 18, 2017

Contributor

There should be a period. Some translators complained to me about the inconsistency of the period symbols at the end of the strings in game recently so I'm paying attention to that in new PRs.

@BorkBorkGoesTheCode

This comment has been minimized.

Copy link
Contributor

commented Jun 18, 2017

Could some method of converting eggs into chickens be implemented now, or in a later PR?

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 18, 2017

For proper egg laying, the animals should have an AI that directs them into their nest before laying eggs and more "conscious" egg laying.
Not to mention that there is still no way to herd chickens properly.

If that's the general consensus, I'm going to see if I can understand and work a way with the AI(is it basically in monmove.cpp for the AI and game::monmove() with some tidbits spread in monster.cpp to actually make them move right?) to make them move to a nest tile. The whole scanning an area from the chicken's position to search of a nest is going to the FUN to figure it out.
I think if I change the pet menu stuff and make the examinemonsters.cpp/.h I could make so chickens only lay eggs if fed and after the laidegg effect is off.
But again, don't take that as a promise, I'm too noob at C++ to work fast or work well. And generally documentation regarding the AI is too little to compensate for my noobness, so it is going to be a try and error thing(pretty much like everything else I made so far). But then it will be fun to try.

Could some method of converting eggs into chickens be implemented now, or in a later PR?

Short answer yes, long answer:
Wouldn't be too hard to make roosters go to a mob and mate with them(I think), but I still have to see a way to make roosters only mate with chickens and not with any other entity.
But then I would need a way to track the health of the fertilized eggs, and make the eggs check for the temperature each turn and then make them hatch. And another way to make chicks grow.

@AlecWhite AlecWhite referenced this pull request Jun 18, 2017

Closed

Milking #21272

@kevingranade

This comment has been minimized.

Copy link
Member

commented Jun 19, 2017

You're going to want two different pieces of code for placing eggs. The main piece would retroactively place eggs when egg-laying birds are loaded onto the map, the secondary piece would have the same birds move to a nesting area when they are ready to lay eggs, then produce eggs. A key thing to remember is which is primary and which is secondary. We expect the vast majority of eggs to be placed when the player is not nearby, so the "on-load" code places most of the eggs. The AI code is just there to keep things consistent in the rare case that the player happens to be nearby when birds are laying eggs.

Also you're going to want some special handling for eggs disappearing, to avoid the player coming across huge caches of eggs late in the game. In reality it's cyclic and you would expect to find similar amounts of eggs independent of date (unless you add in something for seasonal laying rates).

src/monstergenerator.cpp Outdated
@@ -446,6 +446,7 @@ void MonsterGenerator::init_flags()
flag_map["PATH_AVOID_DANGER_2"] = MF_AVOID_DANGER_2;
flag_map["PRIORITIZE_TARGETS"] = MF_PRIORITIZE_TARGETS;
flag_map["NOT_HALLUCINATION"] = MF_NOT_HALLU;
flag_map["EGGLAYING"] = MF_EGGLAYING;

This comment has been minimized.

Copy link
@Night-Pryanik

Night-Pryanik Jun 19, 2017

Member

Tab instead of spaces.

src/mtype.h Outdated
@@ -157,6 +157,7 @@ enum m_flag : int {
MF_AVOID_DANGER_2, // This monster will path around most dangers instead of through them.
MF_PRIORITIZE_TARGETS, // This monster will prioritize targets depending on their danger levels
MF_NOT_HALLU, // Monsters that will NOT appear when player's producing hallucinations
MF_EGGLAYING, // This monster will lay eggs.

This comment has been minimized.

Copy link
@Night-Pryanik

Night-Pryanik Jun 19, 2017

Member

Tab instead of spaces.

@AlecWhite AlecWhite closed this Jun 20, 2017

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 20, 2017

Close as I would need stuff in #21272 to start taming the chickens so they don't flee from you.

@kevingranade

This comment has been minimized.

Copy link
Member

commented Jun 20, 2017

@DangerNoodle

This comment has been minimized.

Copy link
Contributor

commented Jun 20, 2017

Even when tame, chickens scatter when people approach. If you want to farm chickens you either let them free range and go hunt down eggs, or you put them in an enclosure.

Enclosing livestock is something players will likely do anyway, as you would expect tame animals to potentially wander off even if they do not actively flee the player, in addition to players wanting to prevent them from being harmed.

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 21, 2017

Even when tame, chickens scatter when people approach. If you want to farm chickens you either let them free range and go hunt down eggs, or you put them in an enclosure.

My idea was doing something like http://dwarffortresswiki.org/index.php/DF2014:Nest_box coupled with https://www.omlet.co.uk/guide/chickens/chicken_care/how_to_tame_your_chickens

And for chickens laying eggs retroactively on on load, I would need a some kind of next, to control the amount of eggs laid, and to have a place for the eggs to go. Plus that would require to assign a nest for each chicken if you want them to lay egg.

@kevingranade

This comment has been minimized.

Copy link
Member

commented Jun 21, 2017

Something like a nest box is fine, it would just be a piece of furniture that's an ideal nest, so whatever nest-selection code we use would prefer it.

You don't get tame chickens unless you model raising them from chicks, the default is semi-tame chickens, so you need to handle that. You can add hand-rearing if you like, but it will never be the default.

Yes you need code that finds a nest, you need code that regulates number if eggs laid, you need code to avoid crowding. These are just what's required for the thing you're adding.

@AlecWhite AlecWhite reopened this Jun 21, 2017

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 21, 2017

You convinced me to do it without monexamine stuff.

@AlecWhite AlecWhite changed the title [CR]Egglaying [WIP][CR]Egglaying Jun 22, 2017

@mouseturd

This comment has been minimized.

Copy link

commented Jun 23, 2017

Not sure if this is doable - but with my chickens at home, the only way to "herd" them is to chase them, pick them up, then throw them in their fenced enclosure.

Is there a way of "picking up" or "grabbing" a chicken or other small furry animal at this time?

@kevingranade

This comment has been minimized.

Copy link
Member

commented Jun 23, 2017

Is there a way of "picking up" or "grabbing" a chicken or other small furry animal at this time?

There is not, but it wouldn't be that hard to add.

@DangerNoodle

This comment has been minimized.

Copy link
Contributor

commented Jun 23, 2017

There is not, but it wouldn't be that hard to add.

Pet carrier?

@mouseturd

This comment has been minimized.

Copy link

commented Jun 23, 2017

@Coolthulhu

This comment has been minimized.

Copy link
Contributor

commented Jun 26, 2017

Don't implement it as an attitude, this will mess up the AI for other creatures. And also be slow, since attitude checks are common.
Instead, check the egg laying where you currently check the new attitude.
Or better yet: create an "on idle" method, which you invoke in that place, then do the egg laying check in that method.

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 26, 2017

What do you mean by "on idle" method? Calling a method that checks if the monster is fed, searches for a nest and returns a tripoint assigning it to destination at the end of move()'s destination logic at line 550?

I don't fully understand how the AI works or how move() works but I don't mind trying it any other way as long as I'm not too noob to be able to. So any help and ideas I can get would awesome. And if I'm doing this I would rather do it the best possible way I can.

@Coolthulhu

This comment has been minimized.

Copy link
Contributor

commented Jun 26, 2017

What do you mean by "on idle" method?

Just wrapping the code in a new method, as in monster::on_idle. Not necessary, it's just that it would be cleaner than dumping it directly into move.

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 26, 2017

Not necessary, it's just that it would be cleaner than dumping it directly into move.

Thanks, I understand now, and it makes sense after reading the cooment about // TODO: Move this to attack_at/move_to/etc. functions.

And without the attitude check in which part inside of move() would be the correct place to call it?

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jun 27, 2017

Time to see how to revert a branch in which I have merged the latest change of master. If anything github related weird things happens, it will be due to that.

Edit: I think I did it now I need to update the branch with the master changes and then work on it.

@AlecWhite AlecWhite force-pushed the AlecWhite:egglaying branch Jun 27, 2017

@AlecWhite AlecWhite closed this Jun 27, 2017

@AlecWhite AlecWhite force-pushed the AlecWhite:egglaying branch to 73676e5 Jun 27, 2017

Added EGGLAYING flag, added EGGLAYING flag to chicken, added NEST fla…
…g to makeshift nest, added makeshift nest furniture
@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Jul 4, 2017

15:32:19 ERROR: Format error at line 8273 15:32:19 < },{ 15:32:19 > }, 15:32:19 15:32:19 HINT: Canonical output for this block was:

No idea how to fix that.

@Coolthulhu

This comment has been minimized.

Copy link
Contributor

commented Jul 4, 2017

No idea how to fix that.

Lint

@DangerNoodle

This comment has been minimized.

Copy link
Contributor

commented Jul 4, 2017

You can use the linting tool here: http://dev.narc.ro/cataclysm/format.html

AlecWhite added some commits Jul 5, 2017

"deconstruct": {
"items": [
{ "item": "2x4", "count": 10 },
{ "item": "rag", "count": [30, 33] },

This comment has been minimized.

Copy link
@BevapDin

BevapDin Jul 8, 2017

Contributor

Deconstruction this gives much more rags and 2x4s than constructing it needs. Same with rags and bashing (construction requires 10 rags, bashing give 15-20).

@@ -8270,5 +8270,34 @@
"ammo": "battery",
"initial_charges": 100,
"max_charges": 100
},
{
"result": "washboard",

This comment has been minimized.

Copy link
@BevapDin

BevapDin Jul 8, 2017

Contributor

Any reason why you moved a recipe into this file (which is for item definitions)? Why did you even touch that recipe at all?

This comment has been minimized.

Copy link
@AlecWhite

AlecWhite Jul 8, 2017

Author Contributor

I mistakenly deleted that recipe and I mistakenly re-insert it on the wrong json.

const int range = 15;
// Loop to find the closest furniture with NEST flag and set it as destination
for( tripoint &p : closest_tripoints_first( range, pos() ) ) {
if( sees( p ) && g->m.has_flag( TFLAG_NEST, p ) ) {

This comment has been minimized.

Copy link
@BevapDin

BevapDin Jul 8, 2017

Contributor

Here you check for the flag via map::has_flag (which for example also considers flags of the terrain). In mattack::lay_egg, you check via furn_t::has_flag. This is inconsistent.

monster &critter = *z;
const furn_t &furn = g->m.furn( critter.pos() ).obj();
// If the monster is in a tile with the NEST flag, lay egg
if( furn.has_flag( TFLAG_NEST ) ) {

This comment has been minimized.

Copy link
@BevapDin

BevapDin Jul 8, 2017

Contributor

There is map::has_flag_furn when you want to check only the furniture for a flag. No need to get the furn_t here.

if( furn.has_flag( TFLAG_NEST ) ) {
item egg( "egg_bird", 0, 1 );
g->m.add_item_or_charges( critter.pos(), egg );
critter.add_effect( effect_laid_egg, ( HOURS( 48 ) ) );

This comment has been minimized.

Copy link
@BevapDin

BevapDin Jul 8, 2017

Contributor

Parentheses around HOUR() are useless.

// Loop to find the closest furniture with NEST flag and set it as destination
for( tripoint &p : closest_tripoints_first( range, pos() ) ) {
if( sees( p ) && g->m.has_flag( TFLAG_NEST, p ) ) {
set_dest( p );

This comment has been minimized.

Copy link
@BevapDin

BevapDin Jul 8, 2017

Contributor

You should probably leave the loop after this via break. Currently the game would go on and check all the other tiles within range as well. The monster would essentially go to the furthest visible point.

AlecWhite added some commits Jul 8, 2017

Changed to use has_flag_furn, added break in on_idle(), added check t…
…o avoid laying more than one egg while stumble() over NEST furniture
@BorkBorkGoesTheCode

This comment has been minimized.

Copy link
Contributor

commented Aug 14, 2017

I wonder if this could be used to create bee swarms which lay honey inside hollow trees.

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Aug 14, 2017

I wonder if this could be used to create bee swarms which lay honey inside hollow trees.

Everything is hardcoded, and wasn't made thinking of modularity and even less moddability, but wouldn't be too hard to do the bee swarms, as another hardcoded PR. Although it would probably need a few more requiremenst because of balance/realism and all that stuff.

And after saying this I should look at how to resolve conflicts in github.

AlecWhite added some commits Aug 19, 2017

@AMurkin

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2017

Incorrect merge. JSON structure is broken.

"name": [ "Disabled" ],
"desc": [ "This creature has laid an egg" ],
"max_duration": 2400
}

This comment has been minimized.

Copy link
@BevapDin

BevapDin Aug 19, 2017

Contributor

, and '{' missing.

"color": "light_brown",
"properties": [ [ "monster_size_capacity", "SMALL" ] ],
"use_action": "CAPTURE_MONSTER_ACT",
"flags": [ "TRADER_AVOID" ]

This comment has been minimized.

Copy link
@BevapDin

BevapDin Aug 19, 2017

Contributor

} and , and { missing.

AlecWhite added some commits Aug 19, 2017

[
{ "id": "HAMMER", "level": 2 }
]
],

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Aug 19, 2017

Contributor

Is this linted? It looks really bad.

This comment has been minimized.

Copy link
@AlecWhite

AlecWhite Aug 19, 2017

Author Contributor

The linting tool doesn't like the fabrication field, so this time I'm going to pass it through without that field, and then add it later.

@@ -1678,6 +1678,13 @@
},
{
"type": "effect_type",
"id": "laid_egg",
"name": [ "Disabled" ],

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Aug 19, 2017

Contributor

Needs a name

@@ -323,6 +323,12 @@ class monster : public Creature, public JsonSerializer, public JsonDeserializer
/** Returns vector containing all body parts this monster has. That is, { bp_torso } */
std::vector<body_part> get_all_body_parts( bool main = false ) const override;

/*
* Decides what to do in case the monster is idle.
* If more idle actions are added change if loop for switch case.

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Aug 19, 2017

Contributor

Not a switch, but rather something like monster attack - a json-coded function wrapper.

@@ -337,6 +337,7 @@ void MonsterGenerator::init_attack()
add_hardcoded_attack( "RANGED_PULL", mattack::ranged_pull );
add_hardcoded_attack( "GRAB", mattack::grab );
add_hardcoded_attack( "GRAB_DRAG", mattack::grab_drag );
add_hardcoded_attack("LAY_EGG", mattack::lay_egg);

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Aug 19, 2017

Contributor

Styling

@kevingranade

This comment has been minimized.

Copy link
Member

commented Oct 18, 2017

This needs to have some code that triggers when an EGGLAYING creature is loaded on the map to find a nearby next and populate it with some eggs.

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Oct 18, 2017

Wouldn't that assume that the area was safe of monsters and the player to not trigger the fleeing state?
I mean, part of making chickens non-tameable was to force them to first, protect them, secon; leave them alone and third; balance, as it would make otherwise an already very good source of food.

And now that I'm reminded of this. I'm still not completely happy with the balance of the egg spawn, after playing it for some time, as our most "hardcore" players may find it a bit too easy.

Would it be good if I added some way like with the milking to configure the cool down between laying eggs?

@kevingranade

This comment has been minimized.

Copy link
Member

commented Oct 18, 2017

I'm not sure we're on the same page, as I said earlier, the vast majority of eggs would be laid when the player isn't present, there needs to be code to retroactively place those eggs when the player enters the area.

To put this another way, the way it works now is birds wait for the player to arrive before laying eggs, as soon as a bird spawns on the map, it will make a beeline for the nearest nest and immediately lay an egg. To see this in action, spawn a bunch of chickens and nests, leave the area, and return after several days have passed. All the chickens will run to the nests in unison and lay their eggs all at once. This is not an ok way for this to work.

@AlecWhite

This comment has been minimized.

Copy link
Contributor Author

commented Dec 10, 2017

Closing due to private reasons.

@AlecWhite AlecWhite closed this Dec 10, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.