-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Monster weight / volume granularity #25631
Monster weight / volume granularity #25631
Conversation
also changes meat chunks calculation
Does it check the monster's material? Non-meat monsters should have different density/weight. |
@SunshineDistillery this is an infrastructure conversion for the starters, any re-balancing and improvement will need to be done later. |
mtype::get_meat_chunks() forced corpses into 5 possible sizes. All corpses of the smallest size (tiny) were 1 kg; all corpses of the next smallest size (small) were 40 kg. There is a huge gap between 1 and 40kg. |
@brianlewisbeck I have no idea what are you trying to tell here. This PR is all about changing that so... whats your point? |
Sorry - guess I was thinking out loud. Does the issue relate to any of the other sizes? If not, would it be possible to keep the existing framework but add subcategories to small? Seems like that would be a lot easier. |
To put it simple: when coding a new monster in JSON you will be able to define its weight and volume instead of forcing it into any constraints. For example you could say your new dog breed now weights 7 kg and is 15 liters of volume. Specific in game calculations would then use that value - for example to calculate meat chunks count, or if it just needs a category of size it would use a size class like before, but that class would be calculated from the given volume - for ex. 15 liter dog falls into MS_SMALL category. Adding subcategories is not an option now - would require to rebalance "half" of the game. |
is there a plan to replace the existing calls to get_size() where appropriate? Replacing the call in vehicle_move.cpp:part_collision() to critter->get_size() and the resulting switch/case set to get critter mass with get_weight(), for instance? Or do you just plan to do this infrastructure and let the rest of us sort it out, which is fine, just want to know the plan. |
If there is an obvious function that uses get _size while it should use true weight or volume then yes. However the only one that I considered obvious was butchery yields up until now. If it would be intuitive for me to incorporate the one you mentioned then I'll try, but if not I'll pass. I will not change or balance creatures’ values either, just the infrastructure for it. Second thing is that my free coding time got extremely scarce lately and I've got two other WIP not yet published PRs on the bench that slow me down in finishing this one. I just hope I'm closing in on finishing them. |
I listed every use of MS_SIZE I could find in the code in my first response in #25298. But if you're too busy, I totally understand and can clean up the vehicles code on my own after you've got this merged. Like I wrote, I don't hugely care what the answer is, I just want to know the plan. If you're only going to make the infrastructure and butchery changes, that's fine and I won't ask you to change the vehicles code if I review this PR. |
@mlangsdorf First of all thanks again for your help on fixing few issues with this PR. I'm not too confident to touch mechanics other then butchery to translate them to weigh/volume (this would require more conceptual work to perceive the desired effect), neither have time to do it. Same for setting correct values for monsters - that might need some extra research, and involving our community would be the best approach. So I've evaluated my take on this, and I think its best to provide this infrastructure as is to allow the community to take over from here and apply weight and volume however it's best - both in switching mechanics from size categories to actual weight/volume and also in setting individual weight and volumes for monsters in JSON files. |
I'm removing [WIP] from this PR but please TEST BEFORE MERGING. |
data/json/monsters.json
Outdated
@@ -7,7 +7,8 @@ | |||
"default_faction": "", | |||
"species": [ "ZOMBIE" ], | |||
"diff": 100, | |||
"size": "MEDIUM", | |||
"volume": "62500 ml", | |||
"weight": "81500", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not "weight": 81500
instead of "weight": "81500"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And in this I will regex quote marks into oblivion ASAP.
src/monstergenerator.cpp
Outdated
@@ -547,8 +548,10 @@ void mtype::load( JsonObject &jo, const std::string &src ) | |||
} | |||
|
|||
assign( jo, "color", color ); | |||
const typed_flag_reader<decltype( Creature::size_map )> size_reader{ Creature::size_map, "invalid creature size" }; | |||
optional( jo, was_loaded, "size", size, size_reader, MS_MEDIUM ); | |||
//const typed_flag_reader<decltype( Creature::size_map )> size_reader{ Creature::size_map, "invalid creature size" }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not check in commented out code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call, didn't even noticed that I left it behind
src/mtype.cpp
Outdated
@@ -52,6 +57,23 @@ std::string mtype::nname( unsigned int quantity ) const | |||
return ngettext( name.c_str(), name_plural.c_str(), quantity ); | |||
} | |||
|
|||
m_size mtype::volume_to_size( const units::volume vol ) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a non-static functions? It does not access any of the members of mtype
, it does not needthe implicit this
pointer. Make it a static function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, this requires moving it to monstergenerator.cpp
, I thought it might be more universal in the future by placing it in mtype
, but lets leave the future to govern itself.
src/mtype.cpp
Outdated
{ | ||
if( vol > 0_ml && vol <= 7500_ml ) { | ||
return MS_TINY; | ||
} else if( vol > 7500_ml && vol <= 46250_ml ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need the first check, write it like this instead:
if( vol <= 7500_ml ) {
return ...;
} else if( vol <= 46250_ml ) {
return ...;
} else if( vol <= ...
The second if clause will only be reached if vol > 7500_ml
, which does not need to be cecked again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just hope there will be no situation where vol == 0
then...
src/mtype.cpp
Outdated
return 0; | ||
float ch = units::to_gram( weight ) * ( 0.40f - 2 * log( units::to_gram( weight ) ) ); | ||
const itype *chunk = item::find_type( get_meat_itype() ); | ||
return static_cast<int>( ch / units::to_gram( chunk->weight ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
units::
is not needed when calling to_gram
with a units::mass
argument, the C++ compiler will find it anyway thanks to ADL.
Co-Authored-By: nexusmrsep <[email protected]>
Removed quote marks (") on weight and applied @BevapDin suggestions (thanks for the review). It's all yours @ZhilkinSerg. |
Great. Will test it again tonight. |
I'm not sure if this is the place or the way to report it but this commit has broken butchering completely. I can't debug because the latest experimental refuses to compile under VS but I have taken a look at the commit and I think it has to do with how the mass percent calculation is done:
A quick fix that I can't test at the moment could be: And then divide by the chunk weight in kilograms: EDIT: Now that I think of it, once the percentage is calculated it can be applied to the weight in grams and the return statement doesn't need to be changed. So this should do: |
return 320; | ||
} | ||
return 0; | ||
float ch = to_gram( weight ) * ( 0.40f - 2 * log( to_gram( weight ) ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be:
float ch = to_gram( weight ) * ( 0.40f - 0.02f * log10( to_gram( weight ) ) );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Todo ASAP today.
See also #26450. |
Summary
SUMMARY: Infrastructure "Converts monster size to weight and volume."
Purpose of change
Resolves #25298 Resolves #24921 Resolves #24909
Many game features use monster size classes to determine some effects. While this is a decent method for some cases, in other, like butchery, makes proper balancing impossible because lack of granularity.
Describe the solution
This PR does following things:
weight
andvolume
variables to monsters inmtype
volume
tosize
class viavolume_to_size
methodConversion table below shows how middle values between existing hardcoded weights and volumes (also presented below) were used to determine delimiter (borders) between size classes.
size
entries from json monster files and add decodingvolume
andweight
from them"size"
with"volume"
and"weight"
, that were set at previously hardcoded weights and volumes (presented above)This of course asks for a general refactor of those values according to some more sane values in many cases (example: most dogs weight over 40 kg)
get_meat_chunks()
that is a primary function to determine main butcher yields was redesigned to use monster'sweight
instead of size class. It has also been given dependency on 'meat' type to dynamically resolve number of maximum yielded items as some creatures yield not "meat" per se, but thinks like "tainted meat", "veggies", etc. that might have different weight. In general this new calculation follows @mlangsdorf idea for a function from Size / Weight / Volume of monsters granularity #25298 , but I've lowered its base value and flattened its regression, to keep it around 33% of body mass. It's final (?) form is:weight * ( 0.4 - 2 * ln( weight ) ) divided by mass of a proper 'meat chunk'
Typical results in %:
This is of course dynamic, so different weights of creatures will result in granular effects.
Describe alternatives you've considered
Alternative was granulating size classes, even after introducing this PR, but a need for that would have to emerge, and there are too many places where they are uses, that would need rebalancing.
Additional context
Reference: #24909, #24921, #25244 & #25248, #24878
WARNING