Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monsters will now fire at moving vehicles #64801

Merged
merged 14 commits into from
Apr 7, 2023
2 changes: 2 additions & 0 deletions data/json/monsters/defense_bot.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
"ranges": [ [ 0, 30, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 200,
"targeting_timeout_extend": -10,
Expand Down Expand Up @@ -175,6 +176,7 @@
"ranges": [ [ 0, 20, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 200,
"targeting_timeout_extend": -10,
Expand Down
1 change: 1 addition & 0 deletions data/json/monsters/drones.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
"ranges": [ [ 0, 50, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": true,
"targeting_cost": 700,
"targeting_timeout_extend": -10,
Expand Down
3 changes: 3 additions & 0 deletions data/json/monsters/feral_humans.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"fake_per": 10,
"ranges": [ [ 2, 35, "DEFAULT" ] ],
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The mad militiaman fires their rifle!"
}
],
Expand Down Expand Up @@ -776,6 +777,7 @@
"//": "(ferals don't care about max-effective range.)",
"ranges": [ [ 2, 25, "DEFAULT" ] ],
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The feral biker fires their shotgun!"
}
],
Expand Down Expand Up @@ -999,6 +1001,7 @@
"fake_per": 10,
"ranges": [ [ 2, 14, "DEFAULT" ] ],
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The feral officer fires their M18!"
}
],
Expand Down
1 change: 1 addition & 0 deletions data/json/monsters/mi-go.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@
"fake_dex": 8,
"fake_per": 8,
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The mi-go scout fires its weapon!",
"ranges": [ [ 2, 30, "DEFAULT" ] ]
}
Expand Down
1 change: 1 addition & 0 deletions data/json/monsters/robofac_robots.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"cooldown": 1,
"gun_type": "v29_turret",
"fake_skills": [ [ "gun", 4 ], [ "pistol", 4 ] ],
"target_moving_vehicles": true,
"ranges": [ [ 0, 30, "DEFAULT" ] ]
}
],
Expand Down
3 changes: 3 additions & 0 deletions data/json/monsters/turrets.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
"ranges": [ [ 0, 40, "AUTO" ], [ 41, 110, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 200,
"targeting_timeout_extend": -10,
Expand Down Expand Up @@ -175,6 +176,7 @@
"ranges": [ [ 0, 36, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 200,
"targeting_timeout_extend": -10,
Expand Down Expand Up @@ -235,6 +237,7 @@
"ranges": [ [ 0, 60, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 200,
"targeting_timeout_extend": -10,
Expand Down
1 change: 1 addition & 0 deletions data/json/monsters/yrax.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"ranges": [ [ 0, 25, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": true,
"targeting_sound": "a fast sequence of clicking tones.",
"targeting_volume": 50,
Expand Down
1 change: 1 addition & 0 deletions data/json/monsters/zed-animal.json
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@
"fake_dex": 4,
"fake_per": 4,
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The vicious vicuña spits a glob of acid!",
"ranges": [ [ 2, 10, "DEFAULT" ] ]
},
Expand Down
1 change: 1 addition & 0 deletions data/json/monsters/zed_acid.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"fake_dex": 8,
"fake_per": 8,
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The corrosive zombie spits a glob of acid!",
"ranges": [ [ 2, 10, "DEFAULT" ] ]
},
Expand Down
2 changes: 2 additions & 0 deletions data/json/monsters/zed_soldiers.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"fake_dex": 8,
"fake_per": 8,
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The %s launches a corrosive dart!",
"ranges": [ [ 2, 20, "DEFAULT" ] ]
}
Expand Down Expand Up @@ -180,6 +181,7 @@
"fake_dex": 8,
"fake_per": 8,
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The %s launches a hail of corrosive darts!",
"ranges": [ [ 2, 8, "DEFAULT" ] ]
}
Expand Down
1 change: 1 addition & 0 deletions data/mods/DinoMod/monsters/dinosaur_CBM.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"ranges": [ [ 0, 30, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 1,
"targeting_timeout_extend": -1,
Expand Down
1 change: 1 addition & 0 deletions data/mods/DinoMod/monsters/zed-dinosaur_CBM.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"ranges": [ [ 0, 30, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 1,
"targeting_timeout_extend": -1,
Expand Down
3 changes: 3 additions & 0 deletions data/mods/Xedra_Evolved/monsters/bloodsuckers.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
"fake_per": 10,
"ranges": [ [ 2, 14, "DEFAULT" ] ],
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The renfield fires their Glock!"
}
],
Expand Down Expand Up @@ -253,6 +254,7 @@
"//": "(ferals don't care about max-effective range.)",
"ranges": [ [ 2, 25, "DEFAULT" ] ],
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The renfield fires their shotgun!"
}
],
Expand Down Expand Up @@ -318,6 +320,7 @@
"no_ammo_sound": "hiss!",
"ranges": [ [ 0, 10, "DEFAULT" ] ],
"require_targeting_player": false,
"target_moving_vehicles": true,
"description": "The renfield shoots their flamethrower!"
}
],
Expand Down
1 change: 1 addition & 0 deletions data/mods/Xedra_Evolved/monsters/exodii.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"ranges": [ [ 4, 41, "DEFAULT" ] ],
"require_targeting_npc": true,
"require_targeting_monster": true,
"target_moving_vehicles": true,
"laser_lock": false,
"targeting_cost": 400,
"targeting_timeout_extend": -10,
Expand Down
1 change: 1 addition & 0 deletions doc/MONSTER_SPECIAL_ATTACKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ The monster fires a gun at a target. If the monster is friendly, it will avoid
| `require_targeting_player` | If true, the monster will need to "target" the player, wasting `targeting_cost` moves, putting the attack on cooldown and making warning sounds, unless it attacked something that needs to be targeted recently. Gives "grace period" to player. |
| `require_targeting_npc` | As above, but with NPCs. |
| `require_targeting_monster` | As above, but with monsters. |
| 'target_moving_vehicles' | If true, the monster will "target" moving vehicles even if it cannot see the player.
| `targeting_timeout` | Targeting status will be applied for this many turns. Note that targeting applies to turret, not targets. |
| `targeting_timeout_extend` | Successfully attacking will extend the targeting for this many turns. Can be negative. |
| `targeting_cost` | Move cost of targeting the player. Only applied if attacking the player and didn't target player within last 5 turns. |
Expand Down
73 changes: 67 additions & 6 deletions src/mattack_actors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
#include "rng.h"
#include "sounds.h"
#include "translations.h"
#include "vehicle.h"
#include "viewer.h"
#include "vpart_range.h"


static const efftype_id effect_badpoison( "badpoison" );
static const efftype_id effect_bite( "bite" );
Expand Down Expand Up @@ -809,6 +812,8 @@ void gun_actor::load_internal( const JsonObject &obj, const std::string & )

laser_lock = obj.get_bool( "laser_lock", false );

obj.read( "target_moving_vehicles", target_moving_vehicles );

obj.read( "require_sunlight", require_sunlight );
}

Expand All @@ -828,9 +833,32 @@ int gun_actor::get_max_range() const
return max_range;
}

static vehicle *find_target_vehicle( monster &z, int range )
{
map &here = get_map();
vehicle *chosen = nullptr;
for( wrapped_vehicle &v : here.get_vehicles() ) {
if( !z.sees( v.pos ) ) {
continue;
}
if( !fov_3d && v.pos.z != z.pos().z ) {
continue;
}
int new_dist = rl_dist( z.pos(), v.pos );
if( v.v->velocity != 0 && new_dist < range ) {
chosen = v.v;
range = new_dist;
}
}
return chosen;
}


bool gun_actor::call( monster &z ) const
{
Creature *target;
tripoint aim_at;
bool untargeted = false;

if( z.friendly ) {
int max_range = get_max_range();
Expand All @@ -847,20 +875,53 @@ bool gun_actor::call( monster &z ) const
}
return false;
}

aim_at = target->pos();
} else {
target = z.attack_target();
if( !target || !z.sees( *target ) || ( !target->is_monster() && !z.aggro_character ) ) {
return false;
//return false;
if( !target_moving_vehicles ) {
return false;
}
//No living targets, try to find a moving car
vehicle *veh = find_target_vehicle( z, get_max_range() );
if( !veh ) {
return false;
}
std::vector<tripoint> valid_targets;
std::vector<tripoint> visible_points;
for( const tripoint &p : veh->get_points() ) {
if( !z.sees( p ) ) {
continue;
}
visible_points.push_back( p );
if( veh->part_with_feature( p, VPFLAG_CONTROLS, true ) >= 0 &&
veh->part_with_feature( p, VPFLAG_ENGINE, true ) >= 0 &&
veh->part_with_feature( p, VPFLAG_WHEEL, true ) >= 0) {
valid_targets.push_back( p );
}
}
if( !targets.empty() ) {
std::shuffle( valid_targets.begin(), valid_targets.end(), rng_get_seed() );
aim_at = valid_targest.back();
} else if( !visible_points.empty() ) {
std::shuffle( visible_points.begin(), visible_points.end(), rng_get_seed() );
aim_at = visible_points.back();
} else {
return false;
}
}
}

int dist = rl_dist( z.pos(), target->pos() );
add_msg_debug( debugmode::DF_MATTACK, "Target %s at range %d", target->disp_name(), dist );
int dist = rl_dist( z.pos(), aim_at );
if( target ) {
add_msg_debug( debugmode::DF_MATTACK, "Target %s at range %d", target->disp_name(), dist );
}

for( const auto &e : ranges ) {
if( dist >= e.first.first && dist <= e.first.second ) {
if( try_target( z, *target ) ) {
shoot( z, target->pos(), e.second );
if( untargeted || try_target( z, *target ) ) {
shoot( z, aim_at, e.second );
}
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/mattack_actors.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ class gun_actor : public mattack_actor
/** Number of moves required for each attack */
int move_cost = 150;

/** Should moving vehicles be targeted */
bool target_moving_vehicles = false;
/*@{*/
/** Turrets may need to expend moves targeting before firing on certain targets */

Expand Down