Skip to content

Commit

Permalink
Allow Emitters to use vars (#73028)
Browse files Browse the repository at this point in the history
* Emitter uses vars

* Fix is_valid

* Update JSON_INFO.md

* Update map_field.cpp
  • Loading branch information
Ramza13 authored May 7, 2024
1 parent 08a8580 commit f859222
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 55 deletions.
8 changes: 4 additions & 4 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -1517,10 +1517,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 @@ -2104,10 +2105,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

0 comments on commit f859222

Please sign in to comment.