diff --git a/code/modules/projectiles/projectile_parent.dm b/code/modules/projectiles/projectile_parent.dm index 946bba97c4e15..72b406978ffed 100644 --- a/code/modules/projectiles/projectile_parent.dm +++ b/code/modules/projectiles/projectile_parent.dm @@ -28,8 +28,6 @@ var/max_range = PROJ_INFINITE_RANGE /// What kind of implant this projectile leaves in impacted mobs var/implanted = null - /// Forensic ID of the gun, etc that shot this projectile, used for forensics on implanted projectiles - var/forensic_ID = null /// The mob/thing that fired this projectile var/atom/shooter = null /// Mob-typed copy of `shooter` var to save time on casts later diff --git a/code/obj.dm b/code/obj.dm index 083a8a670ccde..2e26ff0c2141a 100644 --- a/code/obj.dm +++ b/code/obj.dm @@ -21,6 +21,9 @@ var/_health = 100 var/_max_health = 100 + /// if gun/bullet related, forensic profile of it + var/forensic_ID = null + New() . = ..() if (HAS_FLAG(object_flags, HAS_DIRECTIONAL_BLOCKING)) @@ -472,3 +475,12 @@ ADMIN_INTERACT_PROCS(/obj, proc/admin_command_obj_speak) return TRUE /obj/proc/after_abcu_spawn() + +/// creates an id profile for any forenics purpose. override as needed +/obj/proc/CreateID() + . = "" + + do + for(var/i = 1 to 10) // 20 characters are way too fuckin' long for anyone to care about + . += "[pick(numbersAndLetters)]" + while(. in forensic_IDs) diff --git a/code/obj/item/clothing/gloves.dm b/code/obj/item/clothing/gloves.dm index 68a309f6062c3..70bb5ee0ba9da 100644 --- a/code/obj/item/clothing/gloves.dm +++ b/code/obj/item/clothing/gloves.dm @@ -58,7 +58,7 @@ ABSTRACT_TYPE(/obj/item/clothing/gloves) . += "It seems to have some wires attached to it.[src.max_uses > 0 ? " There are [src.uses]/[src.max_uses] charges left!" : ""]" // reworked this proc a bit so it can't run more than 5 times, just in case - proc/CreateID() + CreateID() var/newID = null for (var/i=5, i>0, i--) newID = GenID() diff --git a/code/obj/item/deployable_turret.dm b/code/obj/item/deployable_turret.dm index 0c05d62162e06..5f59ed662f539 100644 --- a/code/obj/item/deployable_turret.dm +++ b/code/obj/item/deployable_turret.dm @@ -18,9 +18,15 @@ ABSTRACT_TYPE(/obj/item/turret_deployer) var/associated_turret = null //what kind of turret should this spawn? var/turret_health = 100 - New() + New(newLoc, forensics_id) ..() icon_state = "[src.icon_tag]_deployer" + if (!src.forensic_ID) + if (forensics_id) + src.forensic_ID = forensics_id + else + src.forensic_ID = src.CreateID() + forensic_IDs.Add(src.forensic_ID) get_desc() . = "
[SPAN_NOTICE("It looks [damage_words]")]" @@ -133,11 +139,18 @@ ADMIN_INTERACT_PROCS(/obj/deployable_turret, proc/admincmd_shoot, proc/admincmd_ var/deconstructable = TRUE var/can_toggle_activation = TRUE // whether you can enable or disable the turret with a screwdriver, used for map setpiece turrets - New(loc, direction) + New(loc, direction, forensics_id) ..() src.set_dir(direction || src.dir) // don't set the dir if we weren't passed one src.set_initial_angle() + if (!src.forensic_ID) + if (forensics_id) + src.forensic_ID = forensics_id + else + src.forensic_ID = src.CreateID() + forensic_IDs.Add(src.forensic_ID) + src.icon_state = "[src.icon_tag]_base" src.appearance_flags |= RESET_TRANSFORM src.underlays += src @@ -191,9 +204,25 @@ ADMIN_INTERACT_PROCS(/obj/deployable_turret, proc/admincmd_shoot, proc/admincmd_ proc/shoot(target) SPAWN(0) + var/list/casing_turfs + var/turf/picked_turf + if (src.current_projectile.casing) + casing_turfs = list() + for (var/direction in alldirs) + var/turf/T = get_step(src, direction) + if (T && !T.density) + casing_turfs += T for(var/i in 1 to src.current_projectile.shot_number) //loop animation until finished flick("[src.icon_tag]_fire",src) muzzle_flash_any(src, 0, "muzzle_flash") + if (src.current_projectile.casing) + picked_turf = pick(casing_turfs) + var/obj/item/casing/turret_casing = new src.current_projectile.casing(picked_turf, src.forensic_ID) + // prevent infinite casing stacks + if (length(picked_turf.contents) > 10) + SPAWN(30 SECONDS) + if (!QDELETED(turret_casing) && get_turf(turret_casing) == picked_turf) + qdel(turret_casing) sleep(src.current_projectile.shot_delay) shoot_projectile_ST_pixel_spread(src, current_projectile, target, 0, 0 , spread) @@ -353,7 +382,7 @@ ADMIN_INTERACT_PROCS(/obj/deployable_turret, proc/admincmd_shoot, proc/admincmd_ qdel(src) proc/spawn_deployer() - var/obj/item/turret_deployer/deployer = new src.associated_deployer(src.loc) + var/obj/item/turret_deployer/deployer = new src.associated_deployer(src.loc, src.forensic_ID) deployer.turret_health = src.health // NO FREE REPAIRS, ASSHOLES deployer.damage_words = src.damage_words deployer.quick_deploy_fuel = src.quick_deploy_fuel diff --git a/code/obj/item/gun/gun_parent.dm b/code/obj/item/gun/gun_parent.dm index 5f3f5d14d2c7d..32823893af965 100644 --- a/code/obj/item/gun/gun_parent.dm +++ b/code/obj/item/gun/gun_parent.dm @@ -34,7 +34,6 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder var/slowdown = 0 //Movement delay attack after attack var/slowdown_time = 10 //For this long - var/forensic_ID = null var/add_residue = 0 // Does this gun add gunshot residue when fired (Convair880)? var/shoot_delay = 4 @@ -132,15 +131,6 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder user.back.Attackby(src, user) return TRUE -/obj/item/gun/proc/CreateID() //Creates a new tracking id for the gun and returns it. - . = "" - - do - for(var/i = 1 to 10) // 20 characters are way too fuckin' long for anyone to care about - . += "[pick(numbersAndLetters)]" - while(. in forensic_IDs) - - ///CHECK_LOCK ///Call to run a weaponlock check vs the users implant ///Return 0 for fail diff --git a/code/obj/item/gun/kinetic.dm b/code/obj/item/gun/kinetic.dm index 7a43e252e4557..5be1a45b5b16f 100644 --- a/code/obj/item/gun/kinetic.dm +++ b/code/obj/item/gun/kinetic.dm @@ -378,7 +378,6 @@ ABSTRACT_TYPE(/obj/item/survival_rifle_barrel) icon = 'icons/obj/items/casings.dmi' icon_state = "medium" w_class = W_CLASS_TINY - var/forensic_ID = null burn_possible = FALSE small diff --git a/code/obj/item/implant.dm b/code/obj/item/implant.dm index a5eb1953f878f..54bc62b8ac4ad 100644 --- a/code/obj/item/implant.dm +++ b/code/obj/item/implant.dm @@ -845,7 +845,6 @@ ABSTRACT_TYPE(/obj/item/implant/revenge) scan_category = "not_shown" var/bleed_time = 60 var/bleed_timer = 0 - var/forensic_ID = null // match a bullet to a gun holy heckkkkk var/leaves_wound = TRUE New() diff --git a/code/procs/scanprocs.dm b/code/procs/scanprocs.dm index 51b0d640d66a7..48500a5c2d249 100644 --- a/code/procs/scanprocs.dm +++ b/code/procs/scanprocs.dm @@ -679,20 +679,10 @@ if (G.glove_ID) glove_data += "[G.glove_ID] [G.material_prints ? "([G.material_prints])" : null]" - if (istype(A, /obj/item/casing/)) - var/obj/item/casing/C = A - if(C.forensic_ID) - forensic_data += "
[SPAN_NOTICE("Forensic profile of [C]:")] [C.forensic_ID]" - - if (istype(A, /obj/item/implant/projectile)) - var/obj/item/implant/projectile/P = A - if(P.forensic_ID) - forensic_data += "
[SPAN_NOTICE("Forensic profile of [P]:")] [P.forensic_ID]" - - if (istype(A, /obj/item/gun)) - var/obj/item/gun/G = A - if(G.forensic_ID) - forensic_data += "
[SPAN_NOTICE("Forensic profile of [G]:")] [G.forensic_ID]" + if (istype(A, /obj)) + var/obj/O = A + if(O.forensic_ID) + forensic_data += "
[SPAN_NOTICE("Forensic profile of [O]:")] [O.forensic_ID]" if (istype(A, /turf/simulated/wall)) var/turf/simulated/wall/W = A