mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-24 05:23:22 +01:00
Bugfix batch (Pesticide Edition) (#21556)
Fixes https://github.com/Aurorastation/Aurora.3/issues/18504 Fixes https://github.com/Aurorastation/Aurora.3/issues/21064 Fixes https://github.com/Aurorastation/Aurora.3/issues/21267 Fixes https://github.com/Aurorastation/Aurora.3/issues/21455 Fixes https://github.com/Aurorastation/Aurora.3/issues/21535 Miscellaneous bugfixes, code cleanup, etc. Smaller batches this time. changes: - spellcheck: "Renames 'gibber' to 'autobutcher'." - code_imp: "Cleans up a lot of old autobutcher code." - code_imp: "Simplifies and unifies a lot of circuit board naming code." - code_imp: "Updates various code comments to DMDocs format." - balance: "Slightly increased damage of beating someone with a ladder." - bugfix: "Fixes foreign speech displaying the translated versions in langchat for non-fluent listeners." - bugfix: "Fixes whispered speech langchat; whispers are now correctly italicized." - bugfix: "Fixes shouted speech langchat; shouts are now correctly biggified." - bugfix: "Adds missing Omni Gas Mixer, Gas Meter options from RFD-P." - bugfix: "Adds missing circuit boards for bioballistic delivery system, lysis-isolation centrifuge, and autobutcher to allow for construction and deconstruction." - bugfix: "Fixes empty algae chips bag having description set for its name." - bugfix: "Adds fallback_specific_heat values to several reagents that were missing them." - bugfix: "Fixes antimateriel projectiles being erroneously damage-capped when hitting walls." - bugfix: "Fixes laser beam effects not using the base colors of their beam VFX." - qol: "Added helpful feedback hint to move closer when someone speaks aloud within 4 tiles while you're in vacuum (as features go, this one felt more like a bug to experience)." - qol: "Updated various examine hints." --------- Signed-off-by: Batrachophreno <Batrochophreno@gmail.com>
This commit is contained in:
@@ -138,7 +138,7 @@
|
||||
|
||||
/singleton/cargo_item/circuitboard_bubbleshield
|
||||
category = "engineering"
|
||||
name = "circuit board (bubble shield generator)"
|
||||
name = T_BOARD("bubble shield generator")
|
||||
supplier = "hephaestus"
|
||||
description = "Looks like a circuit. Probably is."
|
||||
price = 250
|
||||
@@ -152,7 +152,7 @@
|
||||
|
||||
/singleton/cargo_item/circuitboard_hullshield
|
||||
category = "engineering"
|
||||
name = "circuit board (hull shield generator)"
|
||||
name = T_BOARD("hull shield generator")
|
||||
supplier = "hephaestus"
|
||||
description = "Looks like a circuit. Probably is."
|
||||
price = 250
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
/singleton/cargo_item/circuitboard_shieldcapacitor
|
||||
category = "engineering"
|
||||
name = "circuit board (shield capacitor)"
|
||||
name = T_BOARD("shield capacitor")
|
||||
supplier = "hephaestus"
|
||||
description = "Looks like a circuit. Probably is."
|
||||
price = 250
|
||||
@@ -180,7 +180,7 @@
|
||||
|
||||
/singleton/cargo_item/circuitboard_solarcontrol
|
||||
category = "engineering"
|
||||
name = "circuit board (solar control console)"
|
||||
name = T_BOARD("solar control console")
|
||||
supplier = "hephaestus"
|
||||
description = "Looks like a circuit. Probably is."
|
||||
price = 250
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
var/icon_base = null
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
///The type of board, a path of `/obj/item/circuitboard`
|
||||
/// The type of board, a path of `/obj/item/circuitboard`
|
||||
var/board_type = null
|
||||
|
||||
///The type of target board, a path of `/obj/item/circuitboard`
|
||||
/// The type of target board, a path of `/obj/item/circuitboard`
|
||||
var/target_board_type = null
|
||||
|
||||
///The type of rig, a path of `/obj/item/rig`
|
||||
/// The type of rig, a path of `/obj/item/rig`
|
||||
var/rig_type = /obj/item/rig
|
||||
|
||||
obj_flags = OBJ_FLAG_CONDUCTABLE
|
||||
|
||||
@@ -1,27 +1,40 @@
|
||||
|
||||
/obj/machinery/gibber
|
||||
name = "gibber"
|
||||
desc = "The name isn't descriptive enough?"
|
||||
desc_extended = "WARNING : Insurance no longer covers entertaining intrusive thoughts. Keep your limbs to yourself."
|
||||
name = "autobutcher"
|
||||
desc = "Also known as the gibber, affectionately."
|
||||
desc_extended = "WARNING: Insurance no longer covers entertaining intrusive thoughts. Keep your limbs to yourself."
|
||||
icon = 'icons/obj/machinery/cooking_machines.dmi'
|
||||
icon_state = "grinder"
|
||||
density = 1
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
req_access = list(ACCESS_GALLEY,ACCESS_MORGUE)
|
||||
|
||||
var/operating = 0 //Is it on?
|
||||
var/dirty = 0 // Does it need cleaning?
|
||||
var/mob/living/occupant // Mob who has been put inside
|
||||
var/gib_time = 40 // Time from starting until meat appears
|
||||
var/gib_throw_dir = WEST // Direction to spit meat and gibs in.
|
||||
/// Is it on?
|
||||
var/operating = FALSE
|
||||
/// Does it need cleaning?
|
||||
var/dirty = FALSE
|
||||
/// Mob who has been put inside
|
||||
var/mob/living/occupant
|
||||
/// Time from starting until meat appears
|
||||
var/gib_time = 4 SECONDS
|
||||
/// Direction to spit meat and gibs in.
|
||||
var/gib_throw_dir = WEST
|
||||
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 500
|
||||
|
||||
//auto-gibs anything that bumps into it
|
||||
/// Auto-gibs anything that moves onto its input plate. This is a fun variant, someone map it in somewhere!
|
||||
/obj/machinery/gibber/autogibber
|
||||
var/turf/input_plate
|
||||
|
||||
/obj/machinery/gibber/feedback_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "The safety guard is [emagged ? SPAN_DANGER("disabled") : "enabled"]."
|
||||
|
||||
/obj/machinery/gibber/antagonist_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "This can be emagged to let you feed people into it; it also removes the ID access requirements."
|
||||
|
||||
/obj/machinery/gibber/autogibber/Initialize()
|
||||
. = ..()
|
||||
for(var/i in GLOB.cardinals)
|
||||
@@ -39,16 +52,44 @@
|
||||
|
||||
/obj/machinery/gibber/autogibber/CollidedWith(atom/bumped_atom)
|
||||
. = ..()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
if(!input_plate)
|
||||
return
|
||||
return FALSE
|
||||
if(!ismob(bumped_atom))
|
||||
return
|
||||
var/mob/M = bumped_atom
|
||||
if(M.loc == input_plate)
|
||||
M.forceMove(src)
|
||||
M.gib()
|
||||
return FALSE
|
||||
var/mob/victim_mob = bumped_atom
|
||||
var/mob/living/carbon/human/victim_human
|
||||
// A lot of reused code here but it's needed to prevent CollidedWith from running DoMob, which makes SpaceDMM sad because of SHOULD_NOT_SLEEP and etc etc etc.
|
||||
if(ishuman(victim_mob))
|
||||
victim_human = victim_mob
|
||||
|
||||
if(occupant)
|
||||
if(victim_human.client)
|
||||
to_chat(victim_human, SPAN_DANGER("[src] is full, you can't fit!"))
|
||||
return FALSE
|
||||
|
||||
if(operating)
|
||||
if(victim_human.client)
|
||||
to_chat(victim_human, SPAN_DANGER("[src] is locked and running, it won't let you in!"))
|
||||
return FALSE
|
||||
|
||||
if(ishuman(victim_human) && !emagged)
|
||||
if(victim_human.client)
|
||||
to_chat(victim_human, SPAN_DANGER("\The [src]'s safety guard is engaged!"))
|
||||
return FALSE
|
||||
|
||||
if(istype(victim_mob, /mob) && victim_mob.loc == input_plate)
|
||||
visible_message(SPAN_DANGER("[victim_mob] gets automatically fed into \the [src]!"))
|
||||
else
|
||||
return FALSE
|
||||
if(victim_human.client)
|
||||
victim_human.client.perspective = EYE_PERSPECTIVE
|
||||
victim_human.client.eye = src
|
||||
victim_mob.forceMove(src)
|
||||
occupant = victim_mob
|
||||
startgibbing(victim_mob)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/gibber/Initialize()
|
||||
. = ..()
|
||||
@@ -56,11 +97,11 @@
|
||||
|
||||
/obj/machinery/gibber/update_icon()
|
||||
ClearOverlays()
|
||||
if (dirty)
|
||||
if(dirty)
|
||||
AddOverlays("grbloody")
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if (!occupant)
|
||||
if(!occupant)
|
||||
AddOverlays("grjam")
|
||||
else if (operating)
|
||||
AddOverlays("gruse")
|
||||
@@ -81,10 +122,6 @@
|
||||
return
|
||||
startgibbing(user)
|
||||
|
||||
/obj/machinery/gibber/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
|
||||
. = ..()
|
||||
. += "The safety guard is [emagged ? SPAN_DANGER("disabled") : "enabled"]."
|
||||
|
||||
/obj/machinery/gibber/emag_act(var/remaining_charges, var/mob/user)
|
||||
emagged = !emagged
|
||||
to_chat(user, SPAN_DANGER("You [emagged ? "disable" : "enable"] [src]'s safety guard."))
|
||||
@@ -112,34 +149,39 @@
|
||||
return
|
||||
move_into_gibber(user, dropped)
|
||||
|
||||
/obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim)
|
||||
|
||||
/**
|
||||
* Moves the victim into the gibber. This can be triggered by a user trying to place the victim inside, or by
|
||||
* being sucked in via the input plate.
|
||||
*/
|
||||
/obj/machinery/gibber/proc/move_into_gibber(var/mob/user, var/mob/victim, var/automatic = FALSE)
|
||||
// All of these check for a user because if the machine is working autonomously, there's no one to send messages to in most cases we'd want to.
|
||||
if(occupant)
|
||||
to_chat(user, SPAN_DANGER("[src] is full, empty it first!"))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(operating)
|
||||
to_chat(user, SPAN_DANGER("[src] is locked and running, wait for it to finish."))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(!(iscarbon(victim) || isanimal(victim)))
|
||||
to_chat(user, SPAN_DANGER("This is not suitable for [src]!"))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(ishuman(victim) && !emagged && !victim.isMonkey())
|
||||
to_chat(user, SPAN_DANGER("[src]'s safety guard is engaged!"))
|
||||
return
|
||||
|
||||
return FALSE
|
||||
|
||||
if(victim.abiotic(1))
|
||||
to_chat(user, SPAN_DANGER("[victim] may not have abiotic items on."))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
user.visible_message(SPAN_DANGER("[user] starts to put [victim] into [src]!"))
|
||||
add_fingerprint(user)
|
||||
if(!do_mob(user, victim, 30 SECONDS) || occupant || !victim.Adjacent(src) || !user.Adjacent(src) || !victim.Adjacent(user))
|
||||
return
|
||||
|
||||
user.visible_message(SPAN_DANGER("[user] stuffs [victim] into [src]!"))
|
||||
|
||||
if(victim.client)
|
||||
victim.client.perspective = EYE_PERSPECTIVE
|
||||
victim.client.eye = src
|
||||
@@ -171,7 +213,6 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/gibber/proc/startgibbing(mob/user as mob)
|
||||
if(operating)
|
||||
return
|
||||
@@ -219,12 +260,11 @@
|
||||
|
||||
spawn(gib_time)
|
||||
|
||||
operating = 0
|
||||
operating = FALSE
|
||||
occupant.gib()
|
||||
occupant = null
|
||||
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
operating = 0
|
||||
for (var/obj/thing in contents)
|
||||
// Todo: unify limbs and internal organs
|
||||
// There's a chance that the gibber will fail to destroy some evidence.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define T_BOARD_MECHA(name) "" + "vehicle software " + "(" + (name) + ")"
|
||||
|
||||
/obj/item/circuitboard/exosystem
|
||||
name = "vehicle software template"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
@@ -9,26 +7,24 @@
|
||||
var/list/contains_software = list()
|
||||
|
||||
/obj/item/circuitboard/exosystem/engineering
|
||||
name = T_BOARD_MECHA("engineering systems")
|
||||
name = T_BOARD_VEHICLE("engineering systems")
|
||||
contains_software = list(MECH_SOFTWARE_ENGINEERING)
|
||||
origin_tech = list(TECH_DATA = 1)
|
||||
|
||||
/obj/item/circuitboard/exosystem/utility
|
||||
name = T_BOARD_MECHA("utility systems")
|
||||
name = T_BOARD_VEHICLE("utility systems")
|
||||
contains_software = list(MECH_SOFTWARE_UTILITY)
|
||||
icon_state = "mcontroller"
|
||||
origin_tech = list(TECH_DATA = 1)
|
||||
|
||||
/obj/item/circuitboard/exosystem/medical
|
||||
name = T_BOARD_MECHA("medical systems")
|
||||
name = T_BOARD_VEHICLE("medical systems")
|
||||
contains_software = list(MECH_SOFTWARE_MEDICAL)
|
||||
icon_state = "mcontroller"
|
||||
origin_tech = list(TECH_DATA = 3,TECH_BIO = 2)
|
||||
|
||||
/obj/item/circuitboard/exosystem/weapons
|
||||
name = T_BOARD_MECHA("ballistic weapon systems")
|
||||
name = T_BOARD_VEHICLE("ballistic weapon systems")
|
||||
contains_software = list(MECH_SOFTWARE_WEAPONS)
|
||||
icon_state = "mainboard"
|
||||
origin_tech = list(TECH_DATA = 3, TECH_COMBAT = 3)
|
||||
|
||||
#undef T_BOARD_MECHA
|
||||
|
||||
@@ -131,6 +131,11 @@
|
||||
/obj/machinery/botany/extractor
|
||||
name = "lysis-isolation centrifuge"
|
||||
icon_state = "centrifuge"
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/botany_extractor,
|
||||
/obj/item/stock_parts/manipulator = 3,
|
||||
/obj/item/stock_parts/scanning_module = 1
|
||||
)
|
||||
|
||||
var/datum/seed/genetics // Currently scanned seed genetic structure.
|
||||
var/degradation = 0 // Increments with each scan, stops allowing gene mods after a certain point.
|
||||
@@ -263,6 +268,11 @@
|
||||
name = "bioballistic delivery system"
|
||||
icon_state = "traitgun"
|
||||
disk_needs_genes = 1
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/botany_editor,
|
||||
/obj/item/stock_parts/manipulator = 3,
|
||||
/obj/item/stock_parts/scanning_module = 1
|
||||
)
|
||||
|
||||
/obj/machinery/botany/editor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
|
||||
@@ -330,3 +340,14 @@
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
/obj/item/circuitboard/botany_extractor
|
||||
name = T_BOARD("lysis-isolation centrifuge")
|
||||
build_path = /obj/machinery/botany/extractor
|
||||
origin_tech = list(TECH_DATA = 3)
|
||||
|
||||
|
||||
/obj/item/circuitboard/botany_editor
|
||||
name = T_BOARD("bioballistic delivery system")
|
||||
build_path = /obj/machinery/botany/editor
|
||||
origin_tech = list(TECH_DATA = 3)
|
||||
|
||||
@@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(minevendor_list, list(
|
||||
shuttle = set_shuttle
|
||||
|
||||
/obj/item/circuitboard/machine/mining_equipment_vendor
|
||||
name = "circuit board (Mining Equipment Vendor)"
|
||||
name = T_BOARD("Mining Equipment Vendor")
|
||||
build_path = /obj/machinery/mineral/equipment_vendor
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
|
||||
req_components = list( /obj/item/stock_parts/console_screen = 1,
|
||||
|
||||
@@ -1,33 +1,46 @@
|
||||
// At minimum every mob has a hear_say proc.
|
||||
|
||||
/**
|
||||
* hear_say's return value determines whether or not the mob in question also receives a langchat image.
|
||||
*/
|
||||
/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol, var/font_size = null)
|
||||
if(!istype(src, /mob/living/test) && cant_hear())
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(speaker && !istype(speaker, /mob/living/test) && (!speaker.client && istype(src,/mob/abstract/ghost/observer) && client.prefs.toggles & CHAT_GHOSTEARS && !(speaker in view(src))))
|
||||
//Does the speaker have a client? It's either random stuff that observers won't care about (Experiment 97B says, 'EHEHEHEHEHEHEHE')
|
||||
//Or someone snoring. So we make it where they won't hear it.
|
||||
return
|
||||
|
||||
if((language && (language.flags & KNOWONLYHEAR)) && !say_understands(speaker, language))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
//make sure the air can transmit speech - hearer's side
|
||||
var/turf/T = get_turf(src)
|
||||
var/vacuum_proof = ((language && (language.flags & PRESSUREPROOF)) || isghost(src))
|
||||
var/speaker_name
|
||||
|
||||
if(ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
speaker_name = H.GetVoice()
|
||||
|
||||
if(T && !vacuum_proof) //Ghosts can hear even in vacuum.
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = (environment)? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
|
||||
return
|
||||
var/distance_to_speaker = get_dist(speaker, src)
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE && distance_to_speaker > 1)
|
||||
// Yeah, this isn't quite realistic to be able to see if someone is talking through, say, an opaque mask, but for gameplay purposes it should help indicate that you're not bugged.
|
||||
if(distance_to_speaker <= 4 && !italics)
|
||||
to_chat(src, SPAN_NOTICE("[speaker_name] talks, but you're in a vacuum. Maybe if you were close enough for the sound to transmit through touch..."))
|
||||
return FALSE
|
||||
|
||||
if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
italics = 1
|
||||
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
|
||||
|
||||
if((language && (language.flags & KNOWONLYHEAR)) && !say_understands(speaker, language))
|
||||
return TRUE
|
||||
|
||||
if(!vr_mob && (sleeping || stat == UNCONSCIOUS))
|
||||
hear_sleep(message)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
|
||||
if (language && (language.flags & NONVERBAL))
|
||||
@@ -38,10 +51,6 @@
|
||||
message = language ? language.scramble(message, languages) : stars(message)
|
||||
|
||||
var/accent_icon = speaker.get_accent_icon(language, src)
|
||||
var/speaker_name = speaker.name
|
||||
if(ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
speaker_name = H.GetVoice()
|
||||
|
||||
if(italics)
|
||||
message = "<i>[message]</i>"
|
||||
@@ -58,8 +67,10 @@
|
||||
if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set
|
||||
if(speaker == src)
|
||||
to_chat(src, SPAN_WARNING("You cannot hear yourself speak!"))
|
||||
return FALSE
|
||||
else
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear them.")
|
||||
return FALSE
|
||||
else
|
||||
if(language)
|
||||
if(font_size)
|
||||
|
||||
@@ -106,10 +106,6 @@
|
||||
qdel(extracted_slime)
|
||||
update_icon()
|
||||
|
||||
#ifndef T_BOARD
|
||||
#error T_BOARD macro is not defined but we need it!
|
||||
#endif
|
||||
|
||||
/obj/item/circuitboard/slime_extractor
|
||||
name = T_BOARD("slime extractor")
|
||||
build_path = "/obj/machinery/slime_extractor"
|
||||
|
||||
@@ -248,6 +248,13 @@ var/list/channel_to_radio_key = new
|
||||
if(!verb)
|
||||
verb = say_quote(message, speaking, is_singing, whisper)
|
||||
|
||||
var/is_shouting = FALSE
|
||||
if(speaking)
|
||||
for(var/verb_to_check in speaking.shout_verb)
|
||||
if(verb_to_check == verb)
|
||||
is_shouting = TRUE
|
||||
continue
|
||||
|
||||
if(is_muzzled())
|
||||
to_chat(src, SPAN_DANGER("You're muzzled and cannot speak!"))
|
||||
return
|
||||
@@ -357,8 +364,10 @@ var/list/channel_to_radio_key = new
|
||||
var/list/langchat_styles = list()
|
||||
if(istype(speaking, /datum/language/noise))
|
||||
langchat_styles = list("emote", "langchat_small")
|
||||
if(istype(speaking, /datum/language/noise))
|
||||
langchat_styles = list("emote", "langchat_small")
|
||||
if(whisper)
|
||||
langchat_styles = list("langchat_italic")
|
||||
if(is_shouting)
|
||||
langchat_styles = list("langchat_yell")
|
||||
|
||||
langchat_speech(message, get_hearers_in_view(message_range, src), speaking, additional_styles = langchat_styles)
|
||||
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
desc = "An unknown location."
|
||||
invisibility = 101
|
||||
|
||||
var/height = 1 ///< The number of Z-Levels in the map.
|
||||
var/turf/edge_type ///< What the map edge should be formed with. (null = world.turf)
|
||||
/// The number of Z-Levels in the map.
|
||||
var/height = 1
|
||||
/// What the map edge should be formed with. (null = world.turf)
|
||||
var/turf/edge_type
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
GLOBAL_LIST_EMPTY(connected_z_cache)
|
||||
|
||||
// If the height is more than 1, we mark all contained levels as connected.
|
||||
/// If the height is more than 1, we mark all contained levels as connected.
|
||||
/obj/effect/landmark/map_data/New(turf/loc, _height)
|
||||
..()
|
||||
if(!istype(loc)) // Using loc.z is safer when using the maploader and New.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/obj/effect/hoist_hook
|
||||
name = "hoist clamp"
|
||||
desc = "A clamp used to lift people or things."
|
||||
desc = "A clamp used to safely lift (or lower) people or things."
|
||||
icon = 'icons/obj/hoists.dmi'
|
||||
icon_state = "hoist_hook"
|
||||
var/obj/structure/hoist/source_hoist
|
||||
@@ -26,8 +26,9 @@
|
||||
|
||||
/obj/effect/hoist_hook/mechanics_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "To use the hook, click drag the object you want to it to attach it."
|
||||
. += "To remove an object from the hook, click drag the hook to a nearby turf."
|
||||
. += "Use this on yourself to deploy the hoist in the direction you're facing."
|
||||
. += "To load something onto the hook, click-drag the object you want to it to attach it."
|
||||
. += "To remove something from the hook, click-drag the hook to a nearby turf."
|
||||
|
||||
/obj/effect/hoist_hook/attack_hand(mob/living/user)
|
||||
if (use_check_and_message(user, USE_DISALLOW_SILICONS))
|
||||
@@ -89,7 +90,7 @@
|
||||
user.visible_message(SPAN_NOTICE("[user] detaches \the [source_hoist.hoistee] from the hoist clamp."), SPAN_NOTICE("You detach \the [source_hoist.hoistee] from the hoist clamp."), SPAN_NOTICE("You hear something unclamp."))
|
||||
source_hoist.release_hoistee()
|
||||
|
||||
// This will handle mobs unbuckling themselves.
|
||||
/// This will handle mobs unbuckling themselves.
|
||||
/obj/effect/hoist_hook/unbuckle()
|
||||
. = ..()
|
||||
if (. && !QDELETED(source_hoist))
|
||||
@@ -111,8 +112,14 @@
|
||||
|
||||
/obj/structure/hoist/mechanics_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "To use the hook, click drag the object you want to it to attach it."
|
||||
. += "To remove an object from the hook, click drag the hook to a nearby turf."
|
||||
. += "To load something onto the hook, click-drag the object you want to it to attach it."
|
||||
. += "Use an empty hand on the hoist to start the pulley lifting or lowering."
|
||||
. += "To remove something from the hook, click-drag the hook to a nearby turf."
|
||||
|
||||
/obj/structure/hoist/feedback_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
if(broken)
|
||||
. += "It looks broken, and the clamp has retracted back into the hoist. Seems like you'd have to re-deploy it to get it to work again."
|
||||
|
||||
/obj/structure/hoist/Initialize(mapload, ndir)
|
||||
. = ..()
|
||||
@@ -131,6 +138,7 @@
|
||||
source_hoist = null
|
||||
return ..()
|
||||
|
||||
/// Checks that the hoistee and the hook its supposed to be attached to are on the same z-level. If not, release the hoistee.
|
||||
/obj/structure/hoist/proc/check_consistency()
|
||||
if(hoistee && (hoistee.z != source_hook.z))
|
||||
release_hoistee()
|
||||
@@ -146,7 +154,6 @@
|
||||
if(broken)
|
||||
return
|
||||
broken = TRUE
|
||||
desc += " It looks broken, and the clamp has retracted back into the hoist. Seems like you'd have to re-deploy it to get it to work again."
|
||||
if(hoistee)
|
||||
release_hoistee()
|
||||
QDEL_NULL(source_hook)
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
/obj/item/ladder_mobile
|
||||
name = "mobile ladder"
|
||||
desc = "A lightweight deployable ladder, which you can use to move up or down. Or alternatively, you can bash some faces in."
|
||||
desc = "A lightweight deployable ladder, which you can use to move up or down. Alternatively, you can bash some faces in; it'll hurt, a lot."
|
||||
icon_state = "mobile_ladder"
|
||||
item_state = "mobile_ladder"
|
||||
icon = 'icons/obj/multiz_items.dmi'
|
||||
contained_sprite = TRUE
|
||||
throw_range = 3
|
||||
force = 15
|
||||
force = 18
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
/obj/item/ladder_mobile/mechanics_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "Use this on a solid floor (with open space above it) to place the ladder going up."
|
||||
. += "Use this on an open space turf (with solid floor beneath it) to place the ladder going down."
|
||||
|
||||
/obj/item/ladder_mobile/proc/place_ladder(atom/A, mob/user)
|
||||
|
||||
if (isopenturf(A)) //Place into open space
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
/obj/machinery/atmospherics/pipe/zpipe
|
||||
icon = 'icons/atmos/pipes.dmi'
|
||||
icon_state = "up"
|
||||
var/ptype // What direction of pipe this is. Used for icons.
|
||||
/// What direction of pipe this is. Used for icons.
|
||||
var/ptype
|
||||
|
||||
name = "upwards pipe"
|
||||
desc = "A pipe segment to connect upwards."
|
||||
@@ -15,7 +16,8 @@
|
||||
initialize_directions = SOUTH
|
||||
|
||||
var/minimum_temperature_difference = 300
|
||||
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
|
||||
// WALL_HEAT_TRANSFER_COEFFICIENT
|
||||
var/thermal_conductivity = 0
|
||||
|
||||
var/maximum_pressure = ATMOS_DEFAULT_MAX_PRESSURE
|
||||
var/fatigue_pressure = ATMOS_DEFAULT_FATIGUE_PRESSURE
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
req_access = list(ACCESS_ENGINE_EQUIP)
|
||||
obj_flags = OBJ_FLAG_ROTATABLE | OBJ_FLAG_SIGNALER
|
||||
var/id
|
||||
/// uses powernet power, not APC power
|
||||
/// Uses powernet power, not APC power.
|
||||
use_power = POWER_USE_OFF
|
||||
/// 30 kW laser. I guess that means 30 kJ per shot.
|
||||
active_power_usage = 30000
|
||||
@@ -30,7 +30,7 @@
|
||||
var/shot_counter = 0
|
||||
var/state = EMITTER_LOOSE
|
||||
var/locked = FALSE
|
||||
/// special emitters notify admins if something happens to them, to prevent grief
|
||||
/// Special emitters notify admins if something happens to them, to prevent grief.
|
||||
var/special_emitter = FALSE
|
||||
|
||||
var/_wifi_id
|
||||
|
||||
@@ -7,33 +7,44 @@
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "bullet"
|
||||
density = FALSE
|
||||
anchored = TRUE //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots.
|
||||
anchored = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
movement_type = FLYING
|
||||
blocks_emissive = EMISSIVE_BLOCK_GENERIC
|
||||
layer = MOB_LAYER
|
||||
var/hitsound_wall = ""
|
||||
|
||||
unacidable = TRUE //should be `resistance_flags` but we don't have it yet
|
||||
var/def_zone = "" //Aiming at
|
||||
var/atom/movable/firer = null//Who shot it
|
||||
var/datum/fired_from = null // the thing that the projectile was fired from (gun, turret, spell)
|
||||
var/suppressed = FALSE //Attack message
|
||||
/// Should be `resistance_flags` but we don't have it yet.
|
||||
unacidable = TRUE
|
||||
/// What body part/area we're aiming at.
|
||||
var/def_zone = ""
|
||||
/// Who shot it.
|
||||
var/atom/movable/firer = null
|
||||
/// The thing that the projectile was fired from (gun, turret, spell).
|
||||
var/datum/fired_from = null
|
||||
/// Attack message.
|
||||
var/suppressed = FALSE
|
||||
var/yo = null
|
||||
var/xo = null
|
||||
var/atom/original // the original target clicked
|
||||
var/turf/starting // the projectile's starting turf
|
||||
/// The original target clicked.
|
||||
var/atom/original
|
||||
/// The projectile's starting turf.
|
||||
var/turf/starting
|
||||
var/p_x = 16
|
||||
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
|
||||
/// The pixel location of the tile that the player clicked. Default is the center.
|
||||
var/p_y = 16
|
||||
|
||||
//Fired processing vars
|
||||
var/fired = FALSE //Have we been fired yet
|
||||
var/paused = FALSE //for suspending the projectile midair
|
||||
/// Have we been fired yet
|
||||
var/fired = FALSE
|
||||
/// For suspending the projectile midair
|
||||
var/paused = FALSE
|
||||
var/last_projectile_move = 0
|
||||
var/last_process = 0
|
||||
var/time_offset = 0
|
||||
var/datum/point/vector/trajectory
|
||||
var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location!
|
||||
/// Instructs forceMove to NOT reset our trajectory to the new location!
|
||||
var/trajectory_ignore_forcemove = FALSE
|
||||
/// We already impacted these things, do not impact them again. Used to make sure we can pierce things we want to pierce. Lazylist, typecache style (object = TRUE) for performance.
|
||||
var/list/impacted = list()
|
||||
/// If TRUE, we can hit our firer.
|
||||
@@ -55,16 +66,16 @@
|
||||
*/
|
||||
/// The "usual" flags of pass_flags is used in that can_hit_target ignores these unless they're specifically targeted/clicked on. This behavior entirely bypasses process_hit if triggered, rather than phasing which uses prehit_pierce() to check.
|
||||
pass_flags = PASSTABLE|PASSRAILING
|
||||
/// If FALSE, allow us to hit something directly targeted/clicked/whatnot even if we're able to phase through it
|
||||
/// If FALSE, allow us to hit something directly targeted/clicked/whatnot even if we're able to phase through it.
|
||||
var/phasing_ignore_direct_target = FALSE
|
||||
/// Bitflag for things the projectile should just phase through entirely - No hitting unless direct target and [phasing_ignore_direct_target] is FALSE. Uses pass_flags flags.
|
||||
var/projectile_phasing = NONE
|
||||
/// Bitflag for things the projectile should hit, but pierce through without deleting itself. Defers to projectile_phasing. Uses pass_flags flags.
|
||||
var/projectile_piercing = NONE
|
||||
/// number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc!
|
||||
/// Number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc!
|
||||
var/pierces = 0
|
||||
|
||||
/// If objects are below this layer, we pass through them
|
||||
/// If objects are below this layer, we pass through them.
|
||||
var/hit_threshhold = PROJECTILE_HIT_THRESHHOLD_LAYER
|
||||
|
||||
/// During each fire of SSprojectiles, the number of deciseconds since the last fire of SSprojectiles
|
||||
@@ -82,38 +93,45 @@
|
||||
|
||||
/// The current angle of the projectile. Initially null, so if the arg is missing from [/fire()], we can calculate it from firer and target as fallback.
|
||||
var/Angle
|
||||
var/original_angle = 0 //Angle at firing
|
||||
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
|
||||
var/spread = 0 //amount (in degrees) of projectile spread
|
||||
animate_movement = NO_STEPS //Use SLIDE_STEPS in conjunction with legacy
|
||||
/// how many times we've ricochet'd so far (instance variable, not a stat)
|
||||
/// Angle at firing.
|
||||
var/original_angle = 0
|
||||
/// Set TRUE to prevent projectiles from having their sprites rotated based on firing angle.
|
||||
var/nondirectional_sprite = FALSE
|
||||
/// Amount (in degrees) of projectile spread.
|
||||
var/spread = 0
|
||||
/// Use SLIDE_STEPS in conjunction with legacy.
|
||||
animate_movement = NO_STEPS
|
||||
/// How many times we've ricochet'd so far (instance variable, not a stat).
|
||||
var/ricochets = 0
|
||||
/// how many times we can ricochet max
|
||||
/// How many times we can ricochet max.
|
||||
var/ricochets_max = 0
|
||||
/// how many times we have to ricochet min (unless we hit an atom we can ricochet off)
|
||||
/// How many times we have to ricochet min (unless we hit an atom we can ricochet off).
|
||||
var/min_ricochets = 0
|
||||
/// 0-100 (or more, I guess), the base chance of ricocheting, before being modified by the atom we shoot and our chance decay
|
||||
/// 0-100 (or more, I guess), the base chance of ricocheting, before being modified by the atom we shoot and our chance decay.
|
||||
var/ricochet_chance = 0
|
||||
/// 0-1 (or more, I guess) multiplier, the ricochet_chance is modified by multiplying this after each ricochet
|
||||
/// 0-1 (or more, I guess) multiplier, the ricochet_chance is modified by multiplying this after each ricochet.
|
||||
var/ricochet_decay_chance = 0.7
|
||||
/// 0-1 (or more, I guess) multiplier, the projectile's damage is modified by multiplying this after each ricochet
|
||||
/// 0-1 (or more, I guess) multiplier, the projectile's damage is modified by multiplying this after each ricochet.
|
||||
var/ricochet_decay_damage = 0.7
|
||||
/// On ricochet, if nonzero, we consider all mobs within this range of our projectile at the time of ricochet to home in on like Revolver Ocelot, as governed by ricochet_auto_aim_angle
|
||||
/// On ricochet, if nonzero, we consider all mobs within this range of our projectile at the time of ricochet to home in on like Revolver Ocelot, as governed by ricochet_auto_aim_angle.
|
||||
var/ricochet_auto_aim_range = 0
|
||||
/// On ricochet, if ricochet_auto_aim_range is nonzero, we'll consider any mobs within this range of the normal angle of incidence to home in on, higher = more auto aim
|
||||
/// On ricochet, if ricochet_auto_aim_range is nonzero, we'll consider any mobs within this range of the normal angle of incidence to home in on, higher = more auto aim.
|
||||
var/ricochet_auto_aim_angle = 30
|
||||
/// the angle of impact must be within this many degrees of the struck surface, set to 0 to allow any angle
|
||||
/// The angle of impact must be within this many degrees of the struck surface, set to 0 to allow any angle.
|
||||
var/ricochet_incidence_leeway = 40
|
||||
/// Can our ricochet autoaim hit our firer?
|
||||
var/ricochet_shoots_firer = TRUE
|
||||
|
||||
//Hitscan
|
||||
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
|
||||
var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end. Used for hitscan effect generation.
|
||||
/// Whether this is hitscan. If it is, speed is basically ignored.
|
||||
var/hitscan = FALSE
|
||||
/// Assoc list of datum/point or datum/point/vector, start = end. Used for hitscan effect generation.
|
||||
var/list/beam_segments
|
||||
/// Last turf an angle was changed in for hitscan projectiles.
|
||||
var/turf/last_angle_set_hitscan_store
|
||||
var/datum/point/beam_index
|
||||
var/turf/hitscan_last //last turf touched during hitscanning.
|
||||
/// Last turf touched during hitscanning.
|
||||
var/turf/hitscan_last
|
||||
var/tracer_type
|
||||
var/muzzle_type
|
||||
var/impact_type
|
||||
@@ -132,38 +150,47 @@
|
||||
//Homing
|
||||
var/homing = FALSE
|
||||
var/atom/homing_target
|
||||
var/homing_turn_speed = 10 //Angle per tick.
|
||||
var/homing_inaccuracy_min = 0 //in pixels for these. offsets are set once when setting target.
|
||||
/// Angle per tick.
|
||||
var/homing_turn_speed = 10
|
||||
/// In pixels for these. offsets are set once when setting target.
|
||||
var/homing_inaccuracy_min = 0
|
||||
var/homing_inaccuracy_max = 0
|
||||
var/homing_offset_x = 0
|
||||
var/homing_offset_y = 0
|
||||
|
||||
var/damage = 10
|
||||
var/damage_type = DAMAGE_BRUTE //DAMAGE_BRUTE, DAMAGE_BURN, DAMAGE_TOXIN, DAMAGE_OXY, DAMAGE_CLONE, DAMAGE_PAIN are the only things that should be in here
|
||||
/// DAMAGE_BRUTE, DAMAGE_BURN, DAMAGE_TOXIN, DAMAGE_OXY, DAMAGE_CLONE, DAMAGE_PAIN are the only things that should be in here.
|
||||
var/damage_type = DAMAGE_BRUTE
|
||||
|
||||
var/range = 50 //This will de-increment every step. When 0, it will deletze the projectile.
|
||||
var/decayedRange //stores original range
|
||||
var/reflect_range_decrease = 5 //amount of original range that falls off when reflecting, so it doesn't go forever
|
||||
/// This will de-increment every step. When 0, it will deletze the projectile.
|
||||
var/range = 50
|
||||
/// Stores original range.
|
||||
var/decayedRange
|
||||
/// Amount of original range that falls off when reflecting, so it doesn't go forever.
|
||||
var/reflect_range_decrease = 5
|
||||
|
||||
var/impact_effect_type //what type of impact effect to show when hitting something
|
||||
var/log_override = FALSE //is this type spammed enough to not log? (KAs)
|
||||
/// What type of impact effect to show when hitting something.
|
||||
var/impact_effect_type
|
||||
/// Is this type spammed enough to not log? (KAs).
|
||||
var/log_override = FALSE
|
||||
/// If true, the projectile won't cause any logging. Used for hallucinations and shit.
|
||||
var/do_not_log = FALSE
|
||||
|
||||
var/shrapnel_type //type of shrapnel the projectile leaves in its target.
|
||||
/// Type of shrapnel the projectile leaves in its target.
|
||||
var/shrapnel_type
|
||||
|
||||
///If TRUE, hit mobs, even if they are lying on the floor and are not our target within MAX_RANGE_HIT_PRONE_TARGETS tiles
|
||||
/// If TRUE, hit mobs, even if they are lying on the floor and are not our target within MAX_RANGE_HIT_PRONE_TARGETS tiles.
|
||||
var/hit_prone_targets = FALSE
|
||||
///if TRUE, ignores the range of MAX_RANGE_HIT_PRONE_TARGETS tiles of hit_prone_targets
|
||||
/// If TRUE, ignores the range of MAX_RANGE_HIT_PRONE_TARGETS tiles of hit_prone_targets.
|
||||
var/ignore_range_hit_prone_targets = FALSE
|
||||
///How much we want to drop damage per tile as it travels through the air
|
||||
/// How much we want to drop damage per tile as it travels through the air.
|
||||
var/damage_falloff_tile
|
||||
///How much accuracy is lost for each tile travelled
|
||||
/// How much accuracy is lost for each tile travelled.
|
||||
var/accuracy_falloff = 7
|
||||
///How much accuracy before falloff starts to matter. Formula is range - falloff * tiles travelled
|
||||
/// How much accuracy before falloff starts to matter. Formula is range - falloff * tiles travelled.
|
||||
var/accurate_range = 100
|
||||
var/static/list/projectile_connections = list(COMSIG_ATOM_ENTERED = PROC_REF(on_entered))
|
||||
/// If true directly targeted turfs can be hit
|
||||
/// If TRUE, directly targeted turfs can be hit.
|
||||
var/can_hit_turfs = FALSE
|
||||
|
||||
|
||||
@@ -171,18 +198,21 @@
|
||||
START AURORA SNOWFLAKE VARS SECTION
|
||||
#########################################*/
|
||||
|
||||
var/ping_effect = "ping_b" //Effect displayed when a bullet hits a barricade. See atom/proc/bullet_ping.
|
||||
/// Effect displayed when a bullet hits a barricade. See atom/proc/bullet_ping.
|
||||
var/ping_effect = "ping_b"
|
||||
|
||||
///How accurate a bullet is *if it's hitting a mob* at getting the zone aimed at
|
||||
/// How accurate a bullet is *if it's hitting a mob* at getting the zone aimed at.
|
||||
var/accuracy = 0
|
||||
|
||||
//used for shooting at blank range, you shouldn't be able to miss
|
||||
/// Used for shooting at blank range, you shouldn't be able to miss.
|
||||
var/point_blank = FALSE
|
||||
|
||||
//Effects
|
||||
/// Effects (bio and rad are also valid)
|
||||
var/damage_flags = DAMAGE_FLAG_BULLET
|
||||
var/check_armor = BULLET //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid
|
||||
var/list/impact_sounds //for different categories, IMPACT_MEAT etc
|
||||
/// Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb
|
||||
var/check_armor = BULLET
|
||||
/// For different categories, IMPACT_MEAT etc
|
||||
var/list/impact_sounds
|
||||
|
||||
var/stun = 0
|
||||
var/weaken = 0
|
||||
@@ -194,20 +224,24 @@
|
||||
var/agony = 0
|
||||
|
||||
var/incinerate = 0
|
||||
var/embed = 0 // whether or not the projectile can embed itself in the mob
|
||||
var/embed_chance = 0 // a flat bonus to the % chance to embed
|
||||
/// Whether or not the projectile can embed itself in the mob
|
||||
var/embed = 0
|
||||
/// A flat bonus to the % chance to embed
|
||||
var/embed_chance = 0
|
||||
|
||||
//For Maim / Maiming.
|
||||
var/maim_rate = 0 //Factor that the recipiant will be maimed by the projectile (NOT OUT OF 100%.)
|
||||
/// For maiming. Factor that the recipiant will be maimed by the projectile (NOT OUT OF 100%.)
|
||||
var/maim_rate = 0
|
||||
|
||||
var/reflected = FALSE
|
||||
|
||||
var/penetrating = 0 //If greater than zero, the projectile will pass through dense objects as specified by on_penetrate()
|
||||
/// If greater than zero, the projectile will pass through dense objects as specified by on_penetrate()
|
||||
var/penetrating = 0
|
||||
|
||||
/// For KAs, really.
|
||||
var/aoe = 0
|
||||
|
||||
var/aoe = 0 //For KAs, really
|
||||
|
||||
var/anti_materiel_potential = 1 //how much the damage of this bullet is increased against mechs
|
||||
/// How much the damage of this bullet is increased against mechs.
|
||||
var/anti_materiel_potential = 1
|
||||
|
||||
/*########################################
|
||||
END AURORA SNOWFLAKE VARS SECTION
|
||||
@@ -339,7 +373,6 @@
|
||||
return
|
||||
Impact(A)
|
||||
|
||||
|
||||
/**
|
||||
* Called when the projectile hits something
|
||||
* This can either be from it bumping something,
|
||||
@@ -488,9 +521,10 @@
|
||||
// 6. nothing
|
||||
// (returns null)
|
||||
|
||||
|
||||
//Returns true if the target atom is on our current turf and above the right layer
|
||||
//If direct target is true it's the originally clicked target.
|
||||
/**
|
||||
* Returns true if the target atom is on our current turf and above the right layer
|
||||
* If direct target is true it's the originally clicked target.
|
||||
*/
|
||||
/obj/projectile/proc/can_hit_target(atom/target, direct_target = FALSE, ignore_loc = FALSE, cross_failed = FALSE)
|
||||
if(QDELETED(target) || impacted[target.weak_reference])
|
||||
return FALSE
|
||||
@@ -971,19 +1005,19 @@
|
||||
if(!user.client)
|
||||
CRASH("Can't make trajectory calculations without a target or click modifiers and a client.")
|
||||
|
||||
//Split screen-loc up into X+Pixel_X and Y+Pixel_Y
|
||||
/// Split screen-loc up into X+Pixel_X and Y+Pixel_Y
|
||||
var/list/screen_loc_params = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",")
|
||||
//Split X+Pixel_X up into list(X, Pixel_X)
|
||||
/// Split X+Pixel_X up into list(X, Pixel_X)
|
||||
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
|
||||
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
|
||||
/// Split Y+Pixel_Y up into list(Y, Pixel_Y)
|
||||
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
|
||||
|
||||
var/tx = (text2num(screen_loc_X[1]) - 1) * world.icon_size + text2num(screen_loc_X[2])
|
||||
// We are here trying to lower our target location by the firing source's visual offset
|
||||
// So visually things make a nice straight line while properly accounting for actual physical position
|
||||
/// We are here trying to lower our target location by the firing source's visual offset
|
||||
/// So visually things make a nice straight line while properly accounting for actual physical position
|
||||
var/ty = (text2num(screen_loc_Y[1]) - 1) * world.icon_size + text2num(screen_loc_Y[2]) - source.pixel_z
|
||||
|
||||
//Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average.
|
||||
/// Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average.
|
||||
var/list/screenview = view_to_pixels(user.client.view)
|
||||
|
||||
var/ox = round(screenview[1] / 2) - user.client.pixel_x //"origin" x
|
||||
@@ -1100,7 +1134,7 @@
|
||||
AURORA SNOWFLAKE SECTION
|
||||
##############################*/
|
||||
|
||||
//Checks if the projectile is eligible for embedding. Not that it necessarily will.
|
||||
/// Checks if the projectile is eligible for embedding. Not that it necessarily will.
|
||||
/obj/projectile/proc/can_embed()
|
||||
//embed must be enabled and damage type must be brute
|
||||
if(!embed || damage_type != DAMAGE_BRUTE)
|
||||
@@ -1118,8 +1152,7 @@
|
||||
return damage * anti_materiel_potential
|
||||
return FALSE
|
||||
|
||||
//Because I don't want to rewrite half the world to use embed_data just yet,
|
||||
//this is left as is, praise be the omnissiah
|
||||
/// Because I don't want to rewrite half the world to use embed_data just yet, this is left as is, praise be the omnissiah
|
||||
/obj/projectile/proc/do_embed(var/obj/item/organ/external/organ)
|
||||
var/obj/item/SP = new shrapnel_type(organ)
|
||||
SP.edge = TRUE
|
||||
@@ -1137,7 +1170,8 @@
|
||||
original = target
|
||||
setAngle(get_projectile_angle(source, target))
|
||||
|
||||
/obj/projectile/proc/setAngle(new_angle) //wrapper for overrides.
|
||||
/// wrapper for overrides.
|
||||
/obj/projectile/proc/setAngle(new_angle)
|
||||
Angle = new_angle
|
||||
if(!nondirectional_sprite)
|
||||
var/matrix/M = new
|
||||
@@ -1161,7 +1195,7 @@
|
||||
. += "Shrapnel Type: [shrapnel.name]<br>"
|
||||
. += "Armor Penetration: [initial(armor_penetration)]%<br>"
|
||||
|
||||
//This is where the bullet bounces off.
|
||||
/// This is where the bullet bounces off.
|
||||
/atom/proc/bullet_ping(obj/projectile/P, var/pixel_x_offset, var/pixel_y_offset)
|
||||
if(!P || !P.ping_effect)
|
||||
return
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
var/frequency = 1
|
||||
hitscan = 1
|
||||
invisibility = 101 //beam projectiles are invisible as they are rendered by the effect engine
|
||||
color = COLOR_RED
|
||||
// color = COLOR_RED
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser
|
||||
tracer_type = /obj/effect/projectile/tracer/laser
|
||||
@@ -151,6 +151,7 @@
|
||||
name = "emitter beam"
|
||||
icon_state = "emitter"
|
||||
damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm
|
||||
color = COLOR_SPRING_GREEN
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/emitter
|
||||
tracer_type = /obj/effect/projectile/tracer/emitter
|
||||
|
||||
@@ -39,16 +39,16 @@
|
||||
icon_state = "pellets"
|
||||
damage = 20
|
||||
|
||||
///Number of pellets that will be ejected from this bullet
|
||||
/// Number of pellets that will be ejected from this bullet
|
||||
var/pellets = 4
|
||||
|
||||
///The projectile will lose a pellet each time it travels this distance. Can be a non-integer.
|
||||
/// The projectile will lose a pellet each time it travels this distance. Can be a non-integer.
|
||||
var/range_step = 2
|
||||
|
||||
///Lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
|
||||
/// Lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
|
||||
var/base_spread = 90
|
||||
|
||||
///Higher means the pellets spread more across body parts with distance
|
||||
/// Higher means the pellets spread more across body parts with distance
|
||||
var/spread_step = 10
|
||||
|
||||
/obj/projectile/bullet/pellet/proc/get_pellets(var/distance)
|
||||
@@ -69,7 +69,7 @@
|
||||
var/total_pellets = get_pellets(distance)
|
||||
var/spread = max(base_spread - (spread_step*distance), 0)
|
||||
|
||||
//shrapnel explosions miss prone mobs with a chance that increases with distance
|
||||
// Shrapnel explosions miss prone mobs with a chance that increases with distance
|
||||
var/prone_chance = 0
|
||||
if(!base_spread)
|
||||
prone_chance = max(spread_step*(distance - 2), 0)
|
||||
@@ -125,7 +125,7 @@
|
||||
agony = 50
|
||||
embed = FALSE
|
||||
var/balls = 4
|
||||
///projectile will lose a fragment each time it travels this distance. Can be a non-integer.
|
||||
/// Projectile will lose a fragment each time it travels this distance. Can be a non-integer.
|
||||
var/range_step = 3
|
||||
var/base_spread = 90
|
||||
var/spread_step = 10
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
damage_type = DAMAGE_BURN
|
||||
check_armor = ENERGY
|
||||
|
||||
//releases a burst of light on impact or after travelling a distance
|
||||
/// Releases a burst of light on impact or after travelling a distance.
|
||||
/obj/projectile/energy/flash
|
||||
name = "chemical shell"
|
||||
icon_state = "bullet"
|
||||
@@ -36,7 +36,7 @@
|
||||
single_spark(T)
|
||||
new /obj/effect/smoke/illumination(T, brightness=max(flash_range*2, brightness), lifetime=light_duration)
|
||||
|
||||
//blinds people like the flash round, but can also be used for temporary illumination
|
||||
/// blinds people like the flash round, but can also be used for temporary illumination
|
||||
/obj/projectile/energy/flash/flare
|
||||
damage = 10
|
||||
flash_range = 1
|
||||
|
||||
@@ -3,19 +3,25 @@
|
||||
var/description = "A non-descript chemical."
|
||||
var/taste_description = "old rotten bandaids"
|
||||
var/list/species_taste_description
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
/// How this taste compares to others. Higher values means it is more noticable.
|
||||
var/taste_mult = 1
|
||||
var/reagent_state = SOLID
|
||||
var/metabolism = REM // This would be 0.2 normally
|
||||
/// Default value is 0.2.
|
||||
var/metabolism = REM
|
||||
var/ingest_met = 0
|
||||
var/touch_met = 0
|
||||
var/breathe_met = 0
|
||||
var/ingest_mul = 0.5
|
||||
var/touch_mul = 0
|
||||
var/breathe_mul = 0.75
|
||||
var/overdose = 0 // Volume of a chemical required in the blood to meet overdose criteria.
|
||||
var/od_minimum_dose = 5 // Metabolised dose of a chemical required to meet overdose criteria.
|
||||
var/scannable = 0 // Shows up on health analyzers.
|
||||
var/spectro_hidden = FALSE // doesn't show up on basic mass spectrometers, only shows on the advanced variant
|
||||
/// Volume of a chemical required in the blood to meet overdose criteria.
|
||||
var/overdose = 0
|
||||
/// Metabolised dose of a chemical required to meet overdose criteria.
|
||||
var/od_minimum_dose = 5
|
||||
/// Shows up on health analyzers.
|
||||
var/scannable = 0
|
||||
/// Doesn't show up on basic mass spectrometers, only shows on the advanced variant
|
||||
var/spectro_hidden = FALSE
|
||||
var/affects_dead = 0
|
||||
var/glass_icon_state = null
|
||||
var/glass_name = null
|
||||
@@ -28,22 +34,31 @@
|
||||
var/condiment_center_of_mass = null
|
||||
var/color = "#000000"
|
||||
var/color_weight = 1
|
||||
var/unaffected_species = IS_DIONA | IS_MACHINE // Species that aren't affected by this reagent. Does not prevent affect_touch.
|
||||
var/metabolism_min = 0.01 //How much for the medicine to be present in the system to actually have an effect.
|
||||
var/conflicting_reagent //Reagents that conflict with this medicine, and cause adverse effects when in the blood.
|
||||
/// Species that aren't affected by this reagent. Does not prevent affect_touch.
|
||||
var/unaffected_species = IS_DIONA | IS_MACHINE
|
||||
/// How much for the medicine to be present in the system to actually have an effect.
|
||||
var/metabolism_min = 0.01
|
||||
/// Reagents that conflict with this medicine, and cause adverse effects when in the blood.
|
||||
var/conflicting_reagent
|
||||
|
||||
var/default_temperature = T0C + 20 //This is its default spawning temperature, if none is provided.
|
||||
var/specific_heat = -1 //The higher, the more difficult it is to change its temperature. 0 or lower values indicate that the specific heat has yet to be assigned.
|
||||
var/fallback_specific_heat = -1 //Setting this value above 0 will set the specific heat to this value only if the system could not find an appropriate specific heat to assign using the recipe system.
|
||||
//Never ever ever ever change this value for singleton/reagent. This should only be used for massive, yet specific things like drinks or food where it is infeasible to assign a specific heat value.
|
||||
/// This is its default spawning temperature, if none is provided.
|
||||
var/default_temperature = T0C + 20
|
||||
/// The higher, the more difficult it is to change its temperature. 0 or lower values indicate that the specific heat has yet to be assigned.
|
||||
var/specific_heat = -1
|
||||
/// Setting this value above 0 will set the specific heat to this value only if the system could not find an appropriate specific heat to assign using the recipe system.
|
||||
/// Never ever ever ever change this value for singleton/reagent. This should only be used for massive, yet specific things like drinks or food where it is infeasible to assign a specific heat value.
|
||||
var/fallback_specific_heat = -1
|
||||
|
||||
var/germ_adjust = 0 // for makeshift bandages/disinfectant
|
||||
var/carbonated = FALSE // if it's carbonated or not
|
||||
/// For makeshift bandages/disinfectant
|
||||
var/germ_adjust = 0
|
||||
/// If it's carbonated or not.
|
||||
var/carbonated = FALSE
|
||||
|
||||
/// Adds to the value of whatever container's holding it, value * units of reagents
|
||||
var/value = 1
|
||||
|
||||
/singleton/reagent/proc/initialize_data(var/newdata, var/datum/reagents/holder) // Called when the reagent is created.
|
||||
/// Called when the reagent is created.
|
||||
/singleton/reagent/proc/initialize_data(var/newdata, var/datum/reagents/holder)
|
||||
if(!isnull(newdata))
|
||||
return newdata
|
||||
|
||||
@@ -57,7 +72,7 @@
|
||||
else
|
||||
H.vessel.reagent_data[/singleton/reagent/blood]["trace_chem"][type] = amount
|
||||
|
||||
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
|
||||
/// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
|
||||
/singleton/reagent/proc/touch_mob(var/mob/living/M, var/amount, var/datum/reagents/holder)
|
||||
return
|
||||
|
||||
@@ -78,7 +93,8 @@
|
||||
var/OD_min = get_od_min_dose(M, location, holder)
|
||||
return OD && (REAGENT_VOLUME(holder, type) > OD) && (LAZYACCESS(M.chem_doses, type) > OD_min) && (!location || (location != CHEM_TOUCH)) //OD based on volume in blood, but waits for a small amount of the drug to metabolise before kicking in.
|
||||
|
||||
/singleton/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/location, var/datum/reagents/holder) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
|
||||
/// Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
|
||||
/singleton/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/location, var/datum/reagents/holder)
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!affects_dead && M.stat == DEAD)
|
||||
@@ -96,8 +112,9 @@
|
||||
|
||||
removed = M.get_metabolism(removed)
|
||||
|
||||
// ctual overdose threshold now = overdose + od_minimum_dose. ie. Synaptizine; 5u OD threshold + 1 unit min. metab'd dose = 6u actual OD threshold.
|
||||
if(is_overdosing(M, location, holder))
|
||||
overdose(M, alien, removed, LAZYACCESS(M.chem_doses, type)/get_overdose(M, location, holder), holder) //Actual overdose threshold now = overdose + od_minimum_dose. ie. Synaptizine; 5u OD threshold + 1 unit min. metab'd dose = 6u actual OD threshold.
|
||||
overdose(M, alien, removed, LAZYACCESS(M.chem_doses, type)/get_overdose(M, location, holder), holder)
|
||||
|
||||
if(LAZYACCESS(M.chem_doses, type) <= 0)
|
||||
initial_effect(M,alien, holder)
|
||||
@@ -127,22 +144,22 @@
|
||||
|
||||
remove_self(removed, holder)
|
||||
|
||||
// Called when a beaker is thrown or something is hit with it, AND the beaker doesn't break.
|
||||
/// Called when a beaker is thrown or something is hit with it, AND the beaker doesn't break.
|
||||
/singleton/reagent/proc/apply_force(var/force, var/datum/reagents/holder)
|
||||
return force
|
||||
|
||||
//Initial effect is called once when the reagent first starts affecting a mob.
|
||||
/// Initial effect is called once when the reagent first starts affecting a mob.
|
||||
/singleton/reagent/proc/initial_effect(var/mob/living/carbon/M, var/alien, var/datum/reagents/holder)
|
||||
return
|
||||
|
||||
//Final effect is called once when the reagent finishes affecting a mob.
|
||||
/// Final effect is called once when the reagent finishes affecting a mob.
|
||||
/singleton/reagent/proc/final_effect(var/mob/living/carbon/M, var/datum/reagents/holder)
|
||||
return
|
||||
|
||||
/singleton/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
|
||||
return
|
||||
|
||||
// if your chem directly affects other chems, use this to make sure all the chem_effects are applied before the standard chem affect_thing is run
|
||||
/// If your chem directly affects other chems, use this to make sure all the chem_effects are applied before the standard chem affect_thing is run
|
||||
/singleton/reagent/proc/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
@@ -167,13 +184,15 @@
|
||||
if(breathe_mul)
|
||||
affect_blood(M, alien, removed * breathe_mul, holder)
|
||||
|
||||
/singleton/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed = 0, var/scale = 1, var/datum/reagents/holder) // Overdose effect. Doesn't happen instantly.
|
||||
/// Overdose effect. Doesn't happen instantly.
|
||||
/singleton/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed = 0, var/scale = 1, var/datum/reagents/holder)
|
||||
M.adjustToxLoss(REM)
|
||||
|
||||
/singleton/reagent/proc/mix_data(var/newdata, var/newamount, var/datum/reagents/holder) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
|
||||
/// You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
|
||||
/singleton/reagent/proc/mix_data(var/newdata, var/newamount, var/datum/reagents/holder)
|
||||
return REAGENT_DATA(holder, type)
|
||||
|
||||
//Check to use when seeing if the person has the minimum dose of the reagent. Useful for stopping minimum transfer rate IV drips from applying chem effects
|
||||
/// Check to use when seeing if the person has the minimum dose of the reagent. Useful for stopping minimum transfer rate IV drips from applying chem effects
|
||||
/singleton/reagent/proc/check_min_dose(var/mob/living/carbon/M, var/min_dose = 1)
|
||||
var/dose = REAGENT_VOLUME(M.reagents, type) >= min_dose
|
||||
var/obj/item/organ/internal/stomach/S = M.internal_organs_by_name[BP_STOMACH]
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/singleton/reagent/acetone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
|
||||
M.adjustToxLoss(removed * 3)
|
||||
|
||||
/singleton/reagent/acetone/touch_obj(var/obj/O, var/amount, var/datum/reagents/holder) //I copied this wholesale from ethanol and could likely be converted into a shared proc. ~Techhead
|
||||
/singleton/reagent/acetone/touch_obj(var/obj/O, var/amount, var/datum/reagents/holder)
|
||||
if(istype(O, /obj/item/paper))
|
||||
var/obj/item/paper/paperaffected = O
|
||||
paperaffected.clearpaper()
|
||||
|
||||
@@ -783,6 +783,7 @@
|
||||
/singleton/reagent/drugs/dionae_stimulant/diet
|
||||
name = "diet Diesel"
|
||||
description = "Diesel produced straight from the Narrows that has been made \"diet\" or decontaminated of radiation, making it safe for distribution around the Orion Spur."
|
||||
fallback_specific_heat = 1
|
||||
|
||||
/singleton/reagent/drugs/dionae_stimulant/diet/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder)
|
||||
return
|
||||
|
||||
+1
@@ -86,6 +86,7 @@
|
||||
taste_description = "sharp tangy cheese"
|
||||
reagent_state = SOLID
|
||||
taste_mult = 3
|
||||
fallback_specific_heat = 1
|
||||
|
||||
/singleton/reagent/nakarka/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
|
||||
..()
|
||||
|
||||
+15
-7
@@ -5,12 +5,15 @@
|
||||
taste_mult = 4
|
||||
reagent_state = SOLID
|
||||
metabolism = REM * 2
|
||||
var/nutriment_factor = 8 // Per removed in digest.
|
||||
var/hydration_factor = 0 // Per removed in digest.
|
||||
/// Per removed in digest.
|
||||
var/nutriment_factor = 8
|
||||
/// Per removed in digest.
|
||||
var/hydration_factor = 0
|
||||
var/blood_factor = 2
|
||||
var/regen_factor = 0.8
|
||||
var/injectable = 0
|
||||
var/attrition_factor = -(REM * 4)/BASE_MAX_NUTRITION // Decreases attrition rate.
|
||||
/// Decreases attrition rate.
|
||||
var/attrition_factor = -(REM * 4)/BASE_MAX_NUTRITION
|
||||
color = "#664330"
|
||||
unaffected_species = IS_MACHINE
|
||||
taste_description = "food"
|
||||
@@ -59,6 +62,10 @@
|
||||
M.add_chemical_effect(CE_BLOODRESTORE, blood_factor * removed)
|
||||
M.intoxication -= min(M.intoxication,nutriment_factor*removed*0.05) //Nutrients can absorb alcohol.
|
||||
|
||||
/// Parent singleton. Provides fallback specific heat value to condiments unused in recipes.
|
||||
/singleton/reagent/condiment
|
||||
fallback_specific_heat = 1
|
||||
|
||||
//
|
||||
//Lipozine?
|
||||
//
|
||||
@@ -193,18 +200,19 @@
|
||||
if(amount >= 3)
|
||||
T.wet_floor(WET_TYPE_LUBE,amount)
|
||||
|
||||
//Calculates a scaling factor for scalding damage, based on the temperature of the oil and creature's heat resistance
|
||||
/// Calculates a scaling factor for scalding damage, based on the temperature of the oil and creature's heat resistance
|
||||
/singleton/reagent/nutriment/triglyceride/oil/proc/heatdamage(var/mob/living/carbon/M, var/datum/reagents/holder)
|
||||
var/threshold = 360//Human heatdamage threshold
|
||||
/// Human heatdamage threshold.
|
||||
var/threshold = 360
|
||||
var/datum/species/S = M.get_species(1)
|
||||
if (S && istype(S))
|
||||
threshold = S.heat_level_1
|
||||
|
||||
//If temperature is too low to burn, return a factor of 0. no damage
|
||||
// If temperature is too low to burn, return a factor of 0. no damage.
|
||||
if (holder.get_temperature() < threshold)
|
||||
return 0
|
||||
|
||||
//Step = degrees above heat level 1 for 1.0 multiplier
|
||||
/// Step = degrees above heat level 1 for 1.0 multiplier.
|
||||
var/step = 60
|
||||
if (S && istype(S))
|
||||
step = (S.heat_level_2 - S.heat_level_1)*1.5
|
||||
|
||||
+10
-10
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
Coatings are used in cooking. Dipping food items in a reagent container with a coating in it
|
||||
allows it to be covered in that, which will add a masked overlay to the sprite.
|
||||
|
||||
Coatings have both a raw and a cooked image. Raw coating is generally unhealthy
|
||||
Generally coatings are intended for deep frying foods
|
||||
/**
|
||||
* Coatings are used in cooking. Dipping food items in a reagent container with a coating in it
|
||||
* allows it to be covered in that, which will add a masked overlay to the sprite.
|
||||
*
|
||||
* Coatings have both a raw and a cooked image. Raw coating is generally unhealthy
|
||||
* Generally coatings are intended for deep frying foodsGenerally coatings are intended for deep frying foods
|
||||
*/
|
||||
/singleton/reagent/nutriment/coating
|
||||
nutriment_factor = 4 //Less dense than the food itself, but coatings still add extra calories
|
||||
@@ -29,13 +29,13 @@
|
||||
H.delayed_vomit()
|
||||
. = ..()
|
||||
|
||||
/singleton/reagent/nutriment/coating/initialize_data(var/list/newdata, var/datum/reagents/holder) // Called when the reagent is created.
|
||||
/// Called when the reagent is created.
|
||||
/singleton/reagent/nutriment/coating/initialize_data(var/list/newdata, var/datum/reagents/holder)
|
||||
var/list/data = ..()
|
||||
LAZYSET(data, "cooked", istype(holder?.my_atom,/obj/item/reagent_containers/food/snacks))
|
||||
if(data["cooked"])
|
||||
name = cooked_name
|
||||
return data
|
||||
|
||||
//Batter which is part of objects at compiletime spawns in a cooked state
|
||||
|
||||
/singleton/reagent/nutriment/coating/mix_data(var/list/newdata, var/newamount, var/datum/reagents/holder)
|
||||
@@ -270,8 +270,8 @@
|
||||
condiment_name = "hotsauce"
|
||||
condiment_desc = "Hot sauce. It's in the name."
|
||||
condiment_icon_state = "hotsauce"
|
||||
|
||||
var/agony_dose = 15 // Capsaicin required to proc agony. (3 to 5 chilis.)
|
||||
/// Capsaicin required to proc agony. (3 to 5 chilis.)
|
||||
var/agony_dose = 15
|
||||
var/agony_amount = 1
|
||||
var/discomfort_message = SPAN_DANGER("Your insides feel uncomfortably hot.")
|
||||
var/slime_temp_adj = 10
|
||||
|
||||
@@ -2031,6 +2031,7 @@
|
||||
metabolism = REM*0.0001
|
||||
scannable = TRUE
|
||||
taste_description = "pure death"
|
||||
fallback_specific_heat = 1
|
||||
|
||||
/singleton/reagent/antibodies/affect_blood(mob/living/carbon/M, alien, removed, datum/reagents/holder)
|
||||
. = ..()
|
||||
@@ -2042,7 +2043,8 @@
|
||||
Z.curing = TRUE
|
||||
to_chat(M, SPAN_WARNING("Your [E.name] tightens, pulses, and squirms as \the [Z] fights back against the antibodies!"))
|
||||
|
||||
/singleton/reagent/caffeine // Copied from Hyperzine
|
||||
/// Copied from Hyperzine
|
||||
/singleton/reagent/caffeine
|
||||
name = "Caffeine"
|
||||
description = "Caffeine is a central nervous system stimulant found naturally in many plants. It's used as a mild cognitive enhancer to increase alertness, attentional performance, and improve cardiovascular health."
|
||||
reagent_state = SOLID
|
||||
@@ -2053,6 +2055,7 @@
|
||||
taste_description = "bitter"
|
||||
metabolism_min = REM * 0.025
|
||||
breathe_met = REM * 0.15 * 0.5
|
||||
fallback_specific_heat = 1
|
||||
|
||||
/singleton/reagent/caffeine/initial_effect(mob/living/carbon/M, alien, datum/reagents/holder)
|
||||
. = ..()
|
||||
|
||||
@@ -4,19 +4,22 @@
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
icon_state = "auth_off"
|
||||
obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED
|
||||
var/active = 0 //This gets set to 1 on all devices except the one where the initial request was made.
|
||||
/// This gets set to TRUE on all devices except the one where the initial request was made.
|
||||
var/active = FALSE
|
||||
var/event = ""
|
||||
var/screen = 1
|
||||
var/confirmed = 0 //This variable is set by the device that confirms the request.
|
||||
var/confirm_delay = 20 //(2 seconds)
|
||||
var/busy = 0 //Busy when waiting for authentication or an event request has been sent from this device.
|
||||
/// This variable is set by the device that confirms the request.
|
||||
var/confirmed = FALSE
|
||||
var/confirm_delay = 2 SECONDS
|
||||
/// Busy when waiting for authentication, or an event request has been sent from this device.
|
||||
var/busy = FALSE
|
||||
var/obj/machinery/keycard_auth/event_source
|
||||
var/mob/event_triggered_by
|
||||
var/mob/event_confirmed_by
|
||||
var/recorded_message = ""
|
||||
//1 = select event
|
||||
//2 = authenticate
|
||||
anchored = 1.0
|
||||
anchored = TRUE
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 6
|
||||
power_channel = AREA_USAGE_ENVIRON
|
||||
@@ -40,7 +43,7 @@
|
||||
/obj/machinery/keycard_auth/attackby(obj/item/attacking_item, mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "This device is not powered.")
|
||||
return
|
||||
return FALSE
|
||||
if(istype(attacking_item, /obj/item/card/id))
|
||||
var/obj/item/card/id/ID = attacking_item
|
||||
if(ACCESS_KEYCARD_AUTH in ID.access)
|
||||
@@ -63,10 +66,10 @@
|
||||
to_chat(user, "This device is not powered.")
|
||||
return
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return 0
|
||||
return FALSE
|
||||
if(busy)
|
||||
to_chat(user, "This device is busy.")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
@@ -111,10 +114,10 @@
|
||||
return
|
||||
|
||||
/obj/machinery/keycard_auth/proc/reset()
|
||||
active = 0
|
||||
active = FALSE
|
||||
event = ""
|
||||
screen = 1
|
||||
confirmed = 0
|
||||
confirmed = FALSE
|
||||
event_source = null
|
||||
icon_state = "auth_off"
|
||||
event_triggered_by = null
|
||||
@@ -147,7 +150,7 @@
|
||||
|
||||
sleep(confirm_delay)
|
||||
if(confirmed)
|
||||
confirmed = 0
|
||||
confirmed = FALSE
|
||||
trigger_event(event, recorded_message, user)
|
||||
log_game("[key_name(event_triggered_by)] triggered and [key_name(event_confirmed_by)] confirmed event [event]")
|
||||
message_admins("[key_name_admin(event_triggered_by)] triggered and [key_name_admin(event_confirmed_by)] confirmed event [event]", 1)
|
||||
@@ -157,16 +160,16 @@
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
event_source = source
|
||||
busy = 1
|
||||
active = 1
|
||||
busy = TRUE
|
||||
active = TRUE
|
||||
icon_state = "auth_on"
|
||||
|
||||
sleep(confirm_delay)
|
||||
|
||||
event_source = null
|
||||
icon_state = "auth_off"
|
||||
active = 0
|
||||
busy = 0
|
||||
active = FALSE
|
||||
busy = FALSE
|
||||
|
||||
/obj/machinery/keycard_auth/proc/trigger_event(var/event, var/distress_message, var/mob/user)
|
||||
switch(event)
|
||||
@@ -196,12 +199,12 @@
|
||||
|
||||
/obj/machinery/keycard_auth/proc/is_ert_blocked()
|
||||
if(GLOB.config.ert_admin_call_only)
|
||||
return 1
|
||||
return TRUE
|
||||
if(SSticker.mode.ert_disabled)
|
||||
SSticker.mode.announce_ert_disabled()
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
GLOBAL_VAR_INIT(maint_all_access, FALSE)
|
||||
|
||||
@@ -215,7 +218,7 @@ GLOBAL_VAR_INIT(maint_all_access, FALSE)
|
||||
|
||||
/obj/machinery/door/airlock/allowed(mob/M)
|
||||
if(locked)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/obj/item/I = M.GetIdCard()
|
||||
if(!I)
|
||||
@@ -224,7 +227,7 @@ GLOBAL_VAR_INIT(maint_all_access, FALSE)
|
||||
var/maint_sec_access = ((GLOB.security_level > SEC_LEVEL_GREEN) && has_access(ACCESS_SECURITY, accesses = A))
|
||||
var/exceptional_circumstances = GLOB.maint_all_access || maint_sec_access
|
||||
if(exceptional_circumstances && src.check_access_list(list(ACCESS_MAINT_TUNNELS)))
|
||||
return 1
|
||||
return TRUE
|
||||
if(access_by_level || req_one_access_by_level)
|
||||
var/sec_level = get_security_level()
|
||||
if(sec_level in (req_one_access_by_level ? req_one_access_by_level : access_by_level))
|
||||
|
||||
Reference in New Issue
Block a user