From 46c9ac1c55d4acb8974359684327983b9db8afc2 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Fri, 6 Dec 2019 20:37:59 -0600 Subject: [PATCH 1/7] Leech-pod-monster family --- data/json/harvest.json | 17 ++ data/json/items/comestibles/carnivore.json | 46 +++++ data/json/items/gun/monster_gun.json | 31 +++ .../microlab/microlab_special_tiles.json | 43 ++++ data/json/monsters/power_leech.json | 188 ++++++++++++++++++ data/json/species.json | 5 + data/json/speech.json | 24 +++ src/monattack.cpp | 142 +++++++++++++ src/monattack.h | 3 + src/monster.cpp | 6 + src/monster.h | 1 + src/monstergenerator.cpp | 3 + 12 files changed, 509 insertions(+) create mode 100644 data/json/monsters/power_leech.json diff --git a/data/json/harvest.json b/data/json/harvest.json index 49512175917ee..82e6d2fc0b834 100644 --- a/data/json/harvest.json +++ b/data/json/harvest.json @@ -704,6 +704,23 @@ { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.1 } ] }, + { + "id": "flesh_plant", + "type": "harvest", + "entries": [ + { "drop": "meat_bark", "type": "flesh", "mass_ratio": 0.05 }, + { "drop": "meat_frond", "type": "flesh", "mass_ratio": 0.5 } + ] + }, + { + "id": "flesh_plant_bloom", + "type": "harvest", + "entries": [ + { "drop": "meat_bark", "type": "flesh", "mass_ratio": 0.05 }, + { "drop": "leech_flower", "type": "flesh", "mass_ratio": 0.25 }, + { "drop": "meat_frond", "type": "flesh", "mass_ratio": 0.5 } + ] + }, { "id": "biollante", "type": "harvest", diff --git a/data/json/items/comestibles/carnivore.json b/data/json/items/comestibles/carnivore.json index 46ff3c932d530..4122d49d150d8 100644 --- a/data/json/items/comestibles/carnivore.json +++ b/data/json/items/comestibles/carnivore.json @@ -932,5 +932,51 @@ "material": [ "flesh" ], "volume": "250 ml", "fun": -30 + }, + { + "id": "meat_frond", + "copy-from": "meat_tainted", + "type": "COMESTIBLE", + "name": "alien fronds", + "use_action": "POISON", + "description": "The fleshy fronds harvested from an alien plant. The tiny membranous leaves attached and rigid and gut-like stem are certainly poisonous, and yet they have a paradoxically pleasant and inviting sweet smell. Might be non-vegan.", + "fun": 15, + "stim": 3, + "vitamins": [ [ "vitA", 6 ], [ "vitC", 2 ], [ "calcium", 0 ], [ "iron", 8 ], [ "vitB", 6 ], [ "mutant_toxin", 8 ] ] + }, + { + "id": "leech_flower", + "type": "COMESTIBLE", + "comestible_type": "FOOD", + "name": "leech flower", + "color": "blue", + "weight": "10 g", + "volume": "250 ml", + "symbol": "%", + "spoils_in": "30 days", + "description": "The alien beauty of this indigo flower is betrayed by its disgustingly fleshy composition. What from afar appear to be petals are but layered membranes of transparent veiny flesh, given color by a covering of blue iridescent ichor. Even if it is certainly poisonous, it has a pleasant medicinal smell to it.", + "stim": 30, + "healthy": -10, + "fun": 15, + "use_action": { + "type": "consume_drug", + "activation_message": "Even a close smell of this alien flower feels deeply intoxicating.", + "effects": [ + { "id": "pkill3", "duration": 360 }, + { "id": "pkill2", "duration": 810 }, + { "id": "foodpoison", "duration": 810 }, + { "id": "badpoison", "duration": 3600 }, + { "id": "shakes", "duration": 810 } + ] + } + }, + { + "id": "meat_bark", + "copy-from": "meat_frond", + "type": "COMESTIBLE", + "name": "leech bark", + "name_plural": "scraps of leech bark", + "description": "Dry and though bark matter harvested from an alien plant. It is slightly translucent, and if placed against the light you can distinguish glistening blue veins running through it.", + "vitamins": [ [ "vitA", 6 ], [ "vitC", 0 ], [ "calcium", 2 ], [ "iron", 8 ], [ "vitB", 6 ], [ "mutant_toxin", 12 ] ] } ] diff --git a/data/json/items/gun/monster_gun.json b/data/json/items/gun/monster_gun.json index c8506e441fb22..02472fdf49bdf 100644 --- a/data/json/items/gun/monster_gun.json +++ b/data/json/items/gun/monster_gun.json @@ -29,5 +29,36 @@ "range": 12, "dispersion": 100, "durability": 8 + }, + { + "id": "emp_frond", + "type": "GUN", + "symbol": "%", + "color": "red", + "name": "electric alien frond", + "description": "Electricity unnaturally arcs from the tips of this alien frond.", + "material": [ "hflesh" ], + "flags": [ + "PRIMITIVE_RANGED_WEAPON", + "NEVER_JAMS", + "NONCONDUCTIVE", + "NO_REPAIR", + "WATERPROOF_GUN", + "NO_SALVAGE", + "NO_UNLOAD", + "NO_AMMO" + ], + "skill": "pistol", + "ammo_effects": [ "EMP", "LIGHTNING" ], + "ranged_damage": { "damage_type": "electric", "amount": 1 }, + "weight": "540 g", + "volume": "750ml", + "bashing": 2, + "to_hit": 1, + "reload_noise_volume": 2, + "loudness": 2, + "range": 12, + "dispersion": 150, + "durability": 8 } ] diff --git a/data/json/mapgen/microlab/microlab_special_tiles.json b/data/json/mapgen/microlab/microlab_special_tiles.json index f831fcbc02f42..67440f20304b5 100644 --- a/data/json/mapgen/microlab/microlab_special_tiles.json +++ b/data/json/mapgen/microlab/microlab_special_tiles.json @@ -117,6 +117,49 @@ "place_monsters": [ { "monster": "GROUP_LAB", "chance": 2, "x": [ 2, 21 ], "y": [ 2, 21 ], "repeat": [ 1, 5 ] } ] } }, + { + "type": "mapgen", + "om_terrain": [ [ "microlab_generic" ] ], + "method": "json", + "object": { + "fill_ter": "t_strconc_floor", + "rows": [ + " cc | c| |c c|r ", + " cc | c| u|c c|r c ", + " | h 6| k2 2u c ", + " dd |==||| ||||||6h ", + "uhd |tt|-- -----|6uku ", + "|||u ||||- uuu-||||||", + " c|ku|##|-DDd ku-|hd^= ", + " c|u ||||- k-| d = ", + " c| uku( u c-| ] ", + " uk u|-k A u-|=]== ", + "|||k |- ukuu -|kuk||", + " u TAu u ", + " kkuu k kuAc 2 ", + "||u|| uk|-uukuk -| |||", + " kk| Y|-kk Au ( u|r ", + "cc | (k uu ( uk|r ", + "cc |||||- ddd u-| |r ", + " 2 r|-ku h ku-| |r ", + "||2|||rr|-- u--((-| |||", + " ||||||uk|| || |c ", + " c 6|k k|c ", + " iccc 6| uk ", + " c 6| k||22||||| ", + " c c|c | | |cc " + ], + "palettes": [ "microlab" ], + "terrain": { "A": "t_plut_generator" }, + "item": { "u": { "item": "corpse" }, "k": { "item": "corpse" }, "T": { "item": "corpse" } }, + "monster": { + "T": { "monster": "mon_leech_blossom" }, + "k": { "monster": "mon_leech_pod_cluster" }, + "u": { "monster": "mon_leech_stalk" } + }, + "place_monsters": [ { "monster": "GROUP_LAB", "chance": 2, "x": [ 2, 21 ], "y": [ 2, 21 ], "repeat": [ 1, 5 ] } ] + } + }, { "type": "mapgen", "om_terrain": [ [ "microlab_generic" ] ], diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json new file mode 100644 index 0000000000000..e8f79a5919e1a --- /dev/null +++ b/data/json/monsters/power_leech.json @@ -0,0 +1,188 @@ +[ + { + "id": "mon_leech_blossom", + "type": "MONSTER", + "name": "leech blossom", + "description": "A resplendent alien fern, crowned with flowers colored deep indigo. It appears to be the centerpiece of this otherworldly bloom.", + "default_faction": "nether", + "species": [ "LEECH_PLANT" ], + "volume": "92500 ml", + "weight": "40 kg", + "hp": 100, + "speed": 100, + "material": [ "flesh" ], + "symbol": "K", + "color": "light_cyan", + "aggression": 100, + "morale": 100, + "armor_bash": 15, + "vision_day": 30, + "vision_night": 30, + "luminance": 200, + "special_attacks": [ + { + "type": "gun", + "cooldown": 5, + "gun_type": "emp_frond", + "fake_skills": [ [ "gun", 3 ], [ "rifle", 3 ] ], + "ranges": [ [ 0, 12, "DEFAULT" ] ], + "description": "Lightning arcs towards you!" + }, + [ "LEECH_SPAWNER", 25 ], + [ "MON_LEECH_EVOLUTION", 40 ], + [ "PARROT", 40 ] + ], + "death_drops": { }, + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE", "QUEEN", "HARDTOSHOOT" ] + }, + { + "id": "mon_leech_stalk", + "type": "MONSTER", + "name": "leech stalk", + "description": "A resplendent and voluminous alien fern. A faint buzzing sound emanates from it, and the shadow cast by its canopy continuously glows with electric charge.", + "default_faction": "nether", + "species": [ "LEECH_PLANT" ], + "volume": "30000 ml", + "weight": "40 kg", + "hp": 40, + "speed": 100, + "material": [ "flesh" ], + "symbol": "y", + "color": "light_blue", + "aggression": 100, + "morale": 100, + "armor_bash": 15, + "vision_day": 30, + "vision_night": 30, + "luminance": 200, + "special_attacks": [ + { + "type": "gun", + "cooldown": 15, + "gun_type": "emp_frond", + "fake_skills": [ [ "gun", 2 ], [ "rifle", 2 ] ], + "ranges": [ [ 0, 12, "DEFAULT" ] ], + "description": "Lightning arcs towards you!" + }, + [ "MON_LEECH_EVOLUTION", 30 ], + [ "PARROT", 40 ] + ], + "death_drops": { }, + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "IMMOBILE", "NO_BREATHE", "HARDTOSHOOT" ] + }, + { + "id": "mon_leech_pod_cluster", + "type": "MONSTER", + "name": "leech pod cluster", + "description": "The translucent egg pods of an alien plant, firmly attached by luminous rhizomes. You can barely distinguish a root drone floating withing a cloudy substance.", + "default_faction": "nether", + "species": [ "LEECH_PLANT" ], + "volume": "30000 ml", + "weight": "60 kg", + "hp": 40, + "speed": 100, + "material": [ "flesh" ], + "symbol": "g", + "color": "white", + "aggression": 100, + "morale": 100, + "armor_bash": 15, + "luminance": 60, + "starting_ammo": { "9mm": 100 }, + "special_attacks": [ + { + "type": "gun", + "cooldown": 15, + "gun_type": "emp_frond", + "ranges": [ [ 0, 1, "DEFAULT" ] ], + "description": "Lightning arcs towards you!" + }, + [ "LEECH_SPAWNER", 35 ] + ], + "death_drops": { }, + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE" ] + }, + { + "id": "mon_leech_root_runner", + "type": "MONSTER", + "name": "root runner", + "description": "This clump of woody vegetation hastily clambers around in a lizard-like fashion. Three translucent scale-leaves stand tall on the backside of the creature, and the thin ridges within them periodically glow through some unknown mean. Its seemingly a symbiote of the nearby alien ferns, and looks ready to defend them with its life.", + "default_faction": "nether",1 + "species": [ "LEECH_PLANT" ], + "volume": "4000 ml", + "weight": "6 kg", + "hp": 40, + "speed": 120, + "material": [ "flesh" ], + "symbol": "m", + "color": "blue", + "aggression": 100, + "morale": 100, + "melee_skill": 4, + "melee_dice": 1, + "melee_dice_sides": 2, + "armor_bash": 15, + "luminance": 60, + "vision_day": 30, + "vision_night": 10, + "melee_damage": [ { "damage_type": "electric", "amount": 4 } ], + "upgrades": { "half_life": 9999, "into": "mon_leech_stalk" }, + "special_attacks": [ + { + "type": "gun", + "cooldown": 15, + "gun_type": "emp_frond", + "fake_skills": [ [ "gun", 1 ], [ "rifle", 1 ] ], + "ranges": [ [ 0, 2, "DEFAULT" ] ], + "description": "Lightning arcs towards you!" + }, + [ "EVOLVE_KILL_STRIKE", 3 ] + ], + "death_drops": { }, + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "NO_BREATHE", "HARDTOSHOOT" ] + }, + { + "id": "mon_leech_root_drone", + "type": "MONSTER", + "name": "root drone", + "description": "A small bulb with a beak like protuberance, skittishly roaming about under three tendril rhizomes. Dripping and glistening, it resembles a creature newly born rather than a sapling grown from seeds.", + "default_faction": "nether", + "species": [ "LEECH_PLANT" ], + "volume": "3000 ml", + "weight": "2 kg", + "hp": 40, + "speed": 80, + "material": [ "flesh" ], + "symbol": "p", + "color": "blue", + "aggression": 100, + "morale": 100, + "melee_skill": 2, + "melee_dice": 1, + "melee_dice_sides": 2, + "armor_bash": 15, + "luminance": 60, + "vision_day": 30, + "vision_night": 10, + "melee_damage": [ { "damage_type": "electric", "amount": 3 } ], + "upgrades": { "half_life": 999, "into": "mon_leech_pod_cluster" }, + "special_attacks": [ + { + "type": "gun", + "cooldown": 15, + "gun_type": "emp_frond", + "fake_skills": [ [ "gun", 1 ], [ "rifle", 1 ] ], + "ranges": [ [ 0, 2, "DEFAULT" ] ], + "description": "Lightning arcs towards you!" + }, + [ "EVOLVE_KILL_STRIKE", 6 ] + ], + "death_drops": { }, + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "NO_BREATHE", "HARDTOSHOOT" ] + } +] diff --git a/data/json/species.json b/data/json/species.json index 7f083143a9cf0..d41a8656f33e1 100644 --- a/data/json/species.json +++ b/data/json/species.json @@ -44,6 +44,11 @@ "id": "FUNGUS", "fear_triggers": [ "HURT", "FIRE" ] }, + { + "type": "SPECIES", + "id": "LEECH_PLANT", + "fear_triggers": [ "HURT", "FIRE" ] + }, { "type": "SPECIES", "id": "INSECT", diff --git a/data/json/speech.json b/data/json/speech.json index 14f10dba4e212..fc802c9cbef10 100644 --- a/data/json/speech.json +++ b/data/json/speech.json @@ -2135,6 +2135,30 @@ "sound": "\"Police inbound. Stay where you are!\"", "volume": 15 }, + { + "type": "speech", + "speaker": "mon_leech_blossom", + "sound": "\"visceral chittering.\"", + "volume": 15 + }, + { + "type": "speech", + "speaker": "mon_leech_blossom", + "sound": "\"a clear high-pitched hum.\"", + "volume": 15 + }, + { + "type": "speech", + "speaker": "mon_leech_blossom", + "sound": "\"the hum of static electricity.\"", + "volume": 15 + }, + { + "type": "speech", + "speaker": "mon_leech_blossom", + "sound": "\"a low buzzing sound.\"", + "volume": 15 + }, { "type": "speech", "speaker": "foodperson_mask", diff --git a/src/monattack.cpp b/src/monattack.cpp index eb1cc5e891535..a9b9483701b7f 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -94,6 +94,11 @@ static const mtype_id mon_fungal_wall( "mon_fungal_wall" ); static const mtype_id mon_headless_dog_thing( "mon_headless_dog_thing" ); static const mtype_id mon_manhack( "mon_manhack" ); static const mtype_id mon_shadow( "mon_shadow" ); +static const mtype_id mon_leech_stalk( "mon_leech_stalk" ); +static const mtype_id mon_leech_blossom( "mon_leech_blossom" ); +static const mtype_id mon_leech_pod_cluster( "mon_leech_pod_cluster" ); +static const mtype_id mon_leech_root_runner( "mon_leech_root_runner" ); +static const mtype_id mon_leech_root_drone( "mon_leech_root_drone" ); static const mtype_id mon_hound_tindalos_afterimage( "mon_hound_tindalos_afterimage" ); static const mtype_id mon_triffid( "mon_triffid" ); static const mtype_id mon_zombie_gasbag_impaler( "mon_zombie_gasbag_impaler" ); @@ -111,6 +116,7 @@ static const skill_id skill_launcher( "launcher" ); static const species_id ZOMBIE( "ZOMBIE" ); static const species_id BLOB( "BLOB" ); +static const species_id LEECH_PLANT( "LEECH_PLANT" ); static const efftype_id effect_assisted( "assisted" ); static const efftype_id effect_bite( "bite" ); @@ -4720,6 +4726,142 @@ bool mattack::riotbot( monster *z ) return true; } +bool mattack::evolve_kill_strike( monster *z ) +{ + Creature *target = z->attack_target(); + if( target == nullptr || + !is_adjacent( z, target, false ) || + !z->sees( *target ) ) { + return false; + } + if( !z->can_act() ) { + return false; + } + + z->moves -= 100; + bool uncanny = target->uncanny_dodge(); + if( uncanny || dodge_check( z, target ) ) { + auto msg_type = target == &g->u ? m_warning : m_info; + target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), + _( "The %s lunges at , but they dodge!" ), + z->name() ); + if( !uncanny ) { + target->on_dodge( z, z->type->melee_skill * 2 ); + target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), + _( "The %s lunges at , but they dodge!" ), + z->name() ); + } + return true; + } + const std::string old_name = z->name(); + const bool could_see_z = g->u.sees( *z ); + tripoint const target_pos = target->pos(); + const std::string target_name = target->disp_name(); + damage_instance damage( z->type->melee_damage ); + damage.mult_damage( 1.33f ); + int damage_dealt = target->deal_damage( z, bp_torso, damage_instance( DT_STAB, rng( 10, 20 ), + rng( 5, 15 ) ) ).total_damage(); + if( damage_dealt > 0 ) { + auto msg_type = target == &g->u ? m_bad : m_warning; + target->add_msg_player_or_npc( msg_type, + _( "The %1$s impales yor chest for %2$d damage!" ), + _( "The %1$s impales 's chest for %2$d damage!" ), + z->name(), damage_dealt ); + } else { + target->add_msg_player_or_npc( + _( "The %1$s attempts to burrow itself into you, but is stopped by your armor!" ), + _( "The %1$s slashes at 's %2$s, but is stopped by its glances off armor!" ), + z->name() ); + return true; + } + if( target->is_dead_state() && g->is_empty( target_pos ) && + target->made_of_any( Creature::cmat_flesh ) ) { + z->allow_upgrade(); + z->try_upgrade( false ); + z->setpos( target_pos ); + const std::string upgrade_name = z->name(); + const bool can_see_z_upgrade = g->u.sees( *z ); + if( could_see_z && can_see_z_upgrade ) { + add_msg( m_warning, _( "The %1$s burrows within %2$s corpse and a %3$s emerges from the remains!" ), + old_name, + target_name, upgrade_name ); + } else if( could_see_z ) { + add_msg( m_warning, _( "The %1$s burrows within %2$s corpse!" ), old_name, target_name ); + } else if( can_see_z_upgrade ) { + add_msg( m_warning, _( "A %1$s emerges from %2$s corpse!" ), target->disp_name(), target_name ); + } + } + return true; +} + +bool mattack::leech_spawner( monster *z ) +{ + const bool u_see = g->u.sees( *z ); + std::list allies; + for( monster &candidate : g->all_monsters() ) { + if( candidate.type->in_species( LEECH_PLANT ) && !candidate.type->has_flag( MF_IMMOBILE ) ) { + allies.push_back( &candidate ); + } + } + if( allies.size() > 35 ) { + return true; + } + int monsters_spawned = rng( 1, 4 ); + const mtype_id monster_type = one_in( 3 ) ? mon_leech_root_runner : mon_leech_root_drone; + for( int i = 0; i < monsters_spawned; i++ ) { + if( monster *const new_mon = g->place_critter_around( monster_type, z->pos(), 1 ) ) { + if( u_see ) { + add_msg( m_warning, + _( "An egg pod ruptures and a %s crawls out from the remains!" ), new_mon->name() ); + } + } + } + if( one_in( 25 ) ) { + z->poly( mon_leech_stalk ); + if( u_see ) { + add_msg( m_warning, + _( "Resplendent fronds emerge from the still intact pods! " ) ); + } + } + return true; +} + +bool mattack::mon_leech_evolution( monster *z ) +{ + const bool u_see = g->u.sees( *z ); + const bool is_queen = z->type->has_flag( MF_QUEEN ); + std::list queens; + for( monster &candidate : g->all_monsters() ) { + if( candidate.type->in_species( LEECH_PLANT ) && candidate.type->has_flag( MF_QUEEN ) && + rl_dist( z->pos(), candidate.pos() ) ) { + queens.push_back( &candidate ); + } + } + if( !is_queen ) { + if( queens.empty() ) { + z->poly( mon_leech_blossom ); + z->set_hp( z->get_hp_max() ); + if( u_see ) { + add_msg( m_warning, + _( "The %s blooms into flowers!" ), z->name() ); + } + } + + } else { + if( !queens.empty() ) { + if( u_see ) { + add_msg( m_warning, + _( "The %s flowers whiter and fall!" ), z->name() ); + } + z->poly( mon_leech_stalk ); + g->m.spawn_item( z->pos(), "leech_flower", 5, 0, calendar::turn ); + + } + } + return true; +} + + bool mattack::tindalos_teleport( monster *z ) { Creature *target = z->attack_target(); diff --git a/src/monattack.h b/src/monattack.h index 2a261e58075b0..73d3735f14ae5 100644 --- a/src/monattack.h +++ b/src/monattack.h @@ -84,6 +84,9 @@ bool parrot( monster *z ); bool parrot_at_danger( monster *parrot ); bool darkman( monster *z ); bool slimespring( monster *z ); +bool evolve_kill_strike( monster *z ); +bool leech_spawner( monster *z ); +bool mon_leech_evolution( monster *z ); bool tindalos_teleport( monster *z ); bool flesh_tendril( monster *z ); bool bio_op_takedown( monster *z ); diff --git a/src/monster.cpp b/src/monster.cpp index 0c3e76417bc7f..dbb942b82e30c 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -317,6 +317,12 @@ int monster::get_upgrade_time() const return upgrade_time; } +// Sets time to upgrade to 0. +void monster:: allow_upgrade() +{ + upgrade_time = 0; +} + // This will disable upgrades in case max iters have been reached. // Checking for return value of -1 is necessary. int monster::next_upgrade_time() diff --git a/src/monster.h b/src/monster.h index f1e13b3ed9a17..33ca4f22c1ee8 100644 --- a/src/monster.h +++ b/src/monster.h @@ -102,6 +102,7 @@ class monster : public Creature bool can_upgrade(); void hasten_upgrade(); int get_upgrade_time() const; + void allow_upgrade(); void try_upgrade( bool pin_time ); void try_reproduce(); void try_biosignature(); diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 6aebf2d8783ed..da36c4eafa5da 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -527,6 +527,9 @@ void MonsterGenerator::init_attack() add_hardcoded_attack( "PARROT_AT_DANGER", mattack::parrot_at_danger ); add_hardcoded_attack( "DARKMAN", mattack::darkman ); add_hardcoded_attack( "SLIMESPRING", mattack::slimespring ); + add_hardcoded_attack( "EVOLVE_KILL_STRIKE", mattack::evolve_kill_strike ); + add_hardcoded_attack( "LEECH_SPAWNER", mattack::leech_spawner ); + add_hardcoded_attack( "MON_LEECH_EVOLUTION", mattack::mon_leech_evolution ); add_hardcoded_attack( "TINDALOS_TELEPORT", mattack::tindalos_teleport ); add_hardcoded_attack( "FLESH_TENDRIL", mattack::flesh_tendril ); add_hardcoded_attack( "BIO_OP_TAKEDOWN", mattack::bio_op_takedown ); From 5fd024a03b1ff23ca926cce39920ca0be3671630 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Tue, 17 Dec 2019 22:39:08 -0600 Subject: [PATCH 2/7] Fix typo --- data/json/monsters/power_leech.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json index e8f79a5919e1a..b23b696cc390d 100644 --- a/data/json/monsters/power_leech.json +++ b/data/json/monsters/power_leech.json @@ -110,7 +110,7 @@ "type": "MONSTER", "name": "root runner", "description": "This clump of woody vegetation hastily clambers around in a lizard-like fashion. Three translucent scale-leaves stand tall on the backside of the creature, and the thin ridges within them periodically glow through some unknown mean. Its seemingly a symbiote of the nearby alien ferns, and looks ready to defend them with its life.", - "default_faction": "nether",1 + "default_faction": "nether", "species": [ "LEECH_PLANT" ], "volume": "4000 ml", "weight": "6 kg", From 86b3fa6d0cd82f9863aed3158618b01be4ce014b Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Wed, 18 Dec 2019 16:59:41 -0600 Subject: [PATCH 3/7] Apply suggestions from code review Co-Authored-By: Anton Burmistrov Co-Authored-By: BevapDin --- data/json/items/comestibles/carnivore.json | 2 +- data/json/monsters/power_leech.json | 9 ++++----- src/monattack.cpp | 19 ++++++++----------- src/monster.cpp | 2 +- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/data/json/items/comestibles/carnivore.json b/data/json/items/comestibles/carnivore.json index 4122d49d150d8..9b2cbdb8d541a 100644 --- a/data/json/items/comestibles/carnivore.json +++ b/data/json/items/comestibles/carnivore.json @@ -976,7 +976,7 @@ "type": "COMESTIBLE", "name": "leech bark", "name_plural": "scraps of leech bark", - "description": "Dry and though bark matter harvested from an alien plant. It is slightly translucent, and if placed against the light you can distinguish glistening blue veins running through it.", + "description": "Dry and tough bark matter harvested from an alien plant. It is slightly translucent, and if placed against the light you can distinguish glistening blue veins running through it.", "vitamins": [ [ "vitA", 6 ], [ "vitC", 0 ], [ "calcium", 2 ], [ "iron", 8 ], [ "vitB", 6 ], [ "mutant_toxin", 12 ] ] } ] diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json index b23b696cc390d..7b8c80062ca80 100644 --- a/data/json/monsters/power_leech.json +++ b/data/json/monsters/power_leech.json @@ -40,7 +40,7 @@ "id": "mon_leech_stalk", "type": "MONSTER", "name": "leech stalk", - "description": "A resplendent and voluminous alien fern. A faint buzzing sound emanates from it, and the shadow cast by its canopy continuously glows with electric charge.", + "description": "A resplendent and voluminous alien fern. A faint buzzing sound emanates from it, and the shadow cast by its canopy continuously glows with electric charge.", "default_faction": "nether", "species": [ "LEECH_PLANT" ], "volume": "30000 ml", @@ -76,7 +76,7 @@ "id": "mon_leech_pod_cluster", "type": "MONSTER", "name": "leech pod cluster", - "description": "The translucent egg pods of an alien plant, firmly attached by luminous rhizomes. You can barely distinguish a root drone floating withing a cloudy substance.", + "description": "The translucent egg pods of an alien plant, firmly attached by luminous rhizomes. You can barely distinguish a root drone floating within a cloudy substance.", "default_faction": "nether", "species": [ "LEECH_PLANT" ], "volume": "30000 ml", @@ -90,7 +90,6 @@ "morale": 100, "armor_bash": 15, "luminance": 60, - "starting_ammo": { "9mm": 100 }, "special_attacks": [ { "type": "gun", @@ -109,7 +108,7 @@ "id": "mon_leech_root_runner", "type": "MONSTER", "name": "root runner", - "description": "This clump of woody vegetation hastily clambers around in a lizard-like fashion. Three translucent scale-leaves stand tall on the backside of the creature, and the thin ridges within them periodically glow through some unknown mean. Its seemingly a symbiote of the nearby alien ferns, and looks ready to defend them with its life.", + "description": "This clump of woody vegetation hastily clambers around in a lizard-like fashion. Three translucent scale-leaves stand tall on the backside of the creature, and the thin ridges within them periodically glow through some unknown mean. It's seemingly a symbiote of the nearby alien ferns, and looks ready to defend them with its life.", "default_faction": "nether", "species": [ "LEECH_PLANT" ], "volume": "4000 ml", @@ -149,7 +148,7 @@ "id": "mon_leech_root_drone", "type": "MONSTER", "name": "root drone", - "description": "A small bulb with a beak like protuberance, skittishly roaming about under three tendril rhizomes. Dripping and glistening, it resembles a creature newly born rather than a sapling grown from seeds.", + "description": "A small bulb with a beak-like protuberance, skittishly roaming about under three tendril rhizomes. Dripping and glistening, it resembles a creature newly born rather than a sapling grown from seeds.", "default_faction": "nether", "species": [ "LEECH_PLANT" ], "volume": "3000 ml", diff --git a/src/monattack.cpp b/src/monattack.cpp index a9b9483701b7f..4a4ba3cd2807b 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4739,7 +4739,7 @@ bool mattack::evolve_kill_strike( monster *z ) } z->moves -= 100; - bool uncanny = target->uncanny_dodge(); + const bool uncanny = target->uncanny_dodge(); if( uncanny || dodge_check( z, target ) ) { auto msg_type = target == &g->u ? m_warning : m_info; target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), @@ -4770,7 +4770,7 @@ bool mattack::evolve_kill_strike( monster *z ) } else { target->add_msg_player_or_npc( _( "The %1$s attempts to burrow itself into you, but is stopped by your armor!" ), - _( "The %1$s slashes at 's %2$s, but is stopped by its glances off armor!" ), + _( "The %1$s slashes at 's %2$s, but is stopped by their armor!" ), z->name() ); return true; } @@ -4788,7 +4788,7 @@ bool mattack::evolve_kill_strike( monster *z ) } else if( could_see_z ) { add_msg( m_warning, _( "The %1$s burrows within %2$s corpse!" ), old_name, target_name ); } else if( can_see_z_upgrade ) { - add_msg( m_warning, _( "A %1$s emerges from %2$s corpse!" ), target->disp_name(), target_name ); + add_msg( m_warning, _( "A %1$s emerges from %2$s corpse!" ), upgrade_name, target_name ); } } return true; @@ -4799,14 +4799,14 @@ bool mattack::leech_spawner( monster *z ) const bool u_see = g->u.sees( *z ); std::list allies; for( monster &candidate : g->all_monsters() ) { - if( candidate.type->in_species( LEECH_PLANT ) && !candidate.type->has_flag( MF_IMMOBILE ) ) { + if( candidate.in_species( LEECH_PLANT ) && !candidate.has_flag( MF_IMMOBILE ) ) { allies.push_back( &candidate ); } } if( allies.size() > 35 ) { return true; } - int monsters_spawned = rng( 1, 4 ); + const int monsters_spawned = rng( 1, 4 ); const mtype_id monster_type = one_in( 3 ) ? mon_leech_root_runner : mon_leech_root_drone; for( int i = 0; i < monsters_spawned; i++ ) { if( monster *const new_mon = g->place_critter_around( monster_type, z->pos(), 1 ) ) { @@ -4820,7 +4820,7 @@ bool mattack::leech_spawner( monster *z ) z->poly( mon_leech_stalk ); if( u_see ) { add_msg( m_warning, - _( "Resplendent fronds emerge from the still intact pods! " ) ); + _( "Resplendent fronds emerge from the still intact pods!" ) ); } } return true; @@ -4829,10 +4829,10 @@ bool mattack::leech_spawner( monster *z ) bool mattack::mon_leech_evolution( monster *z ) { const bool u_see = g->u.sees( *z ); - const bool is_queen = z->type->has_flag( MF_QUEEN ); + const bool is_queen = z->has_flag( MF_QUEEN ); std::list queens; for( monster &candidate : g->all_monsters() ) { - if( candidate.type->in_species( LEECH_PLANT ) && candidate.type->has_flag( MF_QUEEN ) && + if( candidate.in_species( LEECH_PLANT ) && candidate.has_flag( MF_QUEEN ) && rl_dist( z->pos(), candidate.pos() ) ) { queens.push_back( &candidate ); } @@ -4846,7 +4846,6 @@ bool mattack::mon_leech_evolution( monster *z ) _( "The %s blooms into flowers!" ), z->name() ); } } - } else { if( !queens.empty() ) { if( u_see ) { @@ -4855,13 +4854,11 @@ bool mattack::mon_leech_evolution( monster *z ) } z->poly( mon_leech_stalk ); g->m.spawn_item( z->pos(), "leech_flower", 5, 0, calendar::turn ); - } } return true; } - bool mattack::tindalos_teleport( monster *z ) { Creature *target = z->attack_target(); diff --git a/src/monster.cpp b/src/monster.cpp index dbb942b82e30c..87b36dc00773b 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -318,7 +318,7 @@ int monster::get_upgrade_time() const } // Sets time to upgrade to 0. -void monster:: allow_upgrade() +void monster::allow_upgrade() { upgrade_time = 0; } From ffb5507afa26d628901adce2e192f3516ba486d1 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Wed, 18 Dec 2019 18:40:56 -0600 Subject: [PATCH 4/7] Follow through suggestions --- data/json/monsters/power_leech.json | 28 +++++++++++++++------------- src/monattack.cpp | 10 +++++----- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json index 7b8c80062ca80..fdac101921fdf 100644 --- a/data/json/monsters/power_leech.json +++ b/data/json/monsters/power_leech.json @@ -17,14 +17,14 @@ "morale": 100, "armor_bash": 15, "vision_day": 30, - "vision_night": 30, + "vision_night": 12, "luminance": 200, "special_attacks": [ { "type": "gun", "cooldown": 5, "gun_type": "emp_frond", - "fake_skills": [ [ "gun", 3 ], [ "rifle", 3 ] ], + "fake_skills": [ [ "gun", 3 ], [ "pistol", 3 ] ], "ranges": [ [ 0, 12, "DEFAULT" ] ], "description": "Lightning arcs towards you!" }, @@ -32,6 +32,7 @@ [ "MON_LEECH_EVOLUTION", 40 ], [ "PARROT", 40 ] ], + "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": { }, "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE", "QUEEN", "HARDTOSHOOT" ] @@ -54,23 +55,23 @@ "morale": 100, "armor_bash": 15, "vision_day": 30, - "vision_night": 30, + "vision_night": 8, "luminance": 200, "special_attacks": [ { "type": "gun", "cooldown": 15, "gun_type": "emp_frond", - "fake_skills": [ [ "gun", 2 ], [ "rifle", 2 ] ], + "fake_skills": [ [ "gun", 2 ], [ "pistol", 2 ] ], "ranges": [ [ 0, 12, "DEFAULT" ] ], "description": "Lightning arcs towards you!" }, - [ "MON_LEECH_EVOLUTION", 30 ], - [ "PARROT", 40 ] + [ "MON_LEECH_EVOLUTION", 30 ] ], + "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": { }, "death_function": [ "NORMAL" ], - "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "IMMOBILE", "NO_BREATHE", "HARDTOSHOOT" ] + "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE", "HARDTOSHOOT" ] }, { "id": "mon_leech_pod_cluster", @@ -126,7 +127,7 @@ "armor_bash": 15, "luminance": 60, "vision_day": 30, - "vision_night": 10, + "vision_night": 5, "melee_damage": [ { "damage_type": "electric", "amount": 4 } ], "upgrades": { "half_life": 9999, "into": "mon_leech_stalk" }, "special_attacks": [ @@ -134,15 +135,16 @@ "type": "gun", "cooldown": 15, "gun_type": "emp_frond", - "fake_skills": [ [ "gun", 1 ], [ "rifle", 1 ] ], + "fake_skills": [ [ "gun", 1 ], [ "pistol", 1 ] ], "ranges": [ [ 0, 2, "DEFAULT" ] ], "description": "Lightning arcs towards you!" }, [ "EVOLVE_KILL_STRIKE", 3 ] ], + "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": { }, "death_function": [ "NORMAL" ], - "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "NO_BREATHE", "HARDTOSHOOT" ] + "flags": [ "SEES", "NOHEAD", "NO_BREATHE", "HARDTOSHOOT" ] }, { "id": "mon_leech_root_drone", @@ -166,7 +168,7 @@ "armor_bash": 15, "luminance": 60, "vision_day": 30, - "vision_night": 10, + "vision_night": 5, "melee_damage": [ { "damage_type": "electric", "amount": 3 } ], "upgrades": { "half_life": 999, "into": "mon_leech_pod_cluster" }, "special_attacks": [ @@ -174,7 +176,7 @@ "type": "gun", "cooldown": 15, "gun_type": "emp_frond", - "fake_skills": [ [ "gun", 1 ], [ "rifle", 1 ] ], + "fake_skills": [ [ "gun", 1 ], [ "pistol", 1 ] ], "ranges": [ [ 0, 2, "DEFAULT" ] ], "description": "Lightning arcs towards you!" }, @@ -182,6 +184,6 @@ ], "death_drops": { }, "death_function": [ "NORMAL" ], - "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "NO_BREATHE", "HARDTOSHOOT" ] + "flags": [ "SEES", "NOHEAD", "NO_BREATHE", "HARDTOSHOOT" ] } ] diff --git a/src/monattack.cpp b/src/monattack.cpp index 4a4ba3cd2807b..8ab7d917debda 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4753,8 +4753,6 @@ bool mattack::evolve_kill_strike( monster *z ) } return true; } - const std::string old_name = z->name(); - const bool could_see_z = g->u.sees( *z ); tripoint const target_pos = target->pos(); const std::string target_name = target->disp_name(); damage_instance damage( z->type->melee_damage ); @@ -4770,12 +4768,14 @@ bool mattack::evolve_kill_strike( monster *z ) } else { target->add_msg_player_or_npc( _( "The %1$s attempts to burrow itself into you, but is stopped by your armor!" ), - _( "The %1$s slashes at 's %2$s, but is stopped by their armor!" ), + _( "The %1$s slashes at 's torso, but is stopped by their armor!" ), z->name() ); return true; } if( target->is_dead_state() && g->is_empty( target_pos ) && target->made_of_any( Creature::cmat_flesh ) ) { + const std::string old_name = z->name(); + const bool could_see_z = g->u.sees( *z ); z->allow_upgrade(); z->try_upgrade( false ); z->setpos( target_pos ); @@ -4803,7 +4803,7 @@ bool mattack::leech_spawner( monster *z ) allies.push_back( &candidate ); } } - if( allies.size() > 35 ) { + if( allies.size() > 45 ) { return true; } const int monsters_spawned = rng( 1, 4 ); @@ -4833,7 +4833,7 @@ bool mattack::mon_leech_evolution( monster *z ) std::list queens; for( monster &candidate : g->all_monsters() ) { if( candidate.in_species( LEECH_PLANT ) && candidate.has_flag( MF_QUEEN ) && - rl_dist( z->pos(), candidate.pos() ) ) { + rl_dist( z->pos(), candidate.pos() ) > 35 ) { queens.push_back( &candidate ); } } From 3fcc65b2094b4ae4134bb5e91e5cea2a1a6e6ae5 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Wed, 18 Dec 2019 19:45:45 -0600 Subject: [PATCH 5/7] Reword alien frond description --- data/json/items/comestibles/carnivore.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/comestibles/carnivore.json b/data/json/items/comestibles/carnivore.json index 9b2cbdb8d541a..5be58a68d401c 100644 --- a/data/json/items/comestibles/carnivore.json +++ b/data/json/items/comestibles/carnivore.json @@ -939,7 +939,7 @@ "type": "COMESTIBLE", "name": "alien fronds", "use_action": "POISON", - "description": "The fleshy fronds harvested from an alien plant. The tiny membranous leaves attached and rigid and gut-like stem are certainly poisonous, and yet they have a paradoxically pleasant and inviting sweet smell. Might be non-vegan.", + "description": "The fleshy fronds harvested from an alien plant. Eating these membranous leaves and gut-like stems is likely a terrible idea, and yet they have a paradoxically pleasant and inviting sweet smell. Might be non-vegan.", "fun": 15, "stim": 3, "vitamins": [ [ "vitA", 6 ], [ "vitC", 2 ], [ "calcium", 0 ], [ "iron", 8 ], [ "vitB", 6 ], [ "mutant_toxin", 8 ] ] From adb9e666fc37ffb8e74e82d43a87883a8e10d557 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Thu, 19 Dec 2019 18:15:14 -0600 Subject: [PATCH 6/7] Correct monattack logic --- src/monattack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/monattack.cpp b/src/monattack.cpp index 8ab7d917debda..ba9aa405ef6bd 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4833,7 +4833,7 @@ bool mattack::mon_leech_evolution( monster *z ) std::list queens; for( monster &candidate : g->all_monsters() ) { if( candidate.in_species( LEECH_PLANT ) && candidate.has_flag( MF_QUEEN ) && - rl_dist( z->pos(), candidate.pos() ) > 35 ) { + rl_dist( z->pos(), candidate.pos() ) < 35 ) { queens.push_back( &candidate ); } } From df0f9bae21a3c915c8a81fd2d60007fc6f807c7b Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Thu, 19 Dec 2019 19:48:50 -0600 Subject: [PATCH 7/7] Finalize leech pod monster family --- data/json/monsters/power_leech.json | 19 ++++++++++++++----- src/monattack.cpp | 23 +++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json index fdac101921fdf..72e88f07eb877 100644 --- a/data/json/monsters/power_leech.json +++ b/data/json/monsters/power_leech.json @@ -10,6 +10,7 @@ "weight": "40 kg", "hp": 100, "speed": 100, + "diff": 30, "material": [ "flesh" ], "symbol": "K", "color": "light_cyan", @@ -26,7 +27,8 @@ "gun_type": "emp_frond", "fake_skills": [ [ "gun", 3 ], [ "pistol", 3 ] ], "ranges": [ [ 0, 12, "DEFAULT" ] ], - "description": "Lightning arcs towards you!" + "targeting_sound": "a faint buzz", + "description": "Lightning arcs from the leech blossom!" }, [ "LEECH_SPAWNER", 25 ], [ "MON_LEECH_EVOLUTION", 40 ], @@ -48,6 +50,7 @@ "weight": "40 kg", "hp": 40, "speed": 100, + "diff": 20, "material": [ "flesh" ], "symbol": "y", "color": "light_blue", @@ -64,7 +67,8 @@ "gun_type": "emp_frond", "fake_skills": [ [ "gun", 2 ], [ "pistol", 2 ] ], "ranges": [ [ 0, 12, "DEFAULT" ] ], - "description": "Lightning arcs towards you!" + "targeting_sound": "a faint buzz", + "description": "Lightning arcs from the leech stalk!" }, [ "MON_LEECH_EVOLUTION", 30 ] ], @@ -84,6 +88,7 @@ "weight": "60 kg", "hp": 40, "speed": 100, + "diff": 20, "material": [ "flesh" ], "symbol": "g", "color": "white", @@ -97,7 +102,8 @@ "cooldown": 15, "gun_type": "emp_frond", "ranges": [ [ 0, 1, "DEFAULT" ] ], - "description": "Lightning arcs towards you!" + "targeting_sound": "a faint buzz", + "description": "Lightning arcs from the pod cluster!" }, [ "LEECH_SPAWNER", 35 ] ], @@ -116,6 +122,7 @@ "weight": "6 kg", "hp": 40, "speed": 120, + "diff": 20, "material": [ "flesh" ], "symbol": "m", "color": "blue", @@ -137,7 +144,8 @@ "gun_type": "emp_frond", "fake_skills": [ [ "gun", 1 ], [ "pistol", 1 ] ], "ranges": [ [ 0, 2, "DEFAULT" ] ], - "description": "Lightning arcs towards you!" + "targeting_sound": "a faint buzz", + "description": "Sparks fly from the root runner!" }, [ "EVOLVE_KILL_STRIKE", 3 ] ], @@ -178,7 +186,8 @@ "gun_type": "emp_frond", "fake_skills": [ [ "gun", 1 ], [ "pistol", 1 ] ], "ranges": [ [ 0, 2, "DEFAULT" ] ], - "description": "Lightning arcs towards you!" + "targeting_sound": "a faint buzz", + "description": "Lightning arcs from the root pod!" }, [ "EVOLVE_KILL_STRIKE", 6 ] ], diff --git a/src/monattack.cpp b/src/monattack.cpp index ba9aa405ef6bd..914d39d991d2d 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4814,13 +4814,13 @@ bool mattack::leech_spawner( monster *z ) add_msg( m_warning, _( "An egg pod ruptures and a %s crawls out from the remains!" ), new_mon->name() ); } - } - } - if( one_in( 25 ) ) { - z->poly( mon_leech_stalk ); - if( u_see ) { - add_msg( m_warning, - _( "Resplendent fronds emerge from the still intact pods!" ) ); + if( one_in( 25 ) ) { + z->poly( mon_leech_stalk ); + if( u_see ) { + add_msg( m_warning, + _( "Resplendent fronds emerge from the still intact pods!" ) ); + } + } } } return true; @@ -4846,15 +4846,6 @@ bool mattack::mon_leech_evolution( monster *z ) _( "The %s blooms into flowers!" ), z->name() ); } } - } else { - if( !queens.empty() ) { - if( u_see ) { - add_msg( m_warning, - _( "The %s flowers whiter and fall!" ), z->name() ); - } - z->poly( mon_leech_stalk ); - g->m.spawn_item( z->pos(), "leech_flower", 5, 0, calendar::turn ); - } } return true; }