From df96b6fec1ed676e162c693279c69d9254ac599d Mon Sep 17 00:00:00 2001 From: joveeater Date: Sat, 17 Dec 2022 12:59:25 +0000 Subject: [PATCH] Turrets target moving cars (#2165) * Make turrets shoot cars * Including reversing vehicles * Better range handling --- data/json/monsters/defense_bot.json | 2 ++ data/json/monsters/mi-go.json | 1 + data/json/monsters/turrets.json | 5 +++ src/mattack_actors.cpp | 49 ++++++++++++++++++++++++++--- src/mattack_actors.h | 3 ++ 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/data/json/monsters/defense_bot.json b/data/json/monsters/defense_bot.json index ff125bfb19c3..b2ef5c2ab28d 100644 --- a/data/json/monsters/defense_bot.json +++ b/data/json/monsters/defense_bot.json @@ -101,6 +101,7 @@ "ranges": [ [ 0, 30, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, + "target_moving_vehicles": true, "laser_lock": false, "no_crits": true, "targeting_cost": 200, @@ -150,6 +151,7 @@ "ranges": [ [ 0, 20, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, + "target_moving_vehicles": true, "laser_lock": false, "no_crits": true, "targeting_cost": 200, diff --git a/data/json/monsters/mi-go.json b/data/json/monsters/mi-go.json index 8471ddeadf9a..4a9c236b7bb8 100644 --- a/data/json/monsters/mi-go.json +++ b/data/json/monsters/mi-go.json @@ -292,6 +292,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" ] ] } diff --git a/data/json/monsters/turrets.json b/data/json/monsters/turrets.json index dad50eccd5e7..df9783c632dc 100644 --- a/data/json/monsters/turrets.json +++ b/data/json/monsters/turrets.json @@ -55,6 +55,7 @@ { "type": "gun", "cooldown": 1, + "target_moving_vehicles": true, "gun_type": "laser_cannon_turret_fake", "fake_skills": [ [ "gun", 4 ], [ "rifle", 8 ] ], "ranges": [ [ 0, 30, "DEFAULT" ] ], @@ -107,6 +108,7 @@ "ranges": [ [ 0, 30, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, + "target_moving_vehicles": true, "laser_lock": false, "no_crits": true, "targeting_cost": 200, @@ -159,6 +161,7 @@ "ranges": [ [ 0, 16, "AUTO" ], [ 17, 32, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, + "target_moving_vehicles": true, "laser_lock": false, "no_crits": true, "targeting_cost": 200, @@ -222,6 +225,7 @@ "ranges": [ [ 0, 20, "AUTO" ], [ 21, 36, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, + "target_moving_vehicles": true, "laser_lock": false, "no_crits": true, "targeting_cost": 200, @@ -285,6 +289,7 @@ "ranges": [ [ 0, 60, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, + "target_moving_vehicles": true, "laser_lock": false, "no_crits": true, "targeting_cost": 200, diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index 1e95da3fa810..225fa3ecb630 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -27,6 +27,8 @@ #include "rng.h" #include "sounds.h" #include "translations.h" +#include "vehicle.h" +#include "vpart_range.h" static const efftype_id effect_badpoison( "badpoison" ); static const efftype_id effect_bite( "bite" ); @@ -457,6 +459,8 @@ void gun_actor::load_internal( const JsonObject &obj, const std::string & ) obj.get_bool( "laser_lock", laser_lock ); + obj.read( "target_moving_vehicles", target_moving_vehicles ); + obj.read( "require_sunlight", require_sunlight ); no_crits = obj.get_bool( "no_crits", no_crits ); @@ -476,9 +480,25 @@ 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() ) { + 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(); @@ -494,19 +514,38 @@ bool gun_actor::call( monster &z ) const } return false; } - + aim_at = target->pos(); } else { target = z.attack_target(); if( !target || !z.sees( *target ) ) { - 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; + } + for( const vpart_reference &vp : veh->get_avail_parts( "CONTROLS" ) ) { + if( z.sees( vp.pos() ) ) { + aim_at = vp.pos(); + untargeted = true; + } + } + if( !untargeted ) { + untargeted = true; + aim_at = veh->global_pos3(); + } + } else { + aim_at = target->pos(); } } - int dist = rl_dist( z.pos(), target->pos() ); + int dist = rl_dist( z.pos(), aim_at ); 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; diff --git a/src/mattack_actors.h b/src/mattack_actors.h index 8e1000984ce2..93b82991b187 100644 --- a/src/mattack_actors.h +++ b/src/mattack_actors.h @@ -161,6 +161,9 @@ 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 */