mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-19 02:56:14 +01:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into 12/14/2015_communicators_v2
This commit is contained in:
+22
-22
@@ -1,13 +1,9 @@
|
||||
/*
|
||||
|
||||
Making Bombs with ZAS:
|
||||
Make burny fire with lots of burning
|
||||
Draw off 5000K gas from burny fire
|
||||
Separate gas into oxygen and phoron components
|
||||
Obtain phoron and oxygen tanks filled up about 50-75% with normal-temp gas
|
||||
Fill rest with super hot gas from separated canisters, they should be about 125C now.
|
||||
Attach to transfer valve and open. BOOM.
|
||||
|
||||
Get gas to react in an air tank so that it gains pressure. If it gains enough pressure, it goes boom.
|
||||
The more pressure, the more boom.
|
||||
If it gains pressure too slowly, it may leak or just rupture instead of exploding.
|
||||
*/
|
||||
|
||||
//#define FIREDBG
|
||||
@@ -268,16 +264,16 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
//determine how far the reaction can progress
|
||||
var/reaction_limit = min(total_oxidizers*(FIRE_REACTION_FUEL_AMOUNT/FIRE_REACTION_OXIDIZER_AMOUNT), total_fuel) //stoichiometric limit
|
||||
|
||||
//calculate the firelevel.
|
||||
var/firelevel = calculate_firelevel(total_fuel, total_oxidizers, reaction_limit)
|
||||
var/firelevel_ratio = firelevel / vsc.fire_firelevel_multiplier
|
||||
|
||||
//vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn).)
|
||||
var/gas_firelevel = calculate_firelevel(gas_fuel, total_oxidizers, reaction_limit, volume*group_multiplier) / vsc.fire_firelevel_multiplier
|
||||
var/min_burn = 0.30*volume*group_multiplier/CELL_VOLUME //in moles - so that fires with very small gas concentrations burn out fast
|
||||
var/gas_reaction_progress = min(max(min_burn, firelevel_ratio*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
|
||||
var/gas_reaction_progress = min(max(min_burn, gas_firelevel*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
|
||||
|
||||
//liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning. Limit the burn rate to a certain amount per area.
|
||||
var/liquid_reaction_progress = min((firelevel_ratio*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
|
||||
var/liquid_firelevel = calculate_firelevel(liquid_fuel, total_oxidizers, reaction_limit, 0) / vsc.fire_firelevel_multiplier
|
||||
var/liquid_reaction_progress = min((liquid_firelevel*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
|
||||
|
||||
var/firelevel = (gas_fuel*gas_firelevel + liquid_fuel*liquid_firelevel)/total_fuel
|
||||
|
||||
var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress
|
||||
var/used_fuel = min(total_reaction_progress, reaction_limit)
|
||||
@@ -286,7 +282,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
#ifdef FIREDBG
|
||||
log_debug("gas_fuel = [gas_fuel], liquid_fuel = [liquid_fuel], total_oxidizers = [total_oxidizers]")
|
||||
log_debug("fuel_area = [fuel_area], total_fuel = [total_fuel], reaction_limit = [reaction_limit]")
|
||||
log_debug("firelevel -> [firelevel] / [vsc.fire_firelevel_multiplier]")
|
||||
log_debug("firelevel -> [firelevel] (gas: [gas_firelevel], liquid: [liquid_firelevel])")
|
||||
log_debug("liquid_reaction_progress = [liquid_reaction_progress]")
|
||||
log_debug("gas_reaction_progress = [gas_reaction_progress]")
|
||||
log_debug("total_reaction_progress = [total_reaction_progress]")
|
||||
@@ -315,13 +311,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
//calculate the energy produced by the reaction and then set the new temperature of the mix
|
||||
temperature = (starting_energy + vsc.fire_fuel_energy_release * (used_gas_fuel + used_liquid_fuel)) / heat_capacity()
|
||||
update_values()
|
||||
|
||||
#ifdef FIREDBG
|
||||
log_debug("used_gas_fuel = [used_gas_fuel]; used_liquid_fuel = [used_liquid_fuel]; total = [used_fuel]")
|
||||
log_debug("new temperature = [temperature]")
|
||||
log_debug("new temperature = [temperature]; new pressure = [return_pressure()]")
|
||||
#endif
|
||||
|
||||
update_values()
|
||||
|
||||
return firelevel
|
||||
|
||||
datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
@@ -363,27 +359,31 @@ datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
break
|
||||
|
||||
//returns a value between 0 and vsc.fire_firelevel_multiplier
|
||||
/datum/gas_mixture/proc/calculate_firelevel(total_fuel, total_oxidizers, reaction_limit)
|
||||
/datum/gas_mixture/proc/calculate_firelevel(total_fuel, total_oxidizers, reaction_limit, gas_volume)
|
||||
//Calculates the firelevel based on one equation instead of having to do this multiple times in different areas.
|
||||
var/firelevel = 0
|
||||
|
||||
var/total_combustables = (total_fuel + total_oxidizers)
|
||||
var/active_combustables = (FIRE_REACTION_OXIDIZER_AMOUNT/FIRE_REACTION_FUEL_AMOUNT + 1)*reaction_limit
|
||||
|
||||
if(total_combustables > 0)
|
||||
//slows down the burning when the concentration of the reactants is low
|
||||
var/dampening_multiplier = min(1, reaction_limit / (total_moles/group_multiplier))
|
||||
var/damping_multiplier = min(1, active_combustables / (total_moles/group_multiplier))
|
||||
|
||||
//weight the damping mult so that it only really brings down the firelevel when the ratio is closer to 0
|
||||
damping_multiplier = 2*damping_multiplier - (damping_multiplier*damping_multiplier)
|
||||
|
||||
//calculates how close the mixture of the reactants is to the optimum
|
||||
//fires burn better when there is more oxidizer -- too much fuel will choke them out a bit, reducing firelevel.
|
||||
//fires burn better when there is more oxidizer -- too much fuel will choke the fire out a bit, reducing firelevel.
|
||||
var/mix_multiplier = 1 / (1 + (5 * ((total_fuel / total_combustables) ** 2)))
|
||||
|
||||
#ifdef FIREDBG
|
||||
ASSERT(dampening_multiplier <= 1)
|
||||
ASSERT(damping_multiplier <= 1)
|
||||
ASSERT(mix_multiplier <= 1)
|
||||
#endif
|
||||
|
||||
//toss everything together -- should produce a value between 0 and fire_firelevel_multiplier
|
||||
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
|
||||
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * damping_multiplier
|
||||
|
||||
return max( 0, firelevel)
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ var/global/vs_control/vsc = new
|
||||
var/fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
|
||||
var/fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
|
||||
|
||||
var/fire_fuel_energy_release = 397000
|
||||
//Note that this parameter and the phoron heat capacity have a significant impact on TTV yield.
|
||||
var/fire_fuel_energy_release = 866000 //J/mol. Adjusted to compensate for fire energy release being fixed, was 397000
|
||||
var/fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
|
||||
var/fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
|
||||
|
||||
|
||||
@@ -59,15 +59,15 @@
|
||||
|
||||
//These control the speed at which fire burns
|
||||
#define FIRE_GAS_BURNRATE_MULT 1
|
||||
#define FIRE_LIQUID_BURNRATE_MULT 1
|
||||
#define FIRE_LIQUID_BURNRATE_MULT 0.225
|
||||
|
||||
//If the fire is burning slower than this rate then the reaction is going too slow to be self sustaining and the fire burns itself out.
|
||||
//This ensures that fires don't grind to a near-halt while still remaining active forever.
|
||||
#define FIRE_GAS_MIN_BURNRATE 0.01
|
||||
#define FIRE_LIQUD_MIN_BURNRATE 0.01
|
||||
#define FIRE_LIQUD_MIN_BURNRATE 0.0025
|
||||
|
||||
//How many moles of fuel are contained within one solid/liquid fuel volume unit
|
||||
#define LIQUIDFUEL_AMOUNT_TO_MOL 1 //mol/volume unit
|
||||
#define LIQUIDFUEL_AMOUNT_TO_MOL 0.45 //mol/volume unit
|
||||
|
||||
// XGM gas flags.
|
||||
#define XGM_GAS_FUEL 1
|
||||
|
||||
+18
-18
@@ -63,24 +63,24 @@
|
||||
#define LIFE_HUD 10 // STATUS_HUD that only reports dead or alive
|
||||
|
||||
//some colors
|
||||
#define COLOR_WHITE "#FFFFFF"
|
||||
#define COLOR_SILVER "#C0C0C0"
|
||||
#define COLOR_GRAY "#808080"
|
||||
#define COLOR_BLACK "#000000"
|
||||
#define COLOR_RED "#FF0000"
|
||||
#define COLOR_MAROON "#800000"
|
||||
#define COLOR_YELLOW "#FFFF00"
|
||||
#define COLOR_OLIVE "#808000"
|
||||
#define COLOR_LIME "#00FF00"
|
||||
#define COLOR_GREEN "#008000"
|
||||
#define COLOR_CYAN "#00FFFF"
|
||||
#define COLOR_TEAL "#008080"
|
||||
#define COLOR_BLUE "#0000FF"
|
||||
#define COLOR_NAVY "#000080"
|
||||
#define COLOR_PINK "#FF00FF"
|
||||
#define COLOR_PURPLE "#800080"
|
||||
#define COLOR_ORANGE "#FF9900"
|
||||
|
||||
#define COLOR_WHITE "#FFFFFF"
|
||||
#define COLOR_SILVER "#C0C0C0"
|
||||
#define COLOR_GRAY "#808080"
|
||||
#define COLOR_BLACK "#000000"
|
||||
#define COLOR_RED "#FF0000"
|
||||
#define COLOR_MAROON "#800000"
|
||||
#define COLOR_YELLOW "#FFFF00"
|
||||
#define COLOR_OLIVE "#808000"
|
||||
#define COLOR_LIME "#00FF00"
|
||||
#define COLOR_GREEN "#008000"
|
||||
#define COLOR_CYAN "#00FFFF"
|
||||
#define COLOR_TEAL "#008080"
|
||||
#define COLOR_BLUE "#0000FF"
|
||||
#define COLOR_NAVY "#000080"
|
||||
#define COLOR_PINK "#FF00FF"
|
||||
#define COLOR_PURPLE "#800080"
|
||||
#define COLOR_ORANGE "#FF9900"
|
||||
#define COLOR_LUMINOL "#66FFFF"
|
||||
// Shuttles.
|
||||
|
||||
// These define the time taken for the shuttle to get to the space station, and the time before it leaves again.
|
||||
|
||||
@@ -46,8 +46,12 @@ var/global/list/facial_hair_styles_male_list = list()
|
||||
var/global/list/facial_hair_styles_female_list = list()
|
||||
var/global/list/skin_styles_female_list = list() //unused
|
||||
//Underwear
|
||||
var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6", "None") //Curse whoever made male/female underwear diffrent colours
|
||||
var/global/list/underwear_f = list("Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6", "Black Sports" = "f7","White Sports" = "f8","None")
|
||||
var/global/list/underwear_m = list(
|
||||
"White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6",
|
||||
"Boxers Heart" = "m7", "Boxers Black" = "m8", "Boxers Grey" = "m9", "Boxers Stripe" = "m10", "None") //Curse whoever made male/female underwear diffrent colours
|
||||
var/global/list/underwear_f = list(
|
||||
"Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6",
|
||||
"Black Sports" = "f7","White Sports" = "f8", "Black Sports Alt" = "f9", "White Sports Alt" = "f10", "Baby Blue" = "f11", "Green" = "f12", "Pink" = "f13", "None")
|
||||
//undershirt
|
||||
var/global/list/undershirt_t = list(
|
||||
"White tank top" = "u1", "Black tank top" = "u2", "Black shirt" = "u3",
|
||||
@@ -60,14 +64,15 @@ var/global/list/undershirt_t = list(
|
||||
"Grey-yellow polo shirt" = "grayyellowpolo_s", "Fire tank top" = "tank_fire_s", "NT shirt" = "shirt_nano_s",
|
||||
"Blue shirt 2" = "shirt_blue_s", "Red shirt 2" = "shirt_red_s", "Red tank top" = "tank_red_s", "Green shirt 2" = "shirt_green_s",
|
||||
"Tiedye shirt" = "shirt_tiedye_s", "Green sport shirt" = "greenshirtsport_s", "Red sport shirt" = "redshirtsport_s",
|
||||
"Blue sport shirt" = "blueshirtsport_s", "None")
|
||||
"Blue striped shirt" = "shirt_stripes_s", "Blue sport shirt" = "blueshirtsport_s", "None")
|
||||
//Socks
|
||||
var/global/list/socks_t = list(
|
||||
"White normal" = "white_norm", "White short" = "white_short", "White knee" = "white_knee",
|
||||
"White thigh" = "white_thigh", "Black normal" = "black_norm", "Black short" = "black_short",
|
||||
"Black knee" = "black_knee", "Black thigh" = "black_thigh", "Thin knee" = "thin_knee",
|
||||
"Thin thigh" = "thin_thigh", "Pantyhose" = "pantyhose", "Striped thigh" = "striped_thigh",
|
||||
"Striped knee" = "striped_knee", "Rainbow knee" = "rainbow_knee", "Rainbow thigh" = "rainbow_thigh", "None")
|
||||
"Striped knee" = "striped_knee", "Rainbow knee" = "rainbow_knee", "Rainbow thigh" = "rainbow_thigh",
|
||||
"Fishnets" = "fishnet", "Thin white thigh" = "thinwhite_thigh", "Thin white knee" = "thinwhite_knee", "None")
|
||||
|
||||
//Backpacks
|
||||
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
|
||||
|
||||
@@ -172,6 +172,8 @@ var/list/gamemode_cache = list()
|
||||
var/enter_allowed = 1
|
||||
|
||||
var/use_irc_bot = 0
|
||||
var/use_node_bot = 0
|
||||
var/irc_bot_port = 0
|
||||
var/irc_bot_host = ""
|
||||
var/irc_bot_export = 0 // whether the IRC bot in use is a Bot32 (or similar) instance; Bot32 uses world.Export() instead of nudge.py/libnudge
|
||||
var/main_irc = ""
|
||||
@@ -545,6 +547,12 @@ var/list/gamemode_cache = list()
|
||||
if("use_irc_bot")
|
||||
use_irc_bot = 1
|
||||
|
||||
if("use_node_bot")
|
||||
use_node_bot = 1
|
||||
|
||||
if("irc_bot_port")
|
||||
config.irc_bot_port = value
|
||||
|
||||
if("irc_bot_export")
|
||||
irc_bot_export = 1
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
if (evac)
|
||||
emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station at docks one and two. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.")
|
||||
else
|
||||
priority_announcement.Announce("The scheduled Crew Transfer Shuttle has docked with the station at docks one and two. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.")
|
||||
priority_announcement.Announce("The scheduled shuttle to the Vir Regional Spaceport has docked with the station at docks one and two. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.")
|
||||
|
||||
//arm the escape pods
|
||||
if (evac)
|
||||
@@ -94,7 +94,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
//reset the shuttle transit time if we need to
|
||||
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
|
||||
|
||||
priority_announcement.Announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive at docks one and two in approximately [round(estimate_arrival_time()/60)] minutes.")
|
||||
priority_announcement.Announce("The regularly scheduled shuttle to the Vir Regional Spaceport will arrive in in approximately [round(estimate_arrival_time()/60)] minutes. Those leaving should proceed to docks one and two.")
|
||||
|
||||
//recalls the shuttle
|
||||
/datum/emergency_shuttle_controller/proc/recall()
|
||||
|
||||
+5
-6
@@ -54,6 +54,7 @@
|
||||
var/datum/changeling/changeling //changeling holder
|
||||
|
||||
var/rev_cooldown = 0
|
||||
var/tcrystals = 0
|
||||
|
||||
// the world.time since the mob has been brigged, or -1 if not at all
|
||||
var/brigged_since = -1
|
||||
@@ -375,14 +376,12 @@
|
||||
memory = null//Remove any memory they may have had.
|
||||
if("crystals")
|
||||
if (usr.client.holder.rights & R_FUN)
|
||||
var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
|
||||
// var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink() No longer needed, uses stored in mind
|
||||
var/crystals
|
||||
if (suplink)
|
||||
crystals = suplink.uses
|
||||
crystals = input("Amount of telecrystals for [key]","Operative uplink", crystals) as null|num
|
||||
crystals = tcrystals
|
||||
crystals = input("Amount of telecrystals for [key]", crystals) as null|num
|
||||
if (!isnull(crystals))
|
||||
if (suplink)
|
||||
suplink.uses = crystals
|
||||
tcrystals = crystals
|
||||
|
||||
else if (href_list["obj_announce"])
|
||||
var/obj_count = 1
|
||||
|
||||
@@ -43,6 +43,20 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
group = "Security"
|
||||
hidden = 1
|
||||
|
||||
/datum/supply_packs/forensics
|
||||
name = "Auxiliary forensic tools"
|
||||
contains = list(/obj/item/weapon/forensics/sample_kit,
|
||||
/obj/item/weapon/forensics/sample_kit/powder,
|
||||
/obj/item/weapon/storage/box/swabs,
|
||||
/obj/item/weapon/storage/box/swabs,
|
||||
/obj/item/weapon/storage/box/swabs,
|
||||
/obj/item/weapon/storage/box/slides,
|
||||
/obj/item/weapon/reagent_containers/spray/luminol)
|
||||
cost = 30
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Auxiliary forensic tools"
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/food
|
||||
name = "Kitchen supply crate"
|
||||
contains = list(/obj/item/weapon/reagent_containers/food/condiment/flour,
|
||||
@@ -124,6 +138,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/reagent_containers/food/drinks/flask/barflask,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/patron,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,
|
||||
/obj/item/weapon/lipstick/random,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale,
|
||||
@@ -1550,8 +1565,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
num_contained = 4
|
||||
contains = list(/obj/item/clothing/accessory/storage/black_vest,
|
||||
/obj/item/clothing/accessory/storage/brown_vest,
|
||||
/obj/item/clothing/accessory/storage/webbing,
|
||||
/obj/item/clothing/accessory/storage)
|
||||
/obj/item/clothing/accessory/storage/webbing)
|
||||
cost = 15
|
||||
containertype = "/obj/structure/closet/crate"
|
||||
containername = "Webbing crate"
|
||||
@@ -1628,8 +1642,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
|
||||
/datum/supply_packs/detectivegear
|
||||
name = "Forensic investigation equipment"
|
||||
contains = list(/obj/item/device/detective_scanner,
|
||||
/obj/item/weapon/storage/box/evidence,
|
||||
contains = list(/obj/item/weapon/storage/box/evidence,
|
||||
/obj/item/weapon/storage/box/evidence,
|
||||
/obj/item/clothing/suit/storage/vest/detective,
|
||||
/obj/item/weapon/cartridge/detective,
|
||||
@@ -1639,6 +1652,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/device/camera,
|
||||
/obj/item/weapon/folder/red,
|
||||
/obj/item/weapon/folder/blue,
|
||||
/obj/item/weapon/storage/belt/detective,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/device/mass_spectrometer,
|
||||
|
||||
@@ -41,7 +41,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
|
||||
(A.locked ? "The door bolts have fallen!" : "The door bolts look up."),
|
||||
((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"),
|
||||
((haspower) ? "The test light is on." : "The test light is off!"),
|
||||
((A.backupPowerCablesCut()) ? "The backup power light is off!" : "The backup power light is on."),
|
||||
((A.backup_power_lost_until) ? "The backup power light is off!" : "The backup power light is on."),
|
||||
((A.aiControlDisabled==0 && !A.emagged && haspower)? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."),
|
||||
((A.safe==0 && haspower)? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."),
|
||||
((A.normalspeed==0 && haspower)? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."),
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
/decl/xgm_gas/phoron
|
||||
id = "phoron"
|
||||
name = "Phoron"
|
||||
|
||||
//Note that this has a significant impact on TTV yield.
|
||||
//Because it is so high, any leftover phoron soaks up a lot of heat and drops the yield pressure.
|
||||
specific_heat = 200 // J/(mol*K)
|
||||
|
||||
//Hypothetical group 14 (same as carbon), period 8 element.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
if(!antag_indicator || !other.current || !recipient.current)
|
||||
return
|
||||
var/indicator = (faction_indicator && (other in faction_members)) ? faction_indicator : antag_indicator
|
||||
return image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator)
|
||||
return image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator, layer = LIGHTING_LAYER+0.1)
|
||||
|
||||
/datum/antagonist/proc/update_all_icons()
|
||||
if(!antag_indicator)
|
||||
|
||||
@@ -43,6 +43,7 @@ var/datum/antagonist/mercenary/mercs
|
||||
if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack)
|
||||
player.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT
|
||||
|
||||
if (player.mind == leader)
|
||||
var/obj/item/device/radio/uplink/U = new(player.loc, player.mind, 40)
|
||||
|
||||
@@ -81,6 +81,7 @@ var/datum/antagonist/traitor/traitors
|
||||
return 0
|
||||
|
||||
spawn_uplink(traitor_mob)
|
||||
traitor_mob.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT
|
||||
// Tell them about people they might want to contact.
|
||||
var/mob/living/carbon/human/M = get_nt_opposed()
|
||||
if(M && M != traitor_mob)
|
||||
|
||||
@@ -105,6 +105,7 @@ var/list/ghostteleportlocs = list()
|
||||
power_equip = 0
|
||||
power_environ = 0
|
||||
ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg')
|
||||
base_turf = /turf/space
|
||||
|
||||
area/space/atmosalert()
|
||||
return
|
||||
|
||||
+8
-3
@@ -6,12 +6,14 @@
|
||||
var/list/fingerprintshidden
|
||||
var/fingerprintslast = null
|
||||
var/list/blood_DNA
|
||||
var/was_bloodied
|
||||
var/blood_color
|
||||
var/last_bumped = 0
|
||||
var/pass_flags = 0
|
||||
var/throwpass = 0
|
||||
var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
|
||||
var/simulated = 1 //filter for actions - used by lighting overlays
|
||||
var/fluorescent // Shows up under a UV light.
|
||||
|
||||
///Chemistry.
|
||||
var/datum/reagents/reagents = null
|
||||
@@ -23,6 +25,9 @@
|
||||
//Detective Work, used for the duplicate data points kept in the scanners
|
||||
var/list/original_atom
|
||||
|
||||
/atom/proc/reveal_blood()
|
||||
return
|
||||
|
||||
/atom/proc/assume_air(datum/gas_mixture/giver)
|
||||
return null
|
||||
|
||||
@@ -304,7 +309,7 @@ its easier to just keep the beam vertical.
|
||||
fingerprints = list()
|
||||
|
||||
//Hash this shit.
|
||||
var/full_print = md5(H.dna.uni_identity)
|
||||
var/full_print = H.get_full_print()
|
||||
|
||||
// Add the fingerprints
|
||||
//
|
||||
@@ -387,6 +392,7 @@ its easier to just keep the beam vertical.
|
||||
if(!blood_DNA || !istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it.
|
||||
blood_DNA = list()
|
||||
|
||||
was_bloodied = 1
|
||||
blood_color = "#A10808"
|
||||
if(istype(M))
|
||||
if (!istype(M.dna, /datum/dna))
|
||||
@@ -406,16 +412,15 @@ its easier to just keep the beam vertical.
|
||||
if(toxvomit)
|
||||
this.icon_state = "vomittox_[pick(1,4)]"
|
||||
|
||||
|
||||
/atom/proc/clean_blood()
|
||||
if(!simulated)
|
||||
return
|
||||
fluorescent = 0
|
||||
src.germ_level = 0
|
||||
if(istype(blood_DNA, /list))
|
||||
blood_DNA = null
|
||||
return 1
|
||||
|
||||
|
||||
/atom/proc/get_global_map_pos()
|
||||
if(!islist(global_map) || isemptylist(global_map)) return
|
||||
var/cur_x = null
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/throw_range = 7
|
||||
var/moved_recently = 0
|
||||
var/mob/pulledby = null
|
||||
var/item_state = null // Used to specify the item state for the on-mob overlays.
|
||||
|
||||
var/auto_init = 1
|
||||
|
||||
|
||||
@@ -219,14 +219,12 @@ var/global/list/Holiday = list() //Holidays are lists now, so we can have more t
|
||||
|
||||
//Run at the start of a round
|
||||
/proc/Holiday_Game_Start()
|
||||
world << Holiday
|
||||
if(Holiday.len != 0)
|
||||
var/list/holidays = list()
|
||||
var/list/holiday_blurbs = list()
|
||||
for(var/p in Holiday)
|
||||
holidays.Add(p)
|
||||
holiday_blurbs.Add("[Holiday[p]]")
|
||||
world << "[p] = [Holiday[p]]"
|
||||
var/holidays_string = english_list(holidays, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
|
||||
world << "<font color='blue'>and...</font>"
|
||||
world << "<h4>Happy [holidays_string] Everybody!</h4>"
|
||||
|
||||
@@ -111,12 +111,11 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/flame/lighter/zippo(H), slot_l_store)
|
||||
if(H.backbag == 1)//Why cant some of these things spawn in his office?
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/evidence(H), slot_l_hand)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/detective_scanner(H), slot_r_store)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/evidence(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/detective_scanner(H), slot_in_backpack)
|
||||
if(H.mind.role_alt_title && H.mind.role_alt_title == "Forensic Technician")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/forensics/blue(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase/crimekit, slot_r_hand)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_trench(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/det(H), slot_head)
|
||||
@@ -149,6 +148,7 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/security(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_s_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store)
|
||||
if(H.backbag == 1)
|
||||
|
||||
@@ -413,5 +413,3 @@
|
||||
path = /obj/item/weapon/handcuffs
|
||||
hidden = 1
|
||||
category = "General"
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,4 @@
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/button/attackby(obj/item/weapon/W, mob/user as mob)
|
||||
if(istype(W, /obj/item/device/detective_scanner))
|
||||
return
|
||||
return src.attack_hand(user)
|
||||
@@ -141,7 +141,6 @@
|
||||
assembly.camera_network = english_list(network, NETWORK_EXODUS, ",", ",")
|
||||
assembly.update_icon()
|
||||
assembly.dir = src.dir
|
||||
assembly = null //so qdel doesn't eat it.
|
||||
if(stat & BROKEN)
|
||||
assembly.state = 2
|
||||
user << "<span class='notice'>You repaired \the [src] frame.</span>"
|
||||
@@ -149,6 +148,7 @@
|
||||
assembly.state = 1
|
||||
user << "<span class='notice'>You cut \the [src] free from the wall.</span>"
|
||||
new /obj/item/stack/cable_coil(src.loc, length=2)
|
||||
assembly = null //so qdel doesn't eat it.
|
||||
qdel(src)
|
||||
|
||||
// OTHER
|
||||
|
||||
@@ -24,22 +24,6 @@
|
||||
user << "Error, no route to host."
|
||||
|
||||
/obj/machinery/button/remote/attackby(obj/item/weapon/W, mob/user as mob)
|
||||
/* For later implementation
|
||||
if (istype(W, /obj/item/weapon/screwdriver))
|
||||
{
|
||||
if(wiresexposed)
|
||||
icon_state = "doorctrl0"
|
||||
wiresexposed = 0
|
||||
|
||||
else
|
||||
icon_state = "doorctrl-open"
|
||||
wiresexposed = 1
|
||||
|
||||
return
|
||||
}
|
||||
*/
|
||||
if(istype(W, /obj/item/device/detective_scanner))
|
||||
return
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/button/remote/emag_act(var/remaining_charges, var/mob/user)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
var/electrified_until = 0 //World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it.
|
||||
var/main_power_lost_until = 0 //World time when main power is restored.
|
||||
var/backup_power_lost_until = -1 //World time when backup power is restored.
|
||||
var/next_beep_at = 0 //World time when we may next beep due to doors being blocked by mobs
|
||||
var/has_beeped = 0 //If 1, will not beep on failed closing attempt. Resets when door closes.
|
||||
var/spawnPowerRestoreRunning = 0
|
||||
var/welded = null
|
||||
var/locked = 0
|
||||
@@ -750,7 +750,7 @@ About the new airlock wires panel:
|
||||
if(src.isElectrified())
|
||||
if(src.shock(user, 75))
|
||||
return
|
||||
if(istype(C, /obj/item/device/detective_scanner) || istype(C, /obj/item/taperoll))
|
||||
if(istype(C, /obj/item/taperoll))
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
@@ -958,9 +958,9 @@ About the new airlock wires panel:
|
||||
for(var/turf/turf in locs)
|
||||
for(var/atom/movable/AM in turf)
|
||||
if(AM.blocks_airlock())
|
||||
if(world.time > next_beep_at)
|
||||
if(!has_beeped)
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
next_beep_at = world.time + SecondsToTicks(10)
|
||||
has_beeped = 1
|
||||
close_door_at = world.time + 6
|
||||
return
|
||||
|
||||
@@ -970,6 +970,7 @@ About the new airlock wires panel:
|
||||
take_damage(DOOR_CRUSH_DAMAGE)
|
||||
|
||||
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
|
||||
has_beeped = 0
|
||||
if(arePowerSystemsOn())
|
||||
playsound(src.loc, open_sound_powered, 100, 1)
|
||||
else
|
||||
|
||||
@@ -202,8 +202,6 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/device/detective_scanner))
|
||||
return
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name())
|
||||
|
||||
@@ -72,8 +72,6 @@
|
||||
// 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
|
||||
|
||||
@@ -549,9 +549,8 @@
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user)
|
||||
if(src.panel_open)
|
||||
user << "<span class='notice'>You insert \the [src] in the product receptor.</span>"
|
||||
R.amount++
|
||||
user << "<span class='notice'>You insert \the [src] in the product receptor.</span>"
|
||||
R.amount++
|
||||
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
@@ -687,7 +686,8 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/flask/barflask = 2, /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask = 2,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor = 2,/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 2,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 2,/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5)
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 2,/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey = 4)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10)
|
||||
vend_delay = 15
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
@@ -725,11 +725,11 @@
|
||||
icon_state = "snack"
|
||||
products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/snacks/chips =6,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 6)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 3)
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 6, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 3)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips = 1,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2)
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 4)
|
||||
|
||||
|
||||
|
||||
@@ -781,7 +781,12 @@
|
||||
/obj/item/weapon/storage/fancy/cigarettes/carcinomas = 5,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/professionals = 5,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/killthroat = 5)
|
||||
prices = list(/obj/item/weapon/storage/fancy/cigarettes = 15,/obj/item/weapon/storage/box/matches = 1,/obj/item/weapon/flame/lighter/random = 2)
|
||||
prices = list(/obj/item/weapon/storage/fancy/cigarettes = 15,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/luckystars = 17,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/jerichos = 22,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/menthols = 18,
|
||||
/obj/item/weapon/storage/box/matches = 1,
|
||||
/obj/item/weapon/flame/lighter/random = 2)
|
||||
|
||||
|
||||
/obj/machinery/vending/medical
|
||||
|
||||
@@ -22,6 +22,20 @@ var/global/list/image/splatter_cache=list()
|
||||
var/amount = 5
|
||||
var/drytime
|
||||
|
||||
/obj/effect/decal/cleanable/blood/reveal_blood()
|
||||
if(!fluorescent)
|
||||
fluorescent = 1
|
||||
basecolor = COLOR_LUMINOL
|
||||
update_icon()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/clean_blood()
|
||||
fluorescent = 0
|
||||
if(invisibility != 100)
|
||||
invisibility = 100
|
||||
amount = 0
|
||||
processing_objects -= src
|
||||
..(ignore=1)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/Destroy()
|
||||
for(var/datum/disease/D in viruses)
|
||||
D.cure(0)
|
||||
|
||||
@@ -29,6 +29,13 @@ var/global/list/image/fluidtrack_cache=list()
|
||||
src.basecolor=_color
|
||||
src.wet=_wet
|
||||
|
||||
/obj/effect/decal/cleanable/blood/tracks/reveal_blood()
|
||||
if(!fluorescent)
|
||||
if(stack && stack.len)
|
||||
for(var/datum/fluidtrack/track in stack)
|
||||
track.basecolor = COLOR_LUMINOL
|
||||
..()
|
||||
|
||||
// Footprints, tire trails...
|
||||
/obj/effect/decal/cleanable/blood/tracks
|
||||
amount = 0
|
||||
@@ -114,7 +121,8 @@ var/global/list/image/fluidtrack_cache=list()
|
||||
updated=1
|
||||
|
||||
dirs |= comingdir|realgoing
|
||||
blood_DNA |= DNA.Copy()
|
||||
if(islist(blood_DNA))
|
||||
blood_DNA |= DNA.Copy()
|
||||
if(updated)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
/obj/effect/decal/cleanable
|
||||
var/list/random_icon_states = list()
|
||||
|
||||
/obj/effect/decal/cleanable/clean_blood(var/ignore = 0)
|
||||
if(!ignore)
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/effect/decal/cleanable/New()
|
||||
if (random_icon_states && length(src.random_icon_states) > 0)
|
||||
src.icon_state = pick(src.random_icon_states)
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
latejoin_gateway += loc
|
||||
qdel(src)
|
||||
return
|
||||
if("JoinLateElevator")
|
||||
latejoin_elevator += loc
|
||||
qdel(src)
|
||||
return
|
||||
if("JoinLateCryo")
|
||||
latejoin_cryo += loc
|
||||
qdel(src)
|
||||
|
||||
@@ -105,27 +105,61 @@
|
||||
qdel(src)
|
||||
*/
|
||||
|
||||
/client/proc/spawn_tanktransferbomb()
|
||||
set category = "Debug"
|
||||
set desc = "Spawn a tank transfer valve bomb"
|
||||
set name = "Instant TTV"
|
||||
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/obj/effect/spawner/newbomb/proto = /obj/effect/spawner/newbomb/radio/custom
|
||||
|
||||
var/p = input("Enter phoron amount (mol):","Phoron", initial(proto.phoron_amt)) as num|null
|
||||
if(p == null) return
|
||||
|
||||
var/o = input("Enter oxygen amount (mol):","Oxygen", initial(proto.oxygen_amt)) as num|null
|
||||
if(o == null) return
|
||||
|
||||
var/c = input("Enter carbon dioxide amount (mol):","Carbon Dioxide", initial(proto.carbon_amt)) as num|null
|
||||
if(c == null) return
|
||||
|
||||
new /obj/effect/spawner/newbomb/radio/custom(get_turf(mob), p, o, c)
|
||||
|
||||
/obj/effect/spawner/newbomb
|
||||
name = "bomb"
|
||||
name = "TTV bomb"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "x"
|
||||
var/btype = 0 // 0=radio, 1=prox, 2=time
|
||||
|
||||
var/assembly_type = /obj/item/device/assembly/signaler
|
||||
|
||||
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
|
||||
var/phoron_amt = 10.96
|
||||
var/oxygen_amt = 16.44
|
||||
var/carbon_amt = 0.0
|
||||
|
||||
timer
|
||||
btype = 2
|
||||
/obj/effect/spawner/newbomb/timer
|
||||
name = "TTV bomb - timer"
|
||||
assembly_type = /obj/item/device/assembly/timer
|
||||
|
||||
syndicate
|
||||
/obj/effect/spawner/newbomb/timer/syndicate
|
||||
name = "TTV bomb - merc"
|
||||
//High yield bombs. Yes, it is possible to make these with toxins
|
||||
phoron_amt = 15.66
|
||||
oxygen_amt = 24.66
|
||||
|
||||
proximity
|
||||
btype = 1
|
||||
/obj/effect/spawner/newbomb/proximity
|
||||
name = "TTV bomb - proximity"
|
||||
assembly_type = /obj/item/device/assembly/prox_sensor
|
||||
|
||||
radio
|
||||
btype = 0
|
||||
|
||||
|
||||
/obj/effect/spawner/newbomb/New()
|
||||
/obj/effect/spawner/newbomb/radio/custom/New(var/newloc, ph, ox, co)
|
||||
if(ph != null) phoron_amt = ph
|
||||
if(ox != null) oxygen_amt = ox
|
||||
if(co != null) carbon_amt = co
|
||||
..()
|
||||
|
||||
/obj/effect/spawner/newbomb/New(newloc)
|
||||
..(newloc)
|
||||
|
||||
var/obj/item/device/transfer_valve/V = new(src.loc)
|
||||
var/obj/item/weapon/tank/phoron/PT = new(V)
|
||||
var/obj/item/weapon/tank/oxygen/OT = new(V)
|
||||
@@ -137,28 +171,15 @@
|
||||
OT.master = V
|
||||
|
||||
PT.air_contents.temperature = PHORON_FLASHPOINT
|
||||
PT.air_contents.adjust_multi("phoron", 12, "carbon_dioxide", 8)
|
||||
PT.air_contents.gas["phoron"] = phoron_amt
|
||||
PT.air_contents.gas["carbon_dioxide"] = carbon_amt
|
||||
PT.air_contents.update_values()
|
||||
|
||||
OT.air_contents.temperature = PHORON_FLASHPOINT
|
||||
OT.air_contents.adjust_gas("oxygen", 20)
|
||||
OT.air_contents.gas["oxygen"] = oxygen_amt
|
||||
OT.air_contents.update_values()
|
||||
|
||||
var/obj/item/device/assembly/S
|
||||
|
||||
switch (src.btype)
|
||||
// radio
|
||||
if (0)
|
||||
|
||||
S = new/obj/item/device/assembly/signaler(V)
|
||||
|
||||
// proximity
|
||||
if (1)
|
||||
|
||||
S = new/obj/item/device/assembly/prox_sensor(V)
|
||||
|
||||
// timer
|
||||
if (2)
|
||||
|
||||
S = new/obj/item/device/assembly/timer(V)
|
||||
var/obj/item/device/assembly/S = new assembly_type(V)
|
||||
|
||||
|
||||
V.attached_device = S
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
//It should be used purely for appearance. For gameplay effects caused by items covering body parts, use body_parts_covered.
|
||||
var/flags_inv = 0
|
||||
var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
|
||||
|
||||
|
||||
var/item_flags = 0 //Miscellaneous flags pertaining to equippable objects.
|
||||
|
||||
|
||||
//var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible
|
||||
var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets)
|
||||
var/permeability_coefficient = 1 // for chemicals/diseases
|
||||
@@ -45,7 +45,6 @@
|
||||
var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars.
|
||||
|
||||
var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
|
||||
var/item_state = null // Used to specify the item state for the on-mob overlays.
|
||||
|
||||
//** These specify item/icon overrides for _slots_
|
||||
|
||||
@@ -494,6 +493,12 @@ var/list/global/slot_flags_enumeration = list(
|
||||
var/obj/item/clothing/gloves/G = src
|
||||
G.transfer_blood = 0
|
||||
|
||||
/obj/item/reveal_blood()
|
||||
if(was_bloodied && !fluorescent)
|
||||
fluorescent = 1
|
||||
blood_color = COLOR_LUMINOL
|
||||
blood_overlay.color = COLOR_LUMINOL
|
||||
update_icon()
|
||||
|
||||
/obj/item/add_blood(mob/living/carbon/human/M as mob)
|
||||
if (!..())
|
||||
@@ -608,10 +613,10 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
usr.visible_message("[zoomdevicename ? "[usr] looks up from the [src.name]" : "[usr] lowers the [src.name]"].")
|
||||
|
||||
return
|
||||
|
||||
|
||||
/obj/item/proc/pwr_drain()
|
||||
return 0 // Process Kill
|
||||
|
||||
/obj/item/proc/resolve_attackby(atom/A, mob/source)
|
||||
return A.attackby(src,source)
|
||||
|
||||
|
||||
|
||||
@@ -272,6 +272,13 @@
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/headset_cargo
|
||||
|
||||
/obj/item/device/radio/headset/headset_cargo/alt
|
||||
name = "supply bowman headset"
|
||||
desc = "A bowman headset used by the QM and his slaves."
|
||||
icon_state = "cargo_headset_alt"
|
||||
item_state = "cargo_headset_alt"
|
||||
ks2type = /obj/item/device/encryptionkey/headset_cargo
|
||||
|
||||
/obj/item/device/radio/headset/headset_service
|
||||
name = "service radio headset"
|
||||
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean."
|
||||
|
||||
@@ -100,17 +100,9 @@
|
||||
if (src.loc != usr)
|
||||
return 0
|
||||
if(tank_one && href_list["tankone"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_one.loc = get_turf(src)
|
||||
tank_one = null
|
||||
update_icon()
|
||||
remove_tank(tank_one)
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_two.loc = get_turf(src)
|
||||
tank_two = null
|
||||
update_icon()
|
||||
remove_tank(tank_two)
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
@@ -149,20 +141,43 @@
|
||||
if(attached_device)
|
||||
overlays += "device"
|
||||
|
||||
/obj/item/device/transfer_valve/proc/remove_tank(obj/item/weapon/tank/T)
|
||||
if(tank_one == T)
|
||||
split_gases()
|
||||
tank_one = null
|
||||
else if(tank_two == T)
|
||||
split_gases()
|
||||
tank_two = null
|
||||
else
|
||||
return
|
||||
|
||||
T.loc = get_turf(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/transfer_valve/proc/merge_gases()
|
||||
if(valve_open)
|
||||
return
|
||||
tank_two.air_contents.volume += tank_one.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_one.air_contents.remove_ratio(1)
|
||||
tank_two.air_contents.merge(temp)
|
||||
valve_open = 1
|
||||
|
||||
/obj/item/device/transfer_valve/proc/split_gases()
|
||||
if (!valve_open || !tank_one || !tank_two)
|
||||
if(!valve_open)
|
||||
return
|
||||
|
||||
valve_open = 0
|
||||
|
||||
if(deleted(tank_one) || deleted(tank_two))
|
||||
return
|
||||
|
||||
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_two.air_contents.remove_ratio(ratio1)
|
||||
tank_one.air_contents.merge(temp)
|
||||
tank_two.air_contents.volume -= tank_one.air_contents.volume
|
||||
|
||||
|
||||
/*
|
||||
Exadv1: I know this isn't how it's going to work, but this was just to check
|
||||
@@ -170,8 +185,7 @@
|
||||
*/
|
||||
|
||||
/obj/item/device/transfer_valve/proc/toggle_valve()
|
||||
if(valve_open==0 && (tank_one && tank_two))
|
||||
valve_open = 1
|
||||
if(!valve_open && (tank_one && tank_two))
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
|
||||
@@ -197,16 +211,11 @@
|
||||
message_admins(log_str, 0, 1)
|
||||
log_game(log_str)
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for (var/i=0,i<5,i++)
|
||||
src.update_icon()
|
||||
sleep(10)
|
||||
src.update_icon()
|
||||
|
||||
else if(valve_open==1 && (tank_one && tank_two))
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
src.update_icon()
|
||||
|
||||
src.update_icon()
|
||||
|
||||
// this doesn't do anything but the timer etc. expects it to be here
|
||||
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
|
||||
|
||||
@@ -27,7 +27,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
src.uplink_owner = owner
|
||||
purchase_log = list()
|
||||
world_uplinks += src
|
||||
uses = telecrystals
|
||||
uses = owner.tcrystals
|
||||
|
||||
/obj/item/device/uplink/Destroy()
|
||||
world_uplinks -= src
|
||||
@@ -87,6 +87,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
/obj/item/device/uplink/hidden/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/title = "Remote Uplink"
|
||||
var/data[0]
|
||||
uses = user.mind.tcrystals
|
||||
|
||||
data["welcome"] = welcome
|
||||
data["crystals"] = uses
|
||||
|
||||
@@ -56,7 +56,7 @@ var/datum/uplink/uplink = new()
|
||||
return
|
||||
|
||||
purchase_log(U)
|
||||
U.uses -= cost
|
||||
user.mind.tcrystals -= cost
|
||||
U.used_TC += cost
|
||||
return goods
|
||||
|
||||
@@ -408,8 +408,8 @@ datum/uplink_item/dd_SortValue()
|
||||
path = /obj/item/weapon/storage/box/syndie_kit/imp_explosive
|
||||
|
||||
/datum/uplink_item/item/implants/imp_uplink
|
||||
name = "Uplink Implant (Contains 5 Telecrystals)"
|
||||
item_cost = 10
|
||||
name = "Uplink Implant" //Original name: "Uplink Implant (Contains 5 Telecrystals)"
|
||||
item_cost = 5 //Original cost: 10
|
||||
path = /obj/item/weapon/storage/box/syndie_kit/imp_uplink
|
||||
|
||||
/**********
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/amount = 1
|
||||
var/max_amount //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
|
||||
var/stacktype //determines whether different stack types can merge
|
||||
var/build_type = null //used when directly applied to a turf
|
||||
var/uses_charge = 0
|
||||
var/list/charge_costs = null
|
||||
var/list/datum/matter_synth/synths = null
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
desc = "A non-descript floor tile"
|
||||
w_class = 3
|
||||
max_amount = 60
|
||||
var/build_type = null
|
||||
|
||||
/obj/item/stack/tile/New()
|
||||
..()
|
||||
|
||||
@@ -716,7 +716,7 @@
|
||||
/obj/item/toy/therapy_red
|
||||
name = "red therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is red."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyred"
|
||||
item_state = "egg4" // It's the red egg in items_left/righthand
|
||||
w_class = 1
|
||||
@@ -724,7 +724,7 @@
|
||||
/obj/item/toy/therapy_purple
|
||||
name = "purple therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is purple."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapypurple"
|
||||
item_state = "egg1" // It's the magenta egg in items_left/righthand
|
||||
w_class = 1
|
||||
@@ -732,7 +732,7 @@
|
||||
/obj/item/toy/therapy_blue
|
||||
name = "blue therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is blue."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyblue"
|
||||
item_state = "egg2" // It's the blue egg in items_left/righthand
|
||||
w_class = 1
|
||||
@@ -740,7 +740,7 @@
|
||||
/obj/item/toy/therapy_yellow
|
||||
name = "yellow therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is yellow."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyyellow"
|
||||
item_state = "egg5" // It's the yellow egg in items_left/righthand
|
||||
w_class = 1
|
||||
@@ -748,7 +748,7 @@
|
||||
/obj/item/toy/therapy_orange
|
||||
name = "orange therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is orange."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyorange"
|
||||
item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless
|
||||
w_class = 1
|
||||
@@ -756,7 +756,7 @@
|
||||
/obj/item/toy/therapy_green
|
||||
name = "green therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is green."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapygreen"
|
||||
item_state = "egg3" // It's the green egg in items_left/righthand
|
||||
w_class = 1
|
||||
@@ -886,3 +886,12 @@
|
||||
item_state = "inflatable"
|
||||
icon = 'icons/obj/clothing/belts.dmi'
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/toy/xmastree
|
||||
name = "Miniature Christmas tree"
|
||||
desc = "Tiny cute Christmas tree."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "tinyxmastree"
|
||||
w_class = 1
|
||||
force = 1
|
||||
throwforce = 1
|
||||
@@ -33,7 +33,7 @@ var/list/syndicate_ids = list()
|
||||
if(istype(O, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/I = O
|
||||
src.access |= I.access
|
||||
if(player_is_antag(user))
|
||||
if(player_is_antag(user.mind))
|
||||
user << "<span class='notice'>The microscanner activates as you pass it over the ID, copying its access.</span>"
|
||||
|
||||
/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
|
||||
|
||||
@@ -9,3 +9,16 @@
|
||||
if(empulse(src, 4, 10))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/grenade/empgrenade/low_yield
|
||||
name = "low yield emp grenade"
|
||||
desc = "A weaker variant of the classic emp grenade"
|
||||
icon_state = "lyemp"
|
||||
item_state = "lyempgrenade"
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 3)
|
||||
|
||||
prime()
|
||||
..()
|
||||
if(empulse(src, 4, 1))
|
||||
qdel(src)
|
||||
return
|
||||
@@ -1,16 +1,78 @@
|
||||
//obj/item/weapon/grenade/explosive
|
||||
//desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
|
||||
//name = "frag grenade"
|
||||
//icon = 'icons/obj/grenade.dmi'
|
||||
//det_time = 50
|
||||
//icon_state = "frggrenade"
|
||||
//item_state = "frggrenade"
|
||||
//origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 3)
|
||||
|
||||
//obj/item/weapon/grenade/explosive/prime()
|
||||
// ..()
|
||||
//spawn(0)
|
||||
//explosion(src.loc,-1,-1,2) //If you're within two tiles of the grenade, you get hit twice, which tends to do 50+ brute and cause fractures.
|
||||
//explosion(src.loc,-1,-1,3) //This is preferable to increasing the severity, so we don't decap with frags.
|
||||
//qdel(src)
|
||||
//return
|
||||
|
||||
//Explosive grenade projectile, borrowed from fragmentation grenade code.
|
||||
/obj/item/projectile/bullet/pellet/fragment
|
||||
damage = 10
|
||||
range_step = 2
|
||||
|
||||
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
|
||||
spread_step = 20
|
||||
|
||||
silenced = 1 //embedding messages are still produced so it's kind of weird when enabled.
|
||||
no_attack_log = 1
|
||||
muzzle_type = null
|
||||
|
||||
/obj/item/weapon/grenade/explosive
|
||||
name = "fragmentation grenade"
|
||||
desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
|
||||
name = "frag grenade"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
det_time = 50
|
||||
icon_state = "frggrenade"
|
||||
item_state = "frggrenade"
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 3)
|
||||
|
||||
var/num_fragments = 50 //total number of fragments produced by the grenade
|
||||
var/fragment_damage = 10
|
||||
var/damage_step = 2 //projectiles lose a fragment each time they travel this distance. Can be a non-integer.
|
||||
var/explosion_size = 2 //size of the center explosion
|
||||
|
||||
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
|
||||
var/spread_range = 7
|
||||
|
||||
/obj/item/weapon/grenade/explosive/prime()
|
||||
..()
|
||||
spawn(0)
|
||||
explosion(src.loc,-1,-1,2) //If you're within two tiles of the grenade, you get hit twice, which tends to do 50+ brute and cause fractures.
|
||||
explosion(src.loc,-1,-1,3) //This is preferable to increasing the severity, so we don't decap with frags.
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/turf/O = get_turf(src)
|
||||
if(!O) return
|
||||
|
||||
if(explosion_size)
|
||||
explosion(O, -1, -1, 2, round(explosion_size/2), 0)
|
||||
|
||||
var/list/target_turfs = getcircle(O, spread_range)
|
||||
var/fragments_per_projectile = round(num_fragments/target_turfs.len)
|
||||
|
||||
for(var/turf/T in target_turfs)
|
||||
var/obj/item/projectile/bullet/pellet/fragment/P = new (O)
|
||||
|
||||
P.damage = fragment_damage
|
||||
P.pellets = fragments_per_projectile
|
||||
P.range_step = damage_step
|
||||
P.shot_from = src.name
|
||||
|
||||
P.launch(T)
|
||||
|
||||
//var/cone = new /obj/item/weapon/caution/cone (T)
|
||||
//spawn(100) qdel(cone)
|
||||
|
||||
//Make sure to hit any mobs in the source turf
|
||||
for(var/mob/living/M in O)
|
||||
//lying on a frag grenade while the grenade is on the ground causes you to absorb most of the shrapnel.
|
||||
//you will most likely be dead, but others nearby will be spared the fragments that hit you instead.
|
||||
if(M.lying && isturf(src.loc))
|
||||
P.attack_mob(M, 0, 0)
|
||||
else
|
||||
P.attack_mob(M, 0, 100) //otherwise, allow a decent amount of fragments to pass
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
throw_range = 5
|
||||
origin_tech = list(TECH_MATERIAL = 1)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 500)
|
||||
var/elastic
|
||||
var/dispenser = 0
|
||||
var/breakouttime = 1200 //Deciseconds = 120s = 2 minutes
|
||||
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
|
||||
@@ -53,20 +54,20 @@
|
||||
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!istype(H))
|
||||
return
|
||||
return 0
|
||||
|
||||
if (!H.has_organ_for_slot(slot_handcuffed))
|
||||
user << "<span class='danger'>\The [H] needs at least two wrists before you can cuff them together!</span>"
|
||||
return
|
||||
return 0
|
||||
|
||||
if(istype(H.gloves,/obj/item/clothing/gloves/rig)) // Can't cuff someone who's in a deployed hardsuit.
|
||||
user << "<span class='danger'>The cuffs won't fit around \the [H.gloves]!</span>"
|
||||
return
|
||||
if(istype(H.gloves,/obj/item/clothing/gloves/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
|
||||
user << "<span class='danger'>\The [src] won't fit around \the [H.gloves]!</span>"
|
||||
return 0
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
|
||||
|
||||
if(!do_after(user,30))
|
||||
return
|
||||
return 0
|
||||
|
||||
H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been handcuffed (attempt) by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to handcuff [H.name] ([H.ckey])</font>")
|
||||
@@ -84,7 +85,7 @@
|
||||
cuffs.loc = target
|
||||
target.handcuffed = cuffs
|
||||
target.update_inv_handcuffed()
|
||||
return
|
||||
return 1
|
||||
|
||||
var/last_chew = 0
|
||||
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
|
||||
@@ -118,6 +119,7 @@ var/last_chew = 0
|
||||
breakouttime = 300 //Deciseconds = 30s
|
||||
cuff_sound = 'sound/weapons/cablecuff.ogg'
|
||||
cuff_type = "cable restraints"
|
||||
elastic = 1
|
||||
|
||||
/obj/item/weapon/handcuffs/cable/red
|
||||
color = "#DD0000"
|
||||
@@ -156,3 +158,12 @@ var/last_chew = 0
|
||||
|
||||
/obj/item/weapon/handcuffs/cyborg
|
||||
dispenser = 1
|
||||
|
||||
/obj/item/weapon/handcuffs/cable/tape
|
||||
name = "tape restraints"
|
||||
desc = "DIY!"
|
||||
icon_state = "tape_cross"
|
||||
item_state = null
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
breakouttime = 200
|
||||
cuff_type = "duct tape"
|
||||
@@ -6,7 +6,8 @@
|
||||
/obj/item/weapon/implant/uplink/New()
|
||||
activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 5
|
||||
//hidden_uplink.uses = 5
|
||||
//Code currently uses a mind var for telecrystals, balancing is currently an issue. Will investigate.
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
default_material = "wood"
|
||||
force_divisor = 1.1 // 22 when wielded with weight 20 (steel)
|
||||
unwielded_force_divisor = 0.7 // 15 when unwielded based on above.
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
//Predefined materials go here.
|
||||
/obj/item/weapon/material/twohanded/baseballbat/metal/New(var/newloc)
|
||||
|
||||
@@ -75,6 +75,17 @@
|
||||
icon_state = "knife"
|
||||
force_divisor = 0.1 // 6 when wielded with hardness 60 (steel)
|
||||
|
||||
// Identical to the tactical knife but nowhere near as stabby.
|
||||
// Kind of like the toy esword compared to the real thing.
|
||||
/obj/item/weapon/material/kitchen/utensil/knife/boot
|
||||
name = "boot knife"
|
||||
desc = "A small fixed-blade knife for putting inside a boot."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "tacknife"
|
||||
item_state = "knife"
|
||||
applies_material_colour = 0
|
||||
unbreakable = 1
|
||||
|
||||
/obj/item/weapon/material/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob)
|
||||
if ((CLUMSY in user.mutations) && prob(50))
|
||||
user << "<span class='warning'>You accidentally cut yourself with the [src].</span>"
|
||||
|
||||
@@ -18,8 +18,22 @@ var/list/tape_roll_applications = list()
|
||||
anchored = 1
|
||||
var/lifted = 0
|
||||
var/crumpled = 0
|
||||
var/tape_dir = 0
|
||||
var/icon_base
|
||||
|
||||
/obj/item/tape/update_icon()
|
||||
//Possible directional bitflags: 0 (AIRLOCK), 1 (NORTH), 2 (SOUTH), 4 (EAST), 8 (WEST), 3 (VERTICAL), 12 (HORIZONTAL)
|
||||
switch (tape_dir)
|
||||
if(0) // AIRLOCK
|
||||
icon_state = "[icon_base]_door_[crumpled]"
|
||||
if(3) // VERTICAL
|
||||
icon_state = "[icon_base]_v_[crumpled]"
|
||||
if(12) // HORIZONTAL
|
||||
icon_state = "[icon_base]_h_[crumpled]"
|
||||
else // END POINT (1|2|4|8)
|
||||
icon_state = "[icon_base]_dir_[crumpled]"
|
||||
dir = tape_dir
|
||||
|
||||
/obj/item/tape/New()
|
||||
..()
|
||||
if(!hazard_overlays)
|
||||
@@ -32,7 +46,7 @@ var/list/tape_roll_applications = list()
|
||||
/obj/item/taperoll/police
|
||||
name = "police tape"
|
||||
desc = "A roll of police tape used to block off crime scenes from the public."
|
||||
icon_state = "police_start"
|
||||
icon_state = "police"
|
||||
tape_type = /obj/item/tape/police
|
||||
icon_base = "police"
|
||||
|
||||
@@ -45,7 +59,7 @@ var/list/tape_roll_applications = list()
|
||||
/obj/item/taperoll/engineering
|
||||
name = "engineering tape"
|
||||
desc = "A roll of engineering tape used to block off working areas from the public."
|
||||
icon_state = "engineering_start"
|
||||
icon_state = "engineering"
|
||||
tape_type = /obj/item/tape/engineering
|
||||
icon_base = "engineering"
|
||||
|
||||
@@ -55,58 +69,150 @@ var/list/tape_roll_applications = list()
|
||||
req_one_access = list(access_engine,access_atmospherics)
|
||||
icon_base = "engineering"
|
||||
|
||||
/obj/item/taperoll/atmos
|
||||
name = "atmospherics tape"
|
||||
desc = "A roll of atmospherics tape used to block off working areas from the public."
|
||||
icon_state = "atmos"
|
||||
tape_type = /obj/item/tape/atmos
|
||||
icon_base = "atmos"
|
||||
|
||||
/obj/item/tape/atmos
|
||||
name = "atmospherics tape"
|
||||
desc = "A length of atmospherics tape. Better not cross it."
|
||||
req_one_access = list(access_engine,access_atmospherics)
|
||||
icon_base = "atmos"
|
||||
|
||||
/obj/item/taperoll/update_icon()
|
||||
overlays.Cut()
|
||||
if(ismob(loc))
|
||||
if(!start)
|
||||
overlays += "start"
|
||||
else
|
||||
overlays += "stop"
|
||||
|
||||
/obj/item/taperoll/dropped(mob/user)
|
||||
update_icon()
|
||||
return ..()
|
||||
|
||||
/obj/item/taperoll/pickup(mob/user)
|
||||
update_icon()
|
||||
return ..()
|
||||
|
||||
/obj/item/taperoll/attack_hand()
|
||||
update_icon()
|
||||
return ..()
|
||||
|
||||
/obj/item/taperoll/attack_self(mob/user as mob)
|
||||
if(icon_state == "[icon_base]_start")
|
||||
if(!start)
|
||||
start = get_turf(src)
|
||||
usr << "<span class='notice'>You place the first end of \the [src].</span>"
|
||||
icon_state = "[icon_base]_stop"
|
||||
update_icon()
|
||||
else
|
||||
icon_state = "[icon_base]_start"
|
||||
end = get_turf(src)
|
||||
if(start.y != end.y && start.x != end.x || start.z != end.z)
|
||||
start = null
|
||||
update_icon()
|
||||
usr << "<span class='notice'>\The [src] can only be laid horizontally or vertically.</span>"
|
||||
return
|
||||
|
||||
if(start == end)
|
||||
// spread tape in all directions, provided there is a wall/window
|
||||
var/turf/T
|
||||
var/possible_dirs = 0
|
||||
for(var/dir in cardinal)
|
||||
T = get_step(start, dir)
|
||||
if(T && T.density)
|
||||
possible_dirs += dir
|
||||
else
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.is_fulltile() || W.dir == reverse_dir[dir])
|
||||
possible_dirs += dir
|
||||
if(!possible_dirs)
|
||||
start = null
|
||||
update_icon()
|
||||
usr << "<span class='notice'>You can't place \the [src] here.</span>"
|
||||
return
|
||||
if(possible_dirs & (NORTH|SOUTH))
|
||||
var/obj/item/tape/TP = new tape_type(start)
|
||||
for(var/dir in list(NORTH, SOUTH))
|
||||
if (possible_dirs & dir)
|
||||
TP.tape_dir += dir
|
||||
TP.update_icon()
|
||||
if(possible_dirs & (EAST|WEST))
|
||||
var/obj/item/tape/TP = new tape_type(start)
|
||||
for(var/dir in list(EAST, WEST))
|
||||
if (possible_dirs & dir)
|
||||
TP.tape_dir += dir
|
||||
TP.update_icon()
|
||||
start = null
|
||||
update_icon()
|
||||
usr << "<span class='notice'>You finish placing \the [src].</span>"
|
||||
return
|
||||
|
||||
var/turf/cur = start
|
||||
var/dir
|
||||
if (start.x == end.x)
|
||||
var/d = end.y-start.y
|
||||
if(d) d = d/abs(d)
|
||||
end = get_turf(locate(end.x,end.y+d,end.z))
|
||||
dir = "v"
|
||||
else
|
||||
var/d = end.x-start.x
|
||||
if(d) d = d/abs(d)
|
||||
end = get_turf(locate(end.x+d,end.y,end.z))
|
||||
dir = "h"
|
||||
var/orientation = get_dir(start, end)
|
||||
var/dir = 0
|
||||
switch(orientation)
|
||||
if(NORTH, SOUTH) dir = NORTH|SOUTH // North-South taping
|
||||
if(EAST, WEST) dir = EAST|WEST // East-West taping
|
||||
|
||||
var/can_place = 1
|
||||
while (cur!=end && can_place)
|
||||
while (can_place)
|
||||
if(cur.density == 1)
|
||||
can_place = 0
|
||||
else if (istype(cur, /turf/space))
|
||||
can_place = 0
|
||||
else
|
||||
for(var/obj/O in cur)
|
||||
if(!istype(O, /obj/item/tape) && O.density)
|
||||
if(O.density)
|
||||
can_place = 0
|
||||
break
|
||||
if(cur == end)
|
||||
break
|
||||
cur = get_step_towards(cur,end)
|
||||
if (!can_place)
|
||||
start = null
|
||||
update_icon()
|
||||
usr << "<span class='warning'>You can't run \the [src] through that!</span>"
|
||||
return
|
||||
|
||||
cur = start
|
||||
var/tapetest = 0
|
||||
while (cur!=end)
|
||||
for(var/obj/item/tape/Ptest in cur)
|
||||
if(Ptest.icon_state == "[Ptest.icon_base]_[dir]")
|
||||
var/tapetest
|
||||
var/tape_dir
|
||||
while (1)
|
||||
tapetest = 0
|
||||
tape_dir = dir
|
||||
if(cur == start)
|
||||
var/turf/T = get_step(start, reverse_dir[orientation])
|
||||
if(T && !T.density)
|
||||
tape_dir = orientation
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.is_fulltile() || W.dir == orientation)
|
||||
tape_dir = dir
|
||||
else if(cur == end)
|
||||
var/turf/T = get_step(end, orientation)
|
||||
if(T && !T.density)
|
||||
tape_dir = reverse_dir[orientation]
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.is_fulltile() || W.dir == reverse_dir[orientation])
|
||||
tape_dir = dir
|
||||
for(var/obj/item/tape/T in cur)
|
||||
if((T.tape_dir == tape_dir) && (T.icon_base == icon_base))
|
||||
tapetest = 1
|
||||
if(tapetest != 1)
|
||||
var/obj/item/tape/P = new tape_type(cur)
|
||||
P.icon_state = "[P.icon_base]_[dir]"
|
||||
break
|
||||
if(!tapetest)
|
||||
var/obj/item/tape/T = new tape_type(cur)
|
||||
T.tape_dir = tape_dir
|
||||
T.update_icon()
|
||||
if(tape_dir & SOUTH)
|
||||
T.layer += 0.1 // Must always show above other tapes
|
||||
if(cur == end)
|
||||
break
|
||||
cur = get_step_towards(cur,end)
|
||||
start = null
|
||||
update_icon()
|
||||
usr << "<span class='notice'>You finish placing \the [src].</span>"
|
||||
return
|
||||
|
||||
/obj/item/taperoll/afterattack(var/atom/A, mob/user as mob, proximity)
|
||||
if(!proximity)
|
||||
@@ -116,7 +222,7 @@ var/list/tape_roll_applications = list()
|
||||
var/turf/T = get_turf(A)
|
||||
var/obj/item/tape/P = new tape_type(T.x,T.y,T.z)
|
||||
P.loc = locate(T.x,T.y,T.z)
|
||||
P.icon_state = "[src.icon_base]_door"
|
||||
P.update_icon()
|
||||
P.layer = 3.2
|
||||
user << "<span class='notice'>You finish placing \the [src].</span>"
|
||||
|
||||
@@ -140,7 +246,7 @@ var/list/tape_roll_applications = list()
|
||||
/obj/item/tape/proc/crumple()
|
||||
if(!crumpled)
|
||||
crumpled = 1
|
||||
icon_state = "[icon_state]_c"
|
||||
update_icon()
|
||||
name = "crumpled [name]"
|
||||
|
||||
/obj/item/tape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
@@ -149,6 +255,8 @@ var/list/tape_roll_applications = list()
|
||||
add_fingerprint(M)
|
||||
if (!allowed(M)) //only select few learn art of not crumpling the tape
|
||||
M << "<span class='warning'>You are not supposed to go past [src]...</span>"
|
||||
if(M.a_intent == I_HELP)
|
||||
return 0
|
||||
crumple()
|
||||
return ..(mover)
|
||||
|
||||
@@ -158,13 +266,45 @@ var/list/tape_roll_applications = list()
|
||||
/obj/item/tape/attack_hand(mob/user as mob)
|
||||
if (user.a_intent == I_HELP && src.allowed(user))
|
||||
user.show_viewers("<span class='notice'>\The [user] lifts \the [src], allowing passage.</span>")
|
||||
crumple()
|
||||
lifted = 1
|
||||
spawn(200)
|
||||
lifted = 0
|
||||
for(var/obj/item/tape/T in gettapeline())
|
||||
T.lift(100) //~10 seconds
|
||||
else
|
||||
breaktape(null, user)
|
||||
|
||||
/obj/item/tape/proc/lift(time)
|
||||
lifted = 1
|
||||
layer = 8
|
||||
spawn(time)
|
||||
lifted = 0
|
||||
layer = initial(layer)
|
||||
|
||||
// Returns a list of all tape objects connected to src, including itself.
|
||||
/obj/item/tape/proc/gettapeline()
|
||||
var/list/dirs = list()
|
||||
if(tape_dir & NORTH)
|
||||
dirs += NORTH
|
||||
if(tape_dir & SOUTH)
|
||||
dirs += SOUTH
|
||||
if(tape_dir & WEST)
|
||||
dirs += WEST
|
||||
if(tape_dir & EAST)
|
||||
dirs += EAST
|
||||
|
||||
var/list/obj/item/tape/tapeline = list()
|
||||
for (var/obj/item/tape/T in get_turf(src))
|
||||
tapeline += T
|
||||
for(var/dir in dirs)
|
||||
var/turf/cur = get_step(src, dir)
|
||||
var/not_found = 0
|
||||
while (!not_found)
|
||||
not_found = 1
|
||||
for (var/obj/item/tape/T in cur)
|
||||
tapeline += T
|
||||
not_found = 0
|
||||
cur = get_step(cur, dir)
|
||||
return tapeline
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/tape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob)
|
||||
@@ -173,27 +313,11 @@ var/list/tape_roll_applications = list()
|
||||
return
|
||||
user.show_viewers("<span class='notice'>\The [user] breaks \the [src]!</span>")
|
||||
|
||||
var/dir[2]
|
||||
var/icon_dir = src.icon_state
|
||||
if(icon_dir == "[src.icon_base]_h")
|
||||
dir[1] = EAST
|
||||
dir[2] = WEST
|
||||
if(icon_dir == "[src.icon_base]_v")
|
||||
dir[1] = NORTH
|
||||
dir[2] = SOUTH
|
||||
|
||||
for(var/i=1;i<3;i++)
|
||||
var/N = 0
|
||||
var/turf/cur = get_step(src,dir[i])
|
||||
while(N != 1)
|
||||
N = 1
|
||||
for (var/obj/item/tape/P in cur)
|
||||
if(P.icon_state == icon_dir)
|
||||
N = 0
|
||||
qdel(P)
|
||||
cur = get_step(cur,dir[i])
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
for (var/obj/item/tape/T in gettapeline())
|
||||
if(T == src)
|
||||
continue
|
||||
if(T.tape_dir & get_dir(T, src))
|
||||
qdel(T)
|
||||
|
||||
qdel(src) //TODO: Dropping a trash item holding fibers/fingerprints of all broken tape parts
|
||||
return
|
||||
@@ -148,8 +148,8 @@
|
||||
icon_state = "duffle"
|
||||
item_state = "duffle"
|
||||
slowdown = 1
|
||||
max_storage_space = 56
|
||||
storage_slots = 20
|
||||
max_storage_space = 38
|
||||
storage_slots = 12
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/syndie
|
||||
name = "suspicious looking dufflebag"
|
||||
|
||||
@@ -139,6 +139,37 @@
|
||||
/obj/item/weapon/gun/projectile/colt/detective
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/belt/detective
|
||||
name = "forensic utility belt"
|
||||
desc = "A belt for holding forensics equipment."
|
||||
icon_state = "securitybelt"
|
||||
item_state = "security"
|
||||
storage_slots = 7
|
||||
max_w_class = 3
|
||||
can_hold = list(
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/clothing/glasses,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/reagent_containers/spray/luminol,
|
||||
/obj/item/weapon/sample,
|
||||
/obj/item/weapon/forensics/sample_kit/powder,
|
||||
/obj/item/weapon/forensics/swab,
|
||||
/obj/item/device/uv_light,
|
||||
/obj/item/weapon/forensics/slide,
|
||||
/obj/item/weapon/forensics/sample_kit,
|
||||
/obj/item/weapon/photo,
|
||||
/obj/item/device/camera_film,
|
||||
/obj/item/device/camera,
|
||||
/obj/item/weapon/autopsy_scanner,
|
||||
/obj/item/device/mass_spectrometer,
|
||||
/obj/item/device/reagent_scanner,
|
||||
/obj/item/weapon/reagent_containers/dropper,
|
||||
/obj/item/weapon/reagent_containers/syringe,
|
||||
/obj/item/device/pda,
|
||||
/obj/item/device/radio/headset,
|
||||
/obj/item/taperoll/police
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/belt/soulstone
|
||||
name = "soul stone belt"
|
||||
desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away"
|
||||
|
||||
@@ -298,6 +298,19 @@
|
||||
new /obj/item/weapon/grenade/empgrenade(src)
|
||||
new /obj/item/weapon/grenade/empgrenade(src)
|
||||
|
||||
/obj/item/weapon/storage/box/empslite
|
||||
name = "box of low yield emp grenades"
|
||||
desc = "A box containing 5 low yield EMP grenades.<br> WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur."
|
||||
icon_state = "emp"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/grenade/empgrenade/low_yield(src)
|
||||
new /obj/item/weapon/grenade/empgrenade/low_yield(src)
|
||||
new /obj/item/weapon/grenade/empgrenade/low_yield(src)
|
||||
new /obj/item/weapon/grenade/empgrenade/low_yield(src)
|
||||
new /obj/item/weapon/grenade/empgrenade/low_yield(src)
|
||||
|
||||
/obj/item/weapon/storage/box/smokes
|
||||
name = "box of smoke bombs"
|
||||
desc = "A box containing 5 smoke bombs."
|
||||
@@ -327,7 +340,7 @@
|
||||
|
||||
/obj/item/weapon/storage/box/frags
|
||||
name = "box of fragmentation grenades (WARNING)"
|
||||
desc = "A box containing 7 military grade fragmentation grenades.<br> WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use."
|
||||
desc = "A box containing 5 military grade fragmentation grenades.<br> WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use."
|
||||
icon_state = "frag"
|
||||
|
||||
|
||||
@@ -338,8 +351,7 @@
|
||||
new /obj/item/weapon/grenade/explosive(src)
|
||||
new /obj/item/weapon/grenade/explosive(src)
|
||||
new /obj/item/weapon/grenade/explosive(src)
|
||||
new /obj/item/weapon/grenade/explosive(src)
|
||||
new /obj/item/weapon/grenade/explosive(src)
|
||||
|
||||
/obj/item/weapon/storage/box/trackimp
|
||||
name = "boxed tracking implant kit"
|
||||
desc = "Box full of scum-bag tracking utensils."
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
throwforce = 2
|
||||
slot_flags = SLOT_BELT
|
||||
storage_slots = 6
|
||||
can_hold = list(/obj/item/clothing/mask/smokable/cigarette)
|
||||
can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter)
|
||||
icon_type = "cigarette"
|
||||
|
||||
/obj/item/weapon/storage/fancy/cigarettes/New()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
name = "jetpack (empty)"
|
||||
desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution."
|
||||
icon_state = "jetpack"
|
||||
gauge_icon = null
|
||||
w_class = 4.0
|
||||
item_state = "jetpack"
|
||||
distribute_pressure = ONE_ATMOSPHERE*O2STANDARD
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
name = "phoron tank"
|
||||
desc = "Contains dangerous phoron. Do not inhale. Warning: extremely flammable."
|
||||
icon_state = "phoron"
|
||||
gauge_icon = null
|
||||
flags = CONDUCT
|
||||
slot_flags = null //they have no straps!
|
||||
|
||||
@@ -114,6 +115,8 @@
|
||||
name = "emergency oxygen tank"
|
||||
desc = "Used for emergencies. Contains very little oxygen, so try to conserve it until you actually need it."
|
||||
icon_state = "emergency"
|
||||
gauge_icon = "indicator_emergency"
|
||||
gauge_cap = 4
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = 2.0
|
||||
@@ -142,12 +145,15 @@
|
||||
/obj/item/weapon/tank/emergency_oxygen/double
|
||||
name = "double emergency oxygen tank"
|
||||
icon_state = "emergency_double"
|
||||
gauge_icon = "indicator_emergency_double"
|
||||
volume = 10
|
||||
|
||||
/obj/item/weapon/tank/emergency_nitrogen
|
||||
name = "emergency nitrogen tank"
|
||||
desc = "An emergency air tank hastily painted red and issued to Vox crewmembers."
|
||||
icon_state = "emergency_nitro"
|
||||
gauge_icon = "indicator_emergency"
|
||||
gauge_cap = 4
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = 2.0
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
#define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE)
|
||||
#define TANK_DEFAULT_RELEASE_PRESSURE 24
|
||||
#define TANK_IDEAL_PRESSURE 1015 //Arbitrary.
|
||||
|
||||
var/list/global/tank_gauge_cache = list()
|
||||
|
||||
/obj/item/weapon/tank
|
||||
name = "tank"
|
||||
icon = 'icons/obj/tank.dmi'
|
||||
|
||||
var/gauge_icon = "indicator_tank"
|
||||
var/last_gauge_pressure
|
||||
var/gauge_cap = 6
|
||||
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = 3
|
||||
@@ -31,8 +39,8 @@
|
||||
src.air_contents = new /datum/gas_mixture()
|
||||
src.air_contents.volume = volume //liters
|
||||
src.air_contents.temperature = T20C
|
||||
|
||||
processing_objects.Add(src)
|
||||
update_gauge()
|
||||
return
|
||||
|
||||
/obj/item/weapon/tank/Destroy()
|
||||
@@ -41,6 +49,10 @@
|
||||
|
||||
processing_objects.Remove(src)
|
||||
|
||||
if(istype(loc, /obj/item/device/transfer_valve))
|
||||
var/obj/item/device/transfer_valve/TTV = loc
|
||||
TTV.remove_tank(src)
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/weapon/tank/examine(mob/user)
|
||||
@@ -216,8 +228,28 @@
|
||||
/obj/item/weapon/tank/process()
|
||||
//Allow for reactions
|
||||
air_contents.react() //cooking up air tanks - add phoron and oxygen, then heat above PHORON_MINIMUM_BURN_TEMPERATURE
|
||||
if(gauge_icon)
|
||||
update_gauge()
|
||||
check_status()
|
||||
|
||||
/obj/item/weapon/tank/proc/update_gauge()
|
||||
var/gauge_pressure = 0
|
||||
if(air_contents)
|
||||
gauge_pressure = air_contents.return_pressure()
|
||||
if(gauge_pressure > TANK_IDEAL_PRESSURE)
|
||||
gauge_pressure = -1
|
||||
else
|
||||
gauge_pressure = round((gauge_pressure/TANK_IDEAL_PRESSURE)*gauge_cap)
|
||||
|
||||
if(gauge_pressure == last_gauge_pressure)
|
||||
return
|
||||
|
||||
last_gauge_pressure = gauge_pressure
|
||||
overlays.Cut()
|
||||
var/indicator = "[gauge_icon][(gauge_pressure == -1) ? "overload" : gauge_pressure]"
|
||||
if(!tank_gauge_cache[indicator])
|
||||
tank_gauge_cache[indicator] = image(icon, indicator)
|
||||
overlays += tank_gauge_cache[indicator]
|
||||
|
||||
/obj/item/weapon/tank/proc/check_status()
|
||||
//Handle exploding, leaking, and rupturing of the tank
|
||||
@@ -249,7 +281,10 @@
|
||||
qdel(src)
|
||||
|
||||
else if(pressure > TANK_RUPTURE_PRESSURE)
|
||||
//world << "<span class='notice'>[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]</span>"
|
||||
#ifdef FIREDBG
|
||||
log_debug("\blue[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]")
|
||||
#endif
|
||||
|
||||
if(integrity <= 0)
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -261,7 +296,10 @@
|
||||
integrity--
|
||||
|
||||
else if(pressure > TANK_LEAK_PRESSURE)
|
||||
//world << "<span class='notice'>[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]</span>"
|
||||
#ifdef FIREDBG
|
||||
log_debug("\blue[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]")
|
||||
#endif
|
||||
|
||||
if(integrity <= 0)
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
if(!T)
|
||||
|
||||
@@ -5,18 +5,71 @@
|
||||
icon_state = "taperoll"
|
||||
w_class = 1
|
||||
|
||||
/* -- Disabled for now until it has a use --
|
||||
/obj/item/weapon/tape_roll/attack_self(mob/user as mob)
|
||||
user << "You remove a length of tape from [src]."
|
||||
|
||||
var/obj/item/weapon/ducttape/tape = new()
|
||||
user.put_in_hands(tape)
|
||||
*/
|
||||
/obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user)
|
||||
if(istype(H))
|
||||
if(user.zone_sel.selecting == "eyes")
|
||||
|
||||
if(!H.organs_by_name["head"])
|
||||
user << "<span class='warning'>\The [H] doesn't have a head.</span>"
|
||||
return
|
||||
if(!H.has_eyes())
|
||||
user << "<span class='warning'>\The [H] doesn't have any eyes.</span>"
|
||||
return
|
||||
if(H.glasses)
|
||||
user << "<span class='warning'>\The [H] is already wearing somethign on their eyes.</span>"
|
||||
return
|
||||
if(H.head && (H.head.body_parts_covered & FACE))
|
||||
user << "<span class='warning'>Remove their [H.head] first.</span>"
|
||||
return
|
||||
user.visible_message("<span class='danger'>\The [user] begins taping over \the [H]'s eyes!</span>")
|
||||
|
||||
if(!do_after(user, 30))
|
||||
return
|
||||
|
||||
// Repeat failure checks.
|
||||
if(!H || !src || !H.organs_by_name["head"] || !H.has_eyes() || H.glasses || (H.head && (H.head.body_parts_covered & FACE)))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] has taped up \the [H]'s eyes!</span>")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/blindfold/tape(H), slot_glasses)
|
||||
|
||||
else if(user.zone_sel.selecting == "mouth" || user.zone_sel.selecting == "head")
|
||||
if(!H.organs_by_name["head"])
|
||||
user << "<span class='warning'>\The [H] doesn't have a head.</span>"
|
||||
return
|
||||
if(!H.check_has_mouth())
|
||||
user << "<span class='warning'>\The [H] doesn't have a mouth.</span>"
|
||||
return
|
||||
if(H.wear_mask)
|
||||
user << "<span class='warning'>\The [H] is already wearing a mask.</span>"
|
||||
return
|
||||
if(H.head && (H.head.body_parts_covered & FACE))
|
||||
user << "<span class='warning'>Remove their [H.head] first.</span>"
|
||||
return
|
||||
user.visible_message("<span class='danger'>\The [user] begins taping up \the [H]'s mouth!</span>")
|
||||
|
||||
if(!do_after(user, 30))
|
||||
return
|
||||
|
||||
// Repeat failure checks.
|
||||
if(!H || !src || !H.organs_by_name["head"] || !H.check_has_mouth() || H.wear_mask || (H.head && (H.head.body_parts_covered & FACE)))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] has taped up \the [H]'s mouth!</span>")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/muzzle/tape(H), slot_wear_mask)
|
||||
|
||||
else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand")
|
||||
var/obj/item/weapon/handcuffs/cable/tape/T = new(user)
|
||||
if(!T.place_handcuffs(H, user))
|
||||
user.unEquip(T)
|
||||
qdel(T)
|
||||
else
|
||||
return ..()
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/tape_roll/proc/stick(var/obj/item/weapon/W, mob/user)
|
||||
if(!istype(W, /obj/item/weapon/paper))
|
||||
return
|
||||
|
||||
user.drop_from_inventory(W)
|
||||
var/obj/item/weapon/ducttape/tape = new(get_turf(src))
|
||||
tape.attach(W)
|
||||
@@ -52,7 +105,7 @@
|
||||
return
|
||||
|
||||
user << "You remove \the [initial(name)] from [stuck]."
|
||||
|
||||
|
||||
user.drop_from_inventory(src)
|
||||
stuck.forceMove(get_turf(src))
|
||||
user.put_in_hands(stuck)
|
||||
@@ -61,6 +114,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/ducttape/afterattack(var/A, mob/user, flag, params)
|
||||
|
||||
if(!in_range(user, A) || istype(A, /obj/machinery/door) || !stuck)
|
||||
return
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
|
||||
/obj/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
..()
|
||||
|
||||
/obj/proc/interact(mob/user)
|
||||
return
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
|
||||
New()
|
||||
..()
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/storage/backpack(src)
|
||||
else
|
||||
new /obj/item/weapon/storage/backpack/satchel_norm(src)
|
||||
if(prob(25))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag(src)
|
||||
new /obj/item/clothing/under/rank/cargotech(src)
|
||||
new /obj/item/clothing/under/rank/cargotech/skirt(src)
|
||||
new /obj/item/clothing/under/rank/cargotech/jeans(src)
|
||||
@@ -17,6 +23,7 @@
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/cargo(src)
|
||||
new /obj/item/clothing/shoes/black(src)
|
||||
new /obj/item/device/radio/headset/headset_cargo(src)
|
||||
new /obj/item/device/radio/headset/headset_cargo/alt(src)
|
||||
new /obj/item/clothing/gloves/black(src)
|
||||
new /obj/item/clothing/head/soft(src)
|
||||
// new /obj/item/weapon/cartridge/quartermaster(src)
|
||||
@@ -34,12 +41,19 @@
|
||||
|
||||
New()
|
||||
..()
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/storage/backpack(src)
|
||||
else
|
||||
new /obj/item/weapon/storage/backpack/satchel_norm(src)
|
||||
if(prob(25))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag(src)
|
||||
new /obj/item/clothing/under/rank/cargo(src)
|
||||
new /obj/item/clothing/under/rank/cargo/skirt(src)
|
||||
new /obj/item/clothing/under/rank/cargo/jeans(src)
|
||||
new /obj/item/clothing/under/rank/cargo/jeans/female(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/device/radio/headset/headset_cargo(src)
|
||||
new /obj/item/device/radio/headset/headset_cargo/alt(src)
|
||||
new /obj/item/clothing/gloves/black(src)
|
||||
// new /obj/item/weapon/cartridge/quartermaster(src)
|
||||
new /obj/item/clothing/suit/fire/firefighter(src)
|
||||
|
||||
@@ -160,6 +160,6 @@
|
||||
new /obj/item/clothing/suit/storage/hazardvest(src)
|
||||
new /obj/item/clothing/mask/gas(src)
|
||||
new /obj/item/weapon/cartridge/atmos(src)
|
||||
new /obj/item/taperoll/engineering(src)
|
||||
new /obj/item/taperoll/atmos(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos(src)
|
||||
return
|
||||
|
||||
@@ -278,10 +278,10 @@
|
||||
new /obj/item/clothing/head/det(src)
|
||||
new /obj/item/clothing/head/det/grey(src)
|
||||
new /obj/item/clothing/shoes/laceup(src)
|
||||
new /obj/item/weapon/storage/belt/detective(src)
|
||||
new /obj/item/weapon/storage/box/evidence(src)
|
||||
new /obj/item/device/radio/headset/headset_sec(src)
|
||||
new /obj/item/device/radio/headset/headset_sec/alt(src)
|
||||
new /obj/item/device/detective_scanner(src)
|
||||
new /obj/item/clothing/suit/storage/vest/detective(src)
|
||||
new /obj/item/ammo_magazine/c45m/rubber(src)
|
||||
new /obj/item/ammo_magazine/c45m/rubber(src)
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
new /obj/item/weapon/pinpointer/nukeop(src)
|
||||
new /obj/item/weapon/pinpointer/nukeop(src)
|
||||
new /obj/item/device/pda/syndicate(src)
|
||||
var/obj/item/device/radio/uplink/U = new(src)
|
||||
U.hidden_uplink.uses = 40
|
||||
new /obj/item/device/radio/uplink(src)
|
||||
//U.hidden_uplink.uses = 40
|
||||
return
|
||||
|
||||
/obj/structure/closet/syndicate/resources/
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
/obj/structure/mopbucket/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/mop))
|
||||
if(reagents.total_volume < 1)
|
||||
user << "<span class='warning'>[src] is out of water!</span>"
|
||||
user << "<span class='warning'>\The [src] is out of water!</span>"
|
||||
else
|
||||
reagents.trans_to_obj(I, 5)
|
||||
user << "<span class='notice'>You wet [I] in [src].</span>"
|
||||
user << "<span class='notice'>You wet \the [I] in \the [src].</span>"
|
||||
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
||||
|
||||
@@ -199,4 +199,16 @@
|
||||
/obj/structure/sign/directions/cargo
|
||||
name = "\improper Cargo department"
|
||||
desc = "A direction sign, pointing out which way the Cargo department is."
|
||||
icon_state = "direction_crg"
|
||||
icon_state = "direction_crg"
|
||||
|
||||
/obj/structure/sign/christmas/lights
|
||||
name = "Christmas lights"
|
||||
desc = "Flashy and pretty."
|
||||
icon = 'icons/obj/christmas.dmi'
|
||||
icon_state = "xmaslights"
|
||||
|
||||
/obj/structure/sign/christmas/wreath
|
||||
name = "wreath"
|
||||
desc = "Prickly and festive."
|
||||
icon = 'icons/obj/christmas.dmi'
|
||||
icon_state = "doorwreath"
|
||||
|
||||
@@ -316,11 +316,11 @@
|
||||
|
||||
/obj/machinery/shower/proc/process_heat(mob/living/M)
|
||||
if(!on || !istype(M)) return
|
||||
|
||||
|
||||
var/temperature = temperature_settings[watertemp]
|
||||
var/temp_adj = between(BODYTEMP_COOLING_MAX, temperature - M.bodytemperature, BODYTEMP_HEATING_MAX)
|
||||
M.bodytemperature += temp_adj
|
||||
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(temperature >= H.species.heat_level_1)
|
||||
@@ -411,6 +411,11 @@
|
||||
// Short of a rewrite, this is necessary to stop monkeycubes being washed.
|
||||
else if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
|
||||
return
|
||||
else if(istype(O, /obj/item/weapon/mop))
|
||||
O.reagents.add_reagent("water", 5)
|
||||
user << "<span class='notice'>You wet \the [O] in \the [src].</span>"
|
||||
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
||||
return
|
||||
|
||||
var/turf/location = user.loc
|
||||
if(!isturf(location)) return
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1)
|
||||
user.do_attack_animation(src)
|
||||
usr.visible_message("<span class='danger'>[usr.name] bangs against the [src.name]!</span>",
|
||||
"<<span class='danger'>You bang against the [src.name]!</span>",
|
||||
"<span class='danger'>You bang against the [src.name]!</span>",
|
||||
"You hear a banging sound.")
|
||||
else
|
||||
playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1)
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
|
||||
var/dirt = 0
|
||||
|
||||
/turf/simulated/clean_blood()
|
||||
for(var/obj/effect/decal/cleanable/blood/B in contents)
|
||||
B.clean_blood()
|
||||
..()
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
if(istype(loc, /area/chapel))
|
||||
@@ -127,6 +132,8 @@
|
||||
|
||||
if(istype(M))
|
||||
for(var/obj/effect/decal/cleanable/blood/B in contents)
|
||||
if(!B.blood_DNA)
|
||||
B.blood_DNA = list()
|
||||
if(!B.blood_DNA[M.dna.unique_enzymes])
|
||||
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
|
||||
B.virus2 = virus_copylist(M.virus2)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
var/decl/flooring/F = flooring_types[flooring_type]
|
||||
if(!F.build_type)
|
||||
continue
|
||||
if(C.type == F.build_type)
|
||||
if((S.type == F.build_type) || (S.build_type == F.build_type))
|
||||
use_flooring = F
|
||||
break
|
||||
if(!use_flooring)
|
||||
|
||||
@@ -216,3 +216,6 @@ var/const/enterloopsanity = 100
|
||||
if(A.density && !(A.flags & ON_BORDER))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/turf/proc/update_blood_overlays()
|
||||
return
|
||||
|
||||
+5
-4
@@ -66,10 +66,11 @@ var/list/wizardstart = list()
|
||||
var/list/newplayer_start = list()
|
||||
|
||||
//Spawnpoints.
|
||||
var/list/latejoin = list()
|
||||
var/list/latejoin_gateway = list()
|
||||
var/list/latejoin_cryo = list()
|
||||
var/list/latejoin_cyborg = list()
|
||||
var/list/latejoin = list()
|
||||
var/list/latejoin_gateway = list()
|
||||
var/list/latejoin_elevator = list()
|
||||
var/list/latejoin_cryo = list()
|
||||
var/list/latejoin_cyborg = list()
|
||||
|
||||
var/list/prisonwarp = list() // Prisoners go to these
|
||||
var/list/holdingfacility = list() // Captured people go here
|
||||
|
||||
@@ -1326,3 +1326,19 @@ proc/admin_notice(var/message, var/rights)
|
||||
message_admins("[key_name(usr)] attempting to force mode latespawn.")
|
||||
ticker.mode.next_spawn = 0
|
||||
ticker.mode.try_latespawn()
|
||||
|
||||
/datum/admins/proc/set_tcrystals(mob/living/carbon/human/H as mob)
|
||||
set category = "Debug"
|
||||
set name = "Set Telecrystals"
|
||||
set desc = "Allows admins to change telecrystals of a user."
|
||||
|
||||
var/crystals
|
||||
|
||||
if(check_rights(R_ADMIN))
|
||||
crystals = input("Amount of telecrystals for [H.ckey]", crystals) as null|num
|
||||
if (!isnull(crystals))
|
||||
H.mind.tcrystals = crystals
|
||||
var/msg = "[key_name(usr)] has modified [H.ckey]'s telecrystals to [crystals]."
|
||||
message_admins(msg)
|
||||
else
|
||||
usr << "You do not have access to this command."
|
||||
|
||||
@@ -13,7 +13,8 @@ var/list/admin_verbs_default = list(
|
||||
// /client/proc/deadchat /*toggles deadchat on/off*/
|
||||
)
|
||||
var/list/admin_verbs_admin = list(
|
||||
/client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/
|
||||
/client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/
|
||||
/datum/admins/proc/set_tcrystals,
|
||||
/client/proc/invisimin, /*allows our mob to go invisible/visible*/
|
||||
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage
|
||||
/datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/
|
||||
@@ -283,7 +284,8 @@ var/list/admin_verbs_hideable = list(
|
||||
/client/proc/enable_debug_verbs,
|
||||
/client/proc/roll_dices,
|
||||
/proc/possess,
|
||||
/proc/release
|
||||
/proc/release,
|
||||
/datum/admins/proc/set_tcrystals
|
||||
)
|
||||
var/list/admin_verbs_mod = list(
|
||||
/client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/
|
||||
|
||||
@@ -162,6 +162,7 @@ var/list/debug_verbs = list (
|
||||
,/client/proc/testZAScolors_remove
|
||||
,/client/proc/setup_supermatter_engine
|
||||
,/client/proc/atmos_toggle_debug
|
||||
,/client/proc/spawn_tanktransferbomb
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -424,6 +424,54 @@ var/global/list/gear_datums = list()
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/bluejumpsuit
|
||||
display_name = "jumpsuit, blue"
|
||||
path = /obj/item/clothing/under/color/blue
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/greenjumpsuit
|
||||
display_name = "jumpsuit, green"
|
||||
path = /obj/item/clothing/under/color/green
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/greyjumpsuit
|
||||
display_name = "jumpsuit, grey"
|
||||
path = /obj/item/clothing/under/color/grey
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/pinkjumpsuit
|
||||
display_name = "jumpsuit, pink"
|
||||
path = /obj/item/clothing/under/color/pink
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/whitejumpsuit
|
||||
display_name = "jumpsuit, white"
|
||||
path = /obj/item/clothing/under/color/white
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/yellowjumpsuit
|
||||
display_name = "jumpsuit, yellow"
|
||||
path = /obj/item/clothing/under/color/yellow
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/lightbluejumpsuit
|
||||
display_name = "jumpsuit, lightblue"
|
||||
path = /obj/item/clothing/under/lightblue
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/redjumpsuit
|
||||
display_name = "jumpsuit, red"
|
||||
path = /obj/item/clothing/under/color/red
|
||||
slot = slot_w_uniform
|
||||
cost = 1
|
||||
|
||||
/datum/gear/skirt_blue
|
||||
display_name = "plaid skirt, blue"
|
||||
path = /obj/item/clothing/under/dress/plaid_blue
|
||||
@@ -934,6 +982,7 @@ var/global/list/gear_datums = list()
|
||||
|
||||
/datum/gear/scarf_orange
|
||||
display_name = "scarf, orange"
|
||||
path = /obj/item/clothing/accessory/scarf/orange
|
||||
slot = slot_tie
|
||||
cost = 1
|
||||
|
||||
@@ -1015,7 +1064,7 @@ var/global/list/gear_datums = list()
|
||||
|
||||
/datum/gear/leather_coat
|
||||
display_name = "leather coat"
|
||||
path = /obj/item/clothing/suit/leathercoat/alt
|
||||
path = /obj/item/clothing/suit/leathercoat
|
||||
cost = 2
|
||||
slot = slot_wear_suit
|
||||
|
||||
@@ -1079,6 +1128,12 @@ var/global/list/gear_datums = list()
|
||||
cost = 2
|
||||
slot = slot_wear_suit
|
||||
|
||||
/datum/gear/mil_alt
|
||||
display_name = "military jacket, alt"
|
||||
path = /obj/item/clothing/suit/jacket/miljacket2
|
||||
cost = 2
|
||||
slot = slot_wear_suit
|
||||
|
||||
/datum/gear/hazard_vest
|
||||
display_name = "hazard vest"
|
||||
path = /obj/item/clothing/suit/storage/hazardvest
|
||||
@@ -1561,6 +1616,12 @@ var/global/list/gear_datums = list()
|
||||
sort_category = "misc"
|
||||
cost = 1
|
||||
|
||||
/datum/gear/boot_knife
|
||||
display_name = "boot knife"
|
||||
path = /obj/item/weapon/material/kitchen/utensil/knife/boot
|
||||
sort_category = "misc"
|
||||
cost = 3
|
||||
|
||||
/datum/gear/cane
|
||||
display_name = "cane"
|
||||
path = /obj/item/weapon/cane
|
||||
@@ -1657,6 +1718,12 @@ var/global/list/gear_datums = list()
|
||||
cost = 1
|
||||
sort_category = "ears"
|
||||
|
||||
/datum/gear/headphones
|
||||
display_name = "headphones"
|
||||
path = /obj/item/clothing/ears/earmuffs/headphones
|
||||
cost = 1
|
||||
sort_category = "ears"
|
||||
|
||||
/datum/gear/skrell_chain
|
||||
display_name = "skrell headtail-wear, female, chain"
|
||||
path = /obj/item/clothing/ears/skrell/chain
|
||||
|
||||
@@ -38,6 +38,14 @@ var/list/spawntypes = list()
|
||||
..()
|
||||
turfs = latejoin_gateway
|
||||
|
||||
/datum/spawnpoint/elevator
|
||||
display_name = "Elevator"
|
||||
msg = "has arrived from the residential district"
|
||||
|
||||
/datum/spawnpoint/elevator/New()
|
||||
..()
|
||||
turfs = latejoin_elevator
|
||||
|
||||
/datum/spawnpoint/cryo
|
||||
display_name = "Cryogenic Storage"
|
||||
msg = "has completed cryogenic revival"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "clothing"
|
||||
siemens_coefficient = 0.9
|
||||
var/list/species_restricted = null //Only these species can wear this kit.
|
||||
var/gunshot_residue //Used by forensics.
|
||||
|
||||
/*
|
||||
Sprites used when the clothing item is refit. This is done by setting icon_override.
|
||||
@@ -15,6 +16,11 @@
|
||||
/obj/item/clothing/proc/update_clothing_icon()
|
||||
return
|
||||
|
||||
// Aurora forensics port.
|
||||
/obj/item/clothing/clean_blood()
|
||||
..()
|
||||
gunshot_residue = null
|
||||
|
||||
//BS12: Species-restricted clothing check.
|
||||
/obj/item/clothing/mob_can_equip(M as mob, slot)
|
||||
|
||||
@@ -157,6 +163,32 @@
|
||||
item_state = "earmuffs"
|
||||
slot_flags = SLOT_EARS | SLOT_TWOEARS
|
||||
|
||||
/obj/item/clothing/ears/earmuffs/headphones
|
||||
name = "headphones"
|
||||
desc = "Unce unce unce unce."
|
||||
var/headphones_on = 0
|
||||
icon_state = "headphones_off"
|
||||
item_state = "headphones"
|
||||
slot_flags = SLOT_EARS | SLOT_TWOEARS
|
||||
|
||||
/obj/item/clothing/ears/earmuffs/headphones/verb/togglemusic()
|
||||
set name = "Toggle Headphone Music"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(!istype(usr, /mob/living)) return
|
||||
if(usr.stat) return
|
||||
|
||||
if(headphones_on)
|
||||
icon_state = "headphones_off"
|
||||
headphones_on = 0
|
||||
usr << "<span class='notice'>You turn the music off.</span>"
|
||||
else
|
||||
icon_state = "headphones_on"
|
||||
headphones_on = 1
|
||||
usr << "<span class='notice'>You turn the music on.</span>"
|
||||
|
||||
update_clothing_icon()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//Glasses
|
||||
/*
|
||||
@@ -387,6 +419,9 @@ BLIND // can't see anything
|
||||
body_parts_covered = FEET
|
||||
slot_flags = SLOT_FEET
|
||||
|
||||
var/can_hold_knife
|
||||
var/obj/item/holding
|
||||
|
||||
permeability_coefficient = 0.50
|
||||
slowdown = SHOES_SLOWDOWN
|
||||
force = 2
|
||||
@@ -397,6 +432,54 @@ BLIND // can't see anything
|
||||
"Resomi" = 'icons/mob/species/resomi/shoes.dmi',
|
||||
)
|
||||
|
||||
/obj/item/clothing/shoes/proc/draw_knife()
|
||||
set name = "Draw Boot Knife"
|
||||
set desc = "Pull out your boot knife."
|
||||
set category = "IC"
|
||||
set src in usr
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.incapacitated())
|
||||
return
|
||||
|
||||
holding.forceMove(get_turf(usr))
|
||||
|
||||
if(usr.put_in_hands(holding))
|
||||
usr.visible_message("<span class='danger'>\The [usr] pulls a knife out of their boot!</span>")
|
||||
holding = null
|
||||
else
|
||||
usr << "<span class='warning'>Your need an empty, unbroken hand to do that.</span>"
|
||||
holding.forceMove(src)
|
||||
|
||||
if(!holding)
|
||||
verbs -= /obj/item/clothing/shoes/proc/draw_knife
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/attackby(var/obj/item/I, var/mob/user)
|
||||
if(can_hold_knife && istype(I, /obj/item/weapon/material/shard) || \
|
||||
istype(I, /obj/item/weapon/material/butterfly) || \
|
||||
istype(I, /obj/item/weapon/material/kitchen/utensil) || \
|
||||
istype(I, /obj/item/weapon/material/hatchet/tacknife))
|
||||
if(holding)
|
||||
user << "<span class='warning'>\The [src] is already holding \a [holding].</span>"
|
||||
return
|
||||
user.unEquip(I)
|
||||
I.forceMove(src)
|
||||
holding = I
|
||||
user.visible_message("<span class='notice'>\The [user] shoves \the [I] into \the [src].</span>")
|
||||
verbs |= /obj/item/clothing/shoes/proc/draw_knife
|
||||
update_icon()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/shoes/update_icon()
|
||||
overlays.Cut()
|
||||
if(holding)
|
||||
overlays += image(icon, "[icon_state]_knife")
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/shoes/proc/handle_movement(var/turf/walking, var/running)
|
||||
return
|
||||
|
||||
|
||||
@@ -183,6 +183,14 @@
|
||||
item_state = "blindfold"
|
||||
//vision_flags = BLIND // This flag is only supposed to be used if it causes permanent blindness, not temporary because of glasses
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/blindfold/tape
|
||||
name = "length of tape"
|
||||
desc = "It's a robust DIY blindfold!"
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "tape_cross"
|
||||
item_state = null
|
||||
w_class = 1
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/prescription
|
||||
name = "prescription sunglasses"
|
||||
prescription = 1
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
icon_state = "healthhud"
|
||||
body_parts_covered = 0
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/prescription
|
||||
name = "Prescription Health Scanner HUD"
|
||||
desc = "A medical HUD integrated with a set of prescription glasses"
|
||||
icon_state = "healthhud"
|
||||
prescription = 1
|
||||
icon_state = "healthhudpresc"
|
||||
item_state = "healthhudpresc"
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/process_hud(var/mob/M)
|
||||
process_med_hud(M, 1)
|
||||
@@ -27,6 +34,14 @@
|
||||
body_parts_covered = 0
|
||||
var/global/list/jobs[0]
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/prescription
|
||||
name = "Prescription Security HUD"
|
||||
desc = "A security HUD integrated with a set of prescription glasses"
|
||||
icon_state = "securityhud"
|
||||
prescription = 1
|
||||
icon_state = "sechudpresc"
|
||||
item_state = "sechudpresc"
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/jensenshades
|
||||
name = "Augmented shades"
|
||||
desc = "Polarized bioneural eyewear, designed to augment your vision."
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
gas_transfer_coefficient = 0.90
|
||||
voicechange = 1
|
||||
|
||||
/obj/item/clothing/mask/muzzle/tape
|
||||
name = "length of tape"
|
||||
desc = "It's a robust DIY muzzle!"
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "tape_cross"
|
||||
item_state = null
|
||||
w_class = 1
|
||||
|
||||
/obj/item/clothing/mask/muzzle/New()
|
||||
..()
|
||||
say_messages = list("Mmfph!", "Mmmf mrrfff!", "Mmmf mnnf!")
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
force = 3
|
||||
armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.7
|
||||
can_hold_knife = 1
|
||||
|
||||
/obj/item/clothing/shoes/jackboots/unathi
|
||||
name = "toe-less jackboots"
|
||||
@@ -30,3 +31,4 @@
|
||||
item_state = "workboots"
|
||||
armor = list(melee = 40, bullet = 0, laser = 0, energy = 15, bomb = 20, bio = 0, rad = 20)
|
||||
siemens_coefficient = 0.7
|
||||
can_hold_knife = 1
|
||||
@@ -121,6 +121,11 @@
|
||||
|
||||
if(T.contains_dense_objects())
|
||||
H << "<span class='warning'>You cannot teleport to a location with solid objects.</span>"
|
||||
return 0
|
||||
|
||||
if(T.z != H.z || get_dist(T, get_turf(H)) > world.view)
|
||||
H << "<span class='warning'>You cannot teleport to such a distant object.</span>"
|
||||
return 0
|
||||
|
||||
phase_out(H,get_turf(H))
|
||||
H.forceMove(T)
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
icon_state = "space"
|
||||
desc = "A special helmet designed for work in a hazardous, low-pressure environment."
|
||||
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT
|
||||
flags_inv = BLOCKHAIR
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "s_helmet",
|
||||
slot_r_hand_str = "s_helmet",
|
||||
)
|
||||
permeability_coefficient = 0.01
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR
|
||||
body_parts_covered = HEAD|FACE|EYES
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
name = "black medical space helmet"
|
||||
desc = "A black helmet sporting a medical cross and durable plating. Hopefully the wearer abides by space geneva."
|
||||
icon_state = "syndicate-helm-black-med"
|
||||
item_state_slots = list(slot_head_str = "syndicate-black-med")
|
||||
item_state_slots = list(slot_head_str = "syndicate-helm-black-med")
|
||||
|
||||
/obj/item/clothing/suit/space/syndicate/black/med
|
||||
name = "black medical space suit"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
flags_inv = HIDEEARS | BLOCKHAIR
|
||||
// flags_inv = HIDEEARS|BLOCKHAIR
|
||||
|
||||
//Species-specific stuff.
|
||||
species_restricted = list("Human")
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
/obj/item/clothing/suit/armor/laserproof/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
|
||||
var/obj/item/projectile/P = damage_source
|
||||
|
||||
|
||||
var/reflectchance = 40 - round(damage/3)
|
||||
if(!(def_zone in list("chest", "groin")))
|
||||
reflectchance /= 2
|
||||
@@ -171,12 +171,12 @@
|
||||
if(!turfs.len) turfs += pick(/turf in orange(6))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked)) return
|
||||
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, user.loc)
|
||||
spark_system.start()
|
||||
playsound(user.loc, "sparks", 50, 1)
|
||||
|
||||
|
||||
user.loc = picked
|
||||
return PROJECTILE_FORCE_MISS
|
||||
return 0
|
||||
@@ -275,7 +275,7 @@
|
||||
icon_state = "kvest"
|
||||
item_state = "kvest"
|
||||
armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/device/detective_scanner)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/officer
|
||||
name = "officer armor vest"
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
item_state = "det_suit"
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = UPPER_TORSO|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/storage/fancy/cigarettes,/obj/item/weapon/flame/lighter,/obj/item/device/detective_scanner,/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/storage/fancy/cigarettes,/obj/item/weapon/flame/lighter,/obj/item/device/taperecorder)
|
||||
armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/suit/storage/det_trench/grey
|
||||
@@ -109,7 +109,7 @@
|
||||
desc = "A forensics technician jacket."
|
||||
item_state = "det_suit"
|
||||
body_parts_covered = UPPER_TORSO|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/device/detective_scanner,/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/device/taperecorder)
|
||||
armor = list(melee = 10, bullet = 10, laser = 15, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/suit/storage/forensics/red
|
||||
|
||||
@@ -212,18 +212,12 @@
|
||||
//coats
|
||||
|
||||
/obj/item/clothing/suit/leathercoat
|
||||
name = "leather coat"
|
||||
desc = "A long, thick black leather coat."
|
||||
icon_state = "leathercoat"
|
||||
item_state = "leathercoat"
|
||||
|
||||
/obj/item/clothing/suit/leathercoat/alt
|
||||
name = "leather coat"
|
||||
desc = "A long, thick black leather coat."
|
||||
icon_state = "leathercoat_alt"
|
||||
item_state = "leathercoat_alt"
|
||||
|
||||
/obj/item/clothing/suit/leathercoat/alt/sec
|
||||
/obj/item/clothing/suit/leathercoat/sec
|
||||
name = "leather coat"
|
||||
desc = "A long, thick black leather coat."
|
||||
icon_state = "leathercoat_sec"
|
||||
@@ -367,6 +361,12 @@
|
||||
icon_state = "militaryjacket"
|
||||
item_state = "militaryjacket"
|
||||
|
||||
/obj/item/clothing/suit/jacket/miljacket2
|
||||
name = "military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable."
|
||||
icon_state = "militaryjacket2"
|
||||
item_state = "militaryjacket2"
|
||||
|
||||
/obj/item/clothing/suit/storage/toggle/bomber
|
||||
name = "bomber jacket"
|
||||
desc = "A thick, well-worn WW2 leather bomber jacket."
|
||||
@@ -397,11 +397,8 @@
|
||||
body_parts_covered = UPPER_TORSO|ARMS
|
||||
|
||||
/obj/item/clothing/suit/storage/leather_jacket/alt
|
||||
name = "leather jacket"
|
||||
desc = "A black leather coat."
|
||||
icon_state = "leather_jacket_alt"
|
||||
item_state = "leather_jacket_alt"
|
||||
body_parts_covered = UPPER_TORSO|ARMS
|
||||
|
||||
/obj/item/clothing/suit/storage/leather_jacket/nanotrasen
|
||||
desc = "A black leather coat. A corporate logo is proudly displayed on the back."
|
||||
@@ -409,7 +406,7 @@
|
||||
|
||||
//This one has buttons for some reason
|
||||
/obj/item/clothing/suit/storage/toggle/brown_jacket
|
||||
name = "leather jacket"
|
||||
name = "brown jacket"
|
||||
desc = "A brown leather coat."
|
||||
icon_state = "brown_jacket"
|
||||
item_state = "brown_jacket"
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
holstered.add_fingerprint(user)
|
||||
w_class = max(w_class, holstered.w_class)
|
||||
user.visible_message("<span class='notice'>[user] holsters \the [holstered].</span>", "<span class='notice'>You holster \the [holstered].</span>")
|
||||
name = "occupied [initial(name)]"
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/clear_holster()
|
||||
holstered = null
|
||||
name = initial(name)
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob)
|
||||
if(!holstered)
|
||||
@@ -40,8 +45,8 @@
|
||||
)
|
||||
user.put_in_hands(holstered)
|
||||
holstered.add_fingerprint(user)
|
||||
holstered = null
|
||||
w_class = initial(w_class)
|
||||
clear_holster()
|
||||
|
||||
/obj/item/clothing/accessory/holster/attack_hand(mob/user as mob)
|
||||
if (has_suit) //if we are part of a suit
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/obj/item/weapon/forensics
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
w_class = 1
|
||||
|
||||
//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)
|
||||
var/const/FINGERPRINT_COMPLETE = 6
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
//DNA machine
|
||||
/obj/machinery/dnaforensics
|
||||
name = "DNA analyzer"
|
||||
desc = "A high tech machine that is designed to read DNA samples properly."
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
icon_state = "dnaopen"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
var/obj/item/weapon/forensics/swab/bloodsamp = null
|
||||
var/closed = 0
|
||||
var/scanning = 0
|
||||
var/scanner_progress = 0
|
||||
var/scanner_rate = 2.50
|
||||
var/last_process_worldtime = 0
|
||||
var/report_num = 0
|
||||
|
||||
/obj/machinery/dnaforensics/attackby(var/obj/item/W, mob/user as mob)
|
||||
|
||||
if(bloodsamp)
|
||||
user << "<span class='warning'>There is already a sample in the machine.</span>"
|
||||
return
|
||||
|
||||
if(closed)
|
||||
user << "<span class='warning'>Open the cover before inserting the sample.</span>"
|
||||
return
|
||||
|
||||
var/obj/item/weapon/forensics/swab/swab = W
|
||||
if(istype(swab) && swab.is_used())
|
||||
user.unEquip(W)
|
||||
src.bloodsamp = swab
|
||||
swab.loc = src
|
||||
user << "<span class='notice'>You insert \the [W] into \the [src].</span>"
|
||||
else
|
||||
user << "<span class='warning'>\The [src] only accepts used swabs.</span>"
|
||||
return
|
||||
|
||||
/obj/machinery/dnaforensics/ui_interact(mob/user, ui_key = "main",var/datum/nanoui/ui = null)
|
||||
if(stat & (NOPOWER)) return
|
||||
if(user.stat || user.restrained()) return
|
||||
var/list/data = list()
|
||||
data["scan_progress"] = round(scanner_progress)
|
||||
data["scanning"] = scanning
|
||||
data["bloodsamp"] = (bloodsamp ? bloodsamp.name : "")
|
||||
data["bloodsamp_desc"] = (bloodsamp ? (bloodsamp.desc ? bloodsamp.desc : "No information on record.") : "")
|
||||
data["lidstate"] = closed
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "dnaforensics.tmpl", "QuikScan DNA Analyzer", 540, 326)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/dnaforensics/Topic(href, href_list)
|
||||
|
||||
if(..()) return 1
|
||||
|
||||
if(stat & (NOPOWER))
|
||||
return 0 // don't update UIs attached to this object
|
||||
|
||||
if(href_list["scanItem"])
|
||||
if(scanning)
|
||||
scanning = 0
|
||||
else
|
||||
if(bloodsamp)
|
||||
if(closed == 1)
|
||||
scanner_progress = 0
|
||||
scanning = 1
|
||||
usr << "<span class='notice'>Scan initiated.</span>"
|
||||
update_icon()
|
||||
else
|
||||
usr << "<span class='notice'>Please close sample lid before initiating scan.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Insert an item to scan.</span>"
|
||||
|
||||
if(href_list["ejectItem"])
|
||||
if(bloodsamp)
|
||||
bloodsamp.forceMove(src.loc)
|
||||
bloodsamp = null
|
||||
|
||||
if(href_list["toggleLid"])
|
||||
toggle_lid()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/dnaforensics/process()
|
||||
if(scanning)
|
||||
if(!bloodsamp || bloodsamp.loc != src)
|
||||
bloodsamp = null
|
||||
scanning = 0
|
||||
else if(scanner_progress >= 100)
|
||||
complete_scan()
|
||||
return
|
||||
else
|
||||
//calculate time difference
|
||||
var/deltaT = (world.time - last_process_worldtime) * 0.1
|
||||
scanner_progress = min(100, scanner_progress + scanner_rate * deltaT)
|
||||
last_process_worldtime = world.time
|
||||
|
||||
/obj/machinery/dnaforensics/proc/complete_scan()
|
||||
src.visible_message("<span class='notice'>\icon[src] makes an insistent chime.</span>", 2)
|
||||
update_icon()
|
||||
if(bloodsamp)
|
||||
var/obj/item/weapon/paper/P = new(src)
|
||||
P.name = "[src] report #[++report_num]: [bloodsamp.name]"
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
//dna data itself
|
||||
var/data = "No scan information available."
|
||||
if(bloodsamp.dna != null)
|
||||
data = "Spectometric analysis on provided sample has determined the presence of [bloodsamp.dna.len] strings of DNA.<br><br>"
|
||||
for(var/blood in bloodsamp.dna)
|
||||
data += "\blue Blood type: [bloodsamp.dna[blood]]<br>\nDNA: [blood]<br><br>"
|
||||
else
|
||||
data += "No DNA found.<br>"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
P.info += "<b>Scanned item:</b><br>[bloodsamp.name]<br>[bloodsamp.desc]<br><br>" + data
|
||||
P.forceMove(src.loc)
|
||||
P.update_icon()
|
||||
scanning = 0
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/dnaforensics/attack_ai(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/dnaforensics/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/dnaforensics/verb/toggle_lid()
|
||||
set category = "Object"
|
||||
set name = "Toggle Lid"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.stat || !isliving(usr))
|
||||
return
|
||||
|
||||
if(scanning)
|
||||
usr << "<span class='warning'>You can't do that while [src] is scanning!</span>"
|
||||
return
|
||||
|
||||
closed = !closed
|
||||
src.update_icon()
|
||||
|
||||
/obj/machinery/dnaforensics/update_icon()
|
||||
..()
|
||||
if(!(stat & NOPOWER) && scanning)
|
||||
icon_state = "dnaworking"
|
||||
else if(closed)
|
||||
icon_state = "dnaclosed"
|
||||
else
|
||||
icon_state = "dnaopen"
|
||||
@@ -0,0 +1,116 @@
|
||||
//microscope code itself
|
||||
/obj/machinery/microscope
|
||||
name = "high powered electron microscope"
|
||||
desc = "A highly advanced microscope capable of zooming up to 3000x."
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
icon_state = "microscope"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
var/obj/item/weapon/sample = null
|
||||
var/report_num = 0
|
||||
|
||||
/obj/machinery/microscope/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
if(sample)
|
||||
user << "<span class='warning'>There is already a slide in the microscope.</span>"
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/forensics/slide) || istype(W, /obj/item/weapon/sample/print))
|
||||
user << "<span class='notice'>You insert \the [W] into the microscope.</span>"
|
||||
user.unEquip(W)
|
||||
W.forceMove(src)
|
||||
sample = W
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/microscope/attack_hand(mob/user)
|
||||
|
||||
if(!sample)
|
||||
user << "<span class='warning'>The microscope has no sample to examine.</span>"
|
||||
return
|
||||
|
||||
user << "<span class='notice'>The microscope whirrs as you examine \the [sample].</span>"
|
||||
|
||||
if(!do_after(user, 25) || !sample)
|
||||
return
|
||||
|
||||
user << "<span class='notice'>Printing findings now...</span>"
|
||||
var/obj/item/weapon/paper/report = new(get_turf(src))
|
||||
report.stamped = list(/obj/item/weapon/stamp)
|
||||
report.overlays = list("paper_stamped")
|
||||
report_num++
|
||||
|
||||
if(istype(sample, /obj/item/weapon/forensics/slide))
|
||||
var/obj/item/weapon/forensics/slide/slide = sample
|
||||
if(slide.has_swab)
|
||||
var/obj/item/weapon/forensics/swab/swab = slide.has_swab
|
||||
|
||||
report.name = "GSR report #[++report_num]: [swab.name]"
|
||||
report.info = "<b>Scanned item:</b><br>[swab.name]<br><br>"
|
||||
|
||||
if(swab.gsr)
|
||||
report.info += "Residue from a [swab.gsr] bullet detected."
|
||||
else
|
||||
report.info += "No gunpowder residue found."
|
||||
|
||||
else if(slide.has_sample)
|
||||
var/obj/item/weapon/sample/fibers/fibers = slide.has_sample
|
||||
report.name = "Fiber report #[++report_num]: [fibers.name]"
|
||||
report.info = "<b>Scanned item:</b><br>[fibers.name]<br><br>"
|
||||
if(fibers.evidence)
|
||||
report.info = "Molecular analysis on provided sample has determined the presence of unique fiber strings.<br><br>"
|
||||
for(var/fiber in fibers.evidence)
|
||||
report.info += "<span class='notice'>Most likely match for fibers: [fiber]</span><br><br>"
|
||||
else
|
||||
report.info += "No fibers found."
|
||||
else
|
||||
report.name = "Empty slide report #[report_num]"
|
||||
report.info = "Evidence suggests that there's nothing in this slide."
|
||||
else if(istype(sample, /obj/item/weapon/sample/print))
|
||||
report.name = "Fingerprint report #[report_num]: [sample.name]"
|
||||
report.info = "<b>Fingerprint analysis report #[report_num]</b>: [sample.name]<br>"
|
||||
var/obj/item/weapon/sample/print/card = sample
|
||||
if(card.evidence && card.evidence.len)
|
||||
report.info += "Surface analysis has determined unique fingerprint strings:<br><br>"
|
||||
for(var/prints in card.evidence)
|
||||
report.info += "<span class='notice'>Fingerprint string: </span>"
|
||||
if(!is_complete_print(prints))
|
||||
report.info += "INCOMPLETE PRINT"
|
||||
else
|
||||
report.info += "[prints]"
|
||||
report.info += "<br>"
|
||||
else
|
||||
report.info += "No information available."
|
||||
|
||||
if(report)
|
||||
report.update_icon()
|
||||
if(report.info)
|
||||
user << report.info
|
||||
return
|
||||
|
||||
/obj/machinery/microscope/proc/remove_sample(var/mob/living/remover)
|
||||
if(!istype(remover) || remover.incapacitated() || !Adjacent(remover))
|
||||
return ..()
|
||||
if(!sample)
|
||||
remover << "<span class='warning'>\The [src] does not have a sample in it.</span>"
|
||||
return
|
||||
remover << "<span class='notice'>You remove \the [sample] from \the [src].</span>"
|
||||
sample.forceMove(get_turf(src))
|
||||
remover.put_in_hands(sample)
|
||||
sample = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/microscope/AltClick()
|
||||
remove_sample(usr)
|
||||
|
||||
/obj/machinery/microscope/MouseDrop(var/atom/other)
|
||||
if(usr == other)
|
||||
remove_sample(usr)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/microscope/update_icon()
|
||||
icon_state = "microscope"
|
||||
if(sample)
|
||||
icon_state += "slide"
|
||||
@@ -0,0 +1,42 @@
|
||||
/obj/item/weapon/forensics/slide
|
||||
name = "microscope slide"
|
||||
desc = "A pair of thin glass panes used in the examination of samples beneath a microscope."
|
||||
icon_state = "slide"
|
||||
var/obj/item/weapon/forensics/swab/has_swab
|
||||
var/obj/item/weapon/sample/fibers/has_sample
|
||||
|
||||
/obj/item/weapon/forensics/slide/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
if(has_swab || has_sample)
|
||||
user << "<span class='warning'>There is already a sample in the slide.</span>"
|
||||
return
|
||||
if(istype (W, /obj/item/weapon/forensics/swab))
|
||||
has_swab = W
|
||||
else if(istype(W, /obj/item/weapon/sample/fibers))
|
||||
has_sample = W
|
||||
else
|
||||
user << "<span class='warning'>You don't think this will fit.</span>"
|
||||
return
|
||||
user << "<span class='notice'>You insert the sample into the slide.</span>"
|
||||
user.unEquip(W)
|
||||
W.forceMove(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/forensics/slide/attack_self(var/mob/user)
|
||||
if(has_swab || has_sample)
|
||||
user << "<span class='notice'>You remove \the sample from \the [src].</span>"
|
||||
if(has_swab)
|
||||
has_swab.loc = get_turf(src)
|
||||
has_swab = null
|
||||
if(has_sample)
|
||||
has_sample.forceMove(get_turf(src))
|
||||
has_sample = null
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/forensics/slide/update_icon()
|
||||
if(!has_swab && !has_sample)
|
||||
icon_state = "slide"
|
||||
else if(has_swab)
|
||||
icon_state = "slideswab"
|
||||
else if(has_sample)
|
||||
icon_state = "slidefiber"
|
||||
@@ -1,115 +0,0 @@
|
||||
/obj/item/device/detective_scanner
|
||||
name = "forensic scanner"
|
||||
desc = "Used to scan objects for DNA and fingerprints."
|
||||
icon_state = "forensic1"
|
||||
var/list/stored = list()
|
||||
w_class = 3.0
|
||||
item_state = "electronic"
|
||||
flags = CONDUCT | NOBLUDGEON
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/device/detective_scanner/attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if (!ishuman(M))
|
||||
user << "<span class='warning'>[M] is not human and cannot have the fingerprints.</span>"
|
||||
flick("forensic0",src)
|
||||
return 0
|
||||
if (( !( istype(M.dna, /datum/dna) ) || M.gloves) )
|
||||
user << "<span class='notice'>No fingerprints found on [M]</span>"
|
||||
flick("forensic0",src)
|
||||
return 0
|
||||
else
|
||||
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 << "<span class='notice'>Done printing.</span>"
|
||||
user << "<span class='notice'>[M]'s Fingerprints: [md5(M.dna.uni_identity)]</span>"
|
||||
if ( M.blood_DNA && M.blood_DNA.len )
|
||||
user << "<span class='notice'>Blood found on [M]. Analysing...</span>"
|
||||
spawn(15)
|
||||
for(var/blood in M.blood_DNA)
|
||||
user << "<span class='notice'>Blood type: [M.blood_DNA[blood]]\nDNA: [blood]</span>"
|
||||
return
|
||||
|
||||
/obj/item/device/detective_scanner/afterattack(atom/A as obj|turf, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(ismob(A))
|
||||
return
|
||||
if(istype(A,/obj/machinery/computer/forensic_scanning))
|
||||
user.visible_message("[user] takes a cord out of [src] and hooks its end into [A]" ,\
|
||||
"<span class='notice'>You download data from [src] to [A]</span>")
|
||||
var/obj/machinery/computer/forensic_scanning/F = A
|
||||
F.sync_data(stored)
|
||||
return
|
||||
|
||||
if(istype(A,/obj/item/weapon/f_card))
|
||||
user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\""
|
||||
flick("forensic0",src)
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
//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." : "."]" ,\
|
||||
"<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on [A]!</span>",\
|
||||
"You hear a faint hum of electrical equipment.")
|
||||
flick("forensic0",src)
|
||||
return 0
|
||||
|
||||
if(add_data(A))
|
||||
user << "<span class='notice'>Object already in internal memory. Consolidating data...</span>"
|
||||
flick("forensic2",src)
|
||||
return
|
||||
|
||||
//PRINTS
|
||||
if(A.fingerprints && A.fingerprints.len)
|
||||
user << "<span class='notice'>Isolated [A.fingerprints.len] fingerprints:</span>"
|
||||
user << "Data Stored: Scan with Hi-Res Forensic Scanner to retrieve.</span>"
|
||||
var/list/complete_prints = list()
|
||||
for(var/i in A.fingerprints)
|
||||
var/print = A.fingerprints[i]
|
||||
if(stringpercent(print) <= FINGERPRINT_COMPLETE)
|
||||
complete_prints += print
|
||||
if(complete_prints.len < 1)
|
||||
user << "<span class='notice'>No intact prints found</span>"
|
||||
else
|
||||
user << "<span class='notice'>Found [complete_prints.len] intact prints</span>"
|
||||
for(var/i in complete_prints)
|
||||
user << "<span class='notice'> [i]</span>"
|
||||
|
||||
//FIBERS
|
||||
if(A.suit_fibers && A.suit_fibers.len)
|
||||
user << "<span class='notice'>Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve."
|
||||
flick("forensic2",src)
|
||||
|
||||
//Blood
|
||||
if (A.blood_DNA && A.blood_DNA.len)
|
||||
user << "<span class='notice'>Blood detected. Analysing...</span>"
|
||||
spawn(15)
|
||||
for(var/blood in A.blood_DNA)
|
||||
user << "Blood type: \red [A.blood_DNA[blood]] \t \black DNA: \red [blood]"
|
||||
|
||||
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
|
||||
"<span class='notice'>You finish scanning \the [A].</span>",\
|
||||
"You hear a faint hum of electrical equipment.")
|
||||
flick("forensic2",src)
|
||||
return 0
|
||||
|
||||
/obj/item/device/detective_scanner/proc/add_data(atom/A as mob|obj|turf|area)
|
||||
var/datum/data/record/forensic/old = stored["\ref [A]"]
|
||||
var/datum/data/record/forensic/fresh = new(A)
|
||||
|
||||
if(old)
|
||||
fresh.merge(old)
|
||||
. = 1
|
||||
stored["\ref [A]"] = fresh
|
||||
|
||||
/obj/item/device/detective_scanner/verb/wipe()
|
||||
set name = "Wipe Forensic Data"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
if (alert("Are you sure you want to wipe all data from [src]?",,"Yes","No") == "Yes")
|
||||
stored = list()
|
||||
usr << "<span class='notice'>Forensic data erase complete.</span>"
|
||||
@@ -1,313 +0,0 @@
|
||||
/obj/machinery/computer/forensic_scanning
|
||||
name = "high-res forensic scanning computer"
|
||||
icon_keyboard = "security_key"
|
||||
icon_screen = "forensic"
|
||||
|
||||
var/screen = "database"
|
||||
var/authenticated = 0
|
||||
req_access = list(access_forensics_lockers)
|
||||
var/scan_progress = -1
|
||||
var/obj/item/scanning
|
||||
var/datum/data/record/forensic/current
|
||||
|
||||
var/list/filters = list()
|
||||
var/list/current_list = list()
|
||||
|
||||
var/list/files = list()
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/proc/get_printable_data(var/datum/data/record/forensic/fresh)
|
||||
. += "<h2>[fresh.fields["name"]]</h2>"
|
||||
. += "Scanned in [fresh.fields["area"]] at [worldtime2text(fresh.fields["time"])]<br>"
|
||||
var/list/prints = fresh.fields["fprints"]
|
||||
if(prints.len)
|
||||
. += "<h3>Fingerprints:</h3>"
|
||||
var/incomplete = 0
|
||||
for(var/fullprint in prints)
|
||||
var/print = prints[fullprint]
|
||||
if(is_complete_print(print))
|
||||
. += "[print]<br>"
|
||||
else
|
||||
incomplete++
|
||||
if(incomplete)
|
||||
. += "[incomplete] incomplete fingerprints."
|
||||
else
|
||||
. += "<br>No fingerprints recorded.<br>"
|
||||
|
||||
var/list/fibers = fresh.fields["fibers"]
|
||||
if(fibers.len)
|
||||
. += "<h3>Fibers:</h3>"
|
||||
. += "<ul>"
|
||||
for(var/fiber in fibers)
|
||||
. += "<li>[fiber]</li>"
|
||||
. += "</ul>"
|
||||
else
|
||||
. += "<br>No fibers recorded."
|
||||
|
||||
var/list/bloods = fresh.fields["blood"]
|
||||
if(bloods.len)
|
||||
. += "<h3>Blood:</h3>"
|
||||
. += "<ul>"
|
||||
for(var/blood in bloods)
|
||||
. += "<li>DNA: [blood] Type: [bloods[blood]]</li>"
|
||||
. += "</ul>"
|
||||
else
|
||||
. += "<br>No blood recorded."
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/proc/add_record(var/datum/data/record/forensic/fresh)
|
||||
var/datum/data/record/forensic/old = files[fresh.uid]
|
||||
if(old)
|
||||
fresh.merge(old)
|
||||
fresh.fields["label"] = old.fields["label"]
|
||||
files[fresh.uid] = fresh
|
||||
|
||||
//updating partial prints on other things
|
||||
var/list/fprints = fresh.fields["fprints"]
|
||||
if(fprints.len)
|
||||
for(var/id in files)
|
||||
var/datum/data/record/forensic/rec = files[id]
|
||||
if(rec.update_prints(fprints))
|
||||
files[id] = rec
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/proc/process_card(var/obj/item/weapon/f_card/card)
|
||||
if(card.fingerprints)
|
||||
usr << "<span class='notice'>\The [src] sucks in \the [card] and whirrs, scanning it.</span>"
|
||||
var/found = 0
|
||||
for(var/id in files)
|
||||
var/datum/data/record/forensic/rec = files[id]
|
||||
found = rec.update_prints(card.fingerprints)
|
||||
if (found)
|
||||
files[id] = rec
|
||||
if(found)
|
||||
usr << "<span class='notice'>Complete match found.</span>"
|
||||
else
|
||||
usr << "<span class='notice'>No match found.</span>"
|
||||
return 1
|
||||
else
|
||||
usr << "<span class='warning'>No fingerprints detected on [card].</span>"
|
||||
return 0
|
||||
|
||||
//Takes a list of forensic records, with key being reference to object, and updates internal database.
|
||||
/obj/machinery/computer/forensic_scanning/proc/sync_data(var/list/newdata)
|
||||
for(var/id in newdata)
|
||||
var/datum/data/record/forensic/fresh = newdata[id]
|
||||
add_record(fresh)
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/proc/get_filtered_set()
|
||||
.= list()
|
||||
for(var/id in files)
|
||||
var/datum/data/record/forensic/cur = files[id]
|
||||
var/add = 1
|
||||
if(filters["name"])
|
||||
add = 0
|
||||
for(var/filter in filters["name"])
|
||||
if(findtext(cur.fields["name"], filter))
|
||||
add = 1
|
||||
break
|
||||
|
||||
if(filters["area"])
|
||||
add = 0
|
||||
for(var/filter in filters["area"])
|
||||
if(findtext(cur.fields["area"], filter))
|
||||
add = 1
|
||||
break
|
||||
|
||||
if(filters["fprints"])
|
||||
add = 0
|
||||
var/list/prints = cur.fields["fprints"]
|
||||
for(var/pid in prints)
|
||||
var/print = prints[pid]
|
||||
if (is_complete_print(print))
|
||||
for(var/filter in filters["fprints"])
|
||||
if(findtext(print, filter))
|
||||
add = 1
|
||||
break
|
||||
|
||||
if(filters["fibers"])
|
||||
add = 0
|
||||
for(var/fiber in cur.fields["fibers"])
|
||||
for(var/filter in filters["fibers"])
|
||||
if(findtext(fiber, filter))
|
||||
add = 1
|
||||
break
|
||||
|
||||
if(filters["blood"])
|
||||
add = 0
|
||||
for(var/DNA in cur.fields["blood"])
|
||||
for(var/filter in filters["blood"])
|
||||
if(findtext(DNA, filter))
|
||||
add = 1
|
||||
break
|
||||
|
||||
if(filters["label"])
|
||||
add = 0
|
||||
for(var/filter in filters["label"])
|
||||
if(cur.fields["label"] && findtext(cur.fields["label"], filter))
|
||||
add = 1
|
||||
break
|
||||
if (add)
|
||||
.+=cur
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat
|
||||
if(!authenticated)
|
||||
dat += "<a href='?src=\ref[src];operation=login'>{Log In}</a>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];operation=logout'>{Log Out}</a>"
|
||||
dat += " | "
|
||||
dat += "<a href='?src=\ref[src];operation=screen;screen=database'>Database</a>"
|
||||
dat += " | "
|
||||
dat += "<a href='?src=\ref[src];operation=screen;screen=details'>Record details</a>"
|
||||
dat += " | "
|
||||
dat += "<a href='?src=\ref[src];operation=screen;screen=scan'>Scanning</a>"
|
||||
dat +="<br><hr><br>"
|
||||
switch(screen)
|
||||
if("database") //Database screen
|
||||
dat += "Search filters:<br>"
|
||||
var/list/filternames = list("Object"="name", "Area"="area", "Fingerprints"="fprints", "Fibers"="fibers", "DNA"="blood", "Label"="label")
|
||||
for(var/filter in filternames)
|
||||
var/fname = filternames[filter]
|
||||
dat += "<br>[filter]: <a href='?src=\ref[src];operation=filter;filter=[fname]'>[filters[fname] ? list2text(filters[fname], ",") : "All"]</a>"
|
||||
|
||||
current_list = get_filtered_set()
|
||||
dat+= "<br><hr><br>"
|
||||
if(current_list.len < 1)
|
||||
dat += "No data matching your request found."
|
||||
else
|
||||
dat += "<table><tr>"
|
||||
dat += "<th>Object</th><th>Area</th><th>Fingerprints</th><th>Fibers</th><th>Blood</th><th>Label</th></tr>"
|
||||
for(var/datum/data/record/forensic/record in current_list)
|
||||
dat += "<tr><td><a href='?src=\ref[src];operation=details;identifier=[record.uid]'>[record.fields["name"]]</td>"
|
||||
dat += "<td>[record.fields["area"]]</td>"
|
||||
for(var/criteria in list("fprints", "fibers", "blood"))
|
||||
var/list/data = record.fields[criteria]
|
||||
dat += "<td>[data.len ? data.len : "None"]</td>"
|
||||
dat += "<td>[record.fields["label"] ? record.fields["label"] : ""]</td>"
|
||||
dat += "<td><a href='?src=\ref[src];operation=delete;identifier=[record.uid]'>Delete</a></td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table>"
|
||||
dat += "<a href='?src=\ref[src];operation=printall'>Print all listed</a><br>"
|
||||
|
||||
if("details") //Details screen
|
||||
if(!current)
|
||||
dat += "<br>NO RECORD SELECTED"
|
||||
else
|
||||
dat += get_printable_data(current)
|
||||
dat += "<br><b>Labels:</b> "
|
||||
dat += "<a href='?src=\ref[src];operation=label'>[current.fields["label"] ? current.fields["label"] : "None"]</a><br>"
|
||||
dat += "<a href='?src=\ref[src];operation=print'>Print record</a><br>"
|
||||
|
||||
if("scan") //Scanning screen
|
||||
dat += "Object: <a href='?src=\ref[src];operation=object'>[scanning ? scanning.name : "-----"]</a><br>"
|
||||
if (scanning)
|
||||
if (scan_progress > 0)
|
||||
dat += "Scan in progress."
|
||||
dat += " <a href='?src=\ref[src];operation=cancel'>Cancel</a><br>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];operation=scan'>Scan</a><br>"
|
||||
dat += "Insert fingerprint card here: <a href='?src=\ref[src];operation=card'>-----</a>"
|
||||
|
||||
user << browse(dat,"window=fscanner")
|
||||
onclose(user,"fscanner")
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/Topic(href,href_list)
|
||||
if(..()) return 1
|
||||
switch(href_list["operation"])
|
||||
if("login")
|
||||
var/mob/M = usr
|
||||
if(istype(M,/mob/living/silicon) || allowed(M))
|
||||
authenticated = 1
|
||||
if("logout")
|
||||
authenticated = 0
|
||||
if("filter")
|
||||
var/filterstr = sanitize(input("Input the search criteria. Multiple values can be input, separated by a comma.", "Filter setting") as text|null)
|
||||
if(filterstr)
|
||||
filters[href_list["filter"]] = text2list(filterstr,",")
|
||||
else
|
||||
filters[href_list["filter"]] = null
|
||||
if("screen")
|
||||
screen = href_list["screen"]
|
||||
if("details")
|
||||
if(href_list["identifier"])
|
||||
screen = "details"
|
||||
current = files[href_list["identifier"]]
|
||||
else
|
||||
usr << "<span class='warning'>No record found.</span>"
|
||||
if("delete")
|
||||
if(href_list["identifier"])
|
||||
if(alert("Are you sure you want to delete this record?","Record deletion", "Yes", "No") == "Yes")
|
||||
files.Remove(href_list["identifier"])
|
||||
if(current && current.uid == href_list["identifier"])
|
||||
current = null
|
||||
if("label")
|
||||
if(current)
|
||||
var/label = sanitize(input(usr,"Input the label for this record. Multiple values can be input, separated by a comma.", "Labeling record", current.fields["label"]) as text|null)
|
||||
current.fields["label"] = label
|
||||
if("object")
|
||||
if(scanning)
|
||||
scanning.loc = get_turf(src)
|
||||
scan_progress = -1
|
||||
scanning = null
|
||||
else
|
||||
var/mob/M = usr
|
||||
var/obj/item/I = M.get_active_hand()
|
||||
if(I && istype(I))
|
||||
if(istype(I, /obj/item/weapon/evidencebag))
|
||||
scanning = I.contents[1]
|
||||
scanning.loc = src
|
||||
I.overlays.Cut()
|
||||
I.w_class = 1
|
||||
I.icon_state = "evidenceobj"
|
||||
else
|
||||
scanning = I
|
||||
M.drop_item()
|
||||
I.loc = src
|
||||
else
|
||||
usr << "<span class='warning'>Invalid object, rejected.</span>"
|
||||
if("scan")
|
||||
if(scanning)
|
||||
scan_progress = 10
|
||||
if("cancel")
|
||||
scan_progress = -1
|
||||
if("card")
|
||||
var/mob/M = usr
|
||||
var/obj/item/I = M.get_active_hand()
|
||||
if(istype(I, /obj/item/weapon/f_card))
|
||||
if(process_card(I))
|
||||
M.drop_item()
|
||||
qdel(I)
|
||||
else
|
||||
usr << "<span class='warning'>Invalid fingerprint card, rejected.</span>"
|
||||
if("print")
|
||||
if(current)
|
||||
var/obj/item/weapon/paper/P = new(loc)
|
||||
P.name = "\improper Forensics Data ([current.fields["name"]])"
|
||||
P.icon_state = "paper_words"
|
||||
P.info = "<b>Forensics Database</b> - [worldtime2text(world.time)]<br><br>"
|
||||
P.info += get_printable_data(current)
|
||||
if("printall")
|
||||
var/obj/item/weapon/paper/P = new(loc)
|
||||
P.name = "\improper Forensics Data"
|
||||
P.icon_state = "paper_words"
|
||||
P.info = "<b>Forensics Database</b> - [worldtime2text(world.time)]<br><br>"
|
||||
for(var/datum/data/record/forensic/cur in current_list)
|
||||
P.info += get_printable_data(cur)
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/forensic_scanning/process()
|
||||
if (!..())
|
||||
return
|
||||
if(scanning)
|
||||
if(scan_progress > 0)
|
||||
scan_progress--
|
||||
updateUsrDialog()
|
||||
if(scan_progress == 0)
|
||||
scan_progress = -1
|
||||
ping("Scan complete.")
|
||||
var/datum/data/record/forensic/fresh = new(scanning)
|
||||
add_record(fresh)
|
||||
updateUsrDialog()
|
||||
@@ -0,0 +1,17 @@
|
||||
//crime scene kit
|
||||
/obj/item/weapon/storage/briefcase/crimekit
|
||||
name = "crime scene kit"
|
||||
desc = "A stainless steel-plated carrycase for all your forensic needs. Feels heavy."
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
icon_state = "case"
|
||||
item_state = "case"
|
||||
storage_slots = 14
|
||||
|
||||
/obj/item/weapon/storage/briefcase/crimekit/New()
|
||||
..()
|
||||
new /obj/item/weapon/storage/box/swabs(src)
|
||||
new /obj/item/weapon/storage/box/fingerprints(src)
|
||||
new /obj/item/weapon/reagent_containers/spray/luminol(src)
|
||||
new /obj/item/device/uv_light(src)
|
||||
new /obj/item/weapon/forensics/sample_kit(src)
|
||||
new /obj/item/weapon/forensics/sample_kit/powder(src)
|
||||
-53
@@ -96,56 +96,3 @@
|
||||
/obj/item/weapon/evidencebag/examine(mob/user)
|
||||
..(user)
|
||||
if (stored_item) user.examinate(stored_item)
|
||||
|
||||
/obj/item/weapon/storage/box/evidence
|
||||
name = "evidence bag box"
|
||||
desc = "A box claiming to contain evidence bags. Also holds fingerprint cards."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "box"
|
||||
storage_slots= 14
|
||||
max_w_class = 3
|
||||
max_storage_space = 38
|
||||
can_hold = list(/obj/item/weapon/f_card, /obj/item/weapon/evidencebag)
|
||||
use_to_pickup = 1
|
||||
New()
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/f_card
|
||||
name = "finger print card"
|
||||
desc = "Used to take fingerprints."
|
||||
icon = 'icons/obj/card.dmi'
|
||||
icon_state = "fingerprint0"
|
||||
var/amount = 10.0
|
||||
item_state = "paper"
|
||||
throwforce = 1
|
||||
w_class = 1.0
|
||||
slot_flags = SLOT_EARS
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
|
||||
/obj/item/weapon/f_card/add_fingerprint(mob/living/M as mob, ignoregloves = 0)
|
||||
if(..())
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/full_print = md5(H.dna.uni_identity)
|
||||
fingerprints[full_print] = full_print
|
||||
|
||||
/obj/item/weapon/f_card/examine(mob/user)
|
||||
..()
|
||||
if(fingerprints.len)
|
||||
user << "<span class='notice'>Fingerprints on this card:</span>"
|
||||
for(var/print in fingerprints)
|
||||
user << "<span class='notice'>\t[fingerprints[print]]</span>"
|
||||
|
||||
/obj/item/weapon/fcardholder
|
||||
name = "fingerprint card case"
|
||||
desc = "Apply finger print card."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "fcardholder0"
|
||||
item_state = "clipboard"
|
||||
@@ -0,0 +1,13 @@
|
||||
/obj/item/weapon/reagent_containers/spray/luminol
|
||||
name = "luminol bottle"
|
||||
desc = "A bottle containing an odourless, colorless liquid."
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
icon_state = "luminol"
|
||||
item_state = "cleaner"
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10)
|
||||
volume = 250
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/luminol/New()
|
||||
..()
|
||||
reagents.add_reagent("luminol", 250)
|
||||
+13
-13
@@ -71,7 +71,7 @@
|
||||
icon_state = "raglit"
|
||||
else
|
||||
icon_state = "rag"
|
||||
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/bottle/B = loc
|
||||
if(istype(B))
|
||||
B.update_icon()
|
||||
@@ -83,7 +83,7 @@
|
||||
if(reagents.total_volume)
|
||||
var/target_text = trans_dest? "\the [trans_dest]" : "\the [user.loc]"
|
||||
user.visible_message("<span class='danger'>\The [user] begins to wring out [src] over [target_text].</span>", "<span class='notice'>You begin to wring out [src] over [target_text].</span>")
|
||||
|
||||
|
||||
if(do_after(user, reagents.total_volume*5)) //50 for a fully soaked rag
|
||||
if(trans_dest)
|
||||
reagents.trans_to(trans_dest, reagents.total_volume)
|
||||
@@ -114,29 +114,29 @@
|
||||
if(user.zone_sel.selecting == "mouth")
|
||||
user.do_attack_animation(src)
|
||||
user.visible_message(
|
||||
"<span class='danger'>\The [user] smothers [target] with [src]!</span>",
|
||||
"<span class='warning'>You smother [target] with [src]!</span>",
|
||||
"<span class='danger'>\The [user] smothers [target] with [src]!</span>",
|
||||
"<span class='warning'>You smother [target] with [src]!</span>",
|
||||
"You hear some struggling and muffled cries of surprise"
|
||||
)
|
||||
|
||||
|
||||
//it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now
|
||||
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
|
||||
update_name()
|
||||
else
|
||||
wipe_down(target, user)
|
||||
return
|
||||
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity)
|
||||
if(!proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
if(istype(A, /obj/structure/reagent_dispensers))
|
||||
if(!reagents.get_free_space())
|
||||
user << "<span class='warning'>\The [src] is already soaked.</span>"
|
||||
return
|
||||
|
||||
|
||||
if(A.reagents && A.reagents.trans_to_obj(src, reagents.maximum_volume))
|
||||
user.visible_message("<span class='notice'>\The [user] soaks [src] using [A].</span>", "<span class='notice'>You soak [src] using [A].</span>")
|
||||
update_name()
|
||||
@@ -167,7 +167,7 @@
|
||||
return
|
||||
if(!can_ignite())
|
||||
return
|
||||
|
||||
|
||||
//also copied from matches
|
||||
if(reagents.get_reagent_amount("phoron")) // the phoron explodes when exposed to fire
|
||||
visible_message("<span class='danger'>\The [src] conflagrates violently!</span>")
|
||||
@@ -176,7 +176,7 @@
|
||||
e.start()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
processing_objects += src
|
||||
set_light(2, null, "#E38F46")
|
||||
on_fire = 1
|
||||
@@ -187,7 +187,7 @@
|
||||
processing_objects -= src
|
||||
set_light(0)
|
||||
on_fire = 0
|
||||
|
||||
|
||||
//rags sitting around with 1 second of burn time left is dumb.
|
||||
//ensures players always have a few seconds of burn time left when they light their rag
|
||||
if(burn_time <= 5)
|
||||
@@ -209,7 +209,7 @@
|
||||
var/turf/location = get_turf(src)
|
||||
if(location)
|
||||
location.hotspot_expose(700, 5)
|
||||
|
||||
|
||||
if(burn_time <= 0)
|
||||
processing_objects -= src
|
||||
new /obj/effect/decal/cleanable/ash(location)
|
||||
@@ -0,0 +1,158 @@
|
||||
/obj/item/weapon/sample
|
||||
name = "forensic sample"
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
w_class = 1
|
||||
var/list/evidence = list()
|
||||
|
||||
/obj/item/weapon/sample/New(var/newloc, var/atom/supplied)
|
||||
..(newloc)
|
||||
if(supplied)
|
||||
copy_evidence(supplied)
|
||||
name = "[initial(name)] (\the [supplied])"
|
||||
|
||||
/obj/item/weapon/sample/print/New(var/newloc, var/atom/supplied)
|
||||
..(newloc, supplied)
|
||||
if(evidence && evidence.len)
|
||||
icon_state = "fingerprint1"
|
||||
|
||||
/obj/item/weapon/sample/proc/copy_evidence(var/atom/supplied)
|
||||
if(supplied.suit_fibers && supplied.suit_fibers.len)
|
||||
evidence = supplied.suit_fibers.Copy()
|
||||
supplied.suit_fibers.Cut()
|
||||
|
||||
/obj/item/weapon/sample/proc/merge_evidence(var/obj/item/weapon/sample/supplied, var/mob/user)
|
||||
if(!supplied.evidence || !supplied.evidence.len)
|
||||
return 0
|
||||
evidence |= supplied.evidence
|
||||
name = "[initial(name)] (combined)"
|
||||
user << "<span class='notice'>You transfer the contents of \the [supplied] into \the [src].</span>"
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/sample/print/merge_evidence(var/obj/item/weapon/sample/supplied, var/mob/user)
|
||||
if(!supplied.evidence || !supplied.evidence.len)
|
||||
return 0
|
||||
for(var/print in supplied.evidence)
|
||||
if(evidence[print])
|
||||
evidence[print] = stringmerge(evidence[print],supplied.evidence[print])
|
||||
else
|
||||
evidence[print] = supplied.evidence[print]
|
||||
name = "[initial(name)] (combined)"
|
||||
user << "<span class='notice'>You overlay \the [src] and \the [supplied], combining the print records.</span>"
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/sample/attackby(var/obj/O, var/mob/user)
|
||||
if(O.type == src.type)
|
||||
user.unEquip(O)
|
||||
if(merge_evidence(O, user))
|
||||
qdel(O)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/sample/fibers
|
||||
name = "fiber bag"
|
||||
desc = "Used to hold fiber evidence for the detective."
|
||||
icon_state = "fiberbag"
|
||||
|
||||
/obj/item/weapon/sample/print
|
||||
name = "fingerprint card"
|
||||
desc = "Records a set of fingerprints."
|
||||
icon = 'icons/obj/card.dmi'
|
||||
icon_state = "fingerprint0"
|
||||
item_state = "paper"
|
||||
|
||||
/obj/item/weapon/sample/print/attack_self(var/mob/user)
|
||||
if(evidence && evidence.len)
|
||||
return
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.gloves)
|
||||
user << "<span class='warning'>Take \the [H.gloves] off first.</span>"
|
||||
return
|
||||
|
||||
user << "<span class='notice'>You firmly press your fingertips onto the card.</span>"
|
||||
var/fullprint = H.get_full_print()
|
||||
evidence[fullprint] = fullprint
|
||||
name = "[initial(name)] (\the [H])"
|
||||
icon_state = "fingerprint1"
|
||||
|
||||
/obj/item/weapon/sample/print/attack(var/mob/living/M, var/mob/user)
|
||||
|
||||
if(!ishuman(M))
|
||||
return ..()
|
||||
|
||||
if(evidence && evidence.len)
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(H.gloves)
|
||||
user << "<span class='warning'>\The [H] is wearing gloves.</span>"
|
||||
return 1
|
||||
|
||||
if(user != H && H.a_intent != "help" && !H.lying)
|
||||
user.visible_message("<span class='danger'>\The [user] tries to take prints from \the [H], but they move away.</span>")
|
||||
return 1
|
||||
|
||||
if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand")
|
||||
var/has_hand
|
||||
var/obj/item/organ/external/O = H.organs_by_name["r_hand"]
|
||||
if(istype(O) && !O.is_stump())
|
||||
has_hand = 1
|
||||
else
|
||||
O = H.organs_by_name["l_hand"]
|
||||
if(istype(O) && !O.is_stump())
|
||||
has_hand = 1
|
||||
if(!has_hand)
|
||||
user << "<span class='warning'>They don't have any hands.</span>"
|
||||
return 1
|
||||
user.visible_message("[user] takes a copy of \the [H]'s fingerprints.")
|
||||
var/fullprint = H.get_full_print()
|
||||
evidence[fullprint] = fullprint
|
||||
copy_evidence(src)
|
||||
name = "[initial(name)] (\the [H])"
|
||||
icon_state = "fingerprint1"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/sample/print/copy_evidence(var/atom/supplied)
|
||||
if(supplied.fingerprints && supplied.fingerprints.len)
|
||||
for(var/print in supplied.fingerprints)
|
||||
evidence[print] = supplied.fingerprints[print]
|
||||
supplied.fingerprints.Cut()
|
||||
|
||||
/obj/item/weapon/forensics/sample_kit
|
||||
name = "fiber collection kit"
|
||||
desc = "A magnifying glass and tweezers. Used to lift suit fibers."
|
||||
icon_state = "m_glass"
|
||||
w_class = 2
|
||||
var/evidence_type = "fiber"
|
||||
var/evidence_path = /obj/item/weapon/sample/fibers
|
||||
|
||||
/obj/item/weapon/forensics/sample_kit/proc/can_take_sample(var/mob/user, var/atom/supplied)
|
||||
return (supplied.suit_fibers && supplied.suit_fibers.len)
|
||||
|
||||
/obj/item/weapon/forensics/sample_kit/proc/take_sample(var/mob/user, var/atom/supplied)
|
||||
var/obj/item/weapon/sample/S = new evidence_path(get_turf(user), supplied)
|
||||
user << "<span class='notice'>You transfer [S.evidence.len] [S.evidence.len > 1 ? "[evidence_type]s" : "[evidence_type]"] to \the [S].</span>"
|
||||
|
||||
/obj/item/weapon/forensics/sample_kit/afterattack(var/atom/A, var/mob/user, var/proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
add_fingerprint(user)
|
||||
if(can_take_sample(user, A))
|
||||
take_sample(user,A)
|
||||
return 1
|
||||
else
|
||||
user << "<span class='warning'>You are unable to locate any [evidence_type]s on \the [A].</span>"
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/forensics/sample_kit/powder
|
||||
name = "fingerprint powder"
|
||||
desc = "A jar containing aluminum powder and a specialized brush."
|
||||
icon_state = "dust"
|
||||
evidence_type = "fingerprint"
|
||||
evidence_path = /obj/item/weapon/sample/print
|
||||
|
||||
/obj/item/weapon/forensics/sample_kit/powder/can_take_sample(var/mob/user, var/atom/supplied)
|
||||
return (supplied.fingerprints && supplied.fingerprints.len)
|
||||
@@ -0,0 +1,45 @@
|
||||
/obj/item/weapon/storage/box/swabs
|
||||
name = "box of swab kits"
|
||||
desc = "Sterilized equipment within. Do not contaminate."
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
icon_state = "dnakit"
|
||||
can_hold = list(/obj/item/weapon/forensics/swab)
|
||||
storage_slots = 14
|
||||
|
||||
/obj/item/weapon/storage/box/swabs/New()
|
||||
..()
|
||||
for(var/i=0;i<storage_slots,i++) // Fill 'er up.
|
||||
new /obj/item/weapon/forensics/swab(src)
|
||||
|
||||
/obj/item/weapon/storage/box/slides
|
||||
name = "microscope slide box"
|
||||
icon_state = "solution_trays"
|
||||
storage_slots = 7
|
||||
|
||||
/obj/item/weapon/storage/box/slides/New()
|
||||
..()
|
||||
for(var/i=0;i<storage_slots,i++)
|
||||
new /obj/item/weapon/forensics/slide(src)
|
||||
|
||||
/obj/item/weapon/storage/box/evidence
|
||||
name = "evidence bag box"
|
||||
desc = "A box claiming to contain evidence bags."
|
||||
storage_slots = 6
|
||||
|
||||
/obj/item/weapon/storage/box/evidence/New()
|
||||
..()
|
||||
for(var/i=0;i<storage_slots,i++)
|
||||
new /obj/item/weapon/evidencebag(src)
|
||||
|
||||
/obj/item/weapon/storage/box/fingerprints
|
||||
name = "box of fingerprint cards"
|
||||
desc = "Sterilized equipment within. Do not contaminate."
|
||||
icon = 'icons/obj/forensics.dmi'
|
||||
icon_state = "dnakit"
|
||||
can_hold = list(/obj/item/weapon/sample/print)
|
||||
storage_slots = 14
|
||||
|
||||
/obj/item/weapon/storage/box/fingerprints/New()
|
||||
..()
|
||||
for(var/i=0;i<storage_slots,i++)
|
||||
new /obj/item/weapon/sample/print(src)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user