未验证 提交 22e5a184 编写于 作者: D Dillon Matchett 提交者: GitHub

Basic EMF Detector (#54428)

Co-authored-by: NAnton Burmistrov <Night_Pryanik@mail.ru>
上级 d892fd8f
......@@ -1591,5 +1591,17 @@
"display_items": false,
"display_field": false,
"looks_like": "fd_electricity"
},
{
"id": "fd_direction",
"type": "field_type",
"intensity_levels": [ { "name": "Detected something", "sym": "." } ],
"priority": 10,
"half_life": "1 seconds",
"accelerated_decay": true,
"display_field": true,
"display_items": true,
"phase": "gas",
"looks_like": "footstep"
}
]
......@@ -474,6 +474,16 @@
"id": "ELEC_CHAINSAW_OFF",
"name": { "str": "Turn on" }
},
{
"type": "item_action",
"id": "EMF_PASSIVE_OFF",
"name": { "str": "Turn on" }
},
{
"type": "item_action",
"id": "EMF_PASSIVE_ON",
"name": { "str": "Turn off" }
},
{
"type": "item_action",
"id": "EXTINGUISHER",
......
......@@ -8,6 +8,7 @@
{ "item": "cable", "prob": 25, "count": [ 2, 4 ] },
{ "item": "voltmeter", "prob": 40, "charges": [ 0, 100 ] },
{ "item": "multimeter", "prob": 40, "charges": [ 0, 100 ] },
{ "item": "emf_detector", "prob": 20, "charges": [ 0, 100 ] },
[ "light_detector", 5 ],
[ "amplifier", 40 ],
[ "antenna", 40 ],
......
......@@ -426,6 +426,46 @@
"use_action": [ "NOISE_EMITTER_ON" ],
"flags": [ "RADIO_MODABLE", "RADIO_INVOKE_PROC", "TRADER_AVOID", "WATER_BREAK" ]
},
{
"id": "emf_detector",
"//": "Based off the TRIFIELD EMF Meter Model TF2",
"type": "TOOL",
"name": { "str": "EMF detector (off)", "str_pl": "EMF detectors (off)" },
"description": "This device detects and reads out different electromagnetic wave lengths. It beeps with proximity and is sensitive enough you could use it to get a sense of direction.",
"weight": "240 g",
"volume": "355 ml",
"price": 0,
"price_postapoc": 50,
"to_hit": -1,
"bashing": 6,
"material": [ "plastic", "aluminum" ],
"symbol": ";",
"color": "yellow",
"ammo": [ "battery" ],
"charges_per_use": 1,
"use_action": [ "EMF_PASSIVE_OFF" ],
"flags": [ "WATER_BREAK" ],
"pocket_data": [
{
"pocket_type": "MAGAZINE_WELL",
"rigid": true,
"flag_restriction": [ "BATTERY_LIGHT", "BATTERY_ULTRA_LIGHT" ],
"default_magazine": "light_battery_cell"
}
]
},
{
"id": "emf_detector_on",
"copy-from": "emf_detector",
"type": "TOOL",
"name": { "str": "EMF detector (on)", "str_pl": "EMF detectors (on)" },
"description": "This device detects and reads out different wave lengths. It currently is humming and beeps with proximity. It is sensitive enough you could use it to get a sense of direction.",
"//": "lasts 12 hours with backlight off",
"power_draw": 6000,
"revert_to": "emf_detector",
"use_action": [ "EMF_PASSIVE_ON" ],
"flags": [ "TRADER_AVOID", "WATER_BREAK" ]
},
{
"id": "portable_game",
"type": "TOOL",
......
......@@ -364,7 +364,6 @@ static const skill_id skill_swimming( "swimming" );
static const skill_id skill_throw( "throw" );
static const species_id species_HUMAN( "HUMAN" );
static const species_id species_ROBOT( "ROBOT" );
static const start_location_id start_location_sloc_shelter( "sloc_shelter" );
......@@ -5540,8 +5539,7 @@ float Character::active_light() const
bool Character::sees_with_specials( const Creature &critter ) const
{
// electroreceptors grants vision of robots and electric monsters through walls
if( has_trait( trait_ELECTRORECEPTORS ) &&
( critter.in_species( species_ROBOT ) || critter.has_flag( MF_ELECTRIC ) ) ) {
if( has_trait( trait_ELECTRORECEPTORS ) && critter.is_electrical() ) {
return true;
}
......@@ -10507,6 +10505,12 @@ bool Character::is_hallucination() const
return false;
}
bool Character::is_electrical() const
{
// for now this is false. In the future should have rules
return false;
}
void Character::set_underwater( bool u )
{
if( underwater != u ) {
......
......@@ -686,6 +686,9 @@ class Character : public Creature, public visitable
void recalc_speed_bonus();
void set_underwater( bool );
bool is_hallucination() const override;
// true if the character produces electrical radiation
bool is_electrical() const override;
/** Returns the penalty to speed from thirst */
static int thirst_speed_penalty( int thirst );
/** Returns the effect of pain on stats */
......
......@@ -512,6 +512,10 @@ class Creature : public viewer
virtual bool has_weapon() const = 0;
virtual bool is_hallucination() const = 0;
// returns true if the creature has an electric field
virtual bool is_electrical() const = 0;
// returns true if health is zero or otherwise should be dead
virtual bool is_dead_state() const = 0;
......
......@@ -1344,6 +1344,8 @@ void Item_factory::init()
add_iuse( "EBOOKREAD", &iuse::ebookread );
add_iuse( "ELEC_CHAINSAW_OFF", &iuse::elec_chainsaw_off );
add_iuse( "ELEC_CHAINSAW_ON", &iuse::elec_chainsaw_on );
add_iuse( "EMF_PASSIVE_OFF", &iuse::emf_passive_off );
add_iuse( "EMF_PASSIVE_ON", &iuse::emf_passive_on );
add_iuse( "EXTINGUISHER", &iuse::extinguisher );
add_iuse( "EYEDROPS", &iuse::eyedrops );
add_iuse( "FILL_PIT", &iuse::fill_pit );
......
......@@ -256,6 +256,8 @@ static const itype_id itype_data_card( "data_card" );
static const itype_id itype_detergent( "detergent" );
static const itype_id itype_e_handcuffs( "e_handcuffs" );
static const itype_id itype_ecig( "ecig" );
static const itype_id itype_emf_detector( "emf_detector" );
static const itype_id itype_emf_detector_on( "emf_detector_on" );
static const itype_id itype_fire( "fire" );
static const itype_id itype_firecracker_act( "firecracker_act" );
static const itype_id itype_firecracker_pack_act( "firecracker_pack_act" );
......@@ -391,6 +393,8 @@ static const vitamin_id vitamin_redcells( "redcells" );
static const vproto_id vehicle_prototype_none( "none" );
static const weather_type_id weather_portal_storm( "portal_storm" );
// how many characters per turn of radio
static constexpr int RADIO_PER_TURN = 25;
......@@ -2619,6 +2623,77 @@ cata::optional<int> iuse::noise_emitter_on( Character *p, item *it, bool t, cons
return it->type->charges_to_use();
}
cata::optional<int> iuse::emf_passive_off( Character *p, item *it, bool, const tripoint & )
{
if( !it->ammo_sufficient( p ) ) {
p->add_msg_if_player( _( "It's dead." ) );
return cata::nullopt;
} else {
p->add_msg_if_player( _( "You turn the EMF detector on." ) );
it->convert( itype_emf_detector_on ).active = true;
}
return it->type->charges_to_use();
}
cata::optional<int> iuse::emf_passive_on( Character *p, item *it, bool t, const tripoint &pos )
{
if( t ) { // Normal use
// need to calculate distance to closest electrical thing
// set distance as farther than the radius
const int max = 10;
int distance = max + 1;
creature_tracker &creatures = get_creature_tracker();
map &here = get_map();
// can't get a reading during a portal storm
if( get_weather().weather_id == weather_portal_storm ) {
sounds::sound( pos, 6, sounds::sound_t::alarm, _( "BEEEEE-CHHHHHHH-eeEEEEEEE-CHHHHHHHHHHHH" ), true,
"tool", "emf_detector" );
// skip continuing to check for locations
return it->type->charges_to_use();
}
for( const auto &loc : closest_points_first( pos, max ) ) {
const Creature *critter = creatures.creature_at( loc );
// if the creature exists and is either a robot or electric
bool found = critter != nullptr && critter->is_electrical();
// check for an electrical field
if( !found ) {
for( const auto &fd : here.field_at( loc ) ) {
if( fd.first->has_elec ) {
found = true;
break;
}
}
}
// if an electrical field or creature is nearby
if( found ) {
distance = rl_dist( pos, loc );
if( distance <= 3 ) {
sounds::sound( pos, 4, sounds::sound_t::alarm, _( "BEEEEEEP BEEEEEEP" ), true, "tool",
"emf_detector" );
} else if( distance <= 7 ) {
sounds::sound( pos, 3, sounds::sound_t::alarm, _( "BEEP BEEP" ), true, "tool",
"emf_detector" );
} else if( distance <= 10 ) {
sounds::sound( pos, 2, sounds::sound_t::alarm, _( "beep… beep" ), true, "tool",
"emf_detector" );
}
// skip continuing to check for locations
return it->type->charges_to_use();
}
}
} else { // Turning it off
p->add_msg_if_player( _( "The noise of your EMF detector slows to a halt." ) );
it->convert( itype_emf_detector ).active = false;
}
return it->type->charges_to_use();
}
cata::optional<int> iuse::ma_manual( Character *p, item *it, bool, const tripoint & )
{
// [CR] - should NPCs just be allowed to learn this stuff? Just like that?
......
......@@ -109,6 +109,8 @@ cata::optional<int> ehandcuffs( Character *, item *, bool, const tripoint & );
cata::optional<int> einktabletpc( Character *, item *, bool, const tripoint & );
cata::optional<int> elec_chainsaw_off( Character *, item *, bool, const tripoint & );
cata::optional<int> elec_chainsaw_on( Character *, item *, bool, const tripoint & );
cata::optional<int> emf_passive_off( Character *, item *, bool, const tripoint & );
cata::optional<int> emf_passive_on( Character *, item *, bool, const tripoint & );
cata::optional<int> extinguisher( Character *, item *, bool, const tripoint & );
cata::optional<int> fill_pit( Character *, item *, bool, const tripoint & );
cata::optional<int> firecracker( Character *, item *, bool, const tripoint & );
......
......@@ -127,6 +127,7 @@ static const mfaction_str_id monfaction_bee( "bee" );
static const mfaction_str_id monfaction_wasp( "wasp" );
static const species_id species_AMPHIBIAN( "AMPHIBIAN" );
static const species_id species_CYBORG( "CYBORG" );
static const species_id species_FISH( "FISH" );
static const species_id species_FUNGUS( "FUNGUS" );
static const species_id species_LEECH_PLANT( "LEECH_PLANT" );
......@@ -2871,6 +2872,11 @@ bool monster::is_hallucination() const
return hallucination;
}
bool monster::is_electrical() const
{
return in_species( species_ROBOT ) || has_flag( MF_ELECTRIC ) || in_species( species_CYBORG );
}
field_type_id monster::bloodType() const
{
if( is_hallucination() ) {
......
......@@ -463,6 +463,8 @@ class monster : public Creature
bool is_hallucination() const override; // true if the monster isn't actually real
bool is_electrical() const override; // true if the monster produces electric radiation
field_type_id bloodType() const override;
field_type_id gibType() const override;
......
......@@ -893,6 +893,13 @@ class npc : public Character
return hallucination;
}
// true if the NPC produces electrical radiation
// TODO: make this way less hard coded
bool is_electrical() const override {
// only beep on Rubik for now
return has_trait( trait_id( "EXODII_BODY_1" ) );
}
// Ally of or traveling with p
bool is_friendly( const Character &p ) const;
// Leading the player
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册