bool Creature::remove_effect( const efftype_id &eff_id, body_part bp ) { if (!has_effect(eff_id, bp)) { //Effect doesn't exist, so do nothing return false; } const effect_type &type = eff_id.obj(); if (is_player()) { // Print the removal message and add the memorial log if needed if(type.get_remove_message() != "") { add_msg(type.lose_game_message_type(), _(type.get_remove_message().c_str())); } add_memorial_log(pgettext("memorial_male", type.get_remove_memorial_log().c_str()), pgettext("memorial_female", type.get_remove_memorial_log().c_str())); } // num_bp means remove all of a given effect id if (bp == num_bp) { effects.erase(eff_id); } else { effects[eff_id].erase(bp); // If there are no more effects of a given type remove the type map if (effects[eff_id].empty()) { effects.erase(eff_id); } } return true; }
void Creature::add_effect( const efftype_id &eff_id, const time_duration dur, body_part bp, bool permanent, int intensity, bool force, bool deferred ) { // Check our innate immunity if( !force && is_immune_effect( eff_id ) ) { return; } if( !eff_id.is_valid() ) { debugmsg( "Invalid effect, ID: %s", eff_id.c_str() ); return; } const effect_type &type = eff_id.obj(); // Mutate to a main (HP'd) body_part if necessary. if (type.get_main_parts()) { bp = mutate_to_main_part(bp); } bool found = false; // Check if we already have it auto matching_map = effects->find(eff_id); if (matching_map != effects->end()) { auto &bodyparts = matching_map->second; auto found_effect = bodyparts.find(bp); if (found_effect != bodyparts.end()) { found = true; effect &e = found_effect->second; const int prev_int = e.get_intensity(); // If we do, mod the duration, factoring in the mod value e.mod_duration( dur * e.get_dur_add_perc() / 100); // Limit to max duration if( e.get_max_duration() > 0_turns && e.get_duration() > e.get_max_duration() ) { e.set_duration( e.get_max_duration() ); } // Adding a permanent effect makes it permanent if( e.is_permanent() ) { e.pause_effect(); } // int_dur_factor overrides all other intensity settings // ...but it's handled in set_duration, so explicitly do nothing here if( e.get_int_dur_factor() > 0_turns ) { // Set intensity if value is given } else if (intensity > 0) { e.set_intensity(intensity); // Else intensity uses the type'd step size if it already exists } 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() ); e.set_intensity(1); } else if (e.get_intensity() > e.get_max_intensity()) { e.set_intensity(e.get_max_intensity()); } if( e.get_intensity() != prev_int ) { on_effect_int_change( eff_id, e.get_intensity(), bp ); } } } if( !found ) { // If we don't already have it then add a new one // 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 e( &type, dur, bp, permanent, intensity, calendar::turn ); // Bound to max duration if( e.get_max_duration() > 0_turns && e.get_duration() > e.get_max_duration() ) { e.set_duration( e.get_max_duration() ); } // Force intensity if it is duration based if( e.get_int_dur_factor() != 0_turns ) { // + 1 here so that the lowest is intensity 1, not 0 e.set_intensity( e.get_duration() / e.get_int_dur_factor() + 1 ); } // Bound new effect intensity by [1, max intensity] if (e.get_intensity() < 1) { add_msg( m_debug, "Bad intensity, ID: %s", e.get_id().c_str() ); e.set_intensity(1); } else if (e.get_intensity() > e.get_max_intensity()) { e.set_intensity(e.get_max_intensity()); } ( *effects )[eff_id][bp] = e; if (is_player()) { // Only print the message if we didn't already have it if( !type.get_apply_message().empty() ) { add_msg(type.gain_game_message_type(), _(type.get_apply_message().c_str())); } add_memorial_log(pgettext("memorial_male", type.get_apply_memorial_log().c_str()), pgettext("memorial_female", type.get_apply_memorial_log().c_str())); } on_effect_int_change( eff_id, e.get_intensity(), bp ); // Perform any effect addition effects. // only when not deferred if( !deferred ) { process_one_effect( e, true ); } } }
void Creature::add_effect( efftype_id eff_id, int dur, body_part bp, bool permanent, int intensity, bool force ) { // Check our innate immunity if( !force && is_immune_effect( eff_id ) ) { return; } // First make sure it's a valid effect if (effect_types.find(eff_id) == effect_types.end()) { debugmsg("Invalid effect, ID: %s", eff_id.c_str()); return; } // Mutate to a main (HP'd) body_part if necessary. if (effect_types[eff_id].get_main_parts()) { bp = mutate_to_main_part(bp); } bool found = false; // Check if we already have it auto matching_map = effects.find(eff_id); if (matching_map != effects.end()) { auto found_effect = effects[eff_id].find(bp); if (found_effect != effects[eff_id].end()) { found = true; effect &e = found_effect->second; // If we do, mod the duration, factoring in the mod value e.mod_duration(dur * e.get_dur_add_perc() / 100); // Limit to max duration if (e.get_max_duration() > 0 && e.get_duration() > e.get_max_duration()) { e.set_duration(e.get_max_duration()); } // Adding a permanent effect makes it permanent if( e.is_permanent() ) { e.pause_effect(); } // Set intensity if value is given if (intensity > 0) { e.set_intensity(intensity); // Else intensity uses the type'd step size if it already exists } 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() ); e.set_intensity(1); } else if (e.get_intensity() > e.get_max_intensity()) { e.set_intensity(e.get_max_intensity()); } } } if( found == false ) { // If we don't already have it then add a new one // 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, calendar::turn); effect &e = new_eff; // Bound to max duration if (e.get_max_duration() > 0 && e.get_duration() > e.get_max_duration()) { e.set_duration(e.get_max_duration()); } // Bound new effect intensity by [1, max intensity] if (new_eff.get_intensity() < 1) { add_msg( m_debug, "Bad intensity, ID: %s", new_eff.get_id().c_str() ); new_eff.set_intensity(1); } else if (new_eff.get_intensity() > new_eff.get_max_intensity()) { new_eff.set_intensity(new_eff.get_max_intensity()); } effects[eff_id][bp] = new_eff; if (is_player()) { // Only print the message if we didn't already have it if(effect_types[eff_id].get_apply_message() != "") { add_msg(effect_types[eff_id].gain_game_message_type(), _(effect_types[eff_id].get_apply_message().c_str())); } add_memorial_log(pgettext("memorial_male", effect_types[eff_id].get_apply_memorial_log().c_str()), pgettext("memorial_female", effect_types[eff_id].get_apply_memorial_log().c_str())); } // Perform any effect addition effects. bool reduced = resists_effect(e); add_eff_effects(e, reduced); } }