From c02f9e06e1278f061eff458b27b60bf506887c33 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 13:17:42 +0200 Subject: [PATCH 01/32] initial commit --- data/json/monsters/monster_flags.json | 5 ++ data/json/monsters/zed_dormant.json | 108 ++++++++++++++++++++++++++ data/json/traps.json | 2 +- doc/JSON_FLAGS.md | 1 + doc/JSON_INFO.md | 2 +- doc/MAGIC.md | 2 + doc/MONSTERS.md | 1 + src/magic.cpp | 7 ++ src/magic.h | 7 ++ src/magic_spell_effect.cpp | 39 +++++++++- src/monster.cpp | 21 ++++- src/monstergenerator.cpp | 17 ++++ src/mtype.h | 11 +++ src/npc.cpp | 2 +- src/sounds.cpp | 7 +- src/trap.cpp | 33 ++++++-- src/trap.h | 4 +- src/trapfunc.cpp | 36 +++++---- 18 files changed, 276 insertions(+), 29 deletions(-) create mode 100644 data/json/monsters/zed_dormant.json diff --git a/data/json/monsters/monster_flags.json b/data/json/monsters/monster_flags.json index 05c193a507932..ffb405e571462 100644 --- a/data/json/monsters/monster_flags.json +++ b/data/json/monsters/monster_flags.json @@ -289,6 +289,11 @@ "type": "monster_flag", "//": "Monster corpse will revive after a short period of time" }, + { + "id": "DORMANT", + "type": "monster_flag", + "//": "Monster corpse can be revived by dormant corpse traps" + }, { "id": "VERMIN", "type": "monster_flag", diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json new file mode 100644 index 0000000000000..9a8b26c0a9b8a --- /dev/null +++ b/data/json/monsters/zed_dormant.json @@ -0,0 +1,108 @@ +[ + { + "type": "SPELL", + "id": "kill_pseudo_zombie", + "name": { "str": "kill pseudo zombie" }, + "description": "you should not see this. kills pseudo zombie.", + "valid_targets": [ "self" ], + "max_level": 1, + "flags": [ "SILENT", "PERCENTAGE_DAMAGE", "NO_FAIL" ], + "base_casting_time": 1, + "shape": "blast", + "min_damage": 100, + "max_damage": 100, + "min_aoe": 3, + "max_aoe": 3, + "effect": "attack", + "damage_type": "pure" + }, + { + "type": "SPELL", + "id": "pseudo_dormant_trap_setup", + "name": { "str": "dormant corpse setup" }, + "description": "you should not see this. sets up trap for dormant zombies.", + "valid_targets": [ "self" ], + "max_level": 1, + "flags": [ "SILENT", "NO_EXPLOSION_SFX"], + "base_casting_time": 1, + "shape": "blast", + "min_aoe": 1, + "max_aoe": 1, + "effect": "add_trap", + "effect_str": "tr_dormant_corpse", + "extra_effects": [ { "id": "kill_pseudo_zombie", "hit_self":true } ] + }, + { + "id": "mon_pseudo_dormant_zombie", + "type": "MONSTER", + "name": { "str": "reawakened zombie_d" }, + "description": "Fake zombie used for spawning dormant zombies. If you see this, open an issue on github.", + "copy-from": "mon_zombie", + "hp": 5, + "speed": 1, + "spawn_function": { "effect": { "id": "pseudo_dormant_trap_setup", "hit_self":true } }, + "flags": [ + "FILTHY", + "REVIVES", + "DORMANT", + "NO_NECRO" + ], + "zombify_into": "mon_zombie_reawakened" + }, + { + "id": "mon_zombie_reawakened", + "type": "MONSTER", + "name": { "str": "reawakened zombie" }, + "copy-from": "mon_zombie", + "description": "What you thought was a corpse suddenly gets up and starts walking with sinister intent.", + "flags": [ + "SEES", + "HEARS", + "STUMBLES", + "WARM", + "GRABS", + "BASHES", + "GROUP_BASH", + "POISON", + "NO_BREATHE", + "PUSH_MON", + "FILTHY", + "REVIVES", + "DORMANT", + "NO_NECRO" + ], + "//": "We need to add NO_NECRO, since reviving corpses without triggering the trap won't presently remove the trap. TODO: fix in future PR." + }, + { + "type": "trap", + "id": "tr_dormant_corpse", + "name": "dormant zombie corpse", + "//": "This zombie 'corpse' looks eerily like it could get up and start walking at any moment.", + "color": "light_green", + "symbol": "Z", + "visibility": 3, + "avoidance": 20, + "difficulty": 99, + "flags": [ "UNDODGEABLE", "AVATAR_ONLY" ], + "action": "spell", + "spell_data": { "id": "wake_up_dormant" }, + "trigger_message_u": "A zombie rises from the ground!", + "trigger_message_npc": "A zombie rises from the ground!", + "sound_threshold": [15,25] + }, + { + "type": "SPELL", + "id": "wake_up_dormant", + "name": { "str": "dormant corpse waking up" }, + "description": "you should not see this. Causes all dormant corpses in the tile to revive.", + "valid_targets": [ "ground" ], + "max_level": 1, + "flags": [ "SILENT", "NO_EXPLOSION_SFX"], + "base_casting_time": 1, + "shape": "blast", + "min_aoe": 3, + "max_aoe": 3, + "effect": "revive_dormant", + "effect_str": "ZOMBIE" + } +] diff --git a/data/json/traps.json b/data/json/traps.json index ba23e165df55e..9766db24cc231 100644 --- a/data/json/traps.json +++ b/data/json/traps.json @@ -1166,6 +1166,6 @@ "avoidance": 8, "difficulty": 0, "action": "sound_detect", - "sound_threshold": 5 + "sound_threshold": [ 15, 25 ] } ] diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index f32ace92d5874..4ba03c05367d1 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -1137,6 +1137,7 @@ Other monster flags. - ```COMBAT_MOUNT``` This mount has better chance to ignore hostile monster fear - ```CONSOLE_DESPAWN``` Despawns when a nearby console is properly hacked. - ```CONVERSATION``` This monster can engage in conversation. Will need to have chat_topics as well. +- ```DORMANT``` This monster will be revived by dormant corpse traps. - ```DEADLY_VIRUS``` This monster can inflict the zombie_virus effect - ```DESTROYS``` Bashes down walls and more. (2.5x bash multiplier, where base is the critter's max melee bashing) - ```DIGS``` Digs through the ground. Will not travel through non-diggable terrain such as roads. diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index c35e86983c503..6e2b3b1bb69b3 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3035,7 +3035,7 @@ See [MUTATIONS.md](MUTATIONS.md) }, "trigger_message_u": "A bear trap closes on your foot!", // This message will be printed when player steps on a trap "trigger_message_npc": "A bear trap closes on 's foot!", // This message will be printed when NPC or monster steps on a trap - "sound_threshold": 5 // Optional. Minimum volume of sound that will trigger this trap. Defaults to 0 (Will not trigger from sound). + "sound_threshold": [5,10] // Optional. Minimum volume of sound that will trigger this trap. Defaults to [0,0] (Will not trigger from sound). If two values [min,max] are provided, trap triggers on a linearly increasing chance depending on volume, from 25% (min) to 100%(max). To always trigger at some noise, say noise level N, specify as [N,N]. IMPORTANT: Not all traps work with this system. Make sure to double check and test. ``` ### Vehicle Groups diff --git a/doc/MAGIC.md b/doc/MAGIC.md index bffa162e00091..8270ba8ab6dd2 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -163,6 +163,7 @@ Below is a table of currently implemented effects, along with special rules for Effect | Description --- |--- +`add_trap` | Adds a trap in the target tile. This always succeeds (unless there is an existing trap) and only places 1 trap. The `effect_str` is the id of the trap. `area_pull` | Pulls `valid_targets` in its aoe toward the target location. Currently, the pull distance is set to 1 (see `directed_push`). `area_push` | Pushes `valid_targets` in its aoe away from the target location. Currently, the push distance is set to 1 (see `directed_push`). `attack` | Causes damage to `valid_targets` in its aoe, and applies `effect_str` named effect to targets. To damage terrain use `bash`. @@ -189,6 +190,7 @@ Effect | Description `remove_effect` | Removes `effect_str` effects from all creatures in the aoe. `remove_field` | Removes a `effect_str` field in the aoe. Causes teleglow of varying intensity and potentially teleportation depending on field density, if the field removed is `fd_fatigue`. `revive` | Revives a monster like a zombie necromancer. The monster must have the `REVIVES` flag. +`revive_dormant` | Revives a dormant monster. The monster must have the `REVIVES` AND the `DORMANT` flag. `short_range_teleport` | Teleports the player randomly range spaces with aoe variation. See also the `TARGET_TELEPORT` and `UNSAFE_TELEPORT` flags. `slime_split` | The slime splits into two large or normal slimes, depending on mass. Note: hardcoded for `mon_blob`-type enemies, check the monster `death_function` + spell `summon` combination. `spawn_item` | Spawns an item that will disappear at the end of its duration. Default duration is 0. diff --git a/doc/MONSTERS.md b/doc/MONSTERS.md index e70d594a57333..5cb5873e68e40 100644 --- a/doc/MONSTERS.md +++ b/doc/MONSTERS.md @@ -105,6 +105,7 @@ Property | Description `absorb_move_cost_max` | (int) For monsters with the `ABSORB_ITEMS` special attack. Sets a maximum movement cost for absorbing items regardless of the volume of the consumed item. -1 for no limit. Default -1. `absorb_material` | (array of string) For monsters with the `ABSORB_ITEMS` special attack. Specifies the types of materials that the monster will seek to absorb. Items with multiple materials will be matched as long as it is made of at least one of the materials in this list. If not specified the monster will absorb all materials. `split_move_cost` | (int) For monsters with the `SPLIT` special attack. Determines the move cost when splitting into a copy of itself. +`spawn_function` | (array of strings) How the monster behaves on spawn. Currently only tested with spells. Properties in the above tables are explained in more detail in the sections below. diff --git a/src/magic.cpp b/src/magic.cpp index d6df1984230e1..e38c8a31af6ab 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -2993,6 +2993,13 @@ spell fake_spell::get_spell( const Creature &caster, int min_level_override ) co return sp; } +// intended for spells without casters +spell fake_spell::get_spell() const +{ + spell sp( id ); + return sp; +} + void spell_events::notify( const cata::event &e ) { switch( e.type() ) { diff --git a/src/magic.h b/src/magic.h index 35b1034676589..217c1a799cc83 100644 --- a/src/magic.h +++ b/src/magic.h @@ -179,6 +179,8 @@ struct fake_spell { // gets the spell with an additional override for minimum level (default 0) spell get_spell( const Creature &caster, int min_level_override = 0 ) const; + spell get_spell() const; + bool is_valid() const; void load( const JsonObject &jo ); @@ -788,6 +790,9 @@ void dash( const spell &sp, Creature &caster, const tripoint &target ); void banishment( const spell &sp, Creature &caster, const tripoint &target ); // revives a monster into some kind of zombie if the monster has the revives flag void revive( const spell &sp, Creature &caster, const tripoint &target ); +// revives a dormant monster if it has the revives and the dormant flag +void revive_dormant( const spell &sp, Creature &caster, const tripoint &target ); +void add_trap( const spell &sp, Creature &caster, const tripoint &target ); void upgrade( const spell &sp, Creature &caster, const tripoint &target ); // causes guilt to the target as if it killed the caster void guilt( const spell &sp, Creature &caster, const tripoint &target ); @@ -811,6 +816,7 @@ std::maphas_flag( mon_flag_REVIVES ) && mt->in_species( spec ) && + mt->has_flag( mon_flag_REVIVES ) && !mt->has_flag( mon_flag_DORMANT ) && mt->in_species( spec ) && !mt->has_flag( mon_flag_NO_NECRO ) ) ) { continue; } @@ -1453,6 +1454,36 @@ void spell_effect::revive( const spell &sp, Creature &caster, const tripoint &ta } } +// identical to above, but checks for REVIVES && DORMANT flag. Ignores NO_NECRO. +void spell_effect::revive_dormant( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + ::map &here = get_map(); + const species_id spec( sp.effect_data() ); + for( const tripoint &aoe : area ) { + for( item &corpse : here.i_at( aoe ) ) { + const mtype *mt = corpse.get_mtype(); + if( !( corpse.is_corpse() && corpse.can_revive() && corpse.active && + mt->has_flag( mon_flag_REVIVES ) && mt->has_flag( mon_flag_DORMANT ) && mt->in_species( spec ) ) ) { + continue; + } + if( g->revive_corpse( aoe, corpse ) ) { + here.i_rem( aoe, &corpse ); + break; + } + } + } +} + +void spell_effect::add_trap( const spell &sp, Creature &caster, const tripoint &target ) +{ + ::map &here = get_map(); + const trap_id tr_id( sp.effect_data() ); + if( here.tr_at(target) == tr_null ) { + here.trap_set(target, tr_id ); + } +} + void spell_effect::upgrade( const spell &sp, Creature &caster, const tripoint &target ) { const std::set area = spell_effect_area( sp, target, caster ); @@ -1753,7 +1784,8 @@ void spell_effect::banishment( const spell &sp, Creature &caster, const tripoint } } -void spell_effect::effect_on_condition( const spell &sp, Creature &caster, const tripoint &target ) +void spell_effect::effect_on_condition( const spell &sp, Creature &caster, + const tripoint &target ) { const std::set area = spell_effect_area( sp, target, caster ); @@ -1774,7 +1806,8 @@ void spell_effect::effect_on_condition( const spell &sp, Creature &caster, const } } -void spell_effect::slime_split_on_death( const spell &sp, Creature &caster, const tripoint &target ) +void spell_effect::slime_split_on_death( const spell &sp, Creature &caster, + const tripoint &target ) { sp.make_sound( target, caster ); int mass = caster.get_speed_base(); diff --git a/src/monster.cpp b/src/monster.cpp index bb2ea56357524..75c42191a8c28 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -165,6 +165,7 @@ static const mon_flag_str_id mon_flag_BADVENOM( "BADVENOM" ); static const mon_flag_str_id mon_flag_CAN_DIG( "CAN_DIG" ); static const mon_flag_str_id mon_flag_CLIMBS( "CLIMBS" ); static const mon_flag_str_id mon_flag_CORNERED_FIGHTER( "CORNERED_FIGHTER" ); +static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); static const mon_flag_str_id mon_flag_DIGS( "DIGS" ); static const mon_flag_str_id mon_flag_EATS( "EATS" ); static const mon_flag_str_id mon_flag_ELECTRIC( "ELECTRIC" ); @@ -722,12 +723,30 @@ void monster::spawn( const tripoint &p ) { set_pos_only( p ); unset_dest(); + + // should never happen for dormants but why not support it + add_msg_if_player_sees(*this, m_good, type->mspawn_effect.spawn_message.translated(), name()); + + if (type->mspawn_effect.has_effect) { + //Not a hallucination, go process the spawn effects. + spell spawn_spell = type->mspawn_effect.sp.get_spell(*this); + spawn_spell.cast_all_effects(*this, pos()); + } } void monster::spawn( const tripoint_abs_ms &loc ) { set_location( loc ); unset_dest(); + + // should never happen for dormants but why not support it + add_msg_if_player_sees(*this, m_good, type->mspawn_effect.spawn_message.translated(), name()); + + if (type->mspawn_effect.has_effect) { + //Not a hallucination, go process the spawn effects. + spell spawn_spell = type->mspawn_effect.sp.get_spell(*this); + spawn_spell.cast_all_effects(*this, pos()); + } } std::string monster::get_name() const @@ -3920,7 +3939,7 @@ void monster::on_load() // TODO: regen_morale float regen = type->regenerates; if( regen <= 0 ) { - if( has_flag( mon_flag_REVIVES ) ) { + if( has_flag( mon_flag_REVIVES ) && !has_flag( mon_flag_DORMANT ) ) { regen = 0.02f * type->hp / to_turns( 1_hours ); } else if( made_of( material_flesh ) || made_of( material_iflesh ) || made_of( material_veggy ) ) { diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 2d00f96be4f07..41ad1e67d8c17 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -896,6 +896,7 @@ void mtype::load( const JsonObject &jo, const std::string &src ) optional( jo, was_loaded, "zombify_into", zombify_into, string_id_reader<::mtype> {}, mtype_id() ); + optional( jo, was_loaded, "fungalize_into", fungalize_into, string_id_reader<::mtype> {}, mtype_id() ); @@ -990,6 +991,7 @@ void mtype::load( const JsonObject &jo, const std::string &src ) optional( jo, was_loaded, "speed_description", speed_desc, speed_description_DEFAULT ); optional( jo, was_loaded, "death_function", mdeath_effect ); + optional( jo, was_loaded, "spawn_function", mspawn_effect ); if( jo.has_array( "emit_fields" ) ) { JsonArray jar = jo.get_array( "emit_fields" ); @@ -1706,6 +1708,21 @@ void monster_death_effect::deserialize( const JsonObject &data ) load( data ); } +void monster_spawn_effect::load( const JsonObject &jo ) +{ + optional( jo, was_loaded, "message", spawn_message, to_translation( "The %s appears!" ) ); + optional( jo, was_loaded, "effect", sp ); + has_effect = sp.is_valid(); + if (!has_effect) { + debugmsg( "monster_spawn_effect has no effect" ); + } +} + +void monster_spawn_effect::deserialize( const JsonObject &data ) +{ + load( data ); +} + void pet_food_data::load( const JsonObject &jo ) { mandatory( jo, was_loaded, "food", food ); diff --git a/src/mtype.h b/src/mtype.h index e69341d05b640..05ec1c79629f2 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -130,6 +130,16 @@ struct monster_death_effect { void deserialize( const JsonObject &data ); }; +struct monster_spawn_effect { + bool was_loaded = false; + bool has_effect = false; + fake_spell sp; + translation spawn_message; + + void load( const JsonObject &jo ); + void deserialize( const JsonObject &data ); +}; + struct mount_item_data { /** * If this monster is a rideable mount that spawns with a tied item (leash), this is the tied item id @@ -263,6 +273,7 @@ struct mtype { public: monster_death_effect mdeath_effect; + monster_spawn_effect mspawn_effect; ::weakpoints weakpoints; private: diff --git a/src/npc.cpp b/src/npc.cpp index 896d00843b9ed..12b8d1e0a5294 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -3950,4 +3950,4 @@ std::unique_ptr get_talker_for( npc &guy ) std::unique_ptr get_talker_for( npc *guy ) { return std::make_unique( guy ); -} \ No newline at end of file +} diff --git a/src/sounds.cpp b/src/sounds.cpp index 3022cb56f1fab..47f80824025b6 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -487,8 +487,11 @@ void sounds::process_sounds() for( const tripoint &tp : get_map().trap_locations( trapType->id ) ) { const int dist = sound_distance( source, tp ); const trap &tr = get_map().tr_at( tp ); - if( tr.triggered_by_sound( vol, dist ) ) { - tr.trigger( tp ); + // Exclude traps that certainly won't hear the sound + if( vol * 2 > dist ) { + if( tr.triggered_by_sound( vol, dist ) ) { + tr.trigger( tp ); + } } } } diff --git a/src/trap.cpp b/src/trap.cpp index a03bf0a7251e7..329409473f25d 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -51,6 +51,10 @@ const trap_str_id tr_telepad( "tr_telepad" ); const trap_str_id tr_temple_flood( "tr_temple_flood" ); const trap_str_id tr_temple_toggle( "tr_temple_toggle" ); +static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); +static const mon_flag_str_id mon_flag_NO_NECRO( "NO_NECRO" ); +static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); + static const update_mapgen_id update_mapgen_none( "none" ); namespace @@ -320,10 +324,18 @@ bool trap::can_see( const tripoint &pos, const Character &p ) const void trap::trigger( const tripoint &pos ) const { - if( is_null() ) { - return; + item *chosen_corpse = nullptr; + ::map &here = get_map(); + for( item &corpse : here.i_at( pos ) ) { + const mtype *mt = corpse.get_mtype(); + if( !( corpse.is_corpse() && corpse.can_revive() && corpse.active ) ) { + continue; + } + chosen_corpse = &corpse; + break; } - act( pos, nullptr, nullptr ); + // chosen corpse doesn't actually do anything, but it's useful to include anyway. + return trigger( pos, nullptr, chosen_corpse ); } void trap::trigger( const tripoint &pos, Creature &creature ) const @@ -369,13 +381,24 @@ bool trap::is_funnel() const bool trap::has_sound_trigger() const { - return !is_null() && sound_threshold > 0; + const bool has_sound_thresh = sound_threshold.first > 0 && sound_threshold.second > 0; + return !is_null() && has_sound_thresh; } bool trap::triggered_by_sound( int vol, int dist ) const { const int volume = vol - dist; - return !is_null() && volume >= sound_threshold; + // now determine sound threshold probabilities + // linear model: 0% below sound_min, 25% at sound_min, 100% at sound_max + const int sound_min = sound_threshold.first; + const int sound_max = sound_threshold.second; + const int sound_range = sound_max - sound_min; + if( volume < sound_min ) { + return false; + } + const int sound_chance = 25 + ( 75 * ( volume - sound_min ) / sound_range ); + //debugmsg("Sound chance: %d%%", sound_chance); + return !is_null() && ( rng( 0, 100 ) < sound_chance ); } void trap::on_disarmed( map &m, const tripoint &p ) const diff --git a/src/trap.h b/src/trap.h index ceb57d6164536..d435046120b8e 100644 --- a/src/trap.h +++ b/src/trap.h @@ -153,9 +153,9 @@ struct trap { */ units::mass trigger_weight = 500_gram; /** - * If a sound of at least this volume reaches the trap, it triggers. + * Determines how much sound is needed to trigger the trap. Defined as {min,max}. */ - int sound_threshold = 0; + std::pair sound_threshold = {0, 0}; int funnel_radius_mm = 0; // For disassembly? std::vector> components; diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index 0adaf669f4d7e..84026f6d500b7 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -1527,20 +1527,30 @@ bool trapfunc::drain( const tripoint &, Creature *c, item * ) bool trapfunc::cast_spell( const tripoint &p, Creature *critter, item * ) { if( critter == nullptr ) { - return false; - } - map &here = get_map(); - trap tr = here.tr_at( p ); - const spell trap_spell = tr.spell_data.get_spell( *critter, 0 ); - npc dummy; - if( !tr.has_flag( json_flag_UNCONSUMED ) ) { - here.remove_trap( p ); + map &here = get_map(); + trap tr = here.tr_at( p ); + const spell trap_spell = tr.spell_data.get_spell(); + npc dummy; + if( !tr.has_flag( json_flag_UNCONSUMED ) ) { + here.remove_trap( p ); + } + // we remove the trap before casting the spell because otherwise if we teleport we might be elsewhere at the end and p is no longer valid + trap_spell.cast_all_effects( dummy, p ); + trap_spell.make_sound( p, get_player_character() ); + return true; + } else { + map &here = get_map(); + trap tr = here.tr_at( p ); + const spell trap_spell = tr.spell_data.get_spell( *critter, 0 ); + npc dummy; + if( !tr.has_flag( json_flag_UNCONSUMED ) ) { + here.remove_trap( p ); + } + // we remove the trap before casting the spell because otherwise if we teleport we might be elsewhere at the end and p is no longer valid + trap_spell.cast_all_effects( dummy, critter->pos() ); + trap_spell.make_sound( p, get_player_character() ); + return true; } - // we remove the trap before casting the spell because otherwise if we teleport we might be elsewhere at the end and p is no longer valid - trap_spell.cast_all_effects( dummy, critter->pos() ); - trap_spell.make_sound( p, get_player_character() ); - - return true; } bool trapfunc::snake( const tripoint &p, Creature *, item * ) From 1faf089889a92b71c7bdef65da1ae3197167354e Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 13:37:13 +0200 Subject: [PATCH 02/32] astyle --- data/json/monsters/zed_dormant.json | 21 ++++++++------------- src/magic_spell_effect.cpp | 4 ++-- src/monster.cpp | 20 ++++++++++---------- src/monstergenerator.cpp | 2 +- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 9a8b26c0a9b8a..99e9e4f676dc0 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -23,14 +23,14 @@ "description": "you should not see this. sets up trap for dormant zombies.", "valid_targets": [ "self" ], "max_level": 1, - "flags": [ "SILENT", "NO_EXPLOSION_SFX"], + "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], "base_casting_time": 1, "shape": "blast", "min_aoe": 1, "max_aoe": 1, "effect": "add_trap", "effect_str": "tr_dormant_corpse", - "extra_effects": [ { "id": "kill_pseudo_zombie", "hit_self":true } ] + "extra_effects": [ { "id": "kill_pseudo_zombie", "hit_self": true } ] }, { "id": "mon_pseudo_dormant_zombie", @@ -40,13 +40,8 @@ "copy-from": "mon_zombie", "hp": 5, "speed": 1, - "spawn_function": { "effect": { "id": "pseudo_dormant_trap_setup", "hit_self":true } }, - "flags": [ - "FILTHY", - "REVIVES", - "DORMANT", - "NO_NECRO" - ], + "spawn_function": { "effect": { "id": "pseudo_dormant_trap_setup", "hit_self": true } }, + "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO" ], "zombify_into": "mon_zombie_reawakened" }, { @@ -86,9 +81,9 @@ "flags": [ "UNDODGEABLE", "AVATAR_ONLY" ], "action": "spell", "spell_data": { "id": "wake_up_dormant" }, - "trigger_message_u": "A zombie rises from the ground!", - "trigger_message_npc": "A zombie rises from the ground!", - "sound_threshold": [15,25] + "trigger_message_u": "A zombie rises from the ground!", + "trigger_message_npc": "A zombie rises from the ground!", + "sound_threshold": [ 15, 25 ] }, { "type": "SPELL", @@ -97,7 +92,7 @@ "description": "you should not see this. Causes all dormant corpses in the tile to revive.", "valid_targets": [ "ground" ], "max_level": 1, - "flags": [ "SILENT", "NO_EXPLOSION_SFX"], + "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], "base_casting_time": 1, "shape": "blast", "min_aoe": 3, diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 1086e5ee77090..7fe7d67b5edbe 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -1479,8 +1479,8 @@ void spell_effect::add_trap( const spell &sp, Creature &caster, const tripoint & { ::map &here = get_map(); const trap_id tr_id( sp.effect_data() ); - if( here.tr_at(target) == tr_null ) { - here.trap_set(target, tr_id ); + if( here.tr_at( target ) == tr_null ) { + here.trap_set( target, tr_id ); } } diff --git a/src/monster.cpp b/src/monster.cpp index 75c42191a8c28..d92323ff99681 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -724,13 +724,13 @@ void monster::spawn( const tripoint &p ) set_pos_only( p ); unset_dest(); - // should never happen for dormants but why not support it - add_msg_if_player_sees(*this, m_good, type->mspawn_effect.spawn_message.translated(), name()); + // should never happen for dormants but why not support it + add_msg_if_player_sees( *this, m_good, type->mspawn_effect.spawn_message.translated(), name() ); - if (type->mspawn_effect.has_effect) { + if( type->mspawn_effect.has_effect ) { //Not a hallucination, go process the spawn effects. - spell spawn_spell = type->mspawn_effect.sp.get_spell(*this); - spawn_spell.cast_all_effects(*this, pos()); + spell spawn_spell = type->mspawn_effect.sp.get_spell( *this ); + spawn_spell.cast_all_effects( *this, pos() ); } } @@ -739,13 +739,13 @@ void monster::spawn( const tripoint_abs_ms &loc ) set_location( loc ); unset_dest(); - // should never happen for dormants but why not support it - add_msg_if_player_sees(*this, m_good, type->mspawn_effect.spawn_message.translated(), name()); + // should never happen for dormants but why not support it + add_msg_if_player_sees( *this, m_good, type->mspawn_effect.spawn_message.translated(), name() ); - if (type->mspawn_effect.has_effect) { + if( type->mspawn_effect.has_effect ) { //Not a hallucination, go process the spawn effects. - spell spawn_spell = type->mspawn_effect.sp.get_spell(*this); - spawn_spell.cast_all_effects(*this, pos()); + spell spawn_spell = type->mspawn_effect.sp.get_spell( *this ); + spawn_spell.cast_all_effects( *this, pos() ); } } diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 41ad1e67d8c17..bedfe6189c180 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -1713,7 +1713,7 @@ void monster_spawn_effect::load( const JsonObject &jo ) optional( jo, was_loaded, "message", spawn_message, to_translation( "The %s appears!" ) ); optional( jo, was_loaded, "effect", sp ); has_effect = sp.is_valid(); - if (!has_effect) { + if( !has_effect ) { debugmsg( "monster_spawn_effect has no effect" ); } } From 55b70d4d9880ddd826511b9b79a0a76c663a06c2 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 13:56:20 +0200 Subject: [PATCH 03/32] fixed dormant zombies reviving over time --- src/item.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/item.cpp b/src/item.cpp index 542b3e1c17860..a2fe83214346c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -186,6 +186,7 @@ static const matec_id RAPID( "RAPID" ); static const material_id material_wool( "wool" ); +static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); static const mon_flag_str_id mon_flag_POISON( "POISON" ); static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); @@ -13034,6 +13035,9 @@ bool item::process_corpse( map &here, Character *carrier, const tripoint &pos ) if( corpse == nullptr || damage() >= max_damage() ) { return false; } + if( corpse->has_flag( mon_flag_DORMANT ) ) { + return false; + } // handle human corpses rising as zombies if( corpse->id == mtype_id::NULL_ID() && !has_var( "zombie_form" ) && From 44810b82b6e06bbfe02842f9ef82cf44fd683bed Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:33:14 +0200 Subject: [PATCH 04/32] added proximity triggering for traps --- data/json/monsters/zed_dormant.json | 2 +- src/map.cpp | 59 ++++++++++++++++++++++++++++- src/map.h | 3 ++ src/trap.cpp | 2 +- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 99e9e4f676dc0..c079531101b66 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -78,7 +78,7 @@ "visibility": 3, "avoidance": 20, "difficulty": 99, - "flags": [ "UNDODGEABLE", "AVATAR_ONLY" ], + "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY" ], "action": "spell", "spell_data": { "id": "wake_up_dormant" }, "trigger_message_u": "A zombie rises from the ground!", diff --git a/src/map.cpp b/src/map.cpp index e169d43d51283..a5c1cd1cc0d13 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1,4 +1,5 @@ #include "map.h" +#include "map.h" #include #include @@ -130,6 +131,7 @@ static const field_type_str_id field_fd_clairvoyant( "fd_clairvoyant" ); static const flag_id json_flag_AVATAR_ONLY( "AVATAR_ONLY" ); static const flag_id json_flag_PRESERVE_SPAWN_OMT( "PRESERVE_SPAWN_OMT" ); +static const flag_id json_flag_PROXIMITY( "PROXIMITY" ); static const flag_id json_flag_UNDODGEABLE( "UNDODGEABLE" ); static const item_group_id Item_spawn_data_default_zombie_clothes( "default_zombie_clothes" ); @@ -9705,7 +9707,62 @@ void map::creature_on_trap( Creature &c, const bool may_avoid ) const if( you != nullptr && you->in_vehicle ) { return; } - maybe_trigger_trap( c.pos(), c, may_avoid ); + + tripoint pos = c.pos(); + // proximity traps + std::vector tr_proximity; + // find proximity traps in adjacent tiles + for( int x = pos.x - 1; x <= pos.x + 1; x++ ) { + for( int y = pos.y - 1; y <= pos.y + 1; y++ ) { + if( x == pos.x && y == pos.y ) { + continue; + } + const tripoint loc = tripoint( x, y, pos.z ); + const trap *trap_here = &tr_at( loc ); + if( trap_here->has_flag( json_flag_PROXIMITY ) ) { + tr_proximity.push_back( loc ); + } + } + } + // first trigger proximity traps + for( auto &loc : tr_proximity ) { + maybe_trigger_prox_trap( loc, c, may_avoid ); + } + // then traps we stepped on + maybe_trigger_trap( pos, c, may_avoid ); +} + + +void map::maybe_trigger_prox_trap( const tripoint &pos, Creature &c, const bool may_avoid ) const +{ + const trap &tr = tr_at( pos ); + if( tr.is_null() ) { + return; + } + + //Don't trigger benign traps like cots and funnels + if( tr.is_benign() ) { + return; + } + + if( tr.has_flag( json_flag_AVATAR_ONLY ) && !c.is_avatar() ) { + return; + } + + if( !tr.has_flag( json_flag_UNDODGEABLE ) && may_avoid && c.avoid_trap( pos, tr ) ) { + Character *const pl = c.as_character(); + if( !tr.is_always_invisible() && pl && !pl->knows_trap( pos ) ) { + pl->add_msg_if_player( _( "You've spotted a %1$s!" ), tr.name() ); + pl->add_known_trap( pos, tr ); + } + return; + } + + if( !tr.is_always_invisible() && tr.has_trigger_msg() ) { + c.add_msg_player_or_npc( m_bad, tr.get_trigger_message_u(), tr.get_trigger_message_npc(), + tr.name() ); + } + tr.trigger( pos, c ); } void map::maybe_trigger_trap( const tripoint &pos, Creature &c, const bool may_avoid ) const diff --git a/src/map.h b/src/map.h index 185a04ea69b4d..aabc6bae822a8 100644 --- a/src/map.h +++ b/src/map.h @@ -1516,9 +1516,12 @@ class map * This functions assumes the character is either on top of the trap, * or adjacent to it. */ + // TODO: fix point types (remove the first overload) void maybe_trigger_trap( const tripoint &pos, Creature &c, bool may_avoid ) const; void maybe_trigger_trap( const tripoint_bub_ms &pos, Creature &c, bool may_avoid ) const; + // Handles triggering a proximity trap. Similar but subtly different. + void maybe_trigger_prox_trap( const tripoint &pos, Creature &c, const bool may_avoid ) const; // Spawns byproducts from items destroyed in fire. void create_burnproducts( const tripoint &p, const item &fuel, const units::mass &burned_mass ); diff --git a/src/trap.cpp b/src/trap.cpp index 329409473f25d..0108cd24bfa6a 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -334,7 +334,7 @@ void trap::trigger( const tripoint &pos ) const chosen_corpse = &corpse; break; } - // chosen corpse doesn't actually do anything, but it's useful to include anyway. + // chosen corpse doesn't actually do anything, but needed to not break code below. return trigger( pos, nullptr, chosen_corpse ); } From f8da0dee471a374759d98de179e936e700239578 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 16:03:19 +0200 Subject: [PATCH 05/32] fixed pseudo zombie killing itself on spawn --- data/json/monsters/zed_dormant.json | 28 ++++++++++++++++++++-------- src/monster.cpp | 18 ------------------ src/monstergenerator.cpp | 16 ---------------- src/mtype.h | 11 ----------- 4 files changed, 20 insertions(+), 53 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index c079531101b66..0cf46e20ba42d 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -6,13 +6,14 @@ "description": "you should not see this. kills pseudo zombie.", "valid_targets": [ "self" ], "max_level": 1, - "flags": [ "SILENT", "PERCENTAGE_DAMAGE", "NO_FAIL" ], + "flags": [ "SILENT", "NO_EXPLOSION_SFX", "PERCENTAGE_DAMAGE", "NO_FAIL" ], "base_casting_time": 1, "shape": "blast", "min_damage": 100, "max_damage": 100, - "min_aoe": 3, - "max_aoe": 3, + "min_aoe": 1, + "max_aoe": 1, + "message": "", "effect": "attack", "damage_type": "pure" }, @@ -28,6 +29,7 @@ "shape": "blast", "min_aoe": 1, "max_aoe": 1, + "message": "", "effect": "add_trap", "effect_str": "tr_dormant_corpse", "extra_effects": [ { "id": "kill_pseudo_zombie", "hit_self": true } ] @@ -40,9 +42,18 @@ "copy-from": "mon_zombie", "hp": 5, "speed": 1, - "spawn_function": { "effect": { "id": "pseudo_dormant_trap_setup", "hit_self": true } }, - "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO" ], - "zombify_into": "mon_zombie_reawakened" + "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO", "REVIVES_HEALTHY" ], + "zombify_into": "mon_zombie_reawakened", + "special_attacks":[ + { + "id": "pseudo_dormant_trap_setup_attk", + "type": "spell", + "spell_data": { "id": "pseudo_dormant_trap_setup", "hit_self": true }, + "cooldown": 1, + "allow_no_target": true, + "monster_message": "" + } + ] }, { "id": "mon_zombie_reawakened", @@ -64,7 +75,8 @@ "FILTHY", "REVIVES", "DORMANT", - "NO_NECRO" + "NO_NECRO", + "REVIVES_HEALTHY" ], "//": "We need to add NO_NECRO, since reviving corpses without triggering the trap won't presently remove the trap. TODO: fix in future PR." }, @@ -78,7 +90,7 @@ "visibility": 3, "avoidance": 20, "difficulty": 99, - "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY" ], + "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY", "REVIVES_HEALTHY" ], "action": "spell", "spell_data": { "id": "wake_up_dormant" }, "trigger_message_u": "A zombie rises from the ground!", diff --git a/src/monster.cpp b/src/monster.cpp index d92323ff99681..b7e85f8703a2e 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -723,30 +723,12 @@ void monster::spawn( const tripoint &p ) { set_pos_only( p ); unset_dest(); - - // should never happen for dormants but why not support it - add_msg_if_player_sees( *this, m_good, type->mspawn_effect.spawn_message.translated(), name() ); - - if( type->mspawn_effect.has_effect ) { - //Not a hallucination, go process the spawn effects. - spell spawn_spell = type->mspawn_effect.sp.get_spell( *this ); - spawn_spell.cast_all_effects( *this, pos() ); - } } void monster::spawn( const tripoint_abs_ms &loc ) { set_location( loc ); unset_dest(); - - // should never happen for dormants but why not support it - add_msg_if_player_sees( *this, m_good, type->mspawn_effect.spawn_message.translated(), name() ); - - if( type->mspawn_effect.has_effect ) { - //Not a hallucination, go process the spawn effects. - spell spawn_spell = type->mspawn_effect.sp.get_spell( *this ); - spawn_spell.cast_all_effects( *this, pos() ); - } } std::string monster::get_name() const diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index bedfe6189c180..19fb77759ae5f 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -991,7 +991,6 @@ void mtype::load( const JsonObject &jo, const std::string &src ) optional( jo, was_loaded, "speed_description", speed_desc, speed_description_DEFAULT ); optional( jo, was_loaded, "death_function", mdeath_effect ); - optional( jo, was_loaded, "spawn_function", mspawn_effect ); if( jo.has_array( "emit_fields" ) ) { JsonArray jar = jo.get_array( "emit_fields" ); @@ -1708,21 +1707,6 @@ void monster_death_effect::deserialize( const JsonObject &data ) load( data ); } -void monster_spawn_effect::load( const JsonObject &jo ) -{ - optional( jo, was_loaded, "message", spawn_message, to_translation( "The %s appears!" ) ); - optional( jo, was_loaded, "effect", sp ); - has_effect = sp.is_valid(); - if( !has_effect ) { - debugmsg( "monster_spawn_effect has no effect" ); - } -} - -void monster_spawn_effect::deserialize( const JsonObject &data ) -{ - load( data ); -} - void pet_food_data::load( const JsonObject &jo ) { mandatory( jo, was_loaded, "food", food ); diff --git a/src/mtype.h b/src/mtype.h index 05ec1c79629f2..e69341d05b640 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -130,16 +130,6 @@ struct monster_death_effect { void deserialize( const JsonObject &data ); }; -struct monster_spawn_effect { - bool was_loaded = false; - bool has_effect = false; - fake_spell sp; - translation spawn_message; - - void load( const JsonObject &jo ); - void deserialize( const JsonObject &data ); -}; - struct mount_item_data { /** * If this monster is a rideable mount that spawns with a tied item (leash), this is the tied item id @@ -273,7 +263,6 @@ struct mtype { public: monster_death_effect mdeath_effect; - monster_spawn_effect mspawn_effect; ::weakpoints weakpoints; private: From d8a1b8a0674041664046f3acb3b3838a6ae424d4 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 16:07:36 +0200 Subject: [PATCH 06/32] json style --- data/json/monsters/zed_dormant.json | 2 +- doc/MONSTERS.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 0cf46e20ba42d..a54c9b42481b6 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -44,7 +44,7 @@ "speed": 1, "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO", "REVIVES_HEALTHY" ], "zombify_into": "mon_zombie_reawakened", - "special_attacks":[ + "special_attacks": [ { "id": "pseudo_dormant_trap_setup_attk", "type": "spell", diff --git a/doc/MONSTERS.md b/doc/MONSTERS.md index 5cb5873e68e40..e70d594a57333 100644 --- a/doc/MONSTERS.md +++ b/doc/MONSTERS.md @@ -105,7 +105,6 @@ Property | Description `absorb_move_cost_max` | (int) For monsters with the `ABSORB_ITEMS` special attack. Sets a maximum movement cost for absorbing items regardless of the volume of the consumed item. -1 for no limit. Default -1. `absorb_material` | (array of string) For monsters with the `ABSORB_ITEMS` special attack. Specifies the types of materials that the monster will seek to absorb. Items with multiple materials will be matched as long as it is made of at least one of the materials in this list. If not specified the monster will absorb all materials. `split_move_cost` | (int) For monsters with the `SPLIT` special attack. Determines the move cost when splitting into a copy of itself. -`spawn_function` | (array of strings) How the monster behaves on spawn. Currently only tested with spells. Properties in the above tables are explained in more detail in the sections below. From 4af034f8d28f7d9ca3e4be00e50920368ca67f94 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 16:08:45 +0200 Subject: [PATCH 07/32] small fix --- src/map.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/map.cpp b/src/map.cpp index a5c1cd1cc0d13..bdda8886c133a 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1,5 +1,4 @@ #include "map.h" -#include "map.h" #include #include From deaebda31ac880530927637b722525336d1dc862 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 17:12:59 +0200 Subject: [PATCH 08/32] reinforced zombie revive logic. now should over most edge cases. --- data/json/monsters/zed_dormant.json | 1 - src/game.cpp | 7 ++++++- src/game.h | 2 ++ src/item.cpp | 11 +++++++++++ src/magic_spell_effect.cpp | 5 +++-- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index a54c9b42481b6..5d3c190a57f42 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -74,7 +74,6 @@ "PUSH_MON", "FILTHY", "REVIVES", - "DORMANT", "NO_NECRO", "REVIVES_HEALTHY" ], diff --git a/src/game.cpp b/src/game.cpp index 272bcb464b0bd..2cd32a280123c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -5450,6 +5450,11 @@ bool game::is_sheltered( const tripoint &p ) } bool game::revive_corpse( const tripoint &p, item &it ) +{ + return revive_corpse( p, it, 1 ); +} + +bool game::revive_corpse( const tripoint &p, item &it, int radius ) { if( !it.is_corpse() ) { debugmsg( "Tried to revive a non-corpse." ); @@ -5488,7 +5493,7 @@ bool game::revive_corpse( const tripoint &p, item &it ) } } - return place_critter_at( newmon_ptr, p ); + return place_critter_around( newmon_ptr, p, radius ); } void game::save_cyborg( item *cyborg, const tripoint &couch_pos, Character &installer ) diff --git a/src/game.h b/src/game.h index 5c82e1abbb8bc..c25584ec7b1e6 100644 --- a/src/game.h +++ b/src/game.h @@ -510,6 +510,8 @@ class game * If reviving failed, the item is unchanged, as is the environment (no new monsters). */ bool revive_corpse( const tripoint &p, item &it ); + // same as above, but with relaxed placement radius. + bool revive_corpse( const tripoint &p, item &it, int radius ); /**Turns Broken Cyborg monster into Cyborg NPC via surgery*/ void save_cyborg( item *cyborg, const tripoint &couch_pos, Character &installer ); /** Asks if the player wants to cancel their activity, and if so cancels it. */ diff --git a/src/item.cpp b/src/item.cpp index a2fe83214346c..2973ef6477ab2 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -101,6 +101,7 @@ #include "string_id_utils.h" #include "text_snippets.h" #include "translations.h" +#include "trap.h" #include "try_parse_integer.h" #include "units.h" #include "units_fwd.h" @@ -13035,7 +13036,17 @@ bool item::process_corpse( map &here, Character *carrier, const tripoint &pos ) if( corpse == nullptr || damage() >= max_damage() ) { return false; } + if( corpse->has_flag( mon_flag_DORMANT ) ) { + //if dormant, ensure trap still exists. + const trap *trap_here = &here.tr_at( pos ); + if( trap_here->is_null() ) { + // if there isn't a trap, we need to add one again. + here.trap_set( pos, trap_id( "tr_dormant_corpse" ) ); + } else if( trap_here->loadid != trap_id( "tr_dormant_corpse" ) ) { + // if there is a trap, but it isn't the right one, we need to revive the zombie manually. + return g->revive_corpse( pos, *this, 3 ); + } return false; } diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 7fe7d67b5edbe..7d467f5d94486 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -1467,7 +1467,8 @@ void spell_effect::revive_dormant( const spell &sp, Creature &caster, const trip mt->has_flag( mon_flag_REVIVES ) && mt->has_flag( mon_flag_DORMANT ) && mt->in_species( spec ) ) ) { continue; } - if( g->revive_corpse( aoe, corpse ) ) { + // relaxed revive with radius. + if( g->revive_corpse( aoe, corpse, 3 ) ) { here.i_rem( aoe, &corpse ); break; } @@ -1475,7 +1476,7 @@ void spell_effect::revive_dormant( const spell &sp, Creature &caster, const trip } } -void spell_effect::add_trap( const spell &sp, Creature &caster, const tripoint &target ) +void spell_effect::add_trap( const spell &sp, Creature &, const tripoint &target ) { ::map &here = get_map(); const trap_id tr_id( sp.effect_data() ); From ae4ac14e6366991eece4b58bffd48afa14762543 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 17:25:54 +0200 Subject: [PATCH 09/32] quiet death flag for zombies --- data/json/monsters/monster_flags.json | 5 +++++ data/json/monsters/zed_dormant.json | 2 +- src/mondeath.cpp | 3 ++- src/trap.cpp | 1 - 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/data/json/monsters/monster_flags.json b/data/json/monsters/monster_flags.json index ffb405e571462..2627d94d661af 100644 --- a/data/json/monsters/monster_flags.json +++ b/data/json/monsters/monster_flags.json @@ -294,6 +294,11 @@ "type": "monster_flag", "//": "Monster corpse can be revived by dormant corpse traps" }, + { + "id": "QUIETDEATH", + "type": "monster_flag", + "//": "Monster dies quietly and doesn't display a message." + }, { "id": "VERMIN", "type": "monster_flag", diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 5d3c190a57f42..9fc450aecbfc2 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -42,7 +42,7 @@ "copy-from": "mon_zombie", "hp": 5, "speed": 1, - "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO", "REVIVES_HEALTHY" ], + "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO", "REVIVES_HEALTHY", "QUIETDEATH" ], "zombify_into": "mon_zombie_reawakened", "special_attacks": [ { diff --git a/src/mondeath.cpp b/src/mondeath.cpp index 76bc8e3f8fad5..15cfe225709e0 100644 --- a/src/mondeath.cpp +++ b/src/mondeath.cpp @@ -57,6 +57,7 @@ static const harvest_drop_type_id harvest_drop_flesh( "flesh" ); static const mon_flag_str_id mon_flag_DROPS_AMMO( "DROPS_AMMO" ); static const mon_flag_str_id mon_flag_NOGIB( "NOGIB" ); static const mon_flag_str_id mon_flag_SILENT_DISAPPEAR( "SILENT_DISAPPEAR" ); +static const mon_flag_str_id mon_flag_QUIETDEATH( "QUIETDEATH" ); static const species_id species_ZOMBIE( "ZOMBIE" ); @@ -66,7 +67,7 @@ item_location mdeath::normal( monster &z ) return {}; } - if( !z.quiet_death ) { + if( !z.quiet_death && !z.has_flag( mon_flag_QUIETDEATH ) ) { if( z.type->in_species( species_ZOMBIE ) ) { sfx::play_variant_sound( "mon_death", "zombie_death", sfx::get_heard_volume( z.pos() ) ); } diff --git a/src/trap.cpp b/src/trap.cpp index 0108cd24bfa6a..f0aaa2f54e21e 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -51,7 +51,6 @@ const trap_str_id tr_telepad( "tr_telepad" ); const trap_str_id tr_temple_flood( "tr_temple_flood" ); const trap_str_id tr_temple_toggle( "tr_temple_toggle" ); -static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); static const mon_flag_str_id mon_flag_NO_NECRO( "NO_NECRO" ); static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); From 20c361461ace3d8c612d6d5b77ff257813f0a44c Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 18:33:40 +0200 Subject: [PATCH 10/32] make trap despawn more robust. Should be 100% functional now. --- data/json/monsters/zed_dormant.json | 27 +++++++++++++++++++++------ src/sounds.cpp | 2 +- src/trap.cpp | 16 ++++------------ src/trapfunc.cpp | 23 +++++++++++++++++++++++ 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 9fc450aecbfc2..503aaf67d8ed7 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -89,12 +89,26 @@ "visibility": 3, "avoidance": 20, "difficulty": 99, - "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY", "REVIVES_HEALTHY" ], + "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY" ], "action": "spell", "spell_data": { "id": "wake_up_dormant" }, "trigger_message_u": "A zombie rises from the ground!", "trigger_message_npc": "A zombie rises from the ground!", - "sound_threshold": [ 15, 25 ] + "sound_threshold": [ 10, 20 ] + }, + { + "type": "SPELL", + "id": "cause_loud_moaning", + "name": { "str": "cause loud moaning" }, + "description": "you should not see this. causes loud noise.", + "valid_targets": [ "ground", "ally" ], + "max_level": 1, + "shape": "blast", + "effect": "noise", + "flags": [ "NO_EXPLOSION_SFX", "LOUD" ], + "sound_type": "combat", + "sound_id": "melee_attack", + "sound_variant": "monster_melee_hit" }, { "type": "SPELL", @@ -103,12 +117,13 @@ "description": "you should not see this. Causes all dormant corpses in the tile to revive.", "valid_targets": [ "ground" ], "max_level": 1, - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "NO_EXPLOSION_SFX" ], "base_casting_time": 1, "shape": "blast", - "min_aoe": 3, - "max_aoe": 3, + "min_aoe": 1, + "max_aoe": 1, "effect": "revive_dormant", - "effect_str": "ZOMBIE" + "effect_str": "ZOMBIE", + "extra_effects": [ { "id": "cause_loud_moaning" } ] } ] diff --git a/src/sounds.cpp b/src/sounds.cpp index 47f80824025b6..48f747f62fe99 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -482,7 +482,7 @@ void sounds::process_sounds() critter.hear_sound( source, vol, dist, this_centroid.provocative ); } } - // Trigger sound-triggered traps + // Trigger sound-triggered traps and ensure they are still valid for( const trap *trapType : trap::get_sound_triggered_traps() ) { for( const tripoint &tp : get_map().trap_locations( trapType->id ) ) { const int dist = sound_distance( source, tp ); diff --git a/src/trap.cpp b/src/trap.cpp index f0aaa2f54e21e..bab51a3a37739 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -323,18 +323,7 @@ bool trap::can_see( const tripoint &pos, const Character &p ) const void trap::trigger( const tripoint &pos ) const { - item *chosen_corpse = nullptr; - ::map &here = get_map(); - for( item &corpse : here.i_at( pos ) ) { - const mtype *mt = corpse.get_mtype(); - if( !( corpse.is_corpse() && corpse.can_revive() && corpse.active ) ) { - continue; - } - chosen_corpse = &corpse; - break; - } - // chosen corpse doesn't actually do anything, but needed to not break code below. - return trigger( pos, nullptr, chosen_corpse ); + act( pos, nullptr, nullptr ); } void trap::trigger( const tripoint &pos, Creature &creature ) const @@ -392,6 +381,9 @@ bool trap::triggered_by_sound( int vol, int dist ) const const int sound_min = sound_threshold.first; const int sound_max = sound_threshold.second; const int sound_range = sound_max - sound_min; + if( sound_range <= 0 ) { + return false; + } if( volume < sound_min ) { return false; } diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index 84026f6d500b7..d353df008070e 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -58,6 +58,7 @@ static const efftype_id effect_ridden( "ridden" ); static const efftype_id effect_slimed( "slimed" ); static const efftype_id effect_tetanus( "tetanus" ); +static const flag_id json_flag_PROXIMITY( "PROXIMITY" ); static const flag_id json_flag_LEVITATION( "LEVITATION" ); static const flag_id json_flag_UNCONSUMED( "UNCONSUMED" ); @@ -1534,6 +1535,17 @@ bool trapfunc::cast_spell( const tripoint &p, Creature *critter, item * ) if( !tr.has_flag( json_flag_UNCONSUMED ) ) { here.remove_trap( p ); } + if( tr.has_flag( json_flag_PROXIMITY ) ) { + // remove all traps in 3-3 area area + for( int x = p.x - 1; x <= p.x + 1; x++ ) { + for( int y = p.y - 1; y <= p.y + 1; y++ ) { + tripoint pt( x, y, p.z ); + if( here.tr_at( pt ).loadid == tr.loadid ) { + here.remove_trap( pt ); + } + } + } + } // we remove the trap before casting the spell because otherwise if we teleport we might be elsewhere at the end and p is no longer valid trap_spell.cast_all_effects( dummy, p ); trap_spell.make_sound( p, get_player_character() ); @@ -1546,6 +1558,17 @@ bool trapfunc::cast_spell( const tripoint &p, Creature *critter, item * ) if( !tr.has_flag( json_flag_UNCONSUMED ) ) { here.remove_trap( p ); } + if( tr.has_flag( json_flag_PROXIMITY ) ) { + // remove all traps in 3-3 area area + for( int x = p.x - 1; x <= p.x + 1; x++ ) { + for( int y = p.y - 1; y <= p.y + 1; y++ ) { + tripoint pt( x, y, p.z ); + if( here.tr_at( pt ).loadid == tr.loadid ) { + here.remove_trap( pt ); + } + } + } + } // we remove the trap before casting the spell because otherwise if we teleport we might be elsewhere at the end and p is no longer valid trap_spell.cast_all_effects( dummy, critter->pos() ); trap_spell.make_sound( p, get_player_character() ); From 5e472bb2a04b1df27e4a9de33e03f71e72873cc0 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 18:41:41 +0200 Subject: [PATCH 11/32] zombie chains are now possible. --- data/json/monsters/zed_dormant.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 503aaf67d8ed7..aed667677371b 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -105,10 +105,14 @@ "max_level": 1, "shape": "blast", "effect": "noise", - "flags": [ "NO_EXPLOSION_SFX", "LOUD" ], + "flags": [ "NO_EXPLOSION_SFX" ], "sound_type": "combat", "sound_id": "melee_attack", - "sound_variant": "monster_melee_hit" + "sound_variant": "monster_melee_hit", + "sound_description": "a zombie moaning!", + "min_damage": 60, + "max_damage": 60, + "//": "volume is damage/3, so 20" }, { "type": "SPELL", From d286ef725136ee65f97fa95db5989623b3f304a3 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 19:23:22 +0200 Subject: [PATCH 12/32] small sound range bugfix --- src/trap.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/trap.cpp b/src/trap.cpp index bab51a3a37739..08f861e6ca9f9 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -381,15 +381,15 @@ bool trap::triggered_by_sound( int vol, int dist ) const const int sound_min = sound_threshold.first; const int sound_max = sound_threshold.second; const int sound_range = sound_max - sound_min; - if( sound_range <= 0 ) { - return false; - } if( volume < sound_min ) { return false; } - const int sound_chance = 25 + ( 75 * ( volume - sound_min ) / sound_range ); + int sound_chance = 100; + if( sound_range > 0 ) { + int sound_chance = 25 + ( 75 * ( volume - sound_min ) / sound_range ); + } //debugmsg("Sound chance: %d%%", sound_chance); - return !is_null() && ( rng( 0, 100 ) < sound_chance ); + return !is_null() && ( rng( 0, 100 ) <= sound_chance ); } void trap::on_disarmed( map &m, const tripoint &p ) const From 177bca583e22a672d2bf0f67e6e78873df6ff969 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 00:19:31 +0200 Subject: [PATCH 13/32] clang tidy --- src/map.h | 2 +- src/monster.cpp | 2 +- src/trap.cpp | 5 +---- src/trapfunc.cpp | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/map.h b/src/map.h index aabc6bae822a8..dd21aa907d0be 100644 --- a/src/map.h +++ b/src/map.h @@ -1521,7 +1521,7 @@ class map void maybe_trigger_trap( const tripoint &pos, Creature &c, bool may_avoid ) const; void maybe_trigger_trap( const tripoint_bub_ms &pos, Creature &c, bool may_avoid ) const; // Handles triggering a proximity trap. Similar but subtly different. - void maybe_trigger_prox_trap( const tripoint &pos, Creature &c, const bool may_avoid ) const; + void maybe_trigger_prox_trap( const tripoint &pos, Creature &c, bool may_avoid ) const; // Spawns byproducts from items destroyed in fire. void create_burnproducts( const tripoint &p, const item &fuel, const units::mass &burned_mass ); diff --git a/src/monster.cpp b/src/monster.cpp index b7e85f8703a2e..f6cf6d8c3625d 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -165,8 +165,8 @@ static const mon_flag_str_id mon_flag_BADVENOM( "BADVENOM" ); static const mon_flag_str_id mon_flag_CAN_DIG( "CAN_DIG" ); static const mon_flag_str_id mon_flag_CLIMBS( "CLIMBS" ); static const mon_flag_str_id mon_flag_CORNERED_FIGHTER( "CORNERED_FIGHTER" ); -static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); static const mon_flag_str_id mon_flag_DIGS( "DIGS" ); +static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); static const mon_flag_str_id mon_flag_EATS( "EATS" ); static const mon_flag_str_id mon_flag_ELECTRIC( "ELECTRIC" ); static const mon_flag_str_id mon_flag_ELECTRIC_FIELD( "ELECTRIC_FIELD" ); diff --git a/src/trap.cpp b/src/trap.cpp index 08f861e6ca9f9..00ac2bd3dc2cc 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -51,9 +51,6 @@ const trap_str_id tr_telepad( "tr_telepad" ); const trap_str_id tr_temple_flood( "tr_temple_flood" ); const trap_str_id tr_temple_toggle( "tr_temple_toggle" ); -static const mon_flag_str_id mon_flag_NO_NECRO( "NO_NECRO" ); -static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); - static const update_mapgen_id update_mapgen_none( "none" ); namespace @@ -386,7 +383,7 @@ bool trap::triggered_by_sound( int vol, int dist ) const } int sound_chance = 100; if( sound_range > 0 ) { - int sound_chance = 25 + ( 75 * ( volume - sound_min ) / sound_range ); + sound_chance = 25 + ( 75 * ( volume - sound_min ) / sound_range ); } //debugmsg("Sound chance: %d%%", sound_chance); return !is_null() && ( rng( 0, 100 ) <= sound_chance ); diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index d353df008070e..2ae8f8506c015 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -58,8 +58,8 @@ static const efftype_id effect_ridden( "ridden" ); static const efftype_id effect_slimed( "slimed" ); static const efftype_id effect_tetanus( "tetanus" ); -static const flag_id json_flag_PROXIMITY( "PROXIMITY" ); static const flag_id json_flag_LEVITATION( "LEVITATION" ); +static const flag_id json_flag_PROXIMITY( "PROXIMITY" ); static const flag_id json_flag_UNCONSUMED( "UNCONSUMED" ); static const itype_id itype_bullwhip( "bullwhip" ); From ecccb4dc1643c16d219e7e4ff2f77e78c2680a7d Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 00:26:16 +0200 Subject: [PATCH 14/32] hide json names from player --- data/json/monsters/zed_dormant.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index aed667677371b..78a30e992e479 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -37,7 +37,7 @@ { "id": "mon_pseudo_dormant_zombie", "type": "MONSTER", - "name": { "str": "reawakened zombie_d" }, + "name": { "str": "dormant pseudo zombie" }, "description": "Fake zombie used for spawning dormant zombies. If you see this, open an issue on github.", "copy-from": "mon_zombie", "hp": 5, @@ -58,7 +58,7 @@ { "id": "mon_zombie_reawakened", "type": "MONSTER", - "name": { "str": "reawakened zombie" }, + "name": { "str": "zombie" }, "copy-from": "mon_zombie", "description": "What you thought was a corpse suddenly gets up and starts walking with sinister intent.", "flags": [ From 7e3029001028b31348a2d9ae4d4c4eb6f339d0ae Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 00:48:06 +0200 Subject: [PATCH 15/32] Just realized we can skip the reawakened zombie json. This simplifies everything. --- data/json/monsters/zed_dormant.json | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 78a30e992e479..d521a9779d239 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -37,13 +37,13 @@ { "id": "mon_pseudo_dormant_zombie", "type": "MONSTER", - "name": { "str": "dormant pseudo zombie" }, + "name": { "str": "zombie" }, "description": "Fake zombie used for spawning dormant zombies. If you see this, open an issue on github.", "copy-from": "mon_zombie", "hp": 5, "speed": 1, "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO", "REVIVES_HEALTHY", "QUIETDEATH" ], - "zombify_into": "mon_zombie_reawakened", + "zombify_into": "mon_zombie", "special_attacks": [ { "id": "pseudo_dormant_trap_setup_attk", @@ -55,30 +55,6 @@ } ] }, - { - "id": "mon_zombie_reawakened", - "type": "MONSTER", - "name": { "str": "zombie" }, - "copy-from": "mon_zombie", - "description": "What you thought was a corpse suddenly gets up and starts walking with sinister intent.", - "flags": [ - "SEES", - "HEARS", - "STUMBLES", - "WARM", - "GRABS", - "BASHES", - "GROUP_BASH", - "POISON", - "NO_BREATHE", - "PUSH_MON", - "FILTHY", - "REVIVES", - "NO_NECRO", - "REVIVES_HEALTHY" - ], - "//": "We need to add NO_NECRO, since reviving corpses without triggering the trap won't presently remove the trap. TODO: fix in future PR." - }, { "type": "trap", "id": "tr_dormant_corpse", From e4fb781bb35999de50e5b91170eb7eeb8ed8c740 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:50:05 -0800 Subject: [PATCH 16/32] Update data/json/monsters/zed_dormant.json Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- data/json/monsters/zed_dormant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index d521a9779d239..cdf61987fa14d 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -38,7 +38,7 @@ "id": "mon_pseudo_dormant_zombie", "type": "MONSTER", "name": { "str": "zombie" }, - "description": "Fake zombie used for spawning dormant zombies. If you see this, open an issue on github.", + "description": "Fake zombie used for spawning dormant zombies. If you see this, open an issue on github.", "copy-from": "mon_zombie", "hp": 5, "speed": 1, From ee429d6b21072fff71cd17f4349d0f8908cd3e86 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:50:13 -0800 Subject: [PATCH 17/32] Update data/json/monsters/zed_dormant.json Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- data/json/monsters/zed_dormant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index cdf61987fa14d..bc4ea859fab30 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -21,7 +21,7 @@ "type": "SPELL", "id": "pseudo_dormant_trap_setup", "name": { "str": "dormant corpse setup" }, - "description": "you should not see this. sets up trap for dormant zombies.", + "description": "You should not see this. Sets up trap for dormant zombies.", "valid_targets": [ "self" ], "max_level": 1, "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], From 94aa194b18393243f77fd4e41d94e70decc86754 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:50:22 -0800 Subject: [PATCH 18/32] Update data/json/monsters/zed_dormant.json Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- data/json/monsters/zed_dormant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index bc4ea859fab30..cfa3b0938d97d 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -3,7 +3,7 @@ "type": "SPELL", "id": "kill_pseudo_zombie", "name": { "str": "kill pseudo zombie" }, - "description": "you should not see this. kills pseudo zombie.", + "description": "You should not see this. Kills pseudo zombie to turn it into a corpse for revival.", "valid_targets": [ "self" ], "max_level": 1, "flags": [ "SILENT", "NO_EXPLOSION_SFX", "PERCENTAGE_DAMAGE", "NO_FAIL" ], From 11cdcf4af3c9af11935f61f5408818d329512697 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 00:52:42 +0200 Subject: [PATCH 19/32] grammar fix --- data/json/monsters/zed_dormant.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index d521a9779d239..d4d4f4d4e64f1 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -76,7 +76,7 @@ "type": "SPELL", "id": "cause_loud_moaning", "name": { "str": "cause loud moaning" }, - "description": "you should not see this. causes loud noise.", + "description": "You should not see this. Causes loud noise.", "valid_targets": [ "ground", "ally" ], "max_level": 1, "shape": "blast", @@ -94,7 +94,7 @@ "type": "SPELL", "id": "wake_up_dormant", "name": { "str": "dormant corpse waking up" }, - "description": "you should not see this. Causes all dormant corpses in the tile to revive.", + "description": "You should not see this. Causes all dormant corpses in the tile to revive.", "valid_targets": [ "ground" ], "max_level": 1, "flags": [ "NO_EXPLOSION_SFX" ], From d2800340a189250271326bf554c0748d7a6228b7 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 00:54:56 +0200 Subject: [PATCH 20/32] readd null --- src/trap.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/trap.cpp b/src/trap.cpp index 00ac2bd3dc2cc..f795f8b83c5d1 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -320,6 +320,9 @@ bool trap::can_see( const tripoint &pos, const Character &p ) const void trap::trigger( const tripoint &pos ) const { + if( is_null() ) { + return; + } act( pos, nullptr, nullptr ); } From d2f5dd675514c99ceb873b120b4c406529cd0342 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:58:09 -0800 Subject: [PATCH 21/32] Update doc/JSON_INFO.md Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- doc/JSON_INFO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 6e2b3b1bb69b3..2ccd779fd0875 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3035,7 +3035,7 @@ See [MUTATIONS.md](MUTATIONS.md) }, "trigger_message_u": "A bear trap closes on your foot!", // This message will be printed when player steps on a trap "trigger_message_npc": "A bear trap closes on 's foot!", // This message will be printed when NPC or monster steps on a trap - "sound_threshold": [5,10] // Optional. Minimum volume of sound that will trigger this trap. Defaults to [0,0] (Will not trigger from sound). If two values [min,max] are provided, trap triggers on a linearly increasing chance depending on volume, from 25% (min) to 100%(max). To always trigger at some noise, say noise level N, specify as [N,N]. IMPORTANT: Not all traps work with this system. Make sure to double check and test. + "sound_threshold": [5,10] // Optional. Minimum volume of sound that will trigger this trap. Defaults to [0,0] (Will not trigger from sound). If two values [min,max] are provided, trap triggers on a linearly increasing chance depending on volume, from 25% (min) to 100%(max). To always trigger at some noise, say noise level N, specify as [N,N]. IMPORTANT: Not all traps work with this system. Make sure to double check and test. ``` ### Vehicle Groups From 59976da3bdca30126ba5a1e19974da2f0f6e3649 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:58:29 -0800 Subject: [PATCH 22/32] Update doc/MAGIC.md Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- doc/MAGIC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 8270ba8ab6dd2..2dd1aad49f47c 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -163,7 +163,7 @@ Below is a table of currently implemented effects, along with special rules for Effect | Description --- |--- -`add_trap` | Adds a trap in the target tile. This always succeeds (unless there is an existing trap) and only places 1 trap. The `effect_str` is the id of the trap. +`add_trap` | Adds a trap in the target tile. This always succeeds (unless there is an existing trap) and only places 1 trap. The `effect_str` is the id of the trap. `area_pull` | Pulls `valid_targets` in its aoe toward the target location. Currently, the pull distance is set to 1 (see `directed_push`). `area_push` | Pushes `valid_targets` in its aoe away from the target location. Currently, the push distance is set to 1 (see `directed_push`). `attack` | Causes damage to `valid_targets` in its aoe, and applies `effect_str` named effect to targets. To damage terrain use `bash`. From 6b31362fc561f64207244f4b378c94f225e39454 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 14:58:39 -0800 Subject: [PATCH 23/32] Update doc/MAGIC.md Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- doc/MAGIC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 2dd1aad49f47c..49a179f356343 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -190,7 +190,7 @@ Effect | Description `remove_effect` | Removes `effect_str` effects from all creatures in the aoe. `remove_field` | Removes a `effect_str` field in the aoe. Causes teleglow of varying intensity and potentially teleportation depending on field density, if the field removed is `fd_fatigue`. `revive` | Revives a monster like a zombie necromancer. The monster must have the `REVIVES` flag. -`revive_dormant` | Revives a dormant monster. The monster must have the `REVIVES` AND the `DORMANT` flag. +`revive_dormant` | Revives a dormant monster. The monster must have the `REVIVES` AND the `DORMANT` flag. `short_range_teleport` | Teleports the player randomly range spaces with aoe variation. See also the `TARGET_TELEPORT` and `UNSAFE_TELEPORT` flags. `slime_split` | The slime splits into two large or normal slimes, depending on mass. Note: hardcoded for `mon_blob`-type enemies, check the monster `death_function` + spell `summon` combination. `spawn_item` | Spawns an item that will disappear at the end of its duration. Default duration is 0. From 405584e3f665f75cf5b57767300813fcb678baa1 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 01:08:14 +0200 Subject: [PATCH 24/32] makes zombie necromancer remove dormant zombie traps they resurrect --- data/json/monsters/zed_dormant.json | 2 +- src/monattack.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 67171df49d890..e51e75fcecc02 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -42,7 +42,7 @@ "copy-from": "mon_zombie", "hp": 5, "speed": 1, - "flags": [ "FILTHY", "REVIVES", "DORMANT", "NO_NECRO", "REVIVES_HEALTHY", "QUIETDEATH" ], + "flags": [ "FILTHY", "REVIVES", "DORMANT", "QUIETDEATH" ], "zombify_into": "mon_zombie", "special_attacks": [ { diff --git a/src/monattack.cpp b/src/monattack.cpp index 5c0310edbb4d4..a8a4ec70f1e7c 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -1245,6 +1245,10 @@ bool mattack::resurrect( monster *z ) // Did we successfully raise something? if( g->revive_corpse( raised.first, *raised.second ) ) { here.i_rem( raised.first, raised.second ); + // check to ensure that we destroy any dormant zombie traps in the same tile. + if( here.tr_at( raised.first ) == trap_id( "tr_dormant_corpse" ) ) { + here.remove_trap( raised.first ); + } if( sees_necromancer ) { add_msg( m_info, _( "You feel a strange pulse of energy from the %s." ), z->name() ); } From 82faa27cc8f652d22b24d08ba5a2dd1dcae74c41 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 01:12:11 +0200 Subject: [PATCH 25/32] removed monster flags to comply with #70588 --- src/item.cpp | 4 --- src/magic_spell_effect.cpp | 4 --- src/mondeath.cpp | 5 ---- src/monster.cpp | 56 -------------------------------------- 4 files changed, 69 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 45b6536c72043..e2d63e42fa999 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -187,10 +187,6 @@ static const matec_id RAPID( "RAPID" ); static const material_id material_wool( "wool" ); -static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); -static const mon_flag_str_id mon_flag_POISON( "POISON" ); -static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); - static const morale_type morale_null( "morale_null" ); static const mtype_id debug_mon( "debug_mon" ); diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 2b4772a92410c..b09c4b5ea0daf 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -76,10 +76,6 @@ static const json_character_flag json_flag_PRED2( "PRED2" ); static const json_character_flag json_flag_PRED3( "PRED3" ); static const json_character_flag json_flag_PRED4( "PRED4" ); -static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); -static const mon_flag_str_id mon_flag_NO_NECRO( "NO_NECRO" ); -static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); - static const mtype_id mon_blob( "mon_blob" ); static const mtype_id mon_blob_brain( "mon_blob_brain" ); static const mtype_id mon_blob_large( "mon_blob_large" ); diff --git a/src/mondeath.cpp b/src/mondeath.cpp index 15cfe225709e0..6bb6e70936c65 100644 --- a/src/mondeath.cpp +++ b/src/mondeath.cpp @@ -54,11 +54,6 @@ static const efftype_id effect_no_ammo( "no_ammo" ); static const harvest_drop_type_id harvest_drop_bone( "bone" ); static const harvest_drop_type_id harvest_drop_flesh( "flesh" ); -static const mon_flag_str_id mon_flag_DROPS_AMMO( "DROPS_AMMO" ); -static const mon_flag_str_id mon_flag_NOGIB( "NOGIB" ); -static const mon_flag_str_id mon_flag_SILENT_DISAPPEAR( "SILENT_DISAPPEAR" ); -static const mon_flag_str_id mon_flag_QUIETDEATH( "QUIETDEATH" ); - static const species_id species_ZOMBIE( "ZOMBIE" ); item_location mdeath::normal( monster &z ) diff --git a/src/monster.cpp b/src/monster.cpp index 1ed2b529516fb..fa20c350bf79a 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -157,61 +157,6 @@ static const mfaction_str_id monfaction_bee( "bee" ); static const mfaction_str_id monfaction_nether_player_hate( "nether_player_hate" ); static const mfaction_str_id monfaction_wasp( "wasp" ); -static const mon_flag_str_id mon_flag_ANIMAL( "ANIMAL" ); -static const mon_flag_str_id mon_flag_AQUATIC( "AQUATIC" ); -static const mon_flag_str_id mon_flag_ATTACK_LOWER( "ATTACK_LOWER" ); -static const mon_flag_str_id mon_flag_ATTACK_UPPER( "ATTACK_UPPER" ); -static const mon_flag_str_id mon_flag_BADVENOM( "BADVENOM" ); -static const mon_flag_str_id mon_flag_CAN_DIG( "CAN_DIG" ); -static const mon_flag_str_id mon_flag_CLIMBS( "CLIMBS" ); -static const mon_flag_str_id mon_flag_CORNERED_FIGHTER( "CORNERED_FIGHTER" ); -static const mon_flag_str_id mon_flag_DIGS( "DIGS" ); -static const mon_flag_str_id mon_flag_DORMANT( "DORMANT" ); -static const mon_flag_str_id mon_flag_EATS( "EATS" ); -static const mon_flag_str_id mon_flag_ELECTRIC( "ELECTRIC" ); -static const mon_flag_str_id mon_flag_ELECTRIC_FIELD( "ELECTRIC_FIELD" ); -static const mon_flag_str_id mon_flag_ELECTRONIC( "ELECTRONIC" ); -static const mon_flag_str_id mon_flag_FILTHY( "FILTHY" ); -static const mon_flag_str_id mon_flag_FIREY( "FIREY" ); -static const mon_flag_str_id mon_flag_FLIES( "FLIES" ); -static const mon_flag_str_id mon_flag_GOODHEARING( "GOODHEARING" ); -static const mon_flag_str_id mon_flag_GRABS( "GRABS" ); -static const mon_flag_str_id mon_flag_HAS_MIND( "HAS_MIND" ); -static const mon_flag_str_id mon_flag_HEARS( "HEARS" ); -static const mon_flag_str_id mon_flag_HIT_AND_RUN( "HIT_AND_RUN" ); -static const mon_flag_str_id mon_flag_HUMAN( "HUMAN" ); -static const mon_flag_str_id mon_flag_IMMOBILE( "IMMOBILE" ); -static const mon_flag_str_id mon_flag_KEEP_DISTANCE( "KEEP_DISTANCE" ); -static const mon_flag_str_id mon_flag_MILKABLE( "MILKABLE" ); -static const mon_flag_str_id mon_flag_NEMESIS( "NEMESIS" ); -static const mon_flag_str_id mon_flag_NEVER_WANDER( "NEVER_WANDER" ); -static const mon_flag_str_id mon_flag_NOHEAD( "NOHEAD" ); -static const mon_flag_str_id mon_flag_NO_BREATHE( "NO_BREATHE" ); -static const mon_flag_str_id mon_flag_NO_BREED( "NO_BREED" ); -static const mon_flag_str_id mon_flag_NO_FUNG_DMG( "NO_FUNG_DMG" ); -static const mon_flag_str_id mon_flag_PARALYZEVENOM( "PARALYZEVENOM" ); -static const mon_flag_str_id mon_flag_PATH_AVOID_DANGER_1( "PATH_AVOID_DANGER_1" ); -static const mon_flag_str_id mon_flag_PATH_AVOID_DANGER_2( "PATH_AVOID_DANGER_2" ); -static const mon_flag_str_id mon_flag_PATH_AVOID_FALL( "PATH_AVOID_FALL" ); -static const mon_flag_str_id mon_flag_PATH_AVOID_FIRE( "PATH_AVOID_FIRE" ); -static const mon_flag_str_id mon_flag_PET_MOUNTABLE( "PET_MOUNTABLE" ); -static const mon_flag_str_id mon_flag_PET_WONT_FOLLOW( "PET_WONT_FOLLOW" ); -static const mon_flag_str_id mon_flag_PHOTOPHOBIC( "PHOTOPHOBIC" ); -static const mon_flag_str_id mon_flag_PLASTIC( "PLASTIC" ); -static const mon_flag_str_id mon_flag_PRIORITIZE_TARGETS( "PRIORITIZE_TARGETS" ); -static const mon_flag_str_id mon_flag_QUEEN( "QUEEN" ); -static const mon_flag_str_id mon_flag_REVIVES( "REVIVES" ); -static const mon_flag_str_id mon_flag_REVIVES_HEALTHY( "REVIVES_HEALTHY" ); -static const mon_flag_str_id mon_flag_RIDEABLE_MECH( "RIDEABLE_MECH" ); -static const mon_flag_str_id mon_flag_SEES( "SEES" ); -static const mon_flag_str_id mon_flag_SMELLS( "SMELLS" ); -static const mon_flag_str_id mon_flag_STUN_IMMUNE( "STUN_IMMUNE" ); -static const mon_flag_str_id mon_flag_SUNDEATH( "SUNDEATH" ); -static const mon_flag_str_id mon_flag_SWIMS( "SWIMS" ); -static const mon_flag_str_id mon_flag_VENOM( "VENOM" ); -static const mon_flag_str_id mon_flag_WARM( "WARM" ); -static const mon_flag_str_id mon_flag_WIELDED_WEAPON( "WIELDED_WEAPON" ); - static const species_id species_AMPHIBIAN( "AMPHIBIAN" ); static const species_id species_CYBORG( "CYBORG" ); static const species_id species_FISH( "FISH" ); @@ -228,7 +173,6 @@ static const species_id species_ROBOT( "ROBOT" ); static const species_id species_ZOMBIE( "ZOMBIE" ); static const species_id species_nether_player_hate( "nether_player_hate" ); - static const ter_str_id ter_t_gas_pump( "t_gas_pump" ); static const ter_str_id ter_t_gas_pump_a( "t_gas_pump_a" ); From 6b465a959e286c96c9b28920e475f66e587bbff2 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 01:24:48 +0200 Subject: [PATCH 26/32] merge conflict fix + introduced dormant zombies to mass grave mongroup --- data/json/monstergroups/zombies.json | 3 ++- src/mtype.cpp | 4 ++++ src/mtype.h | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/data/json/monstergroups/zombies.json b/data/json/monstergroups/zombies.json index ef2aaf2202e90..1886067195f6f 100644 --- a/data/json/monstergroups/zombies.json +++ b/data/json/monstergroups/zombies.json @@ -1007,7 +1007,8 @@ "//": "Corpses buried at a mass grave. No ferals, and few animals.", "default": "mon_zombie", "monsters": [ - { "monster": "mon_zombie", "weight": 264, "cost_multiplier": 0 }, + { "monster": "mon_zombie", "weight": 132, "cost_multiplier": 0 }, + { "monster": "mon_pseudo_dormant_zombie", "weight": 132, "cost_multiplier": 0 }, { "monster": "mon_zombie_fat", "weight": 266, "cost_multiplier": 0 }, { "monster": "mon_zombie_child", "weight": 100, "cost_multiplier": 0 }, { "monster": "mon_zombie_tough", "weight": 100, "cost_multiplier": 0 }, diff --git a/src/mtype.cpp b/src/mtype.cpp index a61cb4120381a..054135f44809f 100644 --- a/src/mtype.cpp +++ b/src/mtype.cpp @@ -68,6 +68,7 @@ mon_flag_id mon_flag_ACIDPROOF, mon_flag_DESTROYS, mon_flag_DIGS, mon_flag_DOGFOOD, + mon_flag_DORMANT, mon_flag_DRIPS_GASOLINE, mon_flag_DRIPS_NAPALM, mon_flag_DROPS_AMMO, @@ -126,6 +127,7 @@ mon_flag_id mon_flag_ACIDPROOF, mon_flag_PUSH_MON, mon_flag_PUSH_VEH, mon_flag_QUEEN, + mon_flag_QUIETDEATH, mon_flag_RANGED_ATTACKER, mon_flag_REVIVES, mon_flag_REVIVES_HEALTHY, @@ -183,6 +185,7 @@ void set_mon_flag_ids() mon_flag_DESTROYS = mon_flag_id( "DESTROYS" ); mon_flag_DIGS = mon_flag_id( "DIGS" ); mon_flag_DOGFOOD = mon_flag_id( "DOGFOOD" ); + mon_flag_DORMANT = mon_flag_id( "DORMANT" ); mon_flag_DRIPS_GASOLINE = mon_flag_id( "DRIPS_GASOLINE" ); mon_flag_DRIPS_NAPALM = mon_flag_id( "DRIPS_NAPALM" ); mon_flag_DROPS_AMMO = mon_flag_id( "DROPS_AMMO" ); @@ -241,6 +244,7 @@ void set_mon_flag_ids() mon_flag_PUSH_MON = mon_flag_id( "PUSH_MON" ); mon_flag_PUSH_VEH = mon_flag_id( "PUSH_VEH" ); mon_flag_QUEEN = mon_flag_id( "QUEEN" ); + mon_flag_QUIETDEATH = mon_flag_id( "QUIETDEATH" ); mon_flag_RANGED_ATTACKER = mon_flag_id( "RANGED_ATTACKER" ); mon_flag_REVIVES = mon_flag_id( "REVIVES" ); mon_flag_REVIVES_HEALTHY = mon_flag_id( "REVIVES_HEALTHY" ); diff --git a/src/mtype.h b/src/mtype.h index c8810146f4f66..6b4e7b2f7cd1f 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -108,6 +108,7 @@ extern mon_flag_id mon_flag_ACIDPROOF, mon_flag_DESTROYS, mon_flag_DIGS, mon_flag_DOGFOOD, + mon_flag_DORMANT, mon_flag_DRIPS_GASOLINE, mon_flag_DRIPS_NAPALM, mon_flag_DROPS_AMMO, @@ -166,6 +167,7 @@ extern mon_flag_id mon_flag_ACIDPROOF, mon_flag_PUSH_MON, mon_flag_PUSH_VEH, mon_flag_QUEEN, + mon_flag_QUIETDEATH, mon_flag_RANGED_ATTACKER, mon_flag_REVIVES, mon_flag_REVIVES_HEALTHY, From a613c77041ef5855ea34d4fcd1cee63301e7e87a Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 01:40:09 +0200 Subject: [PATCH 27/32] Updated tileset configs to make corpse look identical to normal zombie. --- gfx/Altica/tile_config.json | 1 + gfx/ChibiUltica/tile_config.json | 2 +- gfx/MshockXotto+/tile_config.json | 2 +- gfx/Ultica_iso/tile_config.json | 1 + gfx/UltimateCataclysm/tile_config.json | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gfx/Altica/tile_config.json b/gfx/Altica/tile_config.json index 2f8a681a0d280..b35c327a1e5ab 100644 --- a/gfx/Altica/tile_config.json +++ b/gfx/Altica/tile_config.json @@ -14167,6 +14167,7 @@ { "id": [ "corpse_mon_zombie", + "corpse_mon_pseudo_dormant_zombie", "corpse_mon_zombie_grappler", "corpse_mon_zombie_biter", "corpse_mon_zombie_hunter", diff --git a/gfx/ChibiUltica/tile_config.json b/gfx/ChibiUltica/tile_config.json index 0d439a2800d47..791e01d0a5db2 100644 --- a/gfx/ChibiUltica/tile_config.json +++ b/gfx/ChibiUltica/tile_config.json @@ -4229,7 +4229,7 @@ { "id": "corpse_mon_woodlouse_manca", "fg": 2908 }, { "id": "corpse_mon_woodpecker", "fg": 2909 }, { "id": "corpse_mon_worm_larva", "fg": 2911 }, - { "id": "corpse_mon_zombie", "fg": 2912 }, + { "id": [ "corpse_mon_zombie", "corpse_mon_pseudo_dormant_zombie" ], "fg": 2912 }, { "id": "corpse_mon_zombie_acidic", "fg": 2913 }, { "id": "corpse_mon_zombie_biter", "fg": 2915 }, { "id": "corpse_mon_zombie_child", "fg": 2917 }, diff --git a/gfx/MshockXotto+/tile_config.json b/gfx/MshockXotto+/tile_config.json index 07a8ece66c11f..b9fcb73574691 100644 --- a/gfx/MshockXotto+/tile_config.json +++ b/gfx/MshockXotto+/tile_config.json @@ -12307,7 +12307,7 @@ { "id": "corpse_mon_woodlouse_manca", "fg": 5154 }, { "id": "corpse_mon_woodpecker", "fg": 5155 }, { "id": "corpse_mon_worm_larva", "fg": 5157 }, - { "id": "corpse_mon_zombie", "fg": 5158 }, + { "id": [ "corpse_mon_zombie", "corpse_mon_pseudo_dormant_zombie" ], "fg": 5158 }, { "id": "corpse_mon_zombie_acidic", "fg": 5159 }, { "id": "corpse_mon_zombie_biter", "fg": 5161 }, { "id": "corpse_mon_zombie_child", "fg": 5163 }, diff --git a/gfx/Ultica_iso/tile_config.json b/gfx/Ultica_iso/tile_config.json index eea0f9d347509..fcb4a6ee877dd 100644 --- a/gfx/Ultica_iso/tile_config.json +++ b/gfx/Ultica_iso/tile_config.json @@ -10846,6 +10846,7 @@ { "id": [ "corpse_mon_zombie", + "corpse_mon_pseudo_dormant_zombie", "corpse_mon_zombie_grappler", "corpse_mon_zombie_biter", "corpse_mon_zombie_hunter", diff --git a/gfx/UltimateCataclysm/tile_config.json b/gfx/UltimateCataclysm/tile_config.json index 25598475f1c10..706111fc9181d 100644 --- a/gfx/UltimateCataclysm/tile_config.json +++ b/gfx/UltimateCataclysm/tile_config.json @@ -15711,6 +15711,7 @@ { "id": [ "corpse_mon_zombie", + "corpse_mon_pseudo_dormant_zombie", "corpse_mon_zombie_grappler", "corpse_mon_zombie_biter", "corpse_mon_zombie_hunter", From 5e9aefb7c254444bc3a3c1fc4709a76ff58b2b92 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 01:42:55 +0200 Subject: [PATCH 28/32] make zombie dormant corpse harder to detect. --- data/json/monsters/zed_dormant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index e51e75fcecc02..994dac9ef2162 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -62,7 +62,7 @@ "//": "This zombie 'corpse' looks eerily like it could get up and start walking at any moment.", "color": "light_green", "symbol": "Z", - "visibility": 3, + "visibility": 6, "avoidance": 20, "difficulty": 99, "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY" ], From 5d42f9c6cf7475470f77f5b5c9cf05264912b04f Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 01:46:42 +0200 Subject: [PATCH 29/32] small rebalance --- data/json/monsters/zed_dormant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index 994dac9ef2162..fb8e0886b5313 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -62,7 +62,7 @@ "//": "This zombie 'corpse' looks eerily like it could get up and start walking at any moment.", "color": "light_green", "symbol": "Z", - "visibility": 6, + "visibility": 8, "avoidance": 20, "difficulty": 99, "flags": [ "UNDODGEABLE", "AVATAR_ONLY", "PROXIMITY" ], From bd06ecf9654fc63088d7944e40a56cedbd0dfd11 Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 02:05:52 +0200 Subject: [PATCH 30/32] reverted tileset change --- gfx/Altica/tile_config.json | 1 - gfx/ChibiUltica/tile_config.json | 2 +- gfx/MshockXotto+/tile_config.json | 2 +- gfx/Ultica_iso/tile_config.json | 1 - gfx/UltimateCataclysm/tile_config.json | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/gfx/Altica/tile_config.json b/gfx/Altica/tile_config.json index b35c327a1e5ab..2f8a681a0d280 100644 --- a/gfx/Altica/tile_config.json +++ b/gfx/Altica/tile_config.json @@ -14167,7 +14167,6 @@ { "id": [ "corpse_mon_zombie", - "corpse_mon_pseudo_dormant_zombie", "corpse_mon_zombie_grappler", "corpse_mon_zombie_biter", "corpse_mon_zombie_hunter", diff --git a/gfx/ChibiUltica/tile_config.json b/gfx/ChibiUltica/tile_config.json index 791e01d0a5db2..0d439a2800d47 100644 --- a/gfx/ChibiUltica/tile_config.json +++ b/gfx/ChibiUltica/tile_config.json @@ -4229,7 +4229,7 @@ { "id": "corpse_mon_woodlouse_manca", "fg": 2908 }, { "id": "corpse_mon_woodpecker", "fg": 2909 }, { "id": "corpse_mon_worm_larva", "fg": 2911 }, - { "id": [ "corpse_mon_zombie", "corpse_mon_pseudo_dormant_zombie" ], "fg": 2912 }, + { "id": "corpse_mon_zombie", "fg": 2912 }, { "id": "corpse_mon_zombie_acidic", "fg": 2913 }, { "id": "corpse_mon_zombie_biter", "fg": 2915 }, { "id": "corpse_mon_zombie_child", "fg": 2917 }, diff --git a/gfx/MshockXotto+/tile_config.json b/gfx/MshockXotto+/tile_config.json index b9fcb73574691..07a8ece66c11f 100644 --- a/gfx/MshockXotto+/tile_config.json +++ b/gfx/MshockXotto+/tile_config.json @@ -12307,7 +12307,7 @@ { "id": "corpse_mon_woodlouse_manca", "fg": 5154 }, { "id": "corpse_mon_woodpecker", "fg": 5155 }, { "id": "corpse_mon_worm_larva", "fg": 5157 }, - { "id": [ "corpse_mon_zombie", "corpse_mon_pseudo_dormant_zombie" ], "fg": 5158 }, + { "id": "corpse_mon_zombie", "fg": 5158 }, { "id": "corpse_mon_zombie_acidic", "fg": 5159 }, { "id": "corpse_mon_zombie_biter", "fg": 5161 }, { "id": "corpse_mon_zombie_child", "fg": 5163 }, diff --git a/gfx/Ultica_iso/tile_config.json b/gfx/Ultica_iso/tile_config.json index fcb4a6ee877dd..eea0f9d347509 100644 --- a/gfx/Ultica_iso/tile_config.json +++ b/gfx/Ultica_iso/tile_config.json @@ -10846,7 +10846,6 @@ { "id": [ "corpse_mon_zombie", - "corpse_mon_pseudo_dormant_zombie", "corpse_mon_zombie_grappler", "corpse_mon_zombie_biter", "corpse_mon_zombie_hunter", diff --git a/gfx/UltimateCataclysm/tile_config.json b/gfx/UltimateCataclysm/tile_config.json index 706111fc9181d..25598475f1c10 100644 --- a/gfx/UltimateCataclysm/tile_config.json +++ b/gfx/UltimateCataclysm/tile_config.json @@ -15711,7 +15711,6 @@ { "id": [ "corpse_mon_zombie", - "corpse_mon_pseudo_dormant_zombie", "corpse_mon_zombie_grappler", "corpse_mon_zombie_biter", "corpse_mon_zombie_hunter", From 861f49ec97f13b1d79dd36b1ffac6330b8e633ca Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Wed, 3 Jan 2024 02:13:13 +0200 Subject: [PATCH 31/32] small looks_like fix. Now looks like the correct corpse before it dies. Need tileset server fix for proper functionality. --- data/json/monsters/zed_dormant.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/monsters/zed_dormant.json b/data/json/monsters/zed_dormant.json index fb8e0886b5313..3cff0f32f6df1 100644 --- a/data/json/monsters/zed_dormant.json +++ b/data/json/monsters/zed_dormant.json @@ -40,6 +40,7 @@ "name": { "str": "zombie" }, "description": "Fake zombie used for spawning dormant zombies. If you see this, open an issue on github.", "copy-from": "mon_zombie", + "looks_like": "corpse_mon_zombie", "hp": 5, "speed": 1, "flags": [ "FILTHY", "REVIVES", "DORMANT", "QUIETDEATH" ], From 86901b02db72df35e40ed9b0459ec521e2ac38bf Mon Sep 17 00:00:00 2001 From: George Karfakis Date: Tue, 2 Jan 2024 16:28:59 -0800 Subject: [PATCH 32/32] meaningless change to restimulate frozen github checks --- src/magic.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/magic.h b/src/magic.h index 217c1a799cc83..f9493ea81c7e6 100644 --- a/src/magic.h +++ b/src/magic.h @@ -181,7 +181,6 @@ struct fake_spell { spell get_spell( const Creature &caster, int min_level_override = 0 ) const; spell get_spell() const; - bool is_valid() const; void load( const JsonObject &jo ); void serialize( JsonOut &json ) const;