From e0d605c2eba3c2a83707f7d548f1b6860b7fc366 Mon Sep 17 00:00:00 2001 From: "joeheinemeyer@gmail.com" Date: Fri, 1 Jun 2012 20:32:26 +0000 Subject: [PATCH] Readded detective work, with much bugfixing and optimizations. Any PDA that can access the Security Records can, via the forensic scanner function (that was already there) store data on what was scanned, the same way that the Detective's scanner can. Scanning a PDA with said stored data in the Detective's computer-o-doom will transfer the data from the PDA to the computer's database. Made some area names improper as needed (Only ones where it makes sense to be improper.) Updated changelog. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3713 316c924e-a436-60f5-8080-3fe189b3f50e --- code/defines/area/Space Station 13 areas.dm | 432 +++++------ code/game/atom_procs.dm | 140 ++-- code/game/jobs/job/security.dm | 4 + code/game/machinery/bots/mulebot.dm | 3 +- code/game/machinery/door_control.dm | 5 + code/game/machinery/doors/airlock.dm | 2 + code/game/machinery/doors/door.dm | 2 + code/game/machinery/igniter.dm | 2 + code/game/magic/cultist/ritual.dm | 6 +- code/game/objects/closets/secure/security.dm | 2 + code/game/objects/devices/PDA/PDA.dm | 40 +- code/game/objects/devices/PDA/cart.dm | 38 + code/game/objects/devices/scanners.dm | 162 ++++ code/game/objects/gibs.dm | 7 +- code/game/objects/items/weapons/cards_ids.dm | 17 +- code/modules/chemical/Chemistry-Reagents.dm | 6 +- code/modules/clothing/suits/detective.dm | 2 +- code/modules/detectivework/detective_work.dm | 728 ++++++++---------- code/modules/detectivework/evidence.dm | 48 +- .../mob/living/carbon/human/human_defense.dm | 4 + code/modules/mob/mob_helpers.dm | 11 + html/changelog.html | 9 + maps/tgstation.2.0.9.dmm | 4 +- tgstation.dme | 2 + 24 files changed, 918 insertions(+), 758 deletions(-) diff --git a/code/defines/area/Space Station 13 areas.dm b/code/defines/area/Space Station 13 areas.dm index 6afda312023..dc0589844cd 100644 --- a/code/defines/area/Space Station 13 areas.dm +++ b/code/defines/area/Space Station 13 areas.dm @@ -110,11 +110,11 @@ proc/process_ghost_teleport_locs() requires_power = 0 /area/arrival/start - name = "Arrival Area" + name = "\improper Arrival Area" icon_state = "start" /area/admin - name = "Admin room" + name = "\improper Admin room" icon_state = "start" @@ -129,7 +129,7 @@ proc/process_ghost_teleport_locs() sd_lighting = 0 /area/shuttle/arrival - name = "Arrival Shuttle" + name = "\improper Arrival Shuttle" /area/shuttle/arrival/pre_game icon_state = "shuttle2" @@ -138,23 +138,23 @@ proc/process_ghost_teleport_locs() icon_state = "shuttle" /area/shuttle/escape - name = "Emergency Shuttle" + name = "\improper Emergency Shuttle" music = "music/escape.ogg" /area/shuttle/escape/station - name = "Emergency Shuttle Station" + name = "\improper Emergency Shuttle Station" icon_state = "shuttle2" /area/shuttle/escape/centcom - name = "Emergency Shuttle Centcom" + name = "\improper Emergency Shuttle Centcom" icon_state = "shuttle" /area/shuttle/escape/transit // the area to pass through for 3 minute transit - name = "Emergency Shuttle Transit" + name = "\improper Emergency Shuttle Transit" icon_state = "shuttle" /area/shuttle/escape_pod1 - name = "Escape Pod One" + name = "\improper Escape Pod One" music = "music/escape.ogg" /area/shuttle/escape_pod1/station @@ -167,7 +167,7 @@ proc/process_ghost_teleport_locs() icon_state = "shuttle" /area/shuttle/escape_pod2 - name = "Escape Pod Two" + name = "\improper Escape Pod Two" music = "music/escape.ogg" /area/shuttle/escape_pod2/station @@ -180,7 +180,7 @@ proc/process_ghost_teleport_locs() icon_state = "shuttle" /area/shuttle/escape_pod3 - name = "Escape Pod Three" + name = "\improper Escape Pod Three" music = "music/escape.ogg" /area/shuttle/escape_pod3/station @@ -193,7 +193,7 @@ proc/process_ghost_teleport_locs() icon_state = "shuttle" /area/shuttle/escape_pod5 //Pod 4 was lost to meteors - name = "Escape Pod Five" + name = "\improper Escape Pod Five" music = "music/escape.ogg" /area/shuttle/escape_pod5/station @@ -206,7 +206,7 @@ proc/process_ghost_teleport_locs() icon_state = "shuttle" /area/shuttle/mining - name = "Mining Shuttle" + name = "\improper Mining Shuttle" music = "music/escape.ogg" /area/shuttle/mining/station @@ -217,31 +217,31 @@ proc/process_ghost_teleport_locs() /area/shuttle/transport1/centcom icon_state = "shuttle" - name = "Transport Shuttle Centcom" + name = "\improper Transport Shuttle Centcom" /area/shuttle/transport1/station icon_state = "shuttle" - name = "Transport Shuttle" + name = "\improper Transport Shuttle" /area/shuttle/transport2/centcom icon_state = "shuttle" /area/shuttle/alien/base icon_state = "shuttle" - name = "Alien Shuttle Base" + name = "\improper Alien Shuttle Base" requires_power = 1 luminosity = 0 sd_lighting = 1 /area/shuttle/alien/mine icon_state = "shuttle" - name = "Alien Shuttle Mine" + name = "\improper Alien Shuttle Mine" requires_power = 1 luminosity = 0 sd_lighting = 1 /area/shuttle/prison/ - name = "Prison Shuttle" + name = "\improper Prison Shuttle" /area/shuttle/prison/station icon_state = "shuttle" @@ -250,54 +250,54 @@ proc/process_ghost_teleport_locs() icon_state = "shuttle2" /area/shuttle/specops/centcom - name = "Special Ops Shuttle" + name = "\improper Special Ops Shuttle" icon_state = "shuttlered" /area/shuttle/specops/station - name = "Special Ops Shuttle" + name = "\improper Special Ops Shuttle" icon_state = "shuttlered2" /area/shuttle/syndicate_elite/mothership - name = "Syndicate Elite Shuttle" + name = "\improper Syndicate Elite Shuttle" icon_state = "shuttlered" /area/shuttle/syndicate_elite/station - name = "Syndicate Elite Shuttle" + name = "\improper Syndicate Elite Shuttle" icon_state = "shuttlered2" /area/shuttle/administration/centcom - name = "Administration Shuttle Centcom" + name = "\improper Administration Shuttle Centcom" icon_state = "shuttlered" /area/shuttle/administration/station - name = "Administration Shuttle" + name = "\improper Administration Shuttle" icon_state = "shuttlered2" /area/shuttle/thunderdome name = "honk" /area/shuttle/thunderdome/grnshuttle - name = "Thunderdome GRN Shuttle" + name = "\improper Thunderdome GRN Shuttle" icon_state = "green" /area/shuttle/thunderdome/grnshuttle/dome - name = "GRN Shuttle" + name = "\improper GRN Shuttle" icon_state = "shuttlegrn" /area/shuttle/thunderdome/grnshuttle/station - name = "GRN Station" + name = "\improper GRN Station" icon_state = "shuttlegrn2" /area/shuttle/thunderdome/redshuttle - name = "Thunderdome RED Shuttle" + name = "\improper Thunderdome RED Shuttle" icon_state = "red" /area/shuttle/thunderdome/redshuttle/dome - name = "RED Shuttle" + name = "\improper RED Shuttle" icon_state = "shuttlered" /area/shuttle/thunderdome/redshuttle/station - name = "RED Station" + name = "\improper RED Station" icon_state = "shuttlered2" // === Trying to remove these areas: @@ -316,76 +316,76 @@ proc/process_ghost_teleport_locs() // === end remove /area/alien - name = "Alien base" + name = "\improper Alien base" icon_state = "yellow" requires_power = 0 // CENTCOM /area/centcom - name = "Centcom" + name = "\improper Centcom" icon_state = "centcom" requires_power = 0 /area/centcom/control - name = "Centcom Control" + name = "\improper Centcom Control" /area/centcom/evac - name = "Centcom Emergency Shuttle" + name = "\improper Centcom Emergency Shuttle" /area/centcom/suppy - name = "Centcom Supply Shuttle" + name = "\improper Centcom Supply Shuttle" /area/centcom/ferry - name = "Centcom Transport Shuttle" + name = "\improper Centcom Transport Shuttle" /area/centcom/shuttle - name = "Centcom Administration Shuttle" + name = "\improper Centcom Administration Shuttle" /area/centcom/test - name = "Centcom Testing Facility" + name = "\improper Centcom Testing Facility" /area/centcom/living - name = "Centcom Living Quarters" + name = "\improper Centcom Living Quarters" /area/centcom/specops - name = "Centcom Special Ops" + name = "\improper Centcom Special Ops" /area/centcom/creed name = "Creed's Office" /area/centcom/holding - name = "Holding Facility" + name = "\improper Holding Facility" //SYNDICATES /area/syndicate_mothership - name = "Syndicate Mothership" + name = "\improper Syndicate Mothership" icon_state = "syndie-ship" requires_power = 0 /area/syndicate_mothership/control - name = "Syndicate Control Room" + name = "\improper Syndicate Control Room" icon_state = "syndie-control" /area/syndicate_mothership/elite_squad - name = "Syndicate Elite Squad" + name = "\improper Syndicate Elite Squad" icon_state = "syndie-elite" //EXTRA /area/asteroid // -- TLE - name = "Asteroid" + name = "\improper Asteroid" icon_state = "asteroid" requires_power = 0 /area/asteroid/cave // -- TLE - name = "Asteroid - Underground" + name = "\improper Asteroid - Underground" icon_state = "cave" requires_power = 0 /area/asteroid/artifactroom - name = "Asteroid - Artifact" + name = "\improper Asteroid - Artifact" icon_state = "cave" @@ -403,84 +403,84 @@ proc/process_ghost_teleport_locs() /area/planet/clown - name = "Clown Planet" + name = "\improper Clown Planet" icon_state = "honk" requires_power = 0 /area/tdome - name = "Thunderdome" + name = "\improper Thunderdome" icon_state = "thunder" requires_power = 0 /area/tdome/tdome1 - name = "Thunderdome (Team 1)" + name = "\improper Thunderdome (Team 1)" icon_state = "green" /area/tdome/tdome2 - name = "Thunderdome (Team 2)" + name = "\improper Thunderdome (Team 2)" icon_state = "yellow" /area/tdome/tdomeadmin - name = "Thunderdome (Admin.)" + name = "\improper Thunderdome (Admin.)" icon_state = "purple" /area/tdome/tdomeobserve - name = "Thunderdome (Observer.)" + name = "\improper Thunderdome (Observer.)" icon_state = "purple" //ENEMY /area/syndicate_station - name = "Syndicate Station" + name = "\improper Syndicate Station" icon_state = "yellow" requires_power = 0 /area/syndicate_station/start - name = "Syndicate Station Start" + name = "\improper Syndicate Station Start" icon_state = "yellow" /area/syndicate_station/one - name = "Syndicate Station Location 1" + name = "\improper Syndicate Station Location 1" icon_state = "green" /area/syndicate_station/two - name = "Syndicate Station Location 2" + name = "\improper Syndicate Station Location 2" icon_state = "green" /area/syndicate_station/three - name = "Syndicate Station Location 3" + name = "\improper Syndicate Station Location 3" icon_state = "green" /area/syndicate_station/four - name = "Syndicate Station Location 4" + name = "\improper Syndicate Station Location 4" icon_state = "green" /area/syndicate_station/five - name = "Syndicate Station Location 5" + name = "\improper Syndicate Station Location 5" icon_state = "green" /area/syndicate_station/six - name = "Syndicate Station Location 6" + name = "\improper Syndicate Station Location 6" icon_state = "green" /area/wizard_station - name = "Wizard's Den" + name = "\improper Wizard's Den" icon_state = "yellow" requires_power = 0 /area/borg_deathsquad - name = "Borg Deathsquad" + name = "\improper Borg Deathsquad" icon_state = "yellow" requires_power = 0 /area/borg_deathsquad/start - name = "Borg Deathsquad - Ready" + name = "\improper Borg Deathsquad - Ready" /area/borg_deathsquad/station - name = "Borg Deathsquad - Arrived" + name = "\improper Borg Deathsquad - Arrived" @@ -491,69 +491,69 @@ proc/process_ghost_teleport_locs() //PRISON /area/prison - name = "Prison Station" + name = "\improper Prison Station" icon_state = "brig" /area/prison/arrival_airlock - name = "Prison Station Airlock" + name = "\improper Prison Station Airlock" icon_state = "green" requires_power = 0 /area/prison/control - name = "Prison Security Checkpoint" + name = "\improper Prison Security Checkpoint" icon_state = "security" /area/prison/crew_quarters - name = "Prison Security Quarters" + name = "\improper Prison Security Quarters" icon_state = "security" /area/prison/rec_room - name = "Prison Rec Room" + name = "\improper Prison Rec Room" icon_state = "green" /area/prison/closet - name = "Prison Supply Closet" + name = "\improper Prison Supply Closet" icon_state = "dk_yellow" /area/prison/hallway/fore - name = "Prison Fore Hallway" + name = "\improper Prison Fore Hallway" icon_state = "yellow" /area/prison/hallway/aft - name = "Prison Aft Hallway" + name = "\improper Prison Aft Hallway" icon_state = "yellow" /area/prison/hallway/port - name = "Prison Port Hallway" + name = "\improper Prison Port Hallway" icon_state = "yellow" /area/prison/hallway/starboard - name = "Prison Starboard Hallway" + name = "\improper Prison Starboard Hallway" icon_state = "yellow" /area/prison/morgue - name = "Prison Morgue" + name = "\improper Prison Morgue" icon_state = "morgue" /area/prison/medical_research - name = "Prison Genetic Research" + name = "\improper Prison Genetic Research" icon_state = "medresearch" /area/prison/medical - name = "Prison Medbay" + name = "\improper Prison Medbay" icon_state = "medbay" /area/prison/solar - name = "Prison Solar Array" + name = "\improper Prison Solar Array" icon_state = "storage" requires_power = 0 /area/prison/podbay - name = "Prison Podbay" + name = "\improper Prison Podbay" icon_state = "dk_yellow" /area/prison/solar_control - name = "Prison Solar Array Control" + name = "\improper Prison Solar Array Control" icon_state = "dk_yellow" /area/prison/solitary @@ -633,7 +633,7 @@ proc/process_ghost_teleport_locs() icon_state = "green" /area/maintenance/incinerator - name = "Incinerator" + name = "\improper Incinerator" icon_state = "disposal" /area/maintenance/disposal @@ -643,141 +643,141 @@ proc/process_ghost_teleport_locs() //Hallway /area/hallway/primary/fore - name = "Fore Primary Hallway" + name = "\improper Fore Primary Hallway" icon_state = "hallF" /area/hallway/primary/starboard - name = "Starboard Primary Hallway" + name = "\improper Starboard Primary Hallway" icon_state = "hallS" /area/hallway/primary/aft - name = "Aft Primary Hallway" + name = "\improper Aft Primary Hallway" icon_state = "hallA" /area/hallway/primary/port - name = "Port Primary Hallway" + name = "\improper Port Primary Hallway" icon_state = "hallP" /area/hallway/primary/central - name = "Central Primary Hallway" + name = "\improper Central Primary Hallway" icon_state = "hallC" /area/hallway/secondary/exit - name = "Escape Shuttle Hallway" + name = "\improper Escape Shuttle Hallway" icon_state = "escape" /area/hallway/secondary/construction - name = "Construction Area" + name = "\improper Construction Area" icon_state = "construction" /area/hallway/secondary/entry - name = "Arrival Shuttle Hallway" + name = "\improper Arrival Shuttle Hallway" icon_state = "entry" //Command /area/bridge - name = "Bridge" + name = "\improper Bridge" icon_state = "bridge" music = "signal" /area/bridge/meeting_room - name = "Heads of Staff Meeting Room" + name = "\improper Heads of Staff Meeting Room" icon_state = "bridge" music = null /area/crew_quarters/captain - name = "Captain's Quarters" + name = "\improper Captain's Quarters" icon_state = "captain" /area/crew_quarters/courtroom - name = "Courtroom" + name = "\improper Courtroom" icon_state = "courtroom" /area/crew_quarters/heads - name = "Head of Personnel's Office" + name = "\improper Head of Personnel's Office" icon_state = "head_quarters" /area/crew_quarters/hor - name = "Research Director's Office" + name = "\improper Research Director's Office" icon_state = "head_quarters" /area/crew_quarters/chief - name = "Chief Engineer's Office" + name = "\improper Chief Engineer's Office" icon_state = "head_quarters" /area/mint - name = "Mint" + name = "\improper Mint" icon_state = "green" //Crew /area/crew_quarters - name = "Dormitories" + name = "\improper Dormitories" icon_state = "Sleep" /area/crew_quarters/toilet - name = "Dormitory Toilets" + name = "\improper Dormitory Toilets" icon_state = "toilet" /area/crew_quarters/sleep_male - name = "Male Dorm" + name = "\improper Male Dorm" icon_state = "Sleep" /area/crew_quarters/sleep_male/toilet_male - name = "Male Toilets" + name = "\improper Male Toilets" icon_state = "toilet" /area/crew_quarters/sleep_female - name = "Female Dorm" + name = "\improper Female Dorm" icon_state = "Sleep" /area/crew_quarters/sleep_female/toilet_female - name = "Female Toilets" + name = "\improper Female Toilets" icon_state = "toilet" /area/crew_quarters/locker - name = "Locker Room" + name = "\improper Locker Room" icon_state = "locker" /area/crew_quarters/locker/locker_toilet - name = "Locker Toilets" + name = "\improper Locker Toilets" icon_state = "toilet" /area/crew_quarters/fitness - name = "Fitness Room" + name = "\improper Fitness Room" icon_state = "fitness" /area/crew_quarters/cafeteria - name = "Cafeteria" + name = "\improper Cafeteria" icon_state = "cafeteria" /area/crew_quarters/kitchen - name = "Kitchen" + name = "\improper Kitchen" icon_state = "kitchen" /area/crew_quarters/bar - name = "Bar" + name = "\improper Bar" icon_state = "bar" /area/crew_quarters/theatre - name = "Theatre" + name = "\improper Theatre" icon_state = "Theatre" /area/library - name = "Library" + name = "\improper Library" icon_state = "library" /area/chapel/main - name = "Chapel" + name = "\improper Chapel" icon_state = "chapel" /area/chapel/office - name = "Chapel Office" + name = "\improper Chapel Office" icon_state = "chapeloffice" /area/lawoffice - name = "Law Office" + name = "\improper Law Office" icon_state = "law" @@ -787,37 +787,37 @@ proc/process_ghost_teleport_locs() /area/holodeck - name = "Holodeck" + name = "\improper Holodeck" icon_state = "Holodeck" luminosity = 1 sd_lighting = 0 /area/holodeck/alphadeck - name = "Holodeck Alpha" + name = "\improper Holodeck Alpha" /area/holodeck/source_plating - name = "Holodeck - Off" + name = "\improper Holodeck - Off" icon_state = "Holodeck" /area/holodeck/source_emptycourt - name = "Holodeck - Empty Court" + name = "\improper Holodeck - Empty Court" /area/holodeck/source_boxingcourt - name = "Holodeck - Boxing Court" + name = "\improper Holodeck - Boxing Court" /area/holodeck/source_thunderdomecourt - name = "Holodeck - Thunderdome Court" + name = "\improper Holodeck - Thunderdome Court" /area/holodeck/source_beach - name = "Holodeck - Beach" + name = "\improper Holodeck - Beach" icon_state = "Holodeck" // Lazy. /area/holodeck/source_burntest - name = "Holodeck - Atmospheric Burn Test" + name = "\improper Holodeck - Atmospheric Burn Test" /area/holodeck/source_wildlife - name = "Holodeck - Wildlife Simulation" + name = "\improper Holodeck - Wildlife Simulation" @@ -833,7 +833,7 @@ proc/process_ghost_teleport_locs() /area/engine engine_smes - name = "Engineering SMES" + name = "\improper Engineering SMES" icon_state = "engine_smes" requires_power = 0//This area only covers the batteries and they deal with their own power @@ -842,11 +842,11 @@ proc/process_ghost_teleport_locs() icon_state = "engine" break_room - name = "Engineering Break Room" + name = "\improper Engineering Break Room" icon_state = "engine" chiefs_office - name = "Chief Engineer's office" + name = "\improper Chief Engineer's office" icon_state = "engine_control" @@ -858,27 +858,27 @@ proc/process_ghost_teleport_locs() sd_lighting = 0 auxport - name = "Port Auxiliary Solar Array" + name = "\improper Port Auxiliary Solar Array" icon_state = "panelsA" auxstarboard - name = "Starboard Auxiliary Solar Array" + name = "\improper Starboard Auxiliary Solar Array" icon_state = "panelsA" fore - name = "Fore Solar Array" + name = "\improper Fore Solar Array" icon_state = "yellow" aft - name = "Aft Solar Array" + name = "\improper Aft Solar Array" icon_state = "aft" starboard - name = "Starboard Solar Array" + name = "\improper Starboard Solar Array" icon_state = "panelsS" port - name = "Port Solar Array" + name = "\improper Port Solar Array" icon_state = "panelsP" /area/maintenance/auxsolarport @@ -899,31 +899,31 @@ proc/process_ghost_teleport_locs() /area/assembly/chargebay - name = "Recharging Bay" + name = "\improper Recharging Bay" icon_state = "mechbay" /area/assembly/showroom - name = "Robotics Showroom" + name = "\improper Robotics Showroom" icon_state = "showroom" /area/assembly/assembly_line - name = "Robotics Assembly Line" + name = "\improper Robotics Assembly Line" icon_state = "ass_line" //Teleporter /area/teleporter - name = "Teleporter" + name = "\improper Teleporter" icon_state = "teleporter" music = "signal" /area/teleporter/gateway - name = "Secure Construction Area" + name = "\improper Secure Construction Area" icon_state = "teleporter" music = "signal" /area/AIsattele - name = "AI Satellite Teleporter Room" + name = "\improper AI Satellite Teleporter Room" icon_state = "teleporter" music = "signal" @@ -935,11 +935,11 @@ proc/process_ghost_teleport_locs() music = 'signal.ogg' /area/medical/patients_rooms - name = "Patients Rooms" + name = "\improper Patient's Rooms" icon_state = "patients" /area/medical/cmo - name = "Chief Medical Officer's office" + name = "\improper Chief Medical Officer's office" icon_state = "CMO" /area/medical/robotics @@ -955,7 +955,7 @@ proc/process_ghost_teleport_locs() icon_state = "virology" /area/medical/morgue - name = "Morgue" + name = "\improper Morgue" icon_state = "morgue" /area/medical/chemistry @@ -971,7 +971,7 @@ proc/process_ghost_teleport_locs() icon_state = "cryo" /area/medical/exam_room - name = "Exam Room" + name = "\improper Exam Room" icon_state = "exam_room" /area/medical/genetics @@ -979,37 +979,37 @@ proc/process_ghost_teleport_locs() icon_state = "genetics" /area/medical/sleeper - name = "Medical Sleepers Room" + name = "\improper Medical Sleepers Room" icon_state = "medbay" //Security /area/security/main - name = "Security Office" + name = "\improper Security Office" icon_state = "security" /area/security/brig - name = "Brig" + name = "\improper Brig" icon_state = "brig" /area/security/prison - name = "Prison Wing" + name = "\improper Prison Wing" icon_state = "security" /area/security/warden - name = "Armory" + name = "\improper Armory" icon_state = "Warden" /area/security/hos - name = "Head of Security's Office" + name = "\improper Head of Security's Office" icon_state = "security" /area/security/detectives_office - name = "Detective's Office" + name = "\improper Detective's Office" icon_state = "detective" /area/security/range - name = "Firing Range" + name = "\improper Firing Range" icon_state = "firingrange" /* @@ -1030,59 +1030,59 @@ proc/process_ghost_teleport_locs() */ /area/security/nuke_storage - name = "Vault" + name = "\improper Vault" icon_state = "nuke_storage" /area/security/checkpoint - name = "Security Checkpoint" + name = "\improper Security Checkpoint" icon_state = "checkpoint1" /area/security/checkpoint2 - name = "Security Checkpoint" + name = "\improper Security Checkpoint" icon_state = "security" /area/security/vacantoffice - name = "Vacant Office" + name = "\improper Vacant Office" icon_state = "security" /area/quartermaster - name = "Quartermasters" + name = "\improper Quartermasters" icon_state = "quart" ///////////WORK IN PROGRESS////////// /area/quartermaster/sorting - name = "Delivery Office" + name = "\improper Delivery Office" icon_state = "quartstorage" ////////////WORK IN PROGRESS////////// /area/quartermaster/office - name = "Cargo Office" + name = "\improper Cargo Office" icon_state = "quartoffice" /area/quartermaster/storage - name = "Cargo Bay" + name = "\improper Cargo Bay" icon_state = "quartstorage" /area/quartermaster/qm - name = "Quartermaster's Office" + name = "\improper Quartermaster's Office" icon_state = "quart" /area/quartermaster/miningdock - name = "Mining Dock" + name = "\improper Mining Dock" icon_state = "mining" /area/quartermaster/miningstorage - name = "Mining Storage" + name = "\improper Mining Storage" icon_state = "green" /area/quartermaster/mechbay - name = "Mech Bay" + name = "\improper Mech Bay" icon_state = "yellow" /area/janitor/ - name = "Custodial Closet" + name = "\improper Custodial Closet" icon_state = "janitor" /area/hydroponics @@ -1092,27 +1092,27 @@ proc/process_ghost_teleport_locs() //Toxins /area/toxins/lab - name = "Research Lab" + name = "\improper Research Lab" icon_state = "toxlab" /area/toxins/xenobiology - name = "Xenobiology Lab" + name = "\improper Xenobiology Lab" icon_state = "toxlab" /area/toxins/storage - name = "Toxins Storage" + name = "\improper Toxins Storage" icon_state = "toxstorage" /area/toxins/test_area - name = "Toxins Test Area" + name = "\improper Toxins Test Area" icon_state = "toxtest" /area/toxins/mixing - name = "Toxins Mixing Room" + name = "\improper Toxins Mixing Room" icon_state = "toxmix" /area/toxins/server - name = "Server Room" + name = "\improper Server Room" icon_state = "server" //Storage @@ -1159,35 +1159,35 @@ proc/process_ghost_teleport_locs() /area/storage/testroom requires_power = 0 - name = "Test Room" + name = "\improper Test Room" icon_state = "storage" //DJSTATION /area/djstation - name = "Ruskie DJ Station" + name = "\improper Ruskie DJ Station" icon_state = "DJ" /area/djstation/solars - name = "DJ Station Solars" + name = "\improper DJ Station Solars" icon_state = "DJ" //DERELICT /area/derelict - name = "Derelict Station" + name = "\improper Derelict Station" icon_state = "storage" /area/derelict/hallway/primary - name = "Derelict Primary Hallway" + name = "\improper Derelict Primary Hallway" icon_state = "hallP" /area/derelict/hallway/secondary - name = "Derelict Secondary Hallway" + name = "\improper Derelict Secondary Hallway" icon_state = "hallS" /area/derelict/arrival - name = "Derelict Arrival Centre" + name = "\improper Derelict Arrival Centre" icon_state = "yellow" /area/derelict/storage/equipment @@ -1201,11 +1201,11 @@ proc/process_ghost_teleport_locs() icon_state = "green" /area/derelict/bridge - name = "Derelict Control Room" + name = "\improper Derelict Control Room" icon_state = "bridge" /area/derelict/secret - name = "Derelict Secret Room" + name = "\improper Derelict Secret Room" icon_state = "library" /area/derelict/bridge/access @@ -1213,15 +1213,15 @@ proc/process_ghost_teleport_locs() icon_state = "auxstorage" /area/derelict/bridge/ai_upload - name = "Derelict Computer Core" + name = "\improper Derelict Computer Core" icon_state = "ai" /area/derelict/solar_control - name = "Derelict Solar Control" + name = "\improper Derelict Solar Control" icon_state = "engine" /area/derelict/crew_quarters - name = "Derelict Crew Quarters" + name = "\improper Derelict Crew Quarters" icon_state = "fitness" /area/derelict/medical @@ -1229,15 +1229,15 @@ proc/process_ghost_teleport_locs() icon_state = "medbay" /area/derelict/medical/morgue - name = "Derelict Morgue" + name = "\improper Derelict Morgue" icon_state = "morgue" /area/derelict/medical/chapel - name = "Derelict Chapel" + name = "\improper Derelict Chapel" icon_state = "chapel" /area/derelict/teleporter - name = "Derelict Teleporter" + name = "\improper Derelict Teleporter" icon_state = "teleporter" /area/derelict/eva @@ -1245,33 +1245,33 @@ proc/process_ghost_teleport_locs() icon_state = "eva" /area/derelict/ship - name = "Abandoned Ship" + name = "\improper Abandoned Ship" icon_state = "yellow" /area/solar/derelict_starboard - name = "Derelict Starboard Solar Array" + name = "\improper Derelict Starboard Solar Array" icon_state = "panelsS" /area/solar/derelict_aft - name = "Derelict Aft Solar Array" + name = "\improper Derelict Aft Solar Array" icon_state = "aft" /area/derelict/singularity_engine - name = "Derelict Singularity Engine" + name = "\improper Derelict Singularity Engine" icon_state = "engine" //Construction /area/construction - name = "Construction Area" + name = "\improper Construction Area" icon_state = "yellow" /area/construction/supplyshuttle - name = "Supply Shuttle" + name = "\improper Supply Shuttle" icon_state = "yellow" /area/construction/quarters - name = "Engineer's Quarters" + name = "\improper Engineer's Quarters" icon_state = "yellow" /area/construction/qmaint @@ -1279,15 +1279,15 @@ proc/process_ghost_teleport_locs() icon_state = "yellow" /area/construction/hallway - name = "Hallway" + name = "\improper Hallway" icon_state = "yellow" /area/construction/solars - name = "Solar Panels" + name = "\improper Solar Panels" icon_state = "yellow" /area/construction/solarscontrol - name = "Solar Panel Control" + name = "\improper Solar Panel Control" icon_state = "yellow" /area/construction/Storage @@ -1309,51 +1309,51 @@ proc/process_ghost_teleport_locs() icon_state = "storage" /area/turret_protected/ai_upload - name = "AI Upload Chamber" + name = "\improper AI Upload Chamber" icon_state = "ai_upload" /area/turret_protected/ai_upload_foyer - name = "AI Upload Foyer" + name = "\improper AI Upload Foyer" icon_state = "ai_foyer" /area/turret_protected/ai - name = "AI Chamber" + name = "\improper AI Chamber" icon_state = "ai_chamber" /area/turret_protected/aisat - name = "AI Satellite" + name = "\improper AI Satellite" icon_state = "ai" /area/turret_protected/aisat_interior - name = "AI Satellite" + name = "\improper AI Satellite" icon_state = "ai" /area/turret_protected/AIsatextFP - name = "AI Sat Ext" + name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 sd_lighting = 0 /area/turret_protected/AIsatextFS - name = "AI Sat Ext" + name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 sd_lighting = 0 /area/turret_protected/AIsatextAS - name = "AI Sat Ext" + name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 sd_lighting = 0 /area/turret_protected/AIsatextAP - name = "AI Sat Ext" + name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 sd_lighting = 0 /area/turret_protected/NewAIMain - name = "AI Main New" + name = "\improper AI Main New" icon_state = "storage" @@ -1363,19 +1363,19 @@ proc/process_ghost_teleport_locs() /area/wreck/ai - name = "AI Chamber" + name = "\improper AI Chamber" icon_state = "ai" /area/wreck/main - name = "Wreck" + name = "\improper Wreck" icon_state = "storage" /area/wreck/engineering - name = "Power Room" + name = "\improper Power Room" icon_state = "engine" /area/wreck/bridge - name = "Bridge" + name = "\improper Bridge" icon_state = "bridge" /area/generic @@ -1387,31 +1387,31 @@ proc/process_ghost_teleport_locs() // Telecommunications Satellite /area/tcommsat/entrance - name = "Telecommunications Satellite Teleporter" + name = "\improper Telecommunications Satellite Teleporter" icon_state = "tcomsatentrance" /area/tcommsat/chamber - name = "Telecommunications Satellite Central Compartment" + name = "\improper Telecommunications Satellite Central Compartment" icon_state = "tcomsatcham" /area/turret_protected/tcomfoyer - name = "Telecommunications Satellite Foyer" + name = "\improper Telecommunications Satellite Foyer" icon_state = "tcomsatlob" /area/turret_protected/tcomwest - name = "Telecommunications Satellite West Wing" + name = "\improper Telecommunications Satellite West Wing" icon_state = "tcomsatwest" /area/turret_protected/tcomeast - name = "Telecommunications Satellite East Wing" + name = "\improper Telecommunications Satellite East Wing" icon_state = "tcomsateast" /area/tcommsat/computer - name = "Telecommunications Satellite Observatory" + name = "\improper Telecommunications Satellite Observatory" icon_state = "tcomsatcomp" /area/tcommsat/lounge - name = "Telecommunications Satellite Lounge" + name = "\improper Telecommunications Satellite Lounge" icon_state = "tcomsatlounge" @@ -1426,7 +1426,7 @@ proc/process_ghost_teleport_locs() /area/turret_protected/AssistantRoom - name = "Assistant Room" + name = "\improper Assistant Room" icon_state = "storage" sd_lighting = 0 diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm index 7d6cd50c518..ce0d3aed735 100644 --- a/code/game/atom_procs.dm +++ b/code/game/atom_procs.dm @@ -62,7 +62,7 @@ return /atom/proc/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (!(istype(W, /obj/item/weapon/grab) ) && !(istype(W, /obj/item/weapon/plastique)) && !(istype(W, /obj/item/weapon/cleaner)) && !(istype(W, /obj/item/weapon/chemsprayer)) && !(istype(W, /obj/item/weapon/pepperspray)) && !(istype(W, /obj/item/weapon/plantbgone)) && !(istype(W, /obj/item/weapon/packageWrap))) + if (!(istype(W, /obj/item/weapon/grab) ) && !(istype(W, /obj/item/weapon/plastique)) && !(istype(W, /obj/item/weapon/cleaner)) && !(istype(W, /obj/item/weapon/chemsprayer)) && !(istype(W, /obj/item/weapon/pepperspray)) && !(istype(W, /obj/item/weapon/plantbgone)) && !(istype(W, /obj/item/weapon/packageWrap)) && !istype(W, /obj/item/device/detective_scanner)) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) O << "\red [src] has been hit by [user] with [W]" @@ -98,64 +98,62 @@ if(isnull(M.key)) return if (!( src.flags ) & FPRINT) return + //Smudge up dem prints some + for(var/P in fingerprints) + var/test_print = stars(fingerprints[P], rand(85,95)) + if(stringpercent(test_print) == 32) //She's full of stars! (No actual print left) + fingerprints.Remove(P) + else + fingerprints[P] = test_print if (ishuman(M)) + //Add the list if it does not exist. if(!fingerprintshidden) fingerprintshidden = list() + //Fibers~ + add_fibers(M) + //Now, lets get to the dirty work. + //First, make sure their DNA makes sense. var/mob/living/carbon/human/H = M if (!istype(H.dna, /datum/dna) || !H.dna.uni_identity || (length(H.dna.uni_identity) != 32)) if(!istype(H.dna, /datum/dna)) H.dna = new /datum/dna(null) H.check_dna() + //Now, deal with gloves. if (H.gloves && H.gloves != src) - if(src.fingerprintslast != H.key) - src.fingerprintshidden += text("(Wearing gloves). Real name: [], Key: []",H.real_name, H.key) - src.fingerprintslast = H.key + if(fingerprintslast != H.key) + fingerprintshidden += text("(Wearing gloves). Real name: [], Key: []",H.real_name, H.key) + fingerprintslast = H.key H.gloves.add_fingerprint(M) + //Deal with gloves the pass finger/palm prints. if(H.gloves != src) if(prob(75) && istype(H.gloves, /obj/item/clothing/gloves/latex)) return 0 else if(H.gloves && !istype(H.gloves, /obj/item/clothing/gloves/latex)) return 0 - if(src.fingerprintslast != H.key) - src.fingerprintshidden += text("Real name: [], Key: []",H.real_name, H.key) - src.fingerprintslast = H.key + //More adminstuffz + if(fingerprintslast != H.key) + fingerprintshidden += text("Real name: [], Key: []",H.real_name, H.key) + fingerprintslast = H.key + //Make the list if it does not exist. if(!fingerprints) fingerprints = list() - var/new_prints = 0 - var/prints - for(var/i = 1, i <= src.fingerprints.len, i++) - var/list/L = params2list(src.fingerprints[i]) - if(L[num2text(1)] == md5(H.dna.uni_identity)) - new_prints = i - prints = L[num2text(2)] - break - else - var/test_print = stars(L[num2text(2)], rand(80,90)) - if(stringpercent(test_print) == 32) - if(src.fingerprints.len == 1) - src.fingerprints = list() - else - for(var/j = (i + 1), j < (src.fingerprints.len), j++) - src.fingerprints[j-1] = src.fingerprints[j] - src.fingerprints.len-- - else - src.fingerprints[i] = "1=[L[num2text(1)]]&2=[test_print]" - if(new_prints) - src.fingerprints[new_prints] = text("1=[]&2=[]", md5(H.dna.uni_identity), stringmerge(prints,stars(md5(H.dna.uni_identity), (H.gloves ? rand(10,20) : rand(25,40))))) - else if(new_prints == 0) - if(!src.fingerprints) - src.fingerprints = list(text("1=[]&2=[]", md5(H.dna.uni_identity), stars(md5(H.dna.uni_identity), H.gloves ? rand(10,20) : rand(25,40)))) - else - src.fingerprints += text("1=[]&2=[]", md5(H.dna.uni_identity), stars(md5(H.dna.uni_identity), H.gloves ? rand(10,20) : rand(25,40))) - for(var/i = 1, i <= src.fingerprints.len, i++) - if(length(src.fingerprints[i]) != 69) - src.fingerprints.Remove(src.fingerprints[i]) - if(fingerprints && !fingerprints.len) del(fingerprints) + //Hash this shit. + var/full_print = md5(H.dna.uni_identity) + var/print = fingerprints[full_print] //Find if the print is already there. + //It is not! We need to add it! + if(!print) + fingerprints[full_print] = stars(full_print, H.gloves ? rand(10,20) : rand(25,40)) + //It's there, lets merge this shit! + else + fingerprints[full_print] = stringmerge(print, stars(full_print, (H.gloves ? rand(10,20) : rand(25,40)))) return 1 else - if(src.fingerprintslast != M.key) - src.fingerprintshidden += text("Real name: [], Key: []",M.real_name, M.key) - src.fingerprintslast = M.key + if(fingerprintslast != M.key) + fingerprintshidden += text("Real name: [], Key: []",M.real_name, M.key) + fingerprintslast = M.key + //Cleaning up shit. + if(fingerprints && !fingerprints.len) + del(fingerprints) return //returns 1 if made bloody, returns 0 otherwise @@ -190,11 +188,10 @@ O.overlays += O.blood_overlay //if this blood isn't already in the list, add it - for(var/i = 1, i <= O.blood_DNA.len, i++) - if((O.blood_DNA[i][1] == M.dna.unique_enzymes) && (O.blood_DNA[i][2] == M.dna.b_type)) - return 0 //already bloodied with this blood. Cannot add more. - O.blood_DNA.len++ - O.blood_DNA[O.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type) + + if(blood_DNA[M.dna.unique_enzymes]) + return 0 //already bloodied with this blood. Cannot add more. + blood_DNA[M.dna.unique_enzymes] = M.dna.b_type return 1 //we applied blood to the item //adding blood to turfs @@ -203,8 +200,8 @@ //get one blood decal and infect it with virus from M.viruses for(var/obj/effect/decal/cleanable/blood/B in T.contents) - B.blood_DNA.len++ - B.blood_DNA[B.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type) + if(!B.blood_DNA[M.dna.unique_enzymes]) + B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type for(var/datum/disease/D in M.viruses) var/datum/disease/newDisease = new D.type B.viruses += newDisease @@ -213,7 +210,7 @@ //if there isn't a blood decal already, make one. var/obj/effect/decal/cleanable/blood/newblood = new /obj/effect/decal/cleanable/blood(T) - newblood.blood_DNA = list(list(M.dna.unique_enzymes, M.dna.b_type)) + newblood.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type for(var/datum/disease/D in M.viruses) var/datum/disease/newDisease = new D.type newblood.viruses += newDisease @@ -224,11 +221,9 @@ else if (istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src //if this blood isn't already in the list, add it - for(var/i = 1, i <= H.blood_DNA.len, i++) - if((H.blood_DNA[i][1] == M.dna.unique_enzymes) && (H.blood_DNA[i][2] == M.dna.b_type)) - return 0 //already bloodied with this blood. Cannot add more. - H.blood_DNA.len++ - H.blood_DNA[H.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type) + if(blood_DNA[H.dna.unique_enzymes]) + return 0 //already bloodied with this blood. Cannot add more. + blood_DNA[H.dna.unique_enzymes] = H.dna.b_type return 1 //we applied blood to the item return @@ -251,7 +246,7 @@ if( istype(src, /turf/simulated) ) var/turf/simulated/source1 = src var/obj/effect/decal/cleanable/blood/this = new /obj/effect/decal/cleanable/blood(source1) - this.blood_DNA = list(list(M.dna.unique_enzymes,M.dna.b_type)) + this.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type for(var/datum/disease/D in M.viruses) var/datum/disease/newDisease = new D.type this.viruses += newDisease @@ -261,6 +256,7 @@ if( istype(src, /turf/simulated) ) var/turf/simulated/source2 = src var/obj/effect/decal/cleanable/xenoblood/this = new /obj/effect/decal/cleanable/xenoblood(source2) + this.blood_DNA["UNKNOWN BLOOD"] = "X*" for(var/datum/disease/D in M.viruses) var/datum/disease/newDisease = new D.type this.viruses += newDisease @@ -281,12 +277,15 @@ if (!( src.flags ) & FPRINT) return - if ( src.blood_DNA ) + if (blood_DNA) //Cleaning blood off of mobs if (istype (src, /mob/living/carbon)) var/mob/living/carbon/M = src del(M.blood_DNA) + if(ishuman(src)) + var/mob/living/carbon/human/H = src + H.bloody_hands = 0 //Cleaning blood off of items else if (istype (src, /obj/item)) @@ -295,6 +294,10 @@ if(O.blood_overlay) O.overlays.Remove(O.blood_overlay) + if(istype(src, /obj/item/clothing/gloves)) + var/obj/item/clothing/gloves/G = src + G.transfer_blood = 0 + //Cleaning blood off of turfs else if (istype(src, /turf/simulated)) var/turf/simulated/T = src @@ -307,25 +310,14 @@ if(blood_DNA && istype(blood_DNA, /list) && !blood_DNA.len) del(blood_DNA) - if(src.fingerprints && src.fingerprints.len) - var/done = 0 - while(!done) - done = 1 - for(var/i = 1, i < (src.fingerprints.len + 1), i++) - var/list/prints = params2list(src.fingerprints[i]) - var/test_print = prints["2"] - var/new_print = stars(test_print, rand(1,20)) - if(stringpercent(new_print) == 32) - if(src.fingerprints.len == 1) - src.fingerprints = list() - else - for(var/j = (i + 1), j < (src.fingerprints.len), j++) - src.fingerprints[j-1] = src.fingerprints[j] - src.fingerprints.len-- - done = 0 - break - else - src.fingerprints[i] = "1=" + prints["1"] + "&2=" + new_print + if(fingerprints && fingerprints.len) + //Smudge up dem prints some + for(var/P in fingerprints) + var/test_print = stars(fingerprints[P], rand(10,20)) + if(stringpercent(test_print) == 32) //She's full of stars! (No actual print left) + fingerprints.Remove(P) + else + fingerprints[P] = test_print if(fingerprints && !fingerprints.len) del(fingerprints) if(istype(src, /mob/living/carbon/human)) diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 548a7eb5fc5..d212c533e28 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -106,9 +106,13 @@ var/obj/item/weapon/storage/box/survival/Evipack = new /obj/item/weapon/storage/box/survival(H) H.equip_if_possible(Evipack, H.slot_r_hand) new /obj/item/weapon/fcardholder(Evipack) + H.equip_if_possible(new /obj/item/weapon/storage/box/evidence(H), H.slot_l_hand) + H.equip_if_possible(new /obj/item/device/detective_scanner(H), H.slot_r_store) else H.equip_if_possible(new /obj/item/weapon/storage/box/survival(H.back), H.slot_in_backpack) H.equip_if_possible(new /obj/item/weapon/fcardholder(H), H.slot_in_backpack) + H.equip_if_possible(new /obj/item/weapon/storage/box/evidence(H), H.slot_in_backpack) + H.equip_if_possible(new /obj/item/device/detective_scanner(H), H.slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 3e07ccbec3e..0eb925c4670 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -797,7 +797,8 @@ H.apply_damage(0.5*damage, BRUTE, "r_arm") var/obj/effect/decal/cleanable/blood/B = new(src.loc) - B.blood_DNA = list(list(H.dna.unique_enzymes, H.dna.b_type)) + B.blood_DNA = list() + B.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type bloodiness += 4 diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 74721a2c8a2..60d606749d5 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -22,6 +22,8 @@ return } */ + if(istype(W, /obj/item/device/detective_scanner)) + return return src.attack_hand(user) /obj/machinery/door_control/attack_hand(mob/user as mob) @@ -103,6 +105,9 @@ return src.attack_hand(user) /obj/machinery/driver_button/attackby(obj/item/weapon/W, mob/user as mob) + + if(istype(W, /obj/item/device/detective_scanner)) + return return src.attack_hand(user) /obj/machinery/driver_button/attack_hand(mob/user as mob) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index e4671de1220..a69794c7b77 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -985,6 +985,8 @@ About the new airlock wires panel: if(src.isElectrified()) if(src.shock(user, 75)) return + if(istype(C, /obj/item/device/detective_scanner)) + return src.add_fingerprint(user) if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 95b5c2e8406..85430410e15 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -115,6 +115,8 @@ attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/device/detective_scanner)) + return if(src.operating || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them. src.add_fingerprint(user) if(!src.requiresID()) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index a19a417e95d..c6ccc0747e2 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -60,6 +60,8 @@ src.sd_SetLuminosity(0) /obj/machinery/sparker/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/device/detective_scanner)) + return if (istype(W, /obj/item/weapon/screwdriver)) add_fingerprint(user) src.disable = !src.disable diff --git a/code/game/magic/cultist/ritual.dm b/code/game/magic/cultist/ritual.dm index ffc782c3f26..d3dba85a782 100644 --- a/code/game/magic/cultist/ritual.dm +++ b/code/game/magic/cultist/ritual.dm @@ -580,7 +580,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", R.word2 = w2 R.word3 = w3 R.check_icon() - R.blood_DNA = list(list(H.dna.unique_enzymes, H.dna.b_type)) + R.blood_DNA = list() + R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type return else user << "The book seems full of illegible scribbles. Is this a joke?" @@ -625,7 +626,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", var/obj/effect/rune/R = new /obj/effect/rune if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - R.blood_DNA = list(list(H.dna.unique_enzymes, H.dna.b_type)) + R.blood_DNA = list() + R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type switch(r) if("teleport") var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri") diff --git a/code/game/objects/closets/secure/security.dm b/code/game/objects/closets/secure/security.dm index 5f98d2a9266..9a5a252aa90 100644 --- a/code/game/objects/closets/secure/security.dm +++ b/code/game/objects/closets/secure/security.dm @@ -170,6 +170,8 @@ new /obj/item/weapon/storage/fcard_kit(src) new /obj/item/weapon/fcardholder(src) new /obj/item/weapon/clipboard(src) + new /obj/item/device/detective_scanner(src) + new /obj/item/weapon/storage/box/evidence(src) return diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm index 36d5c69bcc4..a5c211327f2 100644 --- a/code/game/objects/devices/PDA/PDA.dm +++ b/code/game/objects/devices/PDA/PDA.dm @@ -835,9 +835,8 @@ else user << "\blue Blood found on [C]. Analysing..." spawn(15) - for(var/i = 1, i < C:blood_DNA.len, i++) - var/list/templist = C:blood_DNA[i] - user << "\blue Blood type: [templist[2]]\nDNA: [templist[1]]" + for(var/blood in C:blood_DNA) + user << "\blue Blood type: [C:blood_DNA[blood]]\nDNA: [blood]" if(4) for (var/mob/O in viewers(C, null)) @@ -852,23 +851,26 @@ /obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob) switch(scanmode) if(2) - if (!A.fingerprints) - user << "\blue Unable to locate any fingerprints on [A]!" - else - user << "\blue Isolated [A:fingerprints.len] fingerprints." - var/list/prints = A:fingerprints - var/list/complete_prints = list() - for(var/i in prints) - var/list/templist = params2list(i) - var/temp = stringpercent(templist["2"]) - if(temp <= 6) - complete_prints += templist["2"] - if(complete_prints.len < 1) - user << "\blue No intact prints found" + if(!istype(A, /obj/item/weapon/f_card)) + if (!A.fingerprints) + user << "\blue Unable to locate any fingerprints on [A]!" else - user << "\blue Found [complete_prints.len] intact prints" - for(var/i in complete_prints) - user << "\blue " + i + user << "\blue Isolated [A:fingerprints.len] fingerprints." + var/list/prints = A:fingerprints + var/list/complete_prints = list() + for(var/i in prints) + var/print = prints[i] + if(stringpercent(print) <= FINGERPRINT_COMPLETE) + complete_prints += print + if(complete_prints.len < 1) + user << "\blue No intact prints found" + else + user << "\blue Found [complete_prints.len] intact prints" + for(var/i in complete_prints) + user << "\blue [i]" + if(cartridge && cartridge.access_security) + cartridge.add_data(A) + user << "Data added to internal storage. Scan with a High-Resolution Scanner to retreive." if(3) if(!isnull(A.reagents)) diff --git a/code/game/objects/devices/PDA/cart.dm b/code/game/objects/devices/PDA/cart.dm index 727a613f97e..2e188ff6693 100644 --- a/code/game/objects/devices/PDA/cart.dm +++ b/code/game/objects/devices/PDA/cart.dm @@ -30,6 +30,7 @@ var/list/powermonitors = list() var/message1 // used for status_displays var/message2 + var/list/stored_data = list() engineering name = "Power-ON Cartridge" @@ -598,6 +599,43 @@ Code: else menu += "ERROR: Unable to determine current location." + proc/add_data(atom/A as mob|obj|turf|area) + //I love hashtables. + var/list/data_entry = stored_data["\ref [A]"] + if(islist(data_entry)) //Yay, it was already stored! + //Merge the fingerprints. + var/list/data_prints = data_entry[1] + for(var/print in A.fingerprints) + var/merged_print = data_prints[print] + if(!merged_print) + data_prints[print] = A.fingerprints[print] + else + data_prints[print] = stringmerge(data_prints[print],A.fingerprints[print]) + + //Now the fibers + var/list/fibers = data_entry[2] + if(!fibers) + fibers = list() + if(A.suit_fibers && A.suit_fibers.len) + for(var/j = 1, j <= A.suit_fibers.len, j++) //Fibers~~~ + if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add! + fibers += A.suit_fibers[j] + var/list/blood = data_entry[3] + if(!blood) + blood = list() + if(A.blood_DNA && A.blood_DNA.len) + for(var/main_blood in A.blood_DNA) + if(!blood[main_blood]) + blood[main_blood] = A.blood_DNA[blood] + return 1 + var/list/sum_list[4] //Pack it back up! + sum_list[1] = A.fingerprints + sum_list[2] = A.suit_fibers + sum_list[3] = A.blood_DNA + sum_list[4] = "\The [A] in \the [get_area(A)]" + stored_data["\ref [A]"] = sum_list + return 0 + /obj/item/weapon/cartridge/Topic(href, href_list) ..() diff --git a/code/game/objects/devices/scanners.dm b/code/game/objects/devices/scanners.dm index 61c864dd8df..193ebb2ef3e 100644 --- a/code/game/objects/devices/scanners.dm +++ b/code/game/objects/devices/scanners.dm @@ -60,6 +60,168 @@ MASS SPECTROMETER if(M) M.invisibility = 2 + +/obj/item/device/detective_scanner + name = "Scanner" + desc = "Used to scan objects for DNA and fingerprints." + icon_state = "forensic1" + var/amount = 20.0 + var/list/stored = list() + w_class = 3.0 + item_state = "electronic" + flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY + slot_flags = SLOT_BELT + + attackby(obj/item/weapon/f_card/W as obj, mob/user as mob) + ..() + if (istype(W, /obj/item/weapon/f_card)) + if (W.fingerprints) + return + if (src.amount == 20) + return + if (W.amount + src.amount > 20) + src.amount = 20 + W.amount = W.amount + src.amount - 20 + else + src.amount += W.amount + //W = null + del(W) + add_fingerprint(user) + if (W) + W.add_fingerprint(user) + return + + attack(mob/living/carbon/human/M as mob, mob/user as mob) + if (!ishuman(M)) + user << "\red [M] is not human and cannot have the fingerprints." + return 0 + if (( !( istype(M.dna, /datum/dna) ) || M.gloves) ) + user << "\blue No fingerprints found on [M]" + return 0 + else + if (src.amount < 1) + user << text("\blue Fingerprints scanned on [M]. Need more cards to print.") + else + src.amount-- + var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc ) + F.amount = 1 + F.add_fingerprint(M) + F.icon_state = "fingerprint1" + F.name = text("FPrintC- '[M.name]'") + + user << "\blue Done printing." + user << "\blue [M]'s Fingerprints: [md5(M.dna.uni_identity)]" + if ( !M.blood_DNA || !M.blood_DNA.len ) + user << "\blue No blood found on [M]" + if(M.blood_DNA) + del(M.blood_DNA) + else + user << "\blue Blood found on [M]. Analysing..." + spawn(15) + for(var/blood in M.blood_DNA) + user << "\blue Blood type: [M.blood_DNA[blood]]\nDNA: [blood]" + return + + afterattack(atom/A as obj|turf|area, mob/user as mob) + if(!in_range(A,user)) + return + if(loc != user) + return + if(istype(A,/obj/machinery/computer/forensic_scanning)) //breaks shit. + return + if(istype(A,/obj/item/weapon/f_card)) + user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\"" + return + + add_fingerprint(user) + + + //Special case for blood splaters. + if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune)) + if(!isnull(A.blood_DNA)) + for(var/blood in A.blood_DNA) + user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]" + return + + //General + if ((!A.fingerprints || !A.fingerprints.len) && !A.suit_fibers && !A.blood_DNA) + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ + "\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!",\ + "You hear a faint hum of electrical equipment.") + return 0 + + if(add_data(A)) + user << "\blue Object already in internal memory. Consolidating data..." + return + + + //PRINTS + if(!A.fingerprints || !A.fingerprints.len) + if(A.fingerprints) + del(A.fingerprints) + else + user << "\blue Isolated [A.fingerprints.len] fingerprints: Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + + //FIBERS + if(A.suit_fibers) + user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + + //Blood + if (A.blood_DNA) + user << "\blue Blood found on [A]. Analysing..." + spawn(15) + for(var/blood in A.blood_DNA) + user << "Blood type: \red [A.blood_DNA[blood]] \t \black DNA: \red [blood]" + if(prob(5)) + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ + "You finish scanning \the [A].",\ + "You hear a faint hum of electrical equipment.") + return 0 + else + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]\n[user.gender == MALE ? "He" : "She"] seems to perk up slightly at the readout." ,\ + "The results of the scan pique your interest.",\ + "You hear a faint hum of electrical equipment, and someone making a thoughtful noise.") + return 0 + return + + proc/add_data(atom/A as mob|obj|turf|area) + //I love hashtables. + var/list/data_entry = stored["\ref [A]"] + if(islist(data_entry)) //Yay, it was already stored! + //Merge the fingerprints. + var/list/data_prints = data_entry[1] + for(var/print in A.fingerprints) + var/merged_print = data_prints[print] + if(!merged_print) + data_prints[print] = A.fingerprints[print] + else + data_prints[print] = stringmerge(data_prints[print],A.fingerprints[print]) + + //Now the fibers + var/list/fibers = data_entry[2] + if(!fibers) + fibers = list() + if(A.suit_fibers && A.suit_fibers.len) + for(var/j = 1, j <= A.suit_fibers.len, j++) //Fibers~~~ + if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add! + fibers += A.suit_fibers[j] + var/list/blood = data_entry[3] + if(!blood) + blood = list() + if(A.blood_DNA && A.blood_DNA.len) + for(var/main_blood in A.blood_DNA) + if(!blood[main_blood]) + blood[main_blood] = A.blood_DNA[blood] + return 1 + var/list/sum_list[4] //Pack it back up! + sum_list[1] = A.fingerprints + sum_list[2] = A.suit_fibers + sum_list[3] = A.blood_DNA + sum_list[4] = "\The [A] in \the [get_area(A)]" + stored["\ref [A]"] = sum_list + return 0 + + /obj/item/device/healthanalyzer name = "Health Analyzer" icon_state = "health" diff --git a/code/game/objects/gibs.dm b/code/game/objects/gibs.dm index 807358696bc..f428716c0b9 100644 --- a/code/game/objects/gibs.dm +++ b/code/game/objects/gibs.dm @@ -51,12 +51,13 @@ gib.viruses += viruus viruus.holder = gib viruus.spread_type = CONTACT_FEET + gib.blood_DNA = list() if(MobDNA) - gib.blood_DNA = list(list(MobDNA.unique_enzymes, MobDNA.b_type)) + gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.b_type else if(istype(src, /obj/effect/gibspawner/xeno)) - gib.blood_DNA = list(list("UNKNOWN DNA", "X*")) + gib.blood_DNA["UNKNOWN DNA"] = "X*" else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey - gib.blood_DNA = list(list("Non-human DNA", "A+")) + gib.blood_DNA["Non-human DNA"] = "A+" var/list/directions = gibdirections[i] if(directions.len) gib.streak(directions) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 00351a1bdb8..839af17d01f 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -192,18 +192,13 @@ FINGERPRINT CARD return /obj/item/weapon/f_card/proc/display() - if(!fingerprints) return - if (!istype(src.fingerprints, /list)) - src.fingerprints = params2list(src.fingerprints) - if (length(src.fingerprints)) - var/dat = "Fingerprints on Card
" - for(var/i = 1, i < (src.fingerprints.len + 1), i++) - var/list/L = params2list(src.fingerprints[i]) - dat += text("[]
", L["1"]) - //Foreach goto(41) - return dat - else + if(!fingerprints || !fingerprints.len) return "There are no fingerprints on this card." + else + var/dat = "Fingerprints on Card
" + for(var/name in fingerprints) + dat += "[name]
" + return dat return /* diff --git a/code/modules/chemical/Chemistry-Reagents.dm b/code/modules/chemical/Chemistry-Reagents.dm index c449c45ccdb..902e4d30f0e 100644 --- a/code/modules/chemical/Chemistry-Reagents.dm +++ b/code/modules/chemical/Chemistry-Reagents.dm @@ -135,7 +135,7 @@ datum var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T //find some blood here if(!blood_prop) //first blood! blood_prop = new(T) - blood_prop.blood_DNA = list(list(self.data["blood_DNA"],self.data["blood_type"])) + blood_prop.blood_DNA[self.data["blood_DNA"]] = self.data["blood_type"] for(var/datum/disease/D in self.data["viruses"]) var/datum/disease/newVirus = new D.type @@ -147,7 +147,7 @@ datum var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T if(!blood_prop) blood_prop = new(T) - blood_prop.blood_DNA = list(list("Non-Human DNA","A+")) + blood_prop.blood_DNA["Non-Human DNA"] = "A+" for(var/datum/disease/D in self.data["viruses"]) var/datum/disease/newVirus = new D.type blood_prop.viruses += newVirus @@ -164,7 +164,7 @@ datum var/obj/effect/decal/cleanable/xenoblood/blood_prop = locate() in T if(!blood_prop) blood_prop = new(T) - blood_prop.blood_DNA = list(list("UNKNOWN DNA STRUCTURE","X*")) + blood_prop.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" for(var/datum/disease/D in self.data["viruses"]) var/datum/disease/newVirus = new D.type blood_prop.viruses += newVirus diff --git a/code/modules/clothing/suits/detective.dm b/code/modules/clothing/suits/detective.dm index 033d581efa8..841c9366c69 100644 --- a/code/modules/clothing/suits/detective.dm +++ b/code/modules/clothing/suits/detective.dm @@ -12,7 +12,7 @@ icon_state = "detective" item_state = "det_suit" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/cigpacket,/obj/item/weapon/lighter,/obj/item/device/taperecorder) + allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/cigpacket,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index c3fdc415ff6..a15845f0e6d 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -1,14 +1,13 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - //gloves w_uniform wear_suit shoes atom/var/list/suit_fibers atom/proc/add_fibers(mob/living/carbon/human/M) - if(M.gloves) - if(M.gloves.transfer_blood) //bloodied gloves transfer blood to touched objects - if(add_blood(M.gloves.bloody_hands_mob)) //only reduces the bloodiness of our gloves if the item wasn't already bloody - M.gloves.transfer_blood-- + if(M.gloves && istype(M.gloves,/obj/item/clothing/)) + var/obj/item/clothing/gloves/G = M.gloves + if(G.transfer_blood) //bloodied gloves transfer blood to touched objects + if(add_blood(G.bloody_hands_mob)) //only reduces the bloodiness of our gloves if the item wasn't already bloody + G.transfer_blood-- else if(M.bloody_hands) if(add_blood(M.bloody_hands_mob)) M.bloody_hands-- @@ -49,31 +48,17 @@ atom/proc/add_fibers(mob/living/carbon/human/M) suit_fibers += "Material from a pair of [M.gloves.name]." if(!suit_fibers.len) del suit_fibers -atom/proc/get_duplicate(var/atom/location) - var/atom/movable/temp_atom = new /atom/movable(location) - temp_atom.name = src.name - temp_atom.desc = src.desc - temp_atom.icon = src.icon - temp_atom.icon_state = src.icon_state - temp_atom.fingerprints = src.fingerprints - temp_atom.blood_DNA = src.blood_DNA - temp_atom.suit_fibers = src.suit_fibers - if(src.original_atom) - temp_atom.original_atom = src.original_atom - else - temp_atom.original_atom = list(src) - return temp_atom - -#define FINGERPRINT_COMPLETE 6 //This is the output of the stringpercent(print) proc, and means about 80% of +var/const/FINGERPRINT_COMPLETE = 6 //This is the output of the stringpercent(print) proc, and means about 80% of //the print must be there for it to be complete. (Prints are 32 digits) obj/machinery/computer/forensic_scanning name = "High-Res Forensic Scanning Computer" icon_state = "forensic" - var/obj/item/scanning - var/temp = "" - var/canclear = 1 - var/authenticated = 0 + var + obj/item/scanning + temp = "" + canclear = 1 + authenticated = 0 //Here's the structure for files: each entry is a list, and entry one in that list is the string of their //full and scrambled fingerprint. This acts as the method to arrange evidence. Each subsequent entry is list @@ -83,14 +68,14 @@ obj/machinery/computer/forensic_scanning // 3: All fibers on the object // 4: All blood on the object //This is then used to show what objects were used to "find" the full print, as well as the fibers on it. - var/list/files + list/files //This holds objects (1) without prints, and their fibers(2) and blood(3). - var/list/misc - var/obj/item/weapon/f_card/card + list/misc + obj/item/weapon/f_card/card - var/scan_data = "" - var/scan_name = "" - var/scan_process = 0 + scan_data = "" + scan_name = "" + scan_process = 0 req_access = list(access_forensics_lockers) @@ -182,7 +167,7 @@ obj/machinery/computer/forensic_scanning I.loc = src else usr << "Invalid Object Rejected." - if("card") + if("card") //Processing a fingerprint card. var/mob/M = usr var/obj/item/I = M.equipped() if(!(I && istype(I,/obj/item/weapon/f_card))) @@ -202,151 +187,137 @@ obj/machinery/computer/forensic_scanning process_card() else usr << "\red Invalid Object Rejected." - if("database") + if("database") //Viewing all records in each database canclear = 1 if(href_list["delete_record"]) - delete_dossier(text2num(href_list["delete_record"])) + delete_dossier(href_list["delete_record"]) if(href_list["delete_aux"]) - delete_record(text2num(href_list["delete_aux"])) + delete_record(href_list["delete_aux"]) if((!misc || !misc.len) && (!files || !files.len)) temp = "Database is empty." - for(var/atom/A in contents) - if(A == scanning) - continue - del(A) else if(files && files.len) temp = "Criminal Evidence Database

" temp += "Consolidated data points:
" - for(var/i = 1, i <= files.len, i++) - temp += "{Dossier [i]}
" + var/i = 1 + for(var/print in files) + temp += "{Dossier [i]}
" + i++ temp += "
{Insert Finger Print Card (To complete a Dossier)}


" else temp = "" if(misc && misc.len) - if(href_list["delete"]) - delete_record(text2num(href_list["delete"])) temp += "Auxiliary Evidence Database

" temp += "This is where anything without fingerprints goes.

" - for(var/i = 1, i <= misc.len, i++) - var/list/temp_list = misc[i] - var/item_name = get_name(temp_list[1]) - temp += "{[item_name]}
" - if("record") + for(var/atom in misc) + var/list/data_entry = misc[atom] + temp += "{[data_entry[3]]}
" + if("record") //Viewing a record from the "files" database. canclear = 0 if(files) temp = "Criminal Evidence Database

" - temp += "Consolidated data points: Dossier [href_list["identifier"]]
" - var/identifier = text2num(href_list["identifier"]) - var/list/dossier = files[identifier] - var/list/prints = params2list(dossier[1]) + temp += "Consolidated data points: Dossier [files.Find(href_list["identifier"])]
" + var/list/dossier = files[href_list["identifier"]] var/print_string = "Fingerprints: Print not complete!
" - if(stringpercent(prints[num2text(2)]) <= FINGERPRINT_COMPLETE) - print_string = "Fingerprints: (80% or higher completion reached)
" + prints[num2text(2)] + "
" + if(stringpercent(dossier[1]) <= FINGERPRINT_COMPLETE) + print_string = "Fingerprints: (80% or higher completion reached)
[dossier[1]]
" temp += print_string - for(var/i = 2, i <= dossier.len, i++) + for(var/object in dossier) + if(object == dossier[1]) + continue temp += "
" - var/list/outputs = dossier[i] - var/item_name = get_name(outputs[1]) - var/list/prints_len = outputs[2] - temp += "Object: [item_name]
" + var/list/outputs = dossier[object] + var/list/prints_len = outputs[1] + temp += "Object: [outputs[4]]
" temp += " Fingerprints:
" temp += "    [prints_len.len] Unique fingerprints found.
" - var/list/fibers = outputs[3] + var/list/fibers = outputs[2] if(fibers && fibers.len) temp += " Fibers:
" for(var/j = 1, j <= fibers.len, j++) temp += "      [fibers[j]]
" - var/list/blood = outputs[4] + var/list/blood = outputs[3] if(blood && blood.len) temp += " Blood:
" - for(var/j = 1, j <= blood.len, j++) - var/list/templist2 = blood[j] - temp += "      Type: [templist2[2]], DNA: [templist2[1]]
" + for(var/named in blood) + temp += "      Type: [blood[named]], DNA: [named]
" + temp += "
{Delete this Dossier}" + temp += "
{Print}" else temp = "ERROR. Database not found!
" - temp += "
{Delete this Dossier}" - temp += "
{Print}" temp += "
{Return}" - if("databaseprint") + if("databaseprint") //Printing from the "files" database. if(files) var/obj/item/weapon/paper/P = new(loc) - P.name = "Database File (Dossier [href_list["identifier"]])" + P.name = "Database File (Dossier [files.Find(href_list["identifier"])])" P.overlays += "paper_words" P.info = "Criminal Evidence Database

" P.info += "Consolidated data points: Dossier [href_list["identifier"]]
" - var/list/dossier = files[text2num(href_list["identifier"])] - var/list/prints = params2list(dossier[1]) + var/list/dossier = files[href_list["identifier"]] var/print_string = "Fingerprints: Print not complete!
" - if(stringpercent(prints[num2text(2)]) <= FINGERPRINT_COMPLETE) - print_string = "Fingerprints: " + prints[num2text(2)] + "
" + if(stringpercent(dossier[1]) <= FINGERPRINT_COMPLETE) + print_string = "Fingerprints: (80% or higher completion reached)
[dossier[1]]
" P.info += print_string - for(var/i = 2, i <= dossier.len, i++) + for(var/object in dossier) + if(object == dossier[1]) + continue P.info += "
" - var/list/outputs = dossier[i] - var/item_name = get_name(outputs[1]) - var/list/prints_len = outputs[2] - P.info += "Object: [item_name]
" + var/list/outputs = dossier[object] + var/list/prints_len = outputs[1] + P.info += "Object: [outputs[4]]
" P.info += " Fingerprints:
" P.info += "    [prints_len.len] Unique fingerprints found.
" - var/list/fibers = outputs[3] + var/list/fibers = outputs[2] if(fibers && fibers.len) P.info += " Fibers:
" for(var/j = 1, j <= fibers.len, j++) P.info += "      [fibers[j]]
" - var/list/blood = outputs[4] + var/list/blood = outputs[3] if(blood && blood.len) P.info += " Blood:
" - for(var/j = 1, j <= blood.len, j++) - var/list/templist2 = blood[j] - P.info += "      Type: [templist2[2]], DNA: [templist2[1]]
" + for(var/named in blood) + P.info += "      Type: [blood[named]], DNA: [named]
" else usr << "ERROR. Database not found!
" - if("auxiliary") + if("auxiliary") //Viewing a record from the "misc" database. canclear = 0 if(misc) temp = "Auxiliary Evidence Database

" - var/identifier = text2num(href_list["identifier"]) - var/list/outputs = misc[identifier] - var/item_name = get_name(outputs[1]) - temp += "Consolidated data points: [item_name]
" - var/list/fibers = outputs[2] + var/list/outputs = misc[href_list["identifier"]] + temp += "Consolidated data points: [outputs[3]]
" + var/list/fibers = outputs[1] if(fibers && fibers.len) temp += " Fibers:
" for(var/j = 1, j <= fibers.len, j++) temp += "
      [fibers[j]]" - var/list/blood = outputs[3] + var/list/blood = outputs[2] if(blood && blood.len) temp += " Blood:
" - for(var/j = 1, j <= blood.len, j++) - var/list/templist2 = blood[j] - temp += "      Type: [templist2[2]], DNA: [templist2[1]]
" + for(var/named in blood) + temp += "      Type: [blood[named]], DNA: [named]
" + temp += "
{Delete This Record}" + temp += "
{Print}" else temp = "ERROR. Database not found!
" - temp += "
{Delete This Record}" - temp += "
{Print}" temp += "
{Return}" - if("auxiliaryprint") + if("auxiliaryprint") //Printing from the "misc" database. if(misc) var/obj/item/weapon/paper/P = new(loc) - var/identifier = text2num(href_list["identifier"]) - var/list/outputs = misc[identifier] - var/item_name = get_name(outputs[1]) - P.name = "Auxiliary Database File ([item_name])" + var/list/outputs = misc[href_list["identifier"]] + P.name = "Auxiliary Database File ([outputs[3]])" P.overlays += "paper_words" P.info = "Auxiliary Evidence Database

" - P.info += "Consolidated data points: [item_name]
" - var/list/fibers = outputs[2] + P.info += "Consolidated data points: [outputs[3]]
" + var/list/fibers = outputs[1] if(fibers && fibers.len) P.info += " Fibers:
" for(var/j = 1, j <= fibers.len, j++) P.info += "
      [fibers[j]]" - var/list/blood = outputs[3] + var/list/blood = outputs[2] if(blood && blood.len) P.info += " Blood:
" - for(var/j = 1, j <= blood.len, j++) - var/list/templist2 = blood[j] - P.info += "      Type: [templist2[2]], DNA: [templist2[1]]
" + for(var/named in blood) + P.info += "      Type: [blood[named]], DNA: [named]
" else usr << "ERROR. Database not found!
" if("scan") @@ -379,57 +350,57 @@ obj/machinery/computer/forensic_scanning scan_data = null updateDialog() return - scan_process = 0 - scan_name = scanning.name - scan_data = "[scanning]

" - if (scanning.blood_DNA) - scan_data += "Blood Found:
" - for(var/i = 1, i <= scanning.blood_DNA.len, i++) - var/list/templist = scanning.blood_DNA[i] - scan_data += "-Blood type: [templist[2]]\nDNA: [templist[1]]

" - else - scan_data += "No Blood Found

" - if(!scanning.fingerprints) - scan_data += "No Fingerprints Found

" - else - var/list/L = scanning.fingerprints - scan_data += "Isolated [L.len] Fingerprints. Loaded into database.
" - add_data(scanning) + if(scanning) + scan_process = 0 + scan_name = scanning.name + scan_data = "[scanning]

" + if (scanning.blood_DNA) + scan_data += "Blood Found:
" + for(var/blood in scanning.blood_DNA) + scan_data += "Blood type: [scanning.blood_DNA[blood]]\nDNA: [blood]

" + else + scan_data += "No Blood Found

" + if(!scanning.fingerprints) + scan_data += "No Fingerprints Found

" + else + var/list/L = scanning.fingerprints + scan_data += "Isolated [L.len] Fingerprints. Loaded into database.
" + add_data(scanning) - if(!scanning.suit_fibers) - /*if(istype(scanning,/obj/item/device/detective_scanner)) - var/obj/item/device/detective_scanner/scanner = scanning - if(scanner.stored_name) - scan_data += "Fibers/Materials Data - [scanner.stored_name]:
" - for(var/data in scanner.stored_fibers) - scan_data += "- [data]
" - else - scan_data += "No Fibers/Materials Data
" - else*/ - scan_data += "No Fibers/Materials Located
" - else - /*if(istype(scanning,/obj/item/device/detective_scanner)) - var/obj/item/device/detective_scanner/scanner = scanning - if(scanner.stored_name) - scan_data += "Fibers/Materials Data - [scanner.stored_name]:
" - for(var/data in scanner.stored_fibers) - scan_data += "- [data]
" - else - scan_data += "No Fibers/Materials Data
"*/ + if(!scanning.suit_fibers) + /*if(istype(scanning,/obj/item/device/detective_scanner)) + var/obj/item/device/detective_scanner/scanner = scanning + if(scanner.stored_name) + scan_data += "Fibers/Materials Data - [scanner.stored_name]:
" + for(var/data in scanner.stored_fibers) + scan_data += "- [data]
" + else + scan_data += "No Fibers/Materials Data
" + else*/ + scan_data += "No Fibers/Materials Located
" + else + /*if(istype(scanning,/obj/item/device/detective_scanner)) + var/obj/item/device/detective_scanner/scanner = scanning + if(scanner.stored_name) + scan_data += "Fibers/Materials Data - [scanner.stored_name]:
" + for(var/data in scanner.stored_fibers) + scan_data += "- [data]
" + else + scan_data += "No Fibers/Materials Data
"*/ - scan_data += "Fibers/Materials Found:
" - for(var/data in scanning.suit_fibers) - scan_data += "- [data]
" - if(istype(scanning,/obj/item/device/detective_scanner)) - scan_data += "
Data transfered from Scanner to Database.
" - add_data_scanner(scanning) - else if(!scanning.fingerprints) - scan_data += "
Add to Database?
" + scan_data += "Fibers/Materials Found:
" + for(var/data in scanning.suit_fibers) + scan_data += "- [data]
" + if(istype(scanning,/obj/item/device/detective_scanner) || (istype(scanning, /obj/item/device/pda) && scanning:cartridge && scanning:cartridge.access_security)) + scan_data += "
Data transfered from Scanner to Database.
" + add_data_scanner(scanning) + else if(!scanning.fingerprints) + scan_data += "
Add to Database?
" else temp = "Scan Failed: No Object" - if("print") + if("print") //Printing scan data if(scan_data) temp = "Scan Data Printed." var/obj/item/weapon/paper/P = new(loc) @@ -442,226 +413,151 @@ obj/machinery/computer/forensic_scanning scan_data = "" if("cancel") scan_process = 0 - if("add") + if("add") //Adding an object (Manually) to the database. if(scanning) add_data(scanning) else temp = "Data Transfer Failed: No Object." updateUsrDialog() - verb/reset() - set name = "Reset Database" - set category = "Object" - set src in oview(1) - temp = "" - add_fingerprint(usr) - files = list() - misc = list() - for(var/atom/A in contents) - if(A == scanning) - continue - del(A) - return - - ex_act() return - proc/add_data_scanner(var/obj/item/device/detective_scanner/W) - if(W.stored) - for(var/i = 1, i <= W.stored.len, i++) - var/list/data = W.stored[i] - add_data(data[1],1,data[2],data[3],data[4]) - W.stored = list() - for(var/atom/A in W.contents) - del(A) + proc/add_data_scanner(var/obj/item/device/W) + if(istype(W, /obj/item/device/detective_scanner)) + if(W:stored) + for(var/atom in W:stored) + var/list/data = W:stored[atom] + add_data_master(atom,data[1],data[2],data[3],data[4]) + W:stored = list() + else if(istype(W, /obj/item/device/pda) && W:cartridge && W:cartridge.access_security) + if(W:cartridge.stored_data) + for(var/atom in W:cartridge.stored_data) + var/list/data = W:cartridge.stored_data[atom] + add_data_master(atom,data[1],data[2],data[3],data[4]) + W:cartridge.stored_data = list() return + proc/add_data(var/atom/scanned_atom) + return add_data_master("\ref [scanned_atom]", scanned_atom.fingerprints,\ + scanned_atom.suit_fibers, scanned_atom.blood_DNA, scanned_atom.name) - proc/add_data(var/atom/A, var/override = 0, var/tempfingerprints, var/tempsuit_fibers,var/tempblood_DNA) + + +/******************************** +*****DO NOT DIRECTLY CALL ME***** +********************************/ + proc/add_data_master(var/atom_reference, var/list/atom_fingerprints, var/list/atom_suit_fibers, var/list/atom_blood_DNA, var/atom_name) //What follows is massive. It cross references all stored data in the scanner with the other stored data, //and what is already in the computer. Not sure how bad the lag may/may not be. - var/backup_prints - var/backup_fibers - var/backup_DNA - if(override) - backup_prints = A.fingerprints - A.fingerprints = tempfingerprints - backup_fibers = A.suit_fibers - A.suit_fibers = tempsuit_fibers - backup_DNA = A.blood_DNA - A.blood_DNA = tempblood_DNA - if(!A.fingerprints) //No prints - var/merged = 0 - if(!misc) - misc = list() - if(misc) - for(var/i = 1, i <= misc.len, i++) //Lets see if we can find it. - var/list/templist = misc[i] - var/atom/check = templist[1] - var/atom_checker_scan = (A.original_atom ? check.original_atom[1] == A.original_atom[1] : 0) - if(check.original_atom[1] == A || atom_checker_scan) //There it is! - merged = 1 - var/list/fibers = templist[2] - if(!fibers) - fibers = list() - if(A.suit_fibers) - for(var/j = 1, j <= A.suit_fibers.len, j++) //Fibers~~~ - if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add! - fibers += A.suit_fibers[j] - var/list/blood = templist[3] - if(!blood) - blood = list() - if(A.blood_DNA) - for(var/j = 1, j <= A.blood_DNA.len, j++) //Blood~~~ - if(!blood.Find(A.blood_DNA[j])) //It isn't! Add! - blood += A.blood_DNA[j] - var/list/sum_list[3] //Pack it back up! - sum_list[1] = check - sum_list[2] = fibers - sum_list[3] = blood - misc[i] = sum_list //Store it! - break //We found it, we're done here. - if(!merged) //Nope! Guess we have to add it! - var/list/templist[3] - templist[1] = A.get_duplicate(src) - templist[2] = A.suit_fibers - templist[3] = A.blood_DNA - misc.len++ - misc[misc.len] = templist //Store it! - return !merged - else //Has prints. - var/list/found_prints[A.fingerprints.len] - for(var/i = 1, i <= found_prints.len, i++) - found_prints[i] = 0 + + if(!misc) + misc = list() + var/list/data_entry = misc[atom_reference] + if(data_entry) + var/list/fibers = data_entry[1] + if(!fibers) + fibers = list() + if(atom_suit_fibers) + for(var/j = 1, j <= atom_suit_fibers.len, j++) //Fibers~~~ + if(!fibers.Find(atom_suit_fibers[j])) //It isn't! Add! + fibers += atom_suit_fibers[j] + var/list/blood = data_entry[2] + if(!blood) + blood = list() + if(atom_blood_DNA) + for(var/main_blood in atom_blood_DNA) + if(!blood[main_blood]) + blood[main_blood] = atom_blood_DNA[blood] + else + var/list/templist[3] + templist[1] = atom_suit_fibers + templist[2] = atom_blood_DNA + templist[3] = atom_name + misc[atom_reference] = templist //Store it! + //Has prints. + if(atom_fingerprints) if(!files) files = list() - for(var/i = 1, i <= files.len, i++) //Lets see if we can find the owner of the prints - var/list/perp_list = files[i] - var/list/perp_prints = params2list(perp_list[1]) - var/perp = perp_prints[num2text(1)] - var/found2 = 0 - for(var/m = 1, m <= A.fingerprints.len, m++) //Compare database prints with prints on object. - var/list/test_prints_list = params2list(A.fingerprints[m]) - var/checker = test_prints_list[num2text(1)] - if(checker == perp) //Found 'em! Merge! - found_prints[m] = 1 - for(var/n = 2, n <= perp_list.len, n++) //Lets see if it is already in the database - var/list/target = perp_list[n] - var/atom/atom_checker = target[1] - var/atom_checker_scan = (A.original_atom.len ? atom_checker.original_atom[1] == A.original_atom[1] : 0) - if(atom_checker.original_atom[1] == A || atom_checker_scan) //Found the original object! - found2 = 1 - var/list/prints = target[2] - if(!prints) - prints = list() - if(A.fingerprints) - for(var/j = 1, j <= A.fingerprints.len, j++) //Fingerprints~~~ - var/list/print_test1 = params2list(A.fingerprints[j]) - var/test_print1 = print_test1[num2text(1)] - var/found = 0 - for(var/k = 1, k <= prints.len, k++) //Lets see if the print is already in there - var/list/print_test2 = params2list(prints[k]) - var/test_print2 = print_test2[num2text(1)] - if(test_print2 == test_print1) //It is! Merge! - prints[k] = "1=" + test_print2 + "&2=" + stringmerge(print_test2[num2text(2)],print_test1[num2text(2)]) - found = 1 - break //We found it, we're done here. - if(!found) //It isn't! Add! - prints += A.fingerprints[j] - var/list/fibers = target[3] - if(!fibers) - fibers = list() - if(A.suit_fibers) - for(var/j = 1, j < A.suit_fibers.len, j++) //Fibers~~~ - if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add! - fibers += A.suit_fibers[j] - var/list/blood = target[4] - if(!blood) - blood = list() - if(A.blood_DNA) - for(var/j = 1, j < A.blood_DNA.len, j++) //Blood~~~ - if(!blood.Find(A.blood_DNA[j])) //It isn't! Add! - blood += A.blood_DNA[j] - var/list/sum_list[4] //Pack it back up! - sum_list[1] = atom_checker - sum_list[2] = prints - sum_list[3] = fibers - sum_list[4] = blood - perp_list[n] = sum_list //Store it! - files[i] = perp_list - break //We found it, we're done here. - if(!found2) //Add a new datapoint to this perp! - var/list/sum_list[4] - sum_list[1] = A.get_duplicate(src) - sum_list[2] = A.fingerprints - sum_list[3] = A.suit_fibers - sum_list[4] = A.blood_DNA - perp_list.len++ - perp_list[perp_list.len] = sum_list - files[i] = perp_list - for(var/m = 1, m <= found_prints.len, m++) //Uh Oh! A print wasn't used! New datapoint! - if(found_prints[m] == 0) - var/list/newperp[2] - var/list/sum_list[4] - sum_list[1] = A.get_duplicate(src) - sum_list[2] = A.fingerprints - sum_list[3] = A.suit_fibers - sum_list[4] = A.blood_DNA - newperp[2] = sum_list - newperp[1] = A.fingerprints[m] - if(!files) - files = newperp - else - files.len++ - files[files.len] = newperp - update_fingerprints() //Lets update the calculated sum of the stored prints. - if(override) - A.fingerprints = backup_prints - A.suit_fibers = backup_fibers - A.blood_DNA = backup_DNA - return + for(var/main_print in atom_fingerprints) + data_entry = files[main_print] + if(data_entry)//The print is already in here! + var/list/internal_atom = data_entry[atom_reference] //Lets see if we can find the current object + if(internal_atom) + //We must be on a roll! Just update what needs to be updated. + var/list/internal_prints = internal_atom[1] + for(var/print in atom_fingerprints) //Sorry for the double loop! D: + var/associated_print = internal_prints[print] + var/reference_print = atom_fingerprints[print] + if(associated_print && associated_print != reference_print) //It does not match + internal_prints[print] = stringmerge(associated_print, reference_print) + else if(!associated_print) + internal_prints[print] = reference_print + //If the main print was updated, lets update the master as well. + if(print == main_print && (!associated_print || (associated_print && associated_print != reference_print))) + update_fingerprints(main_print, internal_prints[print]) + //Fibers. + var/list/fibers = internal_atom[2] + if(!fibers) + fibers = list() + if(atom_suit_fibers) + for(var/j = 1, j < atom_suit_fibers.len, j++) //Fibers~~~ + if(!fibers.Find(atom_suit_fibers[j])) //It isn't! Add! + fibers += atom_suit_fibers[j] + //Blood. + var/list/blood = internal_atom[3] + if(!blood) + blood = list() + if(atom_blood_DNA) + for(var/main_blood in atom_blood_DNA) + if(!blood[main_blood]) + blood[main_blood] = atom_blood_DNA[blood] + continue + //It's not in there! We gotta add it. + update_fingerprints(main_print, atom_fingerprints[main_print]) + var/list/data_point[4] + data_point[1] = atom_fingerprints + data_point[2] = atom_suit_fibers + data_point[3] = atom_blood_DNA + data_point[4] = atom_name + data_entry[atom_reference] = data_point + continue + //No print at all! New data entry, go! + var/list/data_point[4] + data_point[1] = atom_fingerprints + data_point[2] = atom_suit_fibers + data_point[3] = atom_blood_DNA + data_point[4] = atom_name + var/list/new_file[1] + new_file[1] = atom_fingerprints[main_print] + new_file[atom_reference] = data_point + files[main_print] = new_file + return 1 +/******************************** +***END DO NOT DIRECTLY CALL ME*** +********************************/ - proc/update_fingerprints() //I am tired, but this updates the master print from evidence, which is used to determine completion of a print. - for(var/k = 1, k <= files.len, k++) - var/list/perp_list = files[k] - var/list/perp_prints = params2list(perp_list[1]) - var/perp = perp_prints[num2text(1)] - var/list/found_prints = list() - for(var/i = 2, i <= perp_list.len, i++) - var/list/test_list = perp_list[i] - var/list/test_prints = test_list[2] - for(var/j = 1, j <= test_prints.len, j++) - var/list/test_list_2 = params2list(test_prints[j]) - var/test_prints_2 = test_list_2[num2text(1)] - if(test_prints_2 == perp) - found_prints += test_list_2[num2text(2)] - break - for(var/prints in found_prints) - perp_prints[num2text(2)] = stringmerge(perp_prints[num2text(2)],prints) - perp_list[1] = "1=" + perp + "&2=" + perp_prints[num2text(2)] - files[k] = perp_list + proc/update_fingerprints(var/ref_print, var/new_print) + var/list/master = files[ref_print] + if(master) + master[1] = stringmerge(master[1],new_print) + else + CRASH("Fucking hell. Something went wrong, and it tried to update a null print or something. Tell SkyMarshal (and give him this call stack)") return proc/process_card() //Same as above, but for fingerprint cards if(card.fingerprints && !(card.amount > 1) && islist(card.fingerprints) && files && files.len) usr << "You insert the card, and it is destroyed by the machinery in the process of comparing prints." var/found = 0 - for(var/k = 1, k <= card.fingerprints.len, k++) - var/list/test_prints = params2list(card.fingerprints[k]) - var/print = test_prints[num2text(1)] - for(var/i = 1, i <= files.len, i++) - var/list/test_list = files[i] - var/list/perp_prints = params2list(test_list[1]) - var/perp = perp_prints[num2text(1)] - if(perp == print) - test_list[1] = "1=" + print + "&2=" + print - files[i] = test_list - break + for(var/master_print in card.fingerprints) + var/list/data_entry = files[master_print] + if(data_entry) + found = 1 + data_entry[1] = master_print if(found) - usr << "The machinery finds can completes a match." + usr << "The machinery finds it can complete a match." else usr << "No match found." del(card) @@ -673,34 +569,24 @@ obj/machinery/computer/forensic_scanning return return - proc/delete_record(var/location) //Deletes an entry in the misc database at the given location + proc/delete_record(var/atom_ref) //Deletes an entry in the misc database at the given location if(misc && misc.len) - for(var/i = location, i < misc.len, i++) - misc[i] = misc[i+i] - misc.len-- + misc.Remove(atom_ref) return - proc/get_name(var/atom/A) //HurrDurr - return A.name - - proc/delete_dossier(var/location) //Deletes a Dossier at a given location. + proc/delete_dossier(var/print) //Deletes a Dossier at a given location. if(files && files.len) - if(files.len > location) - for(var/i = location, i < files.len, i++) - files[i] = files[i + 1] - if(files.len >= location) - files[files.len] = list() - files.len-- + files.Remove(print) return detective icon_state = "old" name = "PowerScan Mk.I" - +/* obj/item/clothing/shoes/var track_blood = 0 mob/living/carbon/human/track_blood_mob - track_blood_type + track_blood_type*/ mob/var bloody_hands = 0 mob/living/carbon/human/bloody_hands_mob @@ -711,30 +597,32 @@ obj/item/clothing/gloves/var transfer_blood = 0 mob/living/carbon/human/bloody_hands_mob - +/* obj/effect/decal/cleanable/var track_amt = 3 mob/blood_owner -/* + turf/Exited(mob/living/carbon/human/M) if(istype(M,/mob/living) && !istype(M,/mob/living/carbon/metroid)) - var/dofoot = 1 - if(istype(M,/mob/living/simple_animal)) - if(!(istype(M,/mob/living/simple_animal/cat) || istype(M,/mob/living/simple_animal/corgi) || istype(M,/mob/living/simple_animal/constructwraith))) - dofoot = 0 + if(!istype(src, /turf/space)) // Bloody tracks code starts here + var/dofoot = 1 + if(istype(M,/mob/living/simple_animal)) + if(!(istype(M,/mob/living/simple_animal/cat) || istype(M,/mob/living/simple_animal/corgi) || istype(M,/mob/living/simple_animal/constructwraith))) + dofoot = 0 - if(dofoot) + if(dofoot) - if(!istype(src, /turf/space)) // Bloody tracks code starts here - if(M.track_blood > 0) - M.track_blood-- - src.add_bloody_footprints(M.track_blood_mob,1,M.dir,get_tracks(M),M.track_blood_type) - else if(istype(M,/mob/living/carbon/human)) - if(M.shoes) - if(M.shoes.track_blood > 0) - M.shoes.track_blood-- - src.add_bloody_footprints(M.shoes.track_blood_mob,1,M.dir,M.shoes.name,M.shoes.track_blood_type) // And bloody tracks end here - . = ..() + if(!istype(src, /turf/space)) // Bloody tracks code starts here + if(M.track_blood > 0) + M.track_blood-- + src.add_bloody_footprints(M.track_blood_mob,1,M.dir,get_tracks(M),M.track_blood_type) + else if(istype(M,/mob/living/carbon/human)) + if(M.shoes && istype(M.shoes,/obj/item/clothing/shoes)) + var/obj/item/clothing/shoes/S = M.shoes + if(S.track_blood > 0) + S.track_blood-- + src.add_bloody_footprints(S.track_blood_mob,1,M.dir,S.name,S.track_blood_type) // And bloody tracks end here + . = ..() turf/Entered(mob/living/carbon/human/M) if(istype(M,/mob/living) && !istype(M,/mob/living/carbon/metroid)) var/dofoot = 1 @@ -748,10 +636,11 @@ turf/Entered(mob/living/carbon/human/M) M.track_blood-- src.add_bloody_footprints(M.track_blood_mob,0,M.dir,get_tracks(M),M.track_blood_type) else if(istype(M,/mob/living/carbon/human)) - if(M.shoes && !istype(src,/turf/space)) - if(M.shoes.track_blood > 0) - M.shoes.track_blood-- - src.add_bloody_footprints(M.shoes.track_blood_mob,0,M.dir,M.shoes.name,M.shoes.track_blood_type) + if(M.shoes && istype(M.shoes,/obj/item/clothing/shoes) && !istype(src,/turf/space)) + var/obj/item/clothing/shoes/S = M.shoes + if(S.track_blood > 0) + S.track_blood-- + src.add_bloody_footprints(S.track_blood_mob,0,M.dir,S.name,S.track_blood_type) for(var/obj/effect/decal/cleanable/B in src) @@ -766,11 +655,12 @@ turf/Entered(mob/living/carbon/human/M) track_type = "oil" if(istype(M,/mob/living/carbon/human)) - if(M.shoes) - M.shoes.add_blood(B.blood_owner) - M.shoes.track_blood_mob = B.blood_owner - M.shoes.track_blood = max(M.shoes.track_blood,8) - M.shoes.track_blood_type = track_type + if(M.shoes && istype(M.shoes,/obj/item/clothing/shoes)) + var/obj/item/clothing/shoes/S = M.shoes + S.add_blood(B.blood_owner) + S.track_blood_mob = B.blood_owner + S.track_blood = max(S.track_blood,8) + S.track_blood_type = track_type else M.add_blood(B.blood_owner) M.track_blood_mob = B.blood_owner @@ -782,17 +672,17 @@ turf/Entered(mob/living/carbon/human/M) turf/proc/add_bloody_footprints(mob/living/carbon/human/M,leaving,d,info,bloodcolor) for(var/obj/effect/decal/cleanable/blood/tracks/T in src) - if(T.dir == d && findtext(T.icon, bloodcolor)) + if(T.dir == d && findtext(T.icon_state, bloodcolor)) if((leaving && T.icon_state == "steps2") || (!leaving && T.icon_state == "steps1")) T.desc = "These bloody footprints appear to have been made by [info]." - if(T.blood_DNA) - T.blood_DNA.len++ + if(!T.blood_DNA) + T.blood_DNA = list() if(istype(M,/mob/living/carbon/human)) - T.blood_DNA[T.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type) + T.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type else if(istype(M,/mob/living/carbon/alien)) - T.blood_DNA[T.blood_DNA.len] = list("UNKNOWN DNA","X*") + T.blood_DNA["UNKNOWN DNA"] = "X*" else if(istype(M,/mob/living/carbon/monkey)) - T.blood_DNA[T.blood_DNA.len] = list("Non-human DNA","A+") + T.blood_DNA["Non-human DNA"] = "A+" return var/obj/effect/decal/cleanable/blood/tracks/this = new(src) this.icon = 'footprints.dmi' @@ -817,14 +707,13 @@ turf/proc/add_bloody_footprints(mob/living/carbon/human/M,leaving,d,info,bloodco else if(bloodcolor == "xeno") this.desc = "These acidic bloody footprints appear to have been made by [info]." else if(bloodcolor == "oil") + this.name = "oil" this.desc = "These oil footprints appear to have been made by [info]." if(istype(M,/mob/living/carbon/human)) - if(this.blood_DNA.len) - this.blood_DNA.len++ - this.blood_DNA[this.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type) - else - this.blood_DNA = list(list(M.dna.unique_enzymes,M.dna.b_type)) + if(!this.blood_DNA) + this.blood_DNA = list() + this.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type proc/get_tracks(mob/M) if(istype(M,/mob/living)) @@ -839,14 +728,15 @@ proc/get_tracks(mob/M) else if(istype(M,/mob/living/carbon/alien/larva)) . = "small alien feet" else - . = "an unknown creature" -*/ + . = "an unknown creature"*/ + proc/blood_incompatible(donor,receiver) - var/donor_antigen = copytext(donor,1,lentext(donor)) - var/receiver_antigen = copytext(receiver,1,lentext(receiver)) - var/donor_rh = findtext("+",donor) - var/receiver_rh = findtext("+",receiver) + var + donor_antigen = copytext(donor,1,lentext(donor)) + receiver_antigen = copytext(receiver,1,lentext(receiver)) + donor_rh = findtext("+",donor) + receiver_rh = findtext("+",receiver) if(donor_rh && !receiver_rh) return 1 switch(receiver_antigen) if("A") @@ -859,16 +749,42 @@ proc/blood_incompatible(donor,receiver) return 0 /obj/item/weapon/rag + New() // So I don't have to grab maplock + spawn(1) + new/obj/item/weapon/reagent_containers/glass/rag(loc) + del src + +/obj/item/weapon/reagent_containers/glass/rag name = "damp rag" - desc = "For cleaning up messes, I suppose." + desc = "For cleaning up messes, you suppose." w_class = 1 icon = 'toy.dmi' icon_state = "rag" + amount_per_transfer_from_this = 5 + possible_transfer_amounts = list(5) + volume = 5 + can_be_placed_into = null + + attack(atom/target as obj|turf|area, mob/user as mob , flag) + if(ismob(target) && target.reagents && reagents.total_volume) + user.visible_message("\red \The [target] has been smothered with \the [src] by \the [user]!", "\red You smother \the [target] with \the [src]!", "You hear some struggling and muffled cries of surprise") + src.reagents.reaction(target, TOUCH) + spawn(5) src.reagents.clear_reagents() + return + else + ..() afterattack(atom/A as obj|turf|area, mob/user as mob) - if(istype(A)) + if(istype(A) && src in user) user.visible_message("[user] starts to wipe down [A] with [src]!") if(do_after(user,30)) user.visible_message("[user] finishes wiping off the [A]!") A.clean_blood() return + + examine() + if (!usr) + return + usr << "That's \a [src]." + usr << desc + return diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index 5597b31a17e..27edf5ef420 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -1,8 +1,6 @@ //CONTAINS: //Evidence bags and stuff /////////// -//Shamelessly ripped from Mini's old code. - /obj/item/weapon/evidencebag name = "evidence bag" desc = "An empty evidence bag." @@ -10,30 +8,38 @@ icon_state = "evidenceobj" w_class = 1 -/* buggy and stuff -/obj/item/weapon/evidencebag/attackby(obj/item/weapon/O, mob/user as mob) - return src.afterattack(O, user) -*/ - /obj/item/weapon/evidencebag/afterattack(obj/item/O, mob/user as mob) + if(!in_range(O,user)) + return + if(istype(O, /obj/item/weapon/storage) && O in user) return ..() + if(!(O && istype(O)) || O.anchored == 1) - user << "You can't put that inside the [src]!" + user << "You can't put that inside \the [src]!" return ..() - if(O in user) + + if(istype(O, /obj/item/weapon/evidencebag)) + user << "You find putting an evidence bag in another evidence bag to be slightly absurd." + return + + if(O in user && (user.l_hand != O && user.r_hand != O)) //If it is in their inventory, but not in their hands, don't grab it off of them. user << "You are wearing that." return - if(src.contents.len > 0) + + if(contents.len) user << "The [src] already has something inside it." return ..() + if(istype(O.loc,/obj/item/weapon/storage)) var/obj/item/weapon/storage/U = O.loc user.client.screen -= O U.contents.Remove(O) - user << "You put the [O] inside the [src]." + + user.visible_message("\The [user] puts \a [O] into \a [src]", "You put \the [O] inside \the [src].",\ + "You hear a rustle as someone puts something into a plastic bag.") icon_state = "evidence" - src.overlays += O + overlays += O desc = "An evidence bag containing \a [O]. [O.desc]" O.loc = src w_class = O.w_class @@ -41,17 +47,19 @@ /obj/item/weapon/evidencebag/attack_self(mob/user as mob) - if (src.contents.len > 0) - var/obj/item/I = src.contents[1] - user << "You take the [I] out of the [src]." - src.overlays -= I - I.loc = get_turf(user.loc) + if (contents.len) + var/obj/item/I = contents[1] + user.visible_message("\The [user] takes \a [I] out of \a [src]", "You take \the [I] out of \the [src].",\ + "You hear someone rustle around in a plastic bag, and remove something.") + overlays -= I + user.put_in_hands(I) w_class = 1 - src.icon_state = "evidenceobj" + icon_state = "evidenceobj" desc = "An empty evidence bag." + else - user << "[src] is empty." - src.icon_state = "evidenceobj" + user << "\The [src] is empty." + icon_state = "evidenceobj" return /obj/item/weapon/storage/box/evidence diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index a307099a72c..a1d29041b1d 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -145,8 +145,12 @@ emp_act else if(H.w_uniform) H.w_uniform.add_blood(src) if (H.gloves) H.gloves.add_blood(H) + H.gloves:transfer_blood = 2 + H.gloves:bloody_hands_mob = H else H.add_blood(H) + H.bloody_hands = 2 + H.bloody_hands_mob = H switch(hit_area) if("head")//Harder to score a stun but if you do it lasts a bit longer diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 3560c5791f9..c666f873328 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -269,3 +269,14 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return 0 +/mob/proc/put_in_hands(var/obj/item/I) //A suprisingly useful proc. Allows a simple way to place an object in a mob's hands, or, if they are full, on the ground below them. + if(!r_hand) + I.loc = src + r_hand = I + I.layer = 20 + else if(!l_hand) + I.loc = src + l_hand = I + I.layer = 20 + else + I.loc = get_turf(src) \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index 1c45d150215..d2b9a0eb9de 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -46,6 +46,15 @@ Stuff which is in development and not yet visible to players or just code relate should be listed in the changelog upon commit tho. Thanks. --> +
+

Friday, June 1st

+

SkyMarshal updated:

+ +

Friday, June 1st

diff --git a/maps/tgstation.2.0.9.dmm b/maps/tgstation.2.0.9.dmm index a0e53b6e55e..ec6b2e753f4 100644 --- a/maps/tgstation.2.0.9.dmm +++ b/maps/tgstation.2.0.9.dmm @@ -829,7 +829,7 @@ "apW" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "apX" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "apY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/security/detectives_office) -"apZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) +"apZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/closet/secure_closet/detective,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "aqa" = (/turf/simulated/floor{dir = 10; icon_state = "carpetside"},/area/security/detectives_office) "aqb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = "Streight"},/turf/simulated/floor{icon_state = "carpetside"},/area/security/detectives_office) "aqc" = (/turf/simulated/floor{dir = 6; icon_state = "carpetside"},/area/security/detectives_office) @@ -879,7 +879,7 @@ "aqU" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; frequency = 1439; icon_state = "off"; id_tag = null; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/light/small,/obj/item/weapon/camera_test{desc = "A one use - polaroid camera. 30 photos left."; name = "detectives camera"; pictures_left = 30},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "aqV" = (/obj/structure/table/woodentable,/obj/item/ammo_magazine/c38,/obj/item/ammo_magazine/c38,/obj/item/weapon/gun/projectile/detective,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "aqW" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = "Streight"},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) -"aqX" = (/obj/machinery/camera{c_tag = "Detective's Office"; dir = 1},/obj/structure/closet/secure_closet/detective,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) +"aqX" = (/obj/machinery/camera{c_tag = "Detective's Office"; dir = 1},/obj/machinery/computer/forensic_scanning,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "aqY" = (/obj/structure/table/woodentable,/obj/item/device/taperecorder{pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = "Streight"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/light,/obj/item/weapon/cartridge/lawyer,/turf/simulated/floor{icon_state = "wood"},/area/lawoffice) "aqZ" = (/obj/structure/table/woodentable,/obj/machinery/camera{c_tag = "Law Office"; dir = 1; network = "SS13"},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/machinery/computer/security/telescreen{name = "Prison Monitor"; network = "Prison"; pixel_x = 0; pixel_y = -30},/turf/simulated/floor{icon_state = "wood"},/area/lawoffice) "ara" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/photocopier,/turf/simulated/floor{icon_state = "wood"},/area/lawoffice) diff --git a/tgstation.dme b/tgstation.dme index eeb1cef8284..bf0145653b6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -823,6 +823,8 @@ #include "code\modules\critters\critter_defenses.dm" #include "code\modules\critters\critters.dm" #include "code\modules\critters\hivebots\hivebot.dm" +#include "code\modules\detectivework\detective_work.dm" +#include "code\modules\detectivework\evidence.dm" #include "code\modules\flufftext\Dreaming.dm" #include "code\modules\flufftext\Hallucination.dm" #include "code\modules\flufftext\TextFilters.dm"