Skip to content

Commit

Permalink
Merge branch 'BlockEffects' of https://github.com/i2amroy/Cataclysm-DDA
Browse files Browse the repository at this point in the history
… into merge-b
  • Loading branch information
KA101 committed Apr 14, 2015
2 parents 213a13e + 1919f49 commit d717383
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 49 deletions.
6 changes: 4 additions & 2 deletions data/json/effects.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
"id": "blind",
"name": ["Blind"],
"desc": ["Range of Sight: 0"],
"removes_effects": ["glare", "darkness"],
"apply_message": "You're blinded!",
"remove_message": "Your sight returns!",
"rating": "bad"
Expand Down Expand Up @@ -848,7 +849,8 @@
},
{
"type": "effect_type",
"id": "flushot"
"id": "flushot",
"blocks_effects": ["flu"]
},
{
"type": "effect_type",
Expand Down Expand Up @@ -917,7 +919,7 @@
"max_intensity": 2,
"int_dur_factor": 150,
"dur_add_perc": 15,
"removes_effect": "winded",
"removes_effects": ["winded"],
"base_mods": {
"speed_mod": [-10],
"str_mod": [-2],
Expand Down
18 changes: 13 additions & 5 deletions doc/EFFECTS_JSON.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,21 @@ These fields are used to determine if an effect is being resisted or not. If the
matching trait or effect then they are "resisting" the effect, which changes its effects and description.
Effects can only have one "resist_trait" and one "resist_effect" at a time.

### Removes effect
### Removes effects
```C++
"removes_effect": "bite"
"removes_effects": ["bite", "flu"]
```
This field will cause an effect to automatically remove any other copies of the listed effect if it is present.
In the example above the placed effect would automatically cure any bite wounds the player had. An effect can only
have one "removes_effect" field at a time.
This field will cause an effect to automatically remove any other copies of the listed effects if they are present.
In the example above the placed effect would automatically cure any bite wounds or flu the player had. Any values here
automatically count for "blocks_effects" as well, no need to duplicate them there.

### Blocks effects
```C++
"blocks_effects": ["cold", "flu"]
```
This field will cause an effect to prevent the placement of the listed effects. In the example above the effect would
prevent the player from catching the cold or the flu (BUT WOULD NOT CURE ANY ONGOING COLDS OR FLUS). Any effects present
in "removes_effects" are automatically added to "blocks_effects", no need for manual duplication.

### Effect limiters
```C++
Expand Down
29 changes: 22 additions & 7 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ void Creature::add_eff_effects(effect e, bool reduced)
(void)reduced;
return;
}

void Creature::add_effect(efftype_id eff_id, int dur, body_part bp, bool permanent, int intensity)
{
// Mutate to a main (HP'd) body_part if necessary.
Expand Down Expand Up @@ -752,7 +752,7 @@ void Creature::add_effect(efftype_id eff_id, int dur, body_part bp, bool permane
} else if (e.get_int_add_val() != 0) {
e.mod_intensity(e.get_int_add_val());
}

// Bound intensity by [1, max intensity]
if (e.get_intensity() < 1) {
add_msg( m_debug, "Bad intensity, ID: %s", e.get_id().c_str() );
Expand All @@ -762,12 +762,27 @@ void Creature::add_effect(efftype_id eff_id, int dur, body_part bp, bool permane
}
}
}

if (found == false) {
// If we don't already have it then add a new one

// First make sure it's a valid effect
if (effect_types.find(eff_id) == effect_types.end()) {
return;
}
// Then check if the effect is blocked by another
for( auto &elem : effects ) {
for( auto &_effect_it : elem.second ) {
for( const auto blocked_effect : _effect_it.second.get_blocks_effects() ) {
if (blocked_effect == eff_id) {
// The effect is blocked by another, return
return;
}
}
}
}

// Now we can make the new effect for application
effect new_eff(&effect_types[eff_id], dur, bp, permanent, intensity);
effect &e = new_eff;
// Bound to max duration
Expand Down Expand Up @@ -819,7 +834,7 @@ bool Creature::remove_effect(efftype_id eff_id, body_part bp)
//Effect doesn't exist, so do nothing
return false;
}

if (is_player()) {
// Print the removal message and add the memorial log if needed
if(effect_types[eff_id].get_remove_message() != "") {
Expand All @@ -831,7 +846,7 @@ bool Creature::remove_effect(efftype_id eff_id, body_part bp)
pgettext("memorial_female",
effect_types[eff_id].get_remove_memorial_log().c_str()));
}

// num_bp means remove all of a given effect id
if (bp == num_bp) {
effects.erase(eff_id);
Expand Down Expand Up @@ -894,7 +909,7 @@ void Creature::process_effects()
// passed in to this function.
std::vector<std::string> rem_ids;
std::vector<body_part> rem_bps;

// Decay/removal of effects
for( auto &elem : effects ) {
for( auto &_it : elem.second ) {
Expand All @@ -907,7 +922,7 @@ void Creature::process_effects()
_it.second.decay( rem_ids, rem_bps, calendar::turn, is_player() );
}
}

// Actually remove effects. This should be the last thing done in process_effects().
for (size_t i = 0; i < rem_ids.size(); ++i) {
remove_effect( rem_ids[i], rem_bps[i] );
Expand Down
7 changes: 7 additions & 0 deletions src/effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,12 @@ const std::vector<std::string> &effect::get_removes_effects() const
{
return eff_type->removes_effects;
}
const std::vector<std::string> effect::get_blocks_effects() const
{
std::vector<std::string> ret = eff_type->removes_effects;
ret.insert(ret.end(), eff_type->blocks_effects.begin(), eff_type->blocks_effects.end());
return ret;
}

int effect::get_mod(std::string arg, bool reduced) const
{
Expand Down Expand Up @@ -1122,6 +1128,7 @@ void load_effect_type(JsonObject &jo)
new_etype.resist_trait = jo.get_string("resist_trait", "");
new_etype.resist_effect = jo.get_string("resist_effect", "");
new_etype.removes_effects = jo.get_string_array("removes_effects");
new_etype.blocks_effects = jo.get_string_array("blocks_effects");

new_etype.max_intensity = jo.get_int("max_intensity", 1);
new_etype.max_duration = jo.get_int("max_duration", 0);
Expand Down
37 changes: 20 additions & 17 deletions src/effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class effect_type

/** Returns if an effect is good or bad for message display. */
effect_rating get_rating() const;

/** Returns true if there is a listed name in the JSON entry for each intensity from
* 1 to max_intensity. */
bool use_name_ints() const;
Expand Down Expand Up @@ -71,26 +71,27 @@ class effect_type
protected:
int max_intensity;
int max_duration;

int dur_add_perc;
int int_add_val;

int int_decay_step;
int int_decay_tick;
int int_dur_factor;

bool main_parts_only;

std::string resist_trait;
std::string resist_effect;
std::vector<std::string> removes_effects;

std::vector<std::string> blocks_effects;

std::vector<std::pair<std::string, int>> miss_msgs;

bool pain_sizing;
bool hurt_sizing;
bool harmful_cough;
// TODO: Once addictions are JSON-ized it should be trivial to convert this to a
// TODO: Once addictions are JSON-ized it should be trivial to convert this to a
// "generic" addiction reduces value
bool pkill_addict_reduces;

Expand All @@ -99,7 +100,7 @@ class effect_type
std::vector<std::string> desc;
std::vector<std::string> reduced_desc;
bool part_descs;

std::vector<std::pair<std::string, game_message_type>> decay_msgs;

effect_rating rating;
Expand All @@ -108,7 +109,7 @@ class effect_type
std::string apply_memorial_log;
std::string remove_message;
std::string remove_memorial_log;

/** Key tuple order is:("base_mods"/"scaling_mods", reduced: bool, type of mod: "STR", desired argument: "tick") */
std::unordered_map<std::tuple<std::string, bool, std::string, std::string>, double> mod_data;
};
Expand Down Expand Up @@ -142,7 +143,7 @@ class effect : public JsonSerializer, public JsonDeserializer

/** Returns the effect's matching effect_type. */
effect_type *get_effect_type() const;

/** Decays effect durations, pushing their id and bp's back to rem_ids and rem_bps for removal later
* if their duration is <= 0. This is called in the middle of a loop through all effects, which is
* why we aren't allowed to remove the effects here. */
Expand All @@ -158,7 +159,7 @@ class effect : public JsonSerializer, public JsonDeserializer
void mod_duration(int dur);
/** Multiplies the duration, capping at max_duration if it exists. */
void mult_duration(double dur);

/** Returns the targeted body_part of the effect. This is num_bp for untargeted effects. */
body_part get_bp() const;
/** Sets the targeted body_part of an effect. */
Expand All @@ -179,14 +180,16 @@ class effect : public JsonSerializer, public JsonDeserializer
void set_intensity(int nintensity);
/** Mods an effect's intensity, capping at max_intensity. */
void mod_intensity(int nintensity);

/** Returns the string id of the resist trait to be used in has_trait("id"). */
std::string get_resist_trait() const;
/** Returns the string id of the resist effect to be used in has_effect("id"). */
std::string get_resist_effect() const;
/** Returns the string ids of the effects removed by this effect to be used in remove_effect("id"). */
const std::vector<std::string> &get_removes_effects() const;

/** Returns the string ids of the effects blocked by this effect to be used in add_effect("id"). */
const std::vector<std::string> get_blocks_effects() const;

/** Returns the matching modifier type from an effect, used for getting actual effect effects. */
int get_mod(std::string arg, bool reduced = false) const;
/** Returns the average return of get_mod for a modifier type. Used in effect description displays. */
Expand All @@ -204,7 +207,7 @@ class effect : public JsonSerializer, public JsonDeserializer
/** Checks to see if a given modifier type can activate, and performs any rolls required to do so. mod is a direct
* multiplier on the overall chance of a modifier type activating. */
bool activated(unsigned int turn, std::string arg, int val, bool reduced = false, double mod = 1) const;

/** Returns the modifier caused by addictions. Currently only handles painkiller addictions. */
double get_addict_mod(std::string arg, int addict_level) const;
/** Returns true if the coughs caused by an effect can harm the player directly. */
Expand All @@ -213,10 +216,10 @@ class effect : public JsonSerializer, public JsonDeserializer
int get_dur_add_perc() const;
/** Returns the amount an already existing effect intensity is modified by further applications of the same effect. */
int get_int_add_val() const;

/** Returns a vector of the miss message messages and chances for use in add_miss_reason() while the effect is in effect. */
std::vector<std::pair<std::string, int>> get_miss_msgs() const;

/** Returns the value used for display on the speed modifier window in the player status menu. */
std::string get_speed_name() const;

Expand Down
Loading

0 comments on commit d717383

Please sign in to comment.