Merge pull request #10337 from mwerezak/turret-aiming

Fixes #10258
This commit is contained in:
Chinsky
2015-07-29 16:18:42 +03:00
11 changed files with 47 additions and 20 deletions

View File

@@ -919,7 +919,7 @@ FIRE ALARM
/obj/machinery/firealarm/attack_ai(mob/user as mob) /obj/machinery/firealarm/attack_ai(mob/user as mob)
return src.attack_hand(user) return src.attack_hand(user)
/obj/machinery/firealarm/bullet_act(BLAH) /obj/machinery/firealarm/bullet_act()
return src.alarm() return src.alarm()
/obj/machinery/firealarm/emp_act(severity) /obj/machinery/firealarm/emp_act(severity)

View File

@@ -624,6 +624,14 @@ var/list/turret_icons
// Emagged turrets again use twice as much power due to higher firing rates // Emagged turrets again use twice as much power due to higher firing rates
use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged)) use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged))
//Turrets aim for the center of mass by default.
//If the target is grabbing someone then the turret smartly aims for extremities
var/obj/item/weapon/grab/G = locate() in target
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
else
A.def_zone = pick("chest", "groin")
//Shooting Code: //Shooting Code:
A.current = T A.current = T
A.starting = T A.starting = T

View File

@@ -266,6 +266,15 @@
else else
A = new /obj/item/projectile/energy/electrode( loc ) A = new /obj/item/projectile/energy/electrode( loc )
use_power(200) use_power(200)
//Turrets aim for the center of mass by default.
//If the target is grabbing someone then the turret smartly aims for extremities
var/obj/item/weapon/grab/G = locate() in target
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
else
A.def_zone = pick("chest", "groin")
A.current = T A.current = T
A.starting = T A.starting = T
A.yo = U.y - T.y A.yo = U.y - T.y

View File

@@ -146,7 +146,7 @@
return return
return -1 // the bullet/projectile goes through the target! Ie, you missed return PROJECTILE_CONTINUE // the bullet/projectile goes through the target!
// Small memory holder entity for transparent bullet holes // Small memory holder entity for transparent bullet holes

View File

@@ -25,7 +25,7 @@
/obj/structure/girder/bullet_act(var/obj/item/projectile/Proj) /obj/structure/girder/bullet_act(var/obj/item/projectile/Proj)
//Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder) //Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder)
if(Proj.original != src && !prob(cover)) if(Proj.original != src && !prob(cover))
return -1 //pass through return PROJECTILE_CONTINUE //pass through
//Tasers and the like should not damage girders. //Tasers and the like should not damage girders.
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))

View File

@@ -94,7 +94,7 @@
passthrough = 1 passthrough = 1
if(passthrough) if(passthrough)
. = -1 . = PROJECTILE_CONTINUE
damage = between(0, (damage - Proj.damage)*(Proj.damage_type == BRUTE? 0.4 : 1), 10) //if the bullet passes through then the grille avoids most of the damage damage = between(0, (damage - Proj.damage)*(Proj.damage_type == BRUTE? 0.4 : 1), 10) //if the bullet passes through then the grille avoids most of the damage
src.health -= damage*0.2 src.health -= damage*0.2

View File

@@ -10,9 +10,11 @@ emp_act
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone) /mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone)) def_zone = check_zone(def_zone)
if(!organ) if(!has_organ(def_zone))
return return PROJECTILE_FORCE_MISS //if they don't have the organ in question then the projectile just passes by.
var/obj/item/organ/external/organ = get_organ()
//Shields //Shields
if(check_shields(P.damage, "the [P.name]")) if(check_shields(P.damage, "the [P.name]"))
@@ -37,7 +39,7 @@ emp_act
// redirect the projectile // redirect the projectile
P.redirect(new_x, new_y, curloc, src) P.redirect(new_x, new_y, curloc, src)
return -1 // complete projectile permutation return PROJECTILE_CONTINUE // complete projectile permutation
//Shrapnel //Shrapnel
if(P.can_embed()) if(P.can_embed())

View File

@@ -264,11 +264,11 @@ var/list/global/organ_rel_size = list(
/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0, var/ranged_attack=0) /proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0, var/ranged_attack=0)
zone = check_zone(zone) zone = check_zone(zone)
if(!ranged_attack)
// you cannot miss if your target is prone or restrained // you cannot miss if your target is prone or restrained
if(target.buckled || target.lying) if(target.buckled || target.lying)
return zone return zone
// if your target is being grabbed aggressively by someone you cannot miss either // if your target is being grabbed aggressively by someone you cannot miss either
if(!ranged_attack)
for(var/obj/item/weapon/grab/G in target.grabbed_by) for(var/obj/item/weapon/grab/G in target.grabbed_by)
if(G.state >= GRAB_AGGRESSIVE) if(G.state >= GRAB_AGGRESSIVE)
return zone return zone

View File

@@ -165,14 +165,17 @@
//roll to-hit //roll to-hit
miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier, 0) miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier, 0)
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1)) var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1 || original != target_mob)) //if the projectile hits a target we weren't originally aiming at then retain the chance to miss
if(!hit_zone)
var/result = PROJECTILE_FORCE_MISS
if(hit_zone)
def_zone = hit_zone //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
result = target_mob.bullet_act(src, def_zone)
if(result == PROJECTILE_FORCE_MISS)
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>") visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
return 0 return 0
//set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
def_zone = hit_zone
//hit messages //hit messages
if(silenced) if(silenced)
target_mob << "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>" target_mob << "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>"
@@ -193,7 +196,7 @@
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with \a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target_mob.x];Y=[target_mob.y];Z=[target_mob.z]'>JMP</a>)") msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with \a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target_mob.x];Y=[target_mob.y];Z=[target_mob.z]'>JMP</a>)")
//sometimes bullet_act() will want the projectile to continue flying //sometimes bullet_act() will want the projectile to continue flying
if (target_mob.bullet_act(src, def_zone) == -1) if (result == PROJECTILE_CONTINUE)
return 0 return 0
return 1 return 1
@@ -227,7 +230,7 @@
else else
passthrough = 1 //so ghosts don't stop bullets passthrough = 1 //so ghosts don't stop bullets
else else
passthrough = (A.bullet_act(src, def_zone) == -1) //backwards compatibility passthrough = (A.bullet_act(src, def_zone) == PROJECTILE_CONTINUE) //backwards compatibility
if(isturf(A)) if(isturf(A))
for(var/obj/O in A) for(var/obj/O in A)
O.bullet_act(src) O.bullet_act(src)

View File

@@ -720,6 +720,10 @@ var/list/be_special_flags = list(
#define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried. #define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried.
#define NETWORK_FAILURE 32 #define NETWORK_FAILURE 32
// Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile.
#define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act()
#define PROJECTILE_FORCE_MISS -2 //if the projectile should treat the attack as a miss (suppresses attack and admin logs) - only applies to mobs.
// Some on_mob_life() procs check for alien races. // Some on_mob_life() procs check for alien races.
#define IS_DIONA 1 #define IS_DIONA 1
#define IS_VOX 2 #define IS_VOX 2

View File

@@ -1,3 +1,4 @@
author: HarpyEagle author: HarpyEagle
changes: []
delete-after: false delete-after: false
changes:
- bugfix: "Fixed projectiles being able to hit people in body parts that they don't have. This will also mean that the less limbs someone has the less effective they will be as a body shield."