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

Allow Emitters to use vars #73028

Merged
merged 5 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -1516,10 +1516,10 @@ Emitters randomly place [fields](#field-types) around their positions - every tu
| Identifier | Description
|--- |---
| `id` | Unique ID
| `field` | Field type emitted
| `intensity` | Initial intensity of the spawned fields (spawning multiple fields will still cause their intensity to increase). Default 1.
| `chance` | **Percent** chance of the emitter emitting, values above 100 will increase the quantity of fields placed via `roll_remainder` (ex: `chance: 150` will place one field 50% of the time and two fields the other 50% ). Failing the roll will disable the whole emission for the tick, not rolled for every `qty`! Default 100.
| `qty` | Number of fields placed. Fields are placed using the field propagation rules, allowing fields to spread. Default 1.
| `field` | Field type emitted. This can be a Variable Object, see the [doc](EFFECT_ON_CONDITION.md) for more info.
| `intensity` | Initial intensity of the spawned fields (spawning multiple fields will still cause their intensity to increase). Default 1. This can be a Variable Object, see the [doc](EFFECT_ON_CONDITION.md) for more info.
| `chance` | **Percent** chance of the emitter emitting, values above 100 will increase the quantity of fields placed via `roll_remainder` (ex: `chance: 150` will place one field 50% of the time and two fields the other 50% ). Failing the roll will disable the whole emission for the tick, not rolled for every `qty`! Default 100. This can be a Variable Object, see the [doc](EFFECT_ON_CONDITION.md) for more info.
| `qty` | Number of fields placed. Fields are placed using the field propagation rules, allowing fields to spread. Default 1. This can be a Variable Object, see the [doc](EFFECT_ON_CONDITION.md) for more info.

```JSON
{
Expand Down
47 changes: 15 additions & 32 deletions src/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,33 @@
#include <utility>

#include "debug.h"

#include "condition.h"
#include "flexbuffer_json-inl.h"
#include "flexbuffer_json.h"
#include "json.h"

static std::map<emit_id, emit> emits_all;

/** @relates string_id */
template<>
bool string_id<emit>::is_valid() const
const emit &string_id<emit>::obj() const
{
const auto found = emits_all.find( *this );
if( found == emits_all.end() ) {
return false;
debugmsg( "Tried to get invalid emission data: %s", c_str() );
static const emit null_emit{};
return null_emit;
}
return !found->second.field().id().is_null();
return found->second;
}

/** @relates string_id */
template<>
const emit &string_id<emit>::obj() const
bool string_id<emit>::is_valid() const
{
const auto found = emits_all.find( *this );
if( found == emits_all.end() ) {
debugmsg( "Tried to get invalid emission data: %s", c_str() );
static const emit null_emit{};
return null_emit;
}
return found->second;
return found != emits_all.end();
}

emit::emit() : id_( emit_id::NULL_ID() ) {}
Expand All @@ -46,11 +46,10 @@ void emit::load_emit( const JsonObject &jo )
emit et;

et.id_ = emit_id( jo.get_string( "id" ) );
et.field_name = jo.get_string( "field" );

jo.read( "intensity", et.intensity_ );
jo.read( "qty", et.qty_ );
jo.read( "chance", et.chance_ );
et.field_ = get_str_or_var( jo.get_member( "field" ), "field" );
et.intensity_ = get_dbl_or_var( jo, "intensity", false, 1.0 );
et.qty_ = get_dbl_or_var( jo, "qty", false, 1.0 );
et.chance_ = get_dbl_or_var( jo, "chance", false, 100.0 );

emits_all[ et.id_ ] = et;
}
Expand All @@ -62,24 +61,8 @@ const std::map<emit_id, emit> &emit::all()

void emit::finalize()
{
for( auto &e : emits_all ) {
e.second.field_ = field_type_id( e.second.field_name );
const int max_intensity = e.second.field_.obj().get_max_intensity();
if( e.second.intensity_ > max_intensity || e.second.intensity_ < 1 ) {
debugmsg( "emission intensity of %s out of range (%d of max %d)", e.second.id_.c_str(),
e.second.intensity_, max_intensity );
e.second.intensity_ = max_intensity;
}
if( e.second.qty_ <= 0 ) {
debugmsg( "emission qty of %s out of range", e.second.id_.c_str() );
}
if( e.second.chance_ > 100 || e.second.chance_ <= 0 ) {
debugmsg( "emission chance of %s out of range (%d of min 1 max 100)", e.second.id_.c_str(),
e.second.chance_ );
e.second.chance_ = std::max( std::min( e.second.chance_, 100 ), 1 );
}
}
}

void emit::check_consistency()
{
}
Expand Down
28 changes: 13 additions & 15 deletions src/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "field_type.h"
#include "type_id.h"
#include <dialogue_helpers.h>

class JsonObject;

Expand All @@ -26,23 +27,23 @@ class emit
bool is_valid() const;

/** Type of field to emit @see emit::is_valid */
field_type_id field() const {
return field_;
field_type_id field( dialogue &d ) const {
return field_type_id( field_.evaluate( d ) );
}

/** Intensity of output fields, range [1..maximum_intensity] */
int intensity() const {
return intensity_;
int intensity( dialogue &d ) const {
return intensity_.evaluate( d );
}

/** Units of field to generate per turn subject to @ref chance */
int qty() const {
return qty_;
int qty( dialogue &d ) const {
return qty_.evaluate( d );
}

/** Chance to emit each turn, range [1..100] */
int chance() const {
return chance_;
int chance( dialogue &d ) const {
return chance_.evaluate( d );
}

/** Load emission data from JSON definition */
Expand All @@ -62,13 +63,10 @@ class emit

private:
emit_id id_;
field_type_id field_ = fd_null.id_or( INVALID_FIELD_TYPE_ID );
int intensity_ = 1;
int qty_ = 1;
int chance_ = 100;

/** used during JSON loading only */
std::string field_name;
str_or_var field_;
dbl_or_var intensity_;
dbl_or_var qty_;
dbl_or_var chance_;
};

#endif // CATA_SRC_EMIT_H
10 changes: 6 additions & 4 deletions src/map_field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <utility>
#include <vector>

#include "avatar.h"
#include "bodypart.h"
#include "calendar.h"
#include "cata_utility.h"
Expand Down Expand Up @@ -2103,10 +2104,11 @@ void map::emit_field( const tripoint &pos, const emit_id &src, float mul )
return;
}

const float chance = src->chance() * mul;
if( src.is_valid() && x_in_y( chance, 100 ) ) {
const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
propagate_field( pos, src->field(), qty, src->intensity() );
dialogue d( get_talker_for( get_avatar() ), nullptr );
const float chance = src->chance( d ) * mul;
if( x_in_y( chance, 100 ) ) {
const int qty = chance > 100.0f ? roll_remainder( src->qty( d ) * chance / 100.0f ) : src->qty( d );
propagate_field( pos, src->field( d ), qty, src->intensity( d ) );
}
}

Expand Down
Loading