Porting the BEPIS research machinery. (#12277)
* Initial B.E.P.I.S port. * All nodes but sticky tape are in. Sweet. * Mapping the BEPIS :DDD * ah * deers.
This commit is contained in:
@@ -200,6 +200,7 @@
|
||||
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
|
||||
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
|
||||
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
|
||||
#define COMSIG_LIVING_SHOCK_PREVENTED "living_shock_prevented" //sent when items with siemen coeff. of 0 block a shock: (power_source, source, siemens_coeff, dist_check)
|
||||
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
|
||||
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
|
||||
#define TRAIT_QUICK_CARRY "quick-carry"
|
||||
#define TRAIT_QUICKER_CARRY "quicker-carry"
|
||||
#define TRAIT_QUICK_BUILD "quick-build"
|
||||
#define TRAIT_STRONG_GRABBER "strong_grabber"
|
||||
#define TRAIT_CALCIUM_HEALER "calcium_healer"
|
||||
#define TRAIT_MAGIC_CHOKE "magic_choke"
|
||||
|
||||
@@ -24,6 +24,7 @@ SUBSYSTEM_DEF(research)
|
||||
var/list/techweb_categories = list() //category name = list(node.id = TRUE)
|
||||
var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount))
|
||||
var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default.
|
||||
var/list/techweb_nodes_experimental = list() //Node ids that are exclusive to the BEPIS.
|
||||
|
||||
var/list/techweb_point_items = list( //path = list(point type = value)
|
||||
/obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000),
|
||||
@@ -508,6 +509,8 @@ SUBSYSTEM_DEF(research)
|
||||
D.unlocked_by += node.id
|
||||
if(node.hidden)
|
||||
techweb_nodes_hidden[node.id] = TRUE
|
||||
if(node.experimental)
|
||||
techweb_nodes_experimental[node.id] = TRUE
|
||||
CHECK_TICK
|
||||
generate_techweb_unlock_linking()
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
if(prob(2))
|
||||
switch(rand(1,2))
|
||||
if(1)
|
||||
to_chat(owner, "<i>...[lowertext(hypnotic_phrase)]...</i>")
|
||||
to_chat(owner, "<span class='hypnophrase'><i>...[lowertext(hypnotic_phrase)]...</i></span>")
|
||||
if(2)
|
||||
new /datum/hallucination/chat(owner, TRUE, FALSE, "<span class='hypnophrase'>[hypnotic_phrase]</span>")
|
||||
|
||||
|
||||
@@ -265,3 +265,37 @@
|
||||
..()
|
||||
if(prob(1) && !owner.has_status_effect(/datum/status_effect/trance))
|
||||
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger
|
||||
name = "Hypnotic Trigger"
|
||||
desc = "Patient has a trigger phrase set in their subconscious that will trigger a suggestible trance-like state."
|
||||
scan_desc = "oneiric feedback loop"
|
||||
gain_text = "<span class='warning'>You feel odd, like you just forgot something important.</span>"
|
||||
lose_text = "<span class='notice'>You feel like a weight was lifted from your mind.</span>"
|
||||
random_gain = FALSE
|
||||
var/trigger_phrase = "Nanotrasen"
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/New(phrase)
|
||||
..()
|
||||
if(phrase)
|
||||
trigger_phrase = phrase
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/on_lose() //hypnosis must be cleared separately, but brain surgery should get rid of both anyway
|
||||
..()
|
||||
owner.remove_status_effect(/datum/status_effect/trance)
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/handle_hearing(datum/source, list/hearing_args)
|
||||
if(!owner.can_hear())
|
||||
return
|
||||
if(owner == hearing_args[HEARING_SPEAKER])
|
||||
return
|
||||
|
||||
var/regex/reg = new("(\\b[REGEX_QUOTE(trigger_phrase)]\\b)","ig")
|
||||
|
||||
if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg))
|
||||
addtimer(CALLBACK(src, .proc/hypnotrigger), 10) //to react AFTER the chat message
|
||||
hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "<span class='hypnophrase'>*********</span>")
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/proc/hypnotrigger()
|
||||
to_chat(owner, "<span class='warning'>The words trigger something deep within you, and you feel your consciousness slipping away...</span>")
|
||||
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
|
||||
|
||||
@@ -434,3 +434,45 @@
|
||||
|
||||
/obj/machinery/sleeper/old
|
||||
icon_state = "oldpod"
|
||||
|
||||
/obj/machinery/sleeper/party
|
||||
name = "party pod"
|
||||
desc = "'Sleeper' units were once known for their healing properties, until a lengthy investigation revealed they were also dosing patients with deadly lead acetate. This appears to be one of those old 'sleeper' units repurposed as a 'Party Pod'. It’s probably not a good idea to use it."
|
||||
icon_state = "partypod"
|
||||
idle_power_usage = 3000
|
||||
circuit = /obj/item/circuitboard/machine/sleeper/party
|
||||
var/leddit = FALSE //Get it like reddit and lead alright fine
|
||||
ui_x = 310
|
||||
ui_y = 400
|
||||
|
||||
controls_inside = TRUE
|
||||
possible_chems = list(
|
||||
list(/datum/reagent/consumable/ethanol/beer, /datum/reagent/consumable/laughter),
|
||||
list(/datum/reagent/spraytan,/datum/reagent/barbers_aid),
|
||||
list(/datum/reagent/colorful_reagent,/datum/reagent/hair_dye),
|
||||
list(/datum/reagent/drug/space_drugs,/datum/reagent/baldium)
|
||||
)//Exclusively uses non-lethal, "fun" chems. At an obvious downside.
|
||||
var/spray_chems = list(
|
||||
/datum/reagent/spraytan, /datum/reagent/hair_dye, /datum/reagent/baldium, /datum/reagent/barbers_aid
|
||||
)//Chemicals that need to have a touch or vapor reaction to be applied, not the standard chamber reaction.
|
||||
enter_message = "<span class='notice'><b>You're surrounded by some funky music inside the chamber. You zone out as you feel waves of krunk vibe within you.</b></span>"
|
||||
|
||||
/obj/machinery/sleeper/party/inject_chem(chem, mob/user)
|
||||
if(leddit)
|
||||
occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, 4) //You're injecting chemicals into yourself from a recalled, decrepit medical machine. What did you expect?
|
||||
else if (prob(20))
|
||||
occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, rand(1,3))
|
||||
if(chem in spray_chems)
|
||||
var/datum/reagents/holder = new()
|
||||
holder.add_reagent(chem_buttons[chem], 10) //I hope this is the correct way to do this.
|
||||
holder.reaction(occupant, VAPOR, 0)
|
||||
holder.trans_to(occupant, 10)
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6)
|
||||
if(user)
|
||||
log_combat(user, occupant, "sprayed [chem] into", addition = "via [src]")
|
||||
return TRUE
|
||||
..()
|
||||
|
||||
/obj/machinery/sleeper/party/emag_act(mob/user)
|
||||
..()
|
||||
leddit = TRUE
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/obj/machinery/hypnochair
|
||||
name = "enhanced interrogation chamber"
|
||||
desc = "A device used to perform \"enhanced interrogation\" through invasive mental conditioning."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "hypnochair"
|
||||
circuit = /obj/item/circuitboard/machine/hypnochair
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
ui_x = 375
|
||||
ui_y = 480
|
||||
var/mob/living/carbon/victim = null ///Keeps track of the victim to apply effects if it teleports away
|
||||
var/interrogating = FALSE ///Is the device currently interrogating someone?
|
||||
var/start_time = 0 ///Time when the interrogation was started, to calculate effect in case of interruption
|
||||
var/trigger_phrase = "" ///Trigger phrase to implant
|
||||
var/timerid = 0 ///Timer ID for interrogations
|
||||
|
||||
var/message_cooldown = 0 ///Cooldown for breakout message
|
||||
|
||||
/obj/machinery/hypnochair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/hypnochair/attackby(obj/item/I, mob/user, params)
|
||||
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(default_pry_open(I))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/hypnochair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "hypnochair", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/hypnochair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? TRUE : FALSE
|
||||
data["open"] = state_open
|
||||
data["interrogating"] = interrogating
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["trigger"] = trigger_phrase
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/hypnochair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
if(!interrogating)
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("set_phrase")
|
||||
set_phrase(params["phrase"])
|
||||
. = TRUE
|
||||
if("interrogate")
|
||||
if(!interrogating)
|
||||
interrogate()
|
||||
else
|
||||
interrupt_interrogation()
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/hypnochair/proc/set_phrase(phrase)
|
||||
trigger_phrase = phrase
|
||||
|
||||
/obj/machinery/hypnochair/proc/interrogate()
|
||||
if(!trigger_phrase)
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE)
|
||||
return
|
||||
var/mob/living/carbon/C = occupant
|
||||
if(!istype(C))
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE)
|
||||
return
|
||||
victim = C
|
||||
if(!(C.get_eye_protection() > 0))
|
||||
to_chat(C, "<span class='warning'>Strobing coloured lights assault you relentlessly! You're losing your ability to think straight!</span>")
|
||||
C.become_blind("hypnochair")
|
||||
ADD_TRAIT(C, TRAIT_DEAF, "hypnochair")
|
||||
interrogating = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
start_time = world.time
|
||||
update_icon()
|
||||
timerid = addtimer(CALLBACK(src, .proc/finish_interrogation), 450, TIMER_STOPPABLE)
|
||||
|
||||
/obj/machinery/hypnochair/process()
|
||||
var/mob/living/carbon/C = occupant
|
||||
if(!istype(C) || C != victim)
|
||||
interrupt_interrogation()
|
||||
return
|
||||
if(prob(10) && !(C.get_eye_protection() > 0))
|
||||
to_chat(C, "<span class='hypnophrase'>[pick(\
|
||||
"...blue... red... green... blue, red, green, blueredgreen<span class='small'>blueredgreen</span>",\
|
||||
"...pretty colors...",\
|
||||
"...you keep hearing words, but you can't seem to understand them...",\
|
||||
"...so peaceful...",\
|
||||
"...an annoying buzz in your ears..."\
|
||||
)]</span>")
|
||||
|
||||
/obj/machinery/hypnochair/proc/finish_interrogation()
|
||||
interrogating = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
var/temp_trigger = trigger_phrase
|
||||
trigger_phrase = "" //Erase evidence, in case the subject is able to look at the panel afterwards
|
||||
audible_message("<span class='notice'>[src] pings!</span>")
|
||||
playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
|
||||
|
||||
if(QDELETED(victim) || victim != occupant)
|
||||
victim = null
|
||||
return
|
||||
victim.cure_blind("hypnochair")
|
||||
REMOVE_TRAIT(victim, TRAIT_DEAF, "hypnochair")
|
||||
if(!(victim.get_eye_protection() > 0))
|
||||
victim.cure_trauma_type(/datum/brain_trauma/severe/hypnotic_trigger, TRAUMA_RESILIENCE_SURGERY)
|
||||
if(prob(90))
|
||||
victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_trigger(temp_trigger), TRAUMA_RESILIENCE_SURGERY)
|
||||
else
|
||||
victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_stupor(), TRAUMA_RESILIENCE_SURGERY)
|
||||
victim = null
|
||||
|
||||
/obj/machinery/hypnochair/proc/interrupt_interrogation()
|
||||
deltimer(timerid)
|
||||
interrogating = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
if(QDELETED(victim))
|
||||
victim = null
|
||||
return
|
||||
victim.cure_blind("hypnochair")
|
||||
REMOVE_TRAIT(victim, TRAIT_DEAF, "hypnochair")
|
||||
if(!(victim.get_eye_protection() > 0))
|
||||
var/time_diff = world.time - start_time
|
||||
switch(time_diff)
|
||||
if(0 to 100)
|
||||
victim.confused += 10
|
||||
victim.Dizzy(100)
|
||||
victim.blur_eyes(5)
|
||||
if(101 to 200)
|
||||
victim.confused += 15
|
||||
victim.Dizzy(200)
|
||||
victim.blur_eyes(10)
|
||||
if(prob(25))
|
||||
victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE)
|
||||
if(201 to INFINITY)
|
||||
victim.confused += 20
|
||||
victim.Dizzy(300)
|
||||
victim.blur_eyes(15)
|
||||
if(prob(65))
|
||||
victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE)
|
||||
victim = null
|
||||
|
||||
/obj/machinery/hypnochair/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
if(interrogating)
|
||||
icon_state += "_active"
|
||||
else
|
||||
icon_state += "_occupied"
|
||||
|
||||
/obj/machinery/hypnochair/container_resist(mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)</span>", \
|
||||
"<span class='hear'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(600), target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/hypnochair/relaymove(mob/user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/hypnochair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(!(L.mobility_flags & MOBILITY_STAND))
|
||||
return
|
||||
close_machine(target)
|
||||
@@ -745,7 +745,7 @@ RLD
|
||||
if(istype(A, /obj/machinery/light/))
|
||||
if(checkResource(deconcost, user))
|
||||
to_chat(user, "<span class='notice'>You start deconstructing [A]...</span>")
|
||||
user.Beam(A,icon_state="nzcrentrs_power",time=15)
|
||||
user.Beam(A,icon_state="light_beam",time=15)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, decondelay, target = A))
|
||||
if(!useResource(deconcost, user))
|
||||
@@ -759,7 +759,7 @@ RLD
|
||||
var/turf/closed/wall/W = A
|
||||
if(checkResource(floorcost, user))
|
||||
to_chat(user, "<span class='notice'>You start building a wall light...</span>")
|
||||
user.Beam(A,icon_state="nzcrentrs_power",time=15)
|
||||
user.Beam(A,icon_state="light_beam",time=15)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 0)
|
||||
if(do_after(user, floordelay, target = A))
|
||||
@@ -805,7 +805,7 @@ RLD
|
||||
var/turf/open/floor/F = A
|
||||
if(checkResource(floorcost, user))
|
||||
to_chat(user, "<span class='notice'>You start building a floor light...</span>")
|
||||
user.Beam(A,icon_state="nzcrentrs_power",time=15)
|
||||
user.Beam(A,icon_state="light_beam",time=15)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
if(do_after(user, floordelay, target = A))
|
||||
@@ -834,6 +834,12 @@ RLD
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/construction/rld/mini
|
||||
name = "mini-rapid-light-device (MRLD)"
|
||||
desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges."
|
||||
matter = 100
|
||||
max_matter = 100
|
||||
|
||||
/obj/item/rcd_upgrade
|
||||
name = "RCD advanced design disk"
|
||||
desc = "It seems to be empty."
|
||||
|
||||
@@ -7,7 +7,7 @@ RSF
|
||||
name = "\improper Rapid-Service-Fabricator"
|
||||
desc = "A device used to rapidly deploy service items."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rcd"
|
||||
icon_state = "rsf"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
opacity = 0
|
||||
@@ -110,7 +110,7 @@ RSF
|
||||
name = "Cookie Synthesizer"
|
||||
desc = "A self-recharging device used to rapidly deploy cookies."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rcd"
|
||||
icon_state = "rsf"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
var/matter = 10
|
||||
|
||||
@@ -125,3 +125,112 @@
|
||||
user.put_in_hands(ink)
|
||||
to_chat(user, "<span class='notice'>You remove [ink] from [src].</span>")
|
||||
ink = null
|
||||
|
||||
|
||||
/obj/item/airlock_painter/decal
|
||||
name = "decal painter"
|
||||
desc = "An airlock painter, reprogramed to use a different style of paint in order to apply decals for floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed. Alt-Click to change design."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "decal_sprayer"
|
||||
item_state = "decalsprayer"
|
||||
custom_materials = list(/datum/material/iron=2000, /datum/material/glass=500)
|
||||
var/stored_dir = 2
|
||||
var/stored_color = ""
|
||||
var/stored_decal = "warningline"
|
||||
var/stored_decal_total = "warningline"
|
||||
var/color_list = list("","red","white")
|
||||
var/dir_list = list(1,2,4,8)
|
||||
var/decal_list = list(list("Warning Line","warningline"),
|
||||
list("Warning Line Corner","warninglinecorner"),
|
||||
list("Caution Label","caution"),
|
||||
list("Directional Arrows","arrows"),
|
||||
list("Stand Clear Label","stand_clear"),
|
||||
list("Box","box"),
|
||||
list("Box Corner","box_corners"),
|
||||
list("Delivery Marker","delivery"),
|
||||
list("Warning Box","warn_full"))
|
||||
|
||||
/obj/item/airlock_painter/decal/afterattack(atom/target, mob/user, proximity)
|
||||
. = ..()
|
||||
var/turf/open/floor/F = target
|
||||
if(!proximity)
|
||||
to_chat(user, "<span class='notice'>You need to get closer!</span>")
|
||||
return
|
||||
if(use_paint(user) && isturf(F))
|
||||
F.AddComponent(/datum/component/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, CLEAN_STRONG, color, null, null, alpha)
|
||||
|
||||
/obj/item/airlock_painter/decal/attack_self(mob/user)
|
||||
if((ink) && (ink.charges >= 1))
|
||||
to_chat(user, "<span class='notice'>[src] beeps to prevent you from removing the toner until out of charges.</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/airlock_painter/decal/AltClick(mob/user)
|
||||
. = ..()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/airlock_painter/decal/Initialize()
|
||||
. = ..()
|
||||
ink = new /obj/item/toner/large(src)
|
||||
|
||||
/obj/item/airlock_painter/decal/proc/update_decal_path()
|
||||
var/yellow_fix = "" //This will have to do until someone refactor's markings.dm
|
||||
if (stored_color)
|
||||
yellow_fix = "_"
|
||||
stored_decal_total = "[stored_decal][yellow_fix][stored_color]"
|
||||
return
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["decal_direction"] = stored_dir
|
||||
data["decal_color"] = stored_color
|
||||
data["decal_style"] = stored_decal
|
||||
data["decal_list"] = list()
|
||||
data["color_list"] = list()
|
||||
data["dir_list"] = list()
|
||||
|
||||
for(var/i in decal_list)
|
||||
data["decal_list"] += list(list(
|
||||
"name" = i[1],
|
||||
"decal" = i[2]
|
||||
))
|
||||
for(var/j in color_list)
|
||||
data["color_list"] += list(list(
|
||||
"colors" = j
|
||||
))
|
||||
for(var/k in dir_list)
|
||||
data["dir_list"] += list(list(
|
||||
"dirs" = k
|
||||
))
|
||||
return data
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_act(action,list/params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
//Lists of decals and designs
|
||||
if("select decal")
|
||||
var/selected_decal = params["decals"]
|
||||
stored_decal = selected_decal
|
||||
if("select color")
|
||||
var/selected_color = params["colors"]
|
||||
stored_color = selected_color
|
||||
if("selected direction")
|
||||
var/selected_direction = text2num(params["dirs"])
|
||||
stored_dir = selected_direction
|
||||
update_decal_path()
|
||||
. = TRUE
|
||||
|
||||
/obj/item/airlock_painter/decal/debug
|
||||
name = "extreme decal painter"
|
||||
icon_state = "decal_sprayer_ex"
|
||||
|
||||
/obj/item/airlock_painter/decal/debug/Initialize()
|
||||
. = ..()
|
||||
ink = new /obj/item/toner/extreme(src)
|
||||
@@ -707,6 +707,10 @@
|
||||
def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high)
|
||||
needs_anchored = FALSE
|
||||
|
||||
/obj/item/circuitboard/machine/sleeper/party
|
||||
name = "Party Pod (Machine Board)"
|
||||
build_path = /obj/machinery/sleeper/party
|
||||
|
||||
/obj/item/circuitboard/machine/smoke_machine
|
||||
name = "Smoke Machine (Machine Board)"
|
||||
build_path = /obj/machinery/smoke_machine
|
||||
@@ -884,6 +888,16 @@
|
||||
name = "Departmental Protolathe - Service (Machine Board)"
|
||||
build_path = /obj/machinery/rnd/production/protolathe/department/service
|
||||
|
||||
/obj/item/circuitboard/machine/bepis
|
||||
name = "BEPIS Chamber (Machine Board)"
|
||||
build_path = /obj/machinery/rnd/bepis
|
||||
req_components = list(
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stock_parts/micro_laser = 1,
|
||||
/obj/item/stock_parts/scanning_module = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/techfab
|
||||
name = "\improper Techfab (Machine Board)"
|
||||
build_path = /obj/machinery/rnd/production/techfab
|
||||
@@ -1068,3 +1082,12 @@
|
||||
/obj/item/stock_parts/matter_bin = 3,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/hypnochair
|
||||
name = "Enhanced Interrogation Chamber (Machine Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/hypnochair
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/micro_laser = 2,
|
||||
/obj/item/stock_parts/scanning_module = 2
|
||||
)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/obj/item/stack/circuit_stack
|
||||
name = "polycircuit aggregate"
|
||||
desc = "A dense, overdesigned cluster of electronics which attempted to function as a multipurpose circuit electronic. Circuits can be removed from it... if you don't bleed out in the process."
|
||||
icon_state = "circuit_mess"
|
||||
item_state = "rods"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_amount = 8
|
||||
var/circuit_type = /obj/item/electronics/airlock
|
||||
var/chosen_circuit = "airlock"
|
||||
|
||||
/obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it.
|
||||
to_chat(user, "<span class='warning'>You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.</span>")
|
||||
|
||||
/obj/item/stack/circuit_stack/attack_hand(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!user.get_inactive_held_item() == src)
|
||||
return ..()
|
||||
else
|
||||
if(zero_amount())
|
||||
return
|
||||
chosen_circuit = input("What type of circuit would you like to remove?", "Choose a Circuit Type", chosen_circuit) in list("airlock","firelock","fire alarm","air alarm","APC")
|
||||
if(zero_amount())
|
||||
return
|
||||
switch(chosen_circuit)
|
||||
if("airlock")
|
||||
circuit_type = /obj/item/electronics/airlock
|
||||
if("firelock")
|
||||
circuit_type = /obj/item/electronics/firelock
|
||||
if("fire alarm")
|
||||
circuit_type = /obj/item/electronics/firealarm
|
||||
if("air alarm")
|
||||
circuit_type = /obj/item/electronics/airalarm
|
||||
if("APC")
|
||||
circuit_type = /obj/item/electronics/apc
|
||||
to_chat(user, "<span class='notice'>You spot your circuit, and carefully attempt to remove it from [src], hold still!</span>")
|
||||
if(do_after(user, 30, target = user))
|
||||
if(!src || QDELETED(src))//Sanity Check.
|
||||
return
|
||||
var/returned_circuit = new circuit_type(src)
|
||||
user.put_in_hands(returned_circuit)
|
||||
use(1)
|
||||
if(!amount)
|
||||
to_chat(user, "<span class='notice'>You navigate the sharp edges of circuitry and remove the last board.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You navigate the sharp edges of circuitry and remove a single board from [src]</span>")
|
||||
else
|
||||
H.apply_damage(15, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
to_chat(user, "<span class='warning'>You give yourself a wicked cut on [src]'s many sharp corners and edges!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/stack/circuit_stack/full
|
||||
amount = 8
|
||||
@@ -71,3 +71,9 @@
|
||||
icon_state = "spacecash1000"
|
||||
singular_name = "one thousand credit bill"
|
||||
value = 1000
|
||||
|
||||
/obj/item/stack/spacecash/c10000
|
||||
icon_state = "spacecash10000"
|
||||
singular_name = "ten thousand credit bill"
|
||||
value = 10000
|
||||
|
||||
|
||||
@@ -89,3 +89,19 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
|
||||
/obj/item/stack/rods/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/rods/lava
|
||||
name = "heat resistant rod"
|
||||
desc = "Treated, specialized metal rods. When exposed to the vaccum of space their coating breaks off, but they can hold up against the extreme heat of active lava."
|
||||
singular_name = "heat resistant rod"
|
||||
icon_state = "rods"
|
||||
item_state = "rods"
|
||||
color = "#5286b9ff"
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
custom_materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000)
|
||||
max_amount = 30
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
/obj/item/stack/rods/lava/thirty
|
||||
amount = 30
|
||||
|
||||
@@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
|
||||
new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
|
||||
new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
|
||||
null, \
|
||||
new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \
|
||||
null, \
|
||||
new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
|
||||
@@ -201,8 +201,13 @@
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
if (R.time)
|
||||
var/adjusted_time = 0
|
||||
usr.visible_message("<span class='notice'>[usr] starts building [R.title].</span>", "<span class='notice'>You start building [R.title]...</span>")
|
||||
if (!do_after(usr, R.time, target = usr))
|
||||
if(HAS_TRAIT(usr, R.trait_booster))
|
||||
adjusted_time = (R.time * R.trait_modifier)
|
||||
else
|
||||
adjusted_time = R.time
|
||||
if (!do_after(usr, adjusted_time, target = usr))
|
||||
return
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
@@ -457,8 +462,10 @@
|
||||
var/window_checks = FALSE
|
||||
var/placement_checks = FALSE
|
||||
var/applies_mats = FALSE
|
||||
var/trait_booster = null
|
||||
var/trait_modifier = 1
|
||||
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE)
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1)
|
||||
|
||||
|
||||
src.title = title
|
||||
@@ -472,6 +479,8 @@
|
||||
src.window_checks = window_checks
|
||||
src.placement_checks = placement_checks
|
||||
src.applies_mats = applies_mats
|
||||
src.trait_booster = trait_booster
|
||||
src.trait_modifier = trait_modifier
|
||||
/*
|
||||
* Recipe list datum
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
|
||||
var/stamforce = 35
|
||||
var/status = FALSE
|
||||
var/turned_on = FALSE
|
||||
var/knockdown = TRUE
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/hitcost = 750
|
||||
@@ -49,7 +49,7 @@
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
//Only mob/living types have stun handling
|
||||
if(status && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
baton_stun(hit_atom)
|
||||
|
||||
/obj/item/melee/baton/loaded //this one starts with a cell pre-installed.
|
||||
@@ -66,16 +66,16 @@
|
||||
copper_top.use(min(chrgdeductamt, copper_top.charge), explode)
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
if(status && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY))))
|
||||
if(turned_on && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY))))
|
||||
//we're below minimum, turn off
|
||||
switch_status(FALSE)
|
||||
|
||||
/obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE)
|
||||
if(status != new_status)
|
||||
status = new_status
|
||||
if(turned_on != new_status)
|
||||
turned_on = new_status
|
||||
if(!silent)
|
||||
playsound(loc, "sparks", 75, 1, -1)
|
||||
if(status)
|
||||
if(turned_on)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -85,7 +85,7 @@
|
||||
deductcharge(round(hitcost * STUNBATON_DEPLETION_RATE), FALSE, FALSE)
|
||||
|
||||
/obj/item/melee/baton/update_icon_state()
|
||||
if(status)
|
||||
if(turned_on)
|
||||
icon_state = "[initial(name)]_active"
|
||||
else if(!cell)
|
||||
icon_state = "[initial(name)]_nocell"
|
||||
@@ -134,8 +134,8 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is out of charge.</span>")
|
||||
else
|
||||
switch_status(!status)
|
||||
to_chat(user, "<span class='notice'>[src] is now [status ? "on" : "off"].</span>")
|
||||
switch_status(!turned_on)
|
||||
to_chat(user, "<span class='notice'>[src] is now [turned_on ? "on" : "off"].</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
|
||||
@@ -151,7 +151,7 @@
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
|
||||
return FALSE
|
||||
if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
if(turned_on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
clowning_around(user)
|
||||
if(IS_STAMCRIT(user)) //CIT CHANGE - makes it impossible to baton in stamina softcrit
|
||||
to_chat(user, "<span class='danger'>You're too exhausted for that.</span>")
|
||||
@@ -160,7 +160,7 @@
|
||||
var/mob/living/carbon/human/L = M
|
||||
if(check_martial_counter(L, user))
|
||||
return TRUE
|
||||
if(status)
|
||||
if(turned_on)
|
||||
if(baton_stun(M, user, disarming))
|
||||
user.do_attack_animation(M)
|
||||
user.adjustStaminaLossBuffered(getweight(user, STAM_COST_BATON_MOB_MULT))
|
||||
@@ -292,6 +292,48 @@
|
||||
sparkler?.activate()
|
||||
. = ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang
|
||||
name = "\improper OZtek Boomerang"
|
||||
desc = "A device invented in 2486 for the great Space Emu War by the confederacy of Australicus, these high-tech boomerangs also work exceptionally well at stunning crewmembers. Just be careful to catch it when thrown!"
|
||||
throw_speed = 1
|
||||
icon_state = "boomerang"
|
||||
item_state = "boomerang"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_range = 5
|
||||
hitcost = 2000
|
||||
throw_hit_chance = 99 //Have you prayed today?
|
||||
custom_materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000)
|
||||
|
||||
/obj/item/melee/baton/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
|
||||
if(turned_on)
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.throw_mode_off() //so they can catch it on the return.
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(turned_on)
|
||||
var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum)
|
||||
if(ishuman(hit_atom) && !caught && prob(throw_hit_chance))//if they are a carbon and they didn't catch it
|
||||
baton_stun(hit_atom)
|
||||
if(thrownby && !caught)
|
||||
sleep(1)
|
||||
if(!QDELETED(src))
|
||||
throw_at(thrownby, throw_range+2, throw_speed, null, TRUE)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang/update_icon()
|
||||
if(turned_on)
|
||||
icon_state = "[initial(icon_state)]_active"
|
||||
else if(!cell)
|
||||
icon_state = "[initial(icon_state)]_nocell"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/melee/baton/boomerang/loaded //Same as above, comes with a cell.
|
||||
preload_cell_type = /obj/item/stock_parts/cell/high
|
||||
|
||||
#undef STUNBATON_CHARGE_LENIENCY
|
||||
#undef STUNBATON_DEPLETION_RATE
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
density = TRUE
|
||||
var/state = GIRDER_NORMAL
|
||||
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
|
||||
var/next_beep = 0 //Prevents spamming of the construction sound
|
||||
var/can_displace = TRUE //If the girder can be moved around by wrenching it
|
||||
max_integrity = 200
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
@@ -27,11 +28,17 @@
|
||||
. += "<span class='notice'>[src] is disassembled! You probably shouldn't be able to see this examine message.</span>"
|
||||
|
||||
/obj/structure/girder/attackby(obj/item/W, mob/user, params)
|
||||
var/platingmodifier = 1
|
||||
if(HAS_TRAIT(user, TRAIT_QUICK_BUILD))
|
||||
platingmodifier = 0.7
|
||||
if(next_beep <= world.time)
|
||||
next_beep = world.time + 10
|
||||
playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(istype(W, /obj/item/gun/energy/plasmacutter))
|
||||
to_chat(user, "<span class='notice'>You start slicing apart the girder...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=100))
|
||||
if(W.use_tool(src, user, 40*platingmodifier, volume=100))
|
||||
to_chat(user, "<span class='notice'>You slice apart the girder.</span>")
|
||||
var/obj/item/stack/sheet/metal/M = new (loc, 2)
|
||||
M.add_fingerprint(user)
|
||||
@@ -62,7 +69,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least two rods to create a false wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a reinforced false wall...</span>")
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -75,7 +82,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least five rods to add plating!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding plating...</span>")
|
||||
if(do_after(user, 40, target = src))
|
||||
if(do_after(user, 40*platingmodifier, target = src))
|
||||
if(S.get_amount() < 5)
|
||||
return
|
||||
S.use(5)
|
||||
@@ -96,7 +103,7 @@
|
||||
to_chat(user, "<span class='warning'>You need two sheets of metal to create a false wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a false wall...</span>")
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -109,7 +116,7 @@
|
||||
to_chat(user, "<span class='warning'>You need two sheets of metal to finish a wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding plating...</span>")
|
||||
if (do_after(user, 40, target = src))
|
||||
if (do_after(user, 40*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -126,7 +133,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a reinforced false wall...</span>")
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -139,7 +146,7 @@
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start finalizing the reinforced wall...</span>")
|
||||
if(do_after(user, 50, target = src))
|
||||
if(do_after(user, 50*platingmodifier, target = src))
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
S.use(1)
|
||||
@@ -153,7 +160,7 @@
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start reinforcing the girder...</span>")
|
||||
if(do_after(user, 60, target = src))
|
||||
if(do_after(user, 60*platingmodifier, target = src))
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
S.use(1)
|
||||
@@ -172,7 +179,7 @@
|
||||
if(S.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
|
||||
return
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -188,7 +195,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to add plating!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding plating...</span>")
|
||||
if (do_after(user, 40, target = src))
|
||||
if (do_after(user, 40*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
|
||||
@@ -149,3 +149,30 @@
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
return TRUE
|
||||
|
||||
/obj/structure/lattice/lava
|
||||
name = "heatproof support lattice"
|
||||
desc = "A specialized support beam for building across lava. Watch your step."
|
||||
icon = 'icons/obj/smooth_structures/catwalk.dmi'
|
||||
icon_state = "catwalk"
|
||||
number_of_rods = 1
|
||||
color = "#5286b9ff"
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
/obj/structure/lattice/lava/deconstruction_hints(mob/user)
|
||||
return "<span class='notice'>The rods look like they could be <b>cut</b>, but the <i>heat treatment will shatter off</i>. There's space for a <i>tile</i>.</span>"
|
||||
|
||||
/obj/structure/lattice/lava/attackby(obj/item/C, mob/user, params)
|
||||
. = ..()
|
||||
if(istype(C, /obj/item/stack/tile/plasteel))
|
||||
var/obj/item/stack/tile/plasteel/P = C
|
||||
if(P.use(1))
|
||||
to_chat(user, "<span class='notice'>You construct a floor plating, as lava settles around the rods.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
new /turf/open/floor/plating(locate(x, y, z))
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one floor tile to build atop [src].</span>")
|
||||
return
|
||||
|
||||
@@ -163,6 +163,9 @@
|
||||
if(istype(I, /obj/item/storage/bag/tray))
|
||||
var/obj/item/storage/bag/tray/T = I
|
||||
if(T.contents.len > 0) // If the tray isn't empty
|
||||
for(var/x in T.contents)
|
||||
var/obj/item/item = x
|
||||
AfterPutItemOnTable(item, user)
|
||||
SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location())
|
||||
user.visible_message("[user] empties [I] on [src].")
|
||||
return
|
||||
@@ -177,10 +180,14 @@
|
||||
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
|
||||
I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
return 1
|
||||
AfterPutItemOnTable(I, user)
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/proc/AfterPutItemOnTable(obj/item/I, mob/living/user)
|
||||
return
|
||||
|
||||
/obj/structure/table/alt_attack_hand(mob/user)
|
||||
if(user && Adjacent(user) && !user.incapacitated())
|
||||
user.changeNext_move(CLICK_CD_MELEE*0.5)
|
||||
@@ -214,6 +221,37 @@
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
buildstack = null //No buildstack, so generate from mat datums
|
||||
|
||||
///Table on wheels
|
||||
/obj/structure/table/rolling
|
||||
name = "Rolling table"
|
||||
desc = "A NT brand \"Rolly poly\" rolling table. It can and will move."
|
||||
anchored = FALSE
|
||||
smooth = SMOOTH_FALSE
|
||||
canSmoothWith = list()
|
||||
icon = 'icons/obj/smooth_structures/rollingtable.dmi'
|
||||
icon_state = "rollingtable"
|
||||
var/list/attached_items = list()
|
||||
|
||||
/obj/structure/table/rolling/AfterPutItemOnTable(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
attached_items += I
|
||||
RegisterSignal(I, COMSIG_MOVABLE_MOVED, .proc/RemoveItemFromTable) //Listen for the pickup event, unregister on pick-up so we aren't moved
|
||||
|
||||
/obj/structure/table/rolling/proc/RemoveItemFromTable(datum/source, newloc, dir)
|
||||
if(newloc != loc) //Did we not move with the table? because that shit's ok
|
||||
return FALSE
|
||||
attached_items -= source
|
||||
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/obj/structure/table/rolling/Moved(atom/OldLoc, Dir)
|
||||
for(var/mob/M in OldLoc.contents)//Kidnap everyone on top
|
||||
M.forceMove(loc)
|
||||
for(var/x in attached_items)
|
||||
var/atom/movable/AM = x
|
||||
if(!AM.Move(loc))
|
||||
RemoveItemFromTable(AM, AM.loc)
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Glass tables
|
||||
*/
|
||||
|
||||
@@ -520,7 +520,7 @@
|
||||
if(istype(O, /obj/item/melee/baton))
|
||||
var/obj/item/melee/baton/B = O
|
||||
if(B.cell)
|
||||
if(B.cell.charge > 0 && B.status == 1)
|
||||
if(B.cell.charge > 0 && B.turned_on)
|
||||
flick("baton_active", src)
|
||||
var/stunforce = B.stamforce
|
||||
user.DefaultCombatKnockdown(stunforce * 2)
|
||||
|
||||
@@ -81,10 +81,25 @@
|
||||
|
||||
/turf/open/lava/TakeTemperature(temp)
|
||||
|
||||
/turf/open/lava/attackby(obj/item/C, mob/user, params)
|
||||
..()
|
||||
if(istype(C, /obj/item/stack/rods/lava))
|
||||
var/obj/item/stack/rods/lava/R = C
|
||||
var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src)
|
||||
if(H)
|
||||
to_chat(user, "<span class='warning'>There is already a lattice here!</span>")
|
||||
return
|
||||
if(R.use(1))
|
||||
to_chat(user, "<span class='notice'>You construct a lattice.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
new /obj/structure/lattice/lava(locate(x, y, z))
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one rod to build a heatproof lattice.</span>")
|
||||
return
|
||||
|
||||
/turf/open/lava/proc/is_safe()
|
||||
//if anything matching this typecache is found in the lava, we don't burn things
|
||||
var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
|
||||
var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile, /obj/structure/lattice/lava))
|
||||
var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache)
|
||||
for(var/obj/structure/stone_tile/S in found_safeties)
|
||||
if(S.fallen)
|
||||
|
||||
@@ -13,6 +13,53 @@
|
||||
custom_price = 1200
|
||||
custom_premium_price = 1200
|
||||
|
||||
/obj/item/toy/sprayoncan
|
||||
name = "spray-on insulation applicator"
|
||||
desc = "What is the number one problem facing our station today?"
|
||||
icon = 'icons/obj/clothing/gloves.dmi'
|
||||
icon_state = "sprayoncan"
|
||||
|
||||
/obj/item/toy/sprayoncan/afterattack(atom/target, mob/living/carbon/user, proximity)
|
||||
if(iscarbon(target) && proximity)
|
||||
var/mob/living/carbon/C = target
|
||||
var/mob/living/carbon/U = user
|
||||
var/success = C.equip_to_slot_if_possible(new /obj/item/clothing/gloves/color/yellow/sprayon, ITEM_SLOT_GLOVES, TRUE, TRUE)
|
||||
if(success)
|
||||
if(C == user)
|
||||
C.visible_message("<span class='notice'>[U] sprays their hands with glittery rubber!</span>")
|
||||
else
|
||||
C.visible_message("<span class='warning'>[U] sprays glittery rubber on the hands of [C]!</span>")
|
||||
else
|
||||
C.visible_message("<span class='warning'>The rubber fails to stick to [C]'s hands!</span>")
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/gloves/color/yellow/sprayon
|
||||
desc = "How're you gonna get 'em off, nerd?"
|
||||
name = "spray-on insulated gloves"
|
||||
icon_state = "sprayon"
|
||||
item_state = "sprayon"
|
||||
permeability_coefficient = 0
|
||||
resistance_flags = ACID_PROOF
|
||||
var/shocks_remaining = 10
|
||||
|
||||
/obj/item/clothing/gloves/color/yellow/sprayon/Initialize()
|
||||
.=..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, GLOVE_TRAIT)
|
||||
|
||||
/obj/item/clothing/gloves/color/yellow/sprayon/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
RegisterSignal(user, COMSIG_LIVING_SHOCK_PREVENTED, .proc/Shocked)
|
||||
|
||||
/obj/item/clothing/gloves/color/yellow/sprayon/proc/Shocked()
|
||||
shocks_remaining--
|
||||
if(shocks_remaining < 0)
|
||||
qdel(src) //if we run out of uses, the gloves crumble away into nothing, just like my dreams after working with .dm
|
||||
|
||||
/obj/item/clothing/gloves/color/yellow/sprayon/dropped()
|
||||
.=..()
|
||||
qdel(src) //loose nodrop items bad
|
||||
|
||||
/obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap
|
||||
desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly."
|
||||
name = "budget insulated gloves"
|
||||
@@ -202,6 +249,17 @@
|
||||
permeability_coefficient = 0.3
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/engineering
|
||||
name = "tinker's gloves"
|
||||
desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn."
|
||||
icon = 'icons/obj/clothing/clockwork_garb.dmi'
|
||||
icon_state = "clockwork_gauntlets"
|
||||
item_state = "clockwork_gauntlets"
|
||||
siemens_coefficient = 0.8
|
||||
permeability_coefficient = 0.3
|
||||
carrytrait = TRAIT_QUICK_BUILD
|
||||
custom_materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000)
|
||||
|
||||
/obj/item/clothing/gloves/color/white
|
||||
name = "white gloves"
|
||||
desc = "These look pretty fancy."
|
||||
|
||||
@@ -60,6 +60,16 @@
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
|
||||
/obj/item/clothing/head/hardhat/red/upgraded
|
||||
name = "workplace-ready firefighter helmet"
|
||||
desc = "By applying state of the art lighting technology to a fire helmet, and using photo-chemical hardening methods, this hardhat will protect you from robust workplace hazards."
|
||||
icon_state = "hardhat0_purple"
|
||||
item_state = "hardhat0_purple"
|
||||
brightness_on = 5
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
custom_materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/plastic = 3000, /datum/material/silver = 500)
|
||||
hat_type = "purple"
|
||||
|
||||
/obj/item/clothing/head/hardhat/white
|
||||
icon_state = "hardhat0_white"
|
||||
item_state = "hardhat0_white"
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
/datum/reagent/pax,
|
||||
/datum/reagent/consumable/laughter,
|
||||
/datum/reagent/concentrated_barbers_aid,
|
||||
/datum/reagent/baldium,
|
||||
/datum/reagent/colorful_reagent,
|
||||
/datum/reagent/peaceborg_confuse,
|
||||
/datum/reagent/peaceborg_tire,
|
||||
|
||||
@@ -137,11 +137,11 @@
|
||||
if(cached_Bdamage <= HEALTH_THRESHOLD_DEAD) //Fixing dead brains yeilds a trauma
|
||||
if((cached_Bdamage <= HEALTH_THRESHOLD_DEAD) && (brainmob.health > HEALTH_THRESHOLD_DEAD))
|
||||
if(prob(80))
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD, natural_gain = TRUE)
|
||||
else if(prob(50))
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE, natural_gain = TRUE)
|
||||
else
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL, natural_gain = TRUE)
|
||||
return
|
||||
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/mannitol)) //attempt to heal the brain
|
||||
@@ -253,16 +253,16 @@
|
||||
damage_delta = damage - prev_damage
|
||||
if(damage > BRAIN_DAMAGE_MILD)
|
||||
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD, natural_gain = TRUE)
|
||||
if(prev_damage <= BRAIN_DAMAGE_MILD && owner)
|
||||
var/datum/skill_modifier/S
|
||||
ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, owner, S)
|
||||
if(damage > BRAIN_DAMAGE_SEVERE)
|
||||
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1%
|
||||
if(prob(20))
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL, natural_gain = TRUE)
|
||||
else
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE, natural_gain = TRUE)
|
||||
if(prev_damage <= BRAIN_DAMAGE_SEVERE && owner)
|
||||
var/datum/skill_modifier/S
|
||||
ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, owner, S)
|
||||
@@ -308,7 +308,7 @@
|
||||
if(istype(BT, brain_trauma_type) && (BT.resilience <= resilience))
|
||||
. += BT
|
||||
|
||||
/obj/item/organ/brain/proc/can_gain_trauma(datum/brain_trauma/trauma, resilience)
|
||||
/obj/item/organ/brain/proc/can_gain_trauma(datum/brain_trauma/trauma, resilience, natural_gain = FALSE)
|
||||
if(!ispath(trauma))
|
||||
trauma = trauma.type
|
||||
if(!initial(trauma.can_gain))
|
||||
@@ -341,7 +341,7 @@
|
||||
if(TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
max_traumas = TRAUMA_LIMIT_ABSOLUTE
|
||||
|
||||
if(resilience_tier_count >= max_traumas)
|
||||
if(natural_gain && resilience_tier_count >= max_traumas)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -381,11 +381,11 @@
|
||||
return actual_trauma
|
||||
|
||||
//Add a random trauma of a certain subtype
|
||||
/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience)
|
||||
/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience, natural_gain = FALSE)
|
||||
var/list/datum/brain_trauma/possible_traumas = list()
|
||||
for(var/T in subtypesof(brain_trauma_type))
|
||||
var/datum/brain_trauma/BT = T
|
||||
if(can_gain_trauma(BT, resilience) && initial(BT.random_gain))
|
||||
if(can_gain_trauma(BT, resilience, natural_gain) && initial(BT.random_gain))
|
||||
possible_traumas += BT
|
||||
|
||||
if(!LAZYLEN(possible_traumas))
|
||||
|
||||
@@ -500,3 +500,33 @@
|
||||
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>The udder is dry. Wait a bit longer...</span>")
|
||||
|
||||
/mob/living/simple_animal/deer
|
||||
name = "doe"
|
||||
desc = "A gentle, peaceful forest animal. How did this get into space?"
|
||||
icon_state = "deer-doe"
|
||||
icon_living = "deer-doe"
|
||||
icon_dead = "deer-doe-dead"
|
||||
gender = FEMALE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
speak = list("Weeeeeeee?","Weeee","WEOOOOOOOOOO")
|
||||
speak_emote = list("grunts","grunts lowly")
|
||||
emote_hear = list("brays.")
|
||||
emote_see = list("shakes its head.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "gently nudges"
|
||||
response_disarm_simple = "gently nudge"
|
||||
response_harm_continuous = "kicks"
|
||||
response_harm_simple = "kick"
|
||||
attack_verb_continuous = "bucks"
|
||||
attack_verb_simple = "buck"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
health = 75
|
||||
maxHealth = 75
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
@@ -84,8 +84,33 @@
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing
|
||||
loot = list()
|
||||
butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
|
||||
search_objects = 1
|
||||
wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond)
|
||||
field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball.
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/Life()
|
||||
. = ..()
|
||||
if(stat == CONSCIOUS)
|
||||
consume_bait()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait()
|
||||
var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in oview(src, 9)
|
||||
var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in oview(src, 9)
|
||||
if(!diamonds && !bait)
|
||||
return
|
||||
if(diamonds)
|
||||
var/distanced = 0
|
||||
distanced = get_dist(loc,diamonds.loc)
|
||||
if(distanced <= 1 && diamonds)
|
||||
qdel(diamonds)
|
||||
src.visible_message("<span class='notice'>[src] consumes [diamonds], and it disappears! ...At least, you think.</span>")
|
||||
if(bait)
|
||||
var/distanceb = 0
|
||||
distanceb = get_dist(loc,bait.loc)
|
||||
if(distanceb <= 1 && bait)
|
||||
qdel(bait)
|
||||
visible_message("<span class='notice'>[src] examines [bait] closer, and telekinetically shatters the pen.</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize()
|
||||
. = ..()
|
||||
if(prob(1))
|
||||
|
||||
@@ -220,3 +220,17 @@
|
||||
item_state = initial(item_state)
|
||||
lefthand_file = initial(lefthand_file)
|
||||
righthand_file = initial(righthand_file)
|
||||
|
||||
/obj/item/pen/survival
|
||||
name = "survival pen"
|
||||
desc = "The latest in portable survival technology, this pen was designed as a miniature diamond pickaxe. Watchers find them very desirable for their diamond exterior."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "digging_pen"
|
||||
item_state = "pen"
|
||||
force = 3
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10)
|
||||
pressure_resistance = 2
|
||||
grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1)
|
||||
tool_behaviour = TOOL_MINING //For the classic "digging out of prison with a spoon but you're in space so this analogy doesn't work" situation.
|
||||
toolspeed = 10 //You will never willingly choose to use one of these over a shovel.
|
||||
|
||||
@@ -337,3 +337,15 @@
|
||||
grind_results = list(/datum/reagent/iodine = 40, /datum/reagent/iron = 10)
|
||||
var/charges = 5
|
||||
var/max_charges = 5
|
||||
|
||||
/obj/item/toner/large
|
||||
name = "large toner cartridge"
|
||||
grind_results = list(/datum/reagent/iodine = 90, /datum/reagent/iron = 10)
|
||||
charges = 15
|
||||
max_charges = 15
|
||||
|
||||
/obj/item/toner/extreme
|
||||
name = "extremely large toner cartridge"
|
||||
desc = "Why would ANYONE need THIS MUCH TONER?"
|
||||
charges = 200
|
||||
max_charges = 200
|
||||
|
||||
@@ -227,6 +227,7 @@
|
||||
icon_state = "h+cell"
|
||||
maxcharge = 15000
|
||||
chargerate = 2250
|
||||
rating = 2
|
||||
|
||||
/obj/item/stock_parts/cell/high/empty
|
||||
start_charged = FALSE
|
||||
@@ -237,6 +238,7 @@
|
||||
maxcharge = 20000
|
||||
custom_materials = list(/datum/material/glass=300)
|
||||
chargerate = 2000
|
||||
rating = 3
|
||||
|
||||
/obj/item/stock_parts/cell/super/empty
|
||||
start_charged = FALSE
|
||||
@@ -247,6 +249,7 @@
|
||||
maxcharge = 30000
|
||||
custom_materials = list(/datum/material/glass=400)
|
||||
chargerate = 3000
|
||||
rating = 4
|
||||
|
||||
/obj/item/stock_parts/cell/hyper/empty
|
||||
start_charged = FALSE
|
||||
@@ -258,6 +261,7 @@
|
||||
maxcharge = 40000
|
||||
custom_materials = list(/datum/material/glass=600)
|
||||
chargerate = 4000
|
||||
rating = 5
|
||||
|
||||
/obj/item/stock_parts/cell/bluespace/empty
|
||||
start_charged = FALSE
|
||||
|
||||
@@ -310,6 +310,7 @@
|
||||
if(H.gloves)
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
if(G.siemens_coefficient == 0)
|
||||
SEND_SIGNAL(M, COMSIG_LIVING_SHOCK_PREVENTED, power_source, source, siemens_coeff, dist_check)
|
||||
return 0 //to avoid spamming with insulated glvoes on
|
||||
|
||||
var/area/source_area
|
||||
|
||||
@@ -13,11 +13,16 @@
|
||||
var/pin_removeable = 0 // Can be replaced by any pin.
|
||||
var/obj/item/gun/gun
|
||||
|
||||
/obj/item/firing_pin/New(newloc)
|
||||
..()
|
||||
/obj/item/firing_pin/Initialize(newloc)
|
||||
. = ..()
|
||||
if(istype(newloc, /obj/item/gun))
|
||||
gun = newloc
|
||||
|
||||
/obj/item/firing_pin/Destroy()
|
||||
if(gun)
|
||||
gun.pin = null
|
||||
return ..()
|
||||
|
||||
/obj/item/firing_pin/afterattack(atom/target, mob/user, proximity_flag)
|
||||
. = ..()
|
||||
if(proximity_flag)
|
||||
@@ -224,24 +229,6 @@
|
||||
suit_requirement = /obj/item/clothing/suit/bluetag
|
||||
tagcolor = "blue"
|
||||
|
||||
/obj/item/firing_pin/Destroy()
|
||||
if(gun)
|
||||
gun.pin = null
|
||||
return ..()
|
||||
|
||||
//Station Locked
|
||||
|
||||
/obj/item/firing_pin/away
|
||||
name = "station locked pin"
|
||||
desc = "A firing pin that only will fire when off the station."
|
||||
|
||||
/obj/item/firing_pin/away/pin_auth(mob/living/user)
|
||||
var/area/station_area = get_area(src)
|
||||
if(!station_area || is_station_level(station_area.z))
|
||||
to_chat(user, "<span class='warning'>The pin beeps, refusing to fire.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/firing_pin/security_level
|
||||
name = "security level firing pin"
|
||||
desc = "A sophisticated firing pin that authorizes operation based on its settings and current security level."
|
||||
@@ -325,3 +312,18 @@
|
||||
|
||||
/obj/item/firing_pin/security_level/pin_auth(mob/living/user)
|
||||
return (only_lethals && !(gun.chambered?.harmful)) || ISINRANGE(GLOB.security_level, min_sec_level, max_sec_level)
|
||||
|
||||
// Explorer Firing Pin- Prevents use on station Z-Level, so it's justifiable to give Explorers guns that don't suck.
|
||||
/obj/item/firing_pin/explorer
|
||||
name = "outback firing pin"
|
||||
desc = "A firing pin used by the austrailian defense force, retrofit to prevent weapon discharge on the station."
|
||||
icon_state = "firing_pin_explorer"
|
||||
fail_message = "<span class='warning'>CANNOT FIRE WHILE ON STATION, MATE!</span>"
|
||||
|
||||
// This checks that the user isn't on the station Z-level.
|
||||
/obj/item/firing_pin/explorer/pin_auth(mob/living/user)
|
||||
var/turf/station_check = get_turf(user)
|
||||
if(!station_check||is_station_level(station_check.z))
|
||||
to_chat(user, "<span class='warning'>You cannot use your weapon while on the station!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -1735,6 +1735,22 @@
|
||||
H.facial_hair_style = "Very Long Beard"
|
||||
H.update_hair()
|
||||
|
||||
/datum/reagent/baldium
|
||||
name = "Baldium"
|
||||
description = "A major cause of hair loss across the world."
|
||||
reagent_state = LIQUID
|
||||
color = "#ecb2cf"
|
||||
taste_description = "bitterness"
|
||||
|
||||
/datum/reagent/baldium/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
if(method == TOUCH || method == VAPOR)
|
||||
if(M && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
to_chat(H, "<span class='danger'>Your hair is falling out in clumps!</span>")
|
||||
H.hair_style = "Bald"
|
||||
H.facial_hair_style = "Shaved"
|
||||
H.update_hair()
|
||||
|
||||
/datum/reagent/saltpetre
|
||||
name = "Saltpetre"
|
||||
description = "Volatile. Controversial. Third Thing."
|
||||
|
||||
@@ -1019,3 +1019,20 @@
|
||||
to_chat(M, "<span class='notice'>[tox_message]</span>")
|
||||
. = 1
|
||||
..()
|
||||
|
||||
/datum/reagent/toxin/leadacetate
|
||||
name = "Lead Acetate"
|
||||
description = "Used hundreds of years ago as a sweetener, before it was realized that it's incredibly poisonous."
|
||||
reagent_state = SOLID
|
||||
color = "#2b2b2b" // rgb: 127, 132, 0
|
||||
toxpwr = 0.5
|
||||
taste_mult = 1.3
|
||||
taste_description = "sugary sweetness"
|
||||
|
||||
/datum/reagent/toxin/leadacetate/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_EARS,1)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN,1)
|
||||
if(prob(1))
|
||||
to_chat(M, "<span class='notice'>Ah, what was that? You thought you heard something...</span>")
|
||||
M.confused += 5
|
||||
return ..()
|
||||
|
||||
@@ -631,6 +631,11 @@
|
||||
results = list(/datum/reagent/concentrated_barbers_aid = 2)
|
||||
required_reagents = list(/datum/reagent/barbers_aid = 1, /datum/reagent/toxin/mutagen = 1)
|
||||
|
||||
/datum/chemical_reaction/baldium
|
||||
results = list(/datum/reagent/baldium = 1)
|
||||
required_reagents = list(/datum/reagent/radium = 1, /datum/reagent/toxin/acid = 1, /datum/reagent/lye = 1)
|
||||
required_temp = 395
|
||||
|
||||
/datum/chemical_reaction/saltpetre
|
||||
name = "saltpetre"
|
||||
id = /datum/reagent/saltpetre
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/obj/item/reagent_containers/glass/maunamug
|
||||
name = "mauna mug"
|
||||
desc = "A drink served in a classy mug. Now with built-in heating!"
|
||||
icon = 'icons/obj/mauna_mug.dmi'
|
||||
icon_state = "maunamug"
|
||||
spillable = TRUE
|
||||
reagent_flags = OPENCONTAINER
|
||||
// fill_icon_state = "maunafilling"
|
||||
// fill_icon_thresholds = list(25)
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/open = FALSE
|
||||
var/on = FALSE
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/Initialize(mapload, vol)
|
||||
. = ..()
|
||||
cell = new /obj/item/stock_parts/cell(src)
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>The status display reads: Current temperature: <b>[reagents.chem_temp]K</b> Current Charge:[cell ? "[cell.charge / cell.maxcharge * 100]%" : "No cell found"].</span>"
|
||||
if(open)
|
||||
. += "<span class='notice'>The battery case is open.</span>"
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/update_overlays()
|
||||
. = ..()
|
||||
if(reagents.total_volume >= 25)
|
||||
. += mutable_appearance('icons/obj/reagentfillings.dmi', "maunafilling25", color = mix_color_from_reagents(reagents.reagent_list))
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/process()
|
||||
..()
|
||||
if(on && (!cell || cell.charge <= 0)) //Check if we ran out of power
|
||||
change_power_status(FALSE)
|
||||
return FALSE
|
||||
cell.use(10) //Basic cell goes for like 200 seconds, bluespace for 8000
|
||||
if(!reagents.total_volume)
|
||||
return FALSE
|
||||
var/max_temp = min(500 + (500 * (0.2 * cell.rating)), 1000) // 373 to 1000
|
||||
reagents.adjust_thermal_energy(0.8 * cell.maxcharge * reagents.total_volume, max_temp = max_temp) // 4 kelvin every tick on a basic cell. 160k on bluespace
|
||||
reagents.handle_reactions()
|
||||
update_icon()
|
||||
if(reagents.chem_temp >= max_temp)
|
||||
change_power_status(FALSE)
|
||||
audible_message("<span class='notice'>The Mauna Mug lets out a happy beep and turns off!</span>")
|
||||
playsound(src, 'sound/machines/chime.ogg', 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/Destroy()
|
||||
if(cell)
|
||||
QDEL_NULL(cell)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/attack_self(mob/user)
|
||||
if(on)
|
||||
change_power_status(FALSE)
|
||||
else
|
||||
if(!cell || cell.charge <= 0)
|
||||
return FALSE //No power, so don't turn on
|
||||
change_power_status(TRUE)
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/proc/change_power_status(status)
|
||||
on = status
|
||||
if(on)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/screwdriver_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
open = !open
|
||||
to_chat(user, "<span class='notice'>You screw the battery case on [src] [open ? "open" : "closed"] .</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/attackby(obj/item/I, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if(!istype(I, /obj/item/stock_parts/cell))
|
||||
return ..()
|
||||
if(!open)
|
||||
to_chat(user, "<span class='warning'>The battery case must be open to insert a power cell!</span>")
|
||||
return FALSE
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>There is already a power cell inside!</span>")
|
||||
return FALSE
|
||||
else if(!user.transferItemToLoc(I, src))
|
||||
return
|
||||
cell = I
|
||||
user.visible_message("<span class='notice'>[user] inserts a power cell into [src].</span>", "<span class='notice'>You insert the power cell into [src].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/attack_hand(mob/living/user)
|
||||
if(cell && open)
|
||||
cell.update_icon()
|
||||
user.put_in_hands(cell)
|
||||
cell = null
|
||||
to_chat(user, "<span class='notice'>You remove the power cell from [src].</span>")
|
||||
on = FALSE
|
||||
update_icon()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/glass/maunamug/update_icon()
|
||||
..()
|
||||
if(open)
|
||||
if(cell)
|
||||
icon_state = "maunamug_bat"
|
||||
else
|
||||
icon_state = "maunamug_no_bat"
|
||||
else if(on)
|
||||
icon_state = "maunamug_on"
|
||||
else
|
||||
icon_state = "maunamug"
|
||||
if(reagents.total_volume && reagents.chem_temp >= 400)
|
||||
var/intensity = (reagents.chem_temp - 400) * 1 / 600 //Get the opacity of the incandescent overlay. Ranging from 400 to 1000
|
||||
var/mutable_appearance/mug_glow = mutable_appearance(icon, "maunamug_incand")
|
||||
mug_glow.alpha = 255 * intensity
|
||||
add_overlay(mug_glow)
|
||||
@@ -0,0 +1,270 @@
|
||||
//This system is designed to act as an in-between for cargo and science, and the first major money sink in the game outside of just buying things from cargo (As of 10/9/19, anyway).
|
||||
|
||||
//economics defined values, subject to change should anything be too high or low in practice.
|
||||
|
||||
#define MACHINE_OPERATION 100000
|
||||
#define MACHINE_OVERLOAD 500000
|
||||
#define MAJOR_THRESHOLD 5500
|
||||
#define MINOR_THRESHOLD 3500
|
||||
#define STANDARD_DEVIATION 1000
|
||||
|
||||
/obj/machinery/rnd/bepis
|
||||
name = "\improper B.E.P.I.S. Chamber"
|
||||
desc = "A high fidelity testing device which unlocks the secrets of the known universe using the two most powerful substances available to man: excessive amounts of electricity and capital."
|
||||
icon = 'icons/obj/machines/bepis.dmi'
|
||||
icon_state = "chamber"
|
||||
density = TRUE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
use_power = IDLE_POWER_USE
|
||||
active_power_usage = 1500
|
||||
circuit = /obj/item/circuitboard/machine/bepis
|
||||
|
||||
var/banking_amount = 100
|
||||
var/banked_cash = 0 //stored player cash
|
||||
var/datum/bank_account/account //payer's account.
|
||||
var/account_name //name of the payer's account.
|
||||
var/error_cause = null
|
||||
//Vars related to probability and chance of success for testing
|
||||
var/major_threshold = MAJOR_THRESHOLD
|
||||
var/minor_threshold = MINOR_THRESHOLD
|
||||
var/std = STANDARD_DEVIATION //That's Standard Deviation, what did you think it was?
|
||||
//Stock part variables
|
||||
var/power_saver = 1
|
||||
var/inaccuracy_percentage = 1.5
|
||||
var/positive_cash_offset = 0
|
||||
var/negative_cash_offset = 0
|
||||
var/minor_rewards = list(/obj/item/stack/circuit_stack/full, //To add a new minor reward, add it here.
|
||||
/obj/item/airlock_painter/decal,
|
||||
/obj/item/pen/survival,
|
||||
/obj/item/circuitboard/machine/sleeper/party,
|
||||
/obj/item/toy/sprayoncan)
|
||||
var/static/list/item_list = list()
|
||||
|
||||
/obj/machinery/rnd/bepis/attackby(obj/item/O, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "chamber_open", "chamber", O))
|
||||
update_icon_state()
|
||||
return
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
if(!is_operational())
|
||||
to_chat(user, "<span class='notice'>[src] can't accept money when it's not functioning.</span>")
|
||||
return
|
||||
if(istype(O, /obj/item/holochip) || istype(O, /obj/item/stack/spacecash))
|
||||
var/deposit_value = O.get_item_credit_value()
|
||||
banked_cash += deposit_value
|
||||
qdel(O)
|
||||
say("Deposited [deposit_value] credits into storage.")
|
||||
update_icon_state()
|
||||
return
|
||||
if(istype(O, /obj/item/card/id))
|
||||
var/obj/item/card/id/Card = O
|
||||
if(Card.registered_account)
|
||||
account = Card.registered_account
|
||||
account_name = Card.registered_name
|
||||
say("New account detected. Console Updated.")
|
||||
else
|
||||
say("No account detected on card. Aborting.")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/rnd/bepis/RefreshParts()
|
||||
var/C = 0
|
||||
var/M = 0
|
||||
var/L = 0
|
||||
var/S = 0
|
||||
for(var/obj/item/stock_parts/capacitor/Cap in component_parts)
|
||||
C += ((Cap.rating - 1) * 0.1)
|
||||
power_saver = 1 - C
|
||||
for(var/obj/item/stock_parts/manipulator/Manip in component_parts)
|
||||
M += ((Manip.rating - 1) * 250)
|
||||
positive_cash_offset = M
|
||||
for(var/obj/item/stock_parts/micro_laser/Laser in component_parts)
|
||||
L += ((Laser.rating - 1) * 250)
|
||||
negative_cash_offset = L
|
||||
for(var/obj/item/stock_parts/scanning_module/Scan in component_parts)
|
||||
S += ((Scan.rating - 1) * 0.25)
|
||||
inaccuracy_percentage = (1.5 - S)
|
||||
|
||||
/obj/machinery/rnd/bepis/proc/depositcash()
|
||||
var/deposit_value = 0
|
||||
deposit_value = banking_amount
|
||||
if(deposit_value == 0)
|
||||
update_icon_state()
|
||||
say("Attempting to deposit 0 credits. Aborting.")
|
||||
return
|
||||
deposit_value = clamp(round(deposit_value, 1), 1, 15000)
|
||||
if(!account)
|
||||
say("Cannot find user account. Please swipe a valid ID.")
|
||||
return
|
||||
if(!account.has_money(deposit_value))
|
||||
say("You do not possess enough credits.")
|
||||
return
|
||||
account.adjust_money(-deposit_value) //The money vanishes, not paid to any accounts.
|
||||
SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value)
|
||||
banked_cash += deposit_value
|
||||
use_power(1000 * power_saver)
|
||||
say("Cash deposit successful. There is [banked_cash] in the chamber.")
|
||||
update_icon_state()
|
||||
return
|
||||
|
||||
/obj/machinery/rnd/bepis/proc/withdrawcash()
|
||||
var/withdraw_value = 0
|
||||
withdraw_value = banking_amount
|
||||
if(withdraw_value > banked_cash)
|
||||
say("Cannot withdraw more than stored funds. Aborting.")
|
||||
else
|
||||
banked_cash -= withdraw_value
|
||||
new /obj/item/holochip(src.loc, withdraw_value)
|
||||
say("Withdrawing [withdraw_value] credits from the chamber.")
|
||||
update_icon_state()
|
||||
return
|
||||
|
||||
/obj/machinery/rnd/bepis/proc/calcsuccess()
|
||||
var/turf/dropturf = null
|
||||
var/gauss_major = 0
|
||||
var/gauss_minor = 0
|
||||
var/gauss_real = 0
|
||||
var/list/turfs = block(locate(x-1,y-1,z),locate(x+1,y+1,z)) //NO MORE DISCS IN WINDOWS
|
||||
while(length(turfs))
|
||||
var/turf/T = pick_n_take(turfs)
|
||||
if(is_blocked_turf(T, exclude_mobs=TRUE))
|
||||
continue
|
||||
else
|
||||
dropturf = T
|
||||
break
|
||||
if (!dropturf)
|
||||
dropturf = drop_location()
|
||||
gauss_major = (gaussian(major_threshold, std) - negative_cash_offset) //This is the randomized profit value that this experiment has to surpass to unlock a tech.
|
||||
gauss_minor = (gaussian(minor_threshold, std) - negative_cash_offset) //And this is the threshold to instead get a minor prize.
|
||||
gauss_real = (gaussian(banked_cash, std*inaccuracy_percentage) + positive_cash_offset) //this is the randomized profit value that your experiment expects to give.
|
||||
say("Real: [gauss_real]. Minor: [gauss_minor]. Major: [gauss_major].")
|
||||
flick("chamber_flash",src)
|
||||
update_icon_state()
|
||||
banked_cash = 0
|
||||
if((gauss_real >= gauss_major) && (SSresearch.techweb_nodes_experimental.len > 0)) //Major Success.
|
||||
say("Experiment concluded with major success. New technology node discovered on technology disc.")
|
||||
new /obj/item/disk/tech_disk/major(dropturf,1)
|
||||
if(SSresearch.techweb_nodes_experimental.len == 0)
|
||||
say("Expended all available experimental technology nodes. Resorting to minor rewards.")
|
||||
return
|
||||
if(gauss_real >= gauss_minor) //Minor Success.
|
||||
var/reward = pick(minor_rewards)
|
||||
new reward(dropturf)
|
||||
say("Experiment concluded with partial success. Dispensing compiled research efforts.")
|
||||
return
|
||||
if(gauss_real <= -1) //Critical Failure
|
||||
say("ERROR: CRITICAL MACHIME MALFUNCTI- ON. CURRENCY IS NOT CRASH. CANNOT COMPUTE COMMAND: 'make bucks'") //not a typo, for once.
|
||||
new /mob/living/simple_animal/deer(dropturf, 1)
|
||||
use_power(MACHINE_OVERLOAD * power_saver) //To prevent gambling at low cost and also prevent spamming for infinite deer.
|
||||
return
|
||||
//Minor Failure
|
||||
error_cause = pick("attempted to sell grey products to American dominated market.","attempted to sell gray products to British dominated market.","placed wild assumption that PDAs would go out of style.","simulated product #76 damaged brand reputation mortally.","simulated business model resembled 'pyramid scheme' by 98.7%.","product accidently granted override access to all station doors.")
|
||||
say("Experiment concluded with zero product viability. Cause of error: [error_cause]")
|
||||
return
|
||||
|
||||
/obj/machinery/rnd/bepis/update_icon_state()
|
||||
if(panel_open == TRUE)
|
||||
icon_state = "chamber_open"
|
||||
return
|
||||
if((use_power == ACTIVE_POWER_USE) && (banked_cash > 0) && (is_operational()))
|
||||
icon_state = "chamber_active_loaded"
|
||||
return
|
||||
if (((use_power == IDLE_POWER_USE) && (banked_cash > 0)) || (banked_cash > 0) && (!is_operational()))
|
||||
icon_state = "chamber_loaded"
|
||||
return
|
||||
if(use_power == ACTIVE_POWER_USE && is_operational())
|
||||
icon_state = "chamber_active"
|
||||
return
|
||||
if(((use_power == IDLE_POWER_USE) && (banked_cash == 0)) || (!is_operational()))
|
||||
icon_state = "chamber"
|
||||
return
|
||||
|
||||
/obj/machinery/rnd/bepis/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "bepis", name, 500, 480, master_ui, state)
|
||||
ui.open()
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/rnd/bepis/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/powered = FALSE
|
||||
var/zvalue = (banked_cash - (major_threshold - positive_cash_offset - negative_cash_offset))/(std)
|
||||
var/std_success = 0
|
||||
var/prob_success = 0
|
||||
//Admittedly this is messy, but not nearly as messy as the alternative, which is jury-rigging an entire Z-table into the code, or making an adaptive z-table.
|
||||
var/z = abs(zvalue)
|
||||
if(z > 0 && z <= 0.5)
|
||||
std_success = 19.1
|
||||
else if(z > 0.5 && z <= 1.0)
|
||||
std_success = 34.1
|
||||
else if(z > 1.0 && z <= 1.5)
|
||||
std_success = 43.3
|
||||
else if(z > 1.5 && z <= 2.0)
|
||||
std_success = 47.7
|
||||
else if(z > 2.0 && z <= 2.5)
|
||||
std_success = 49.4
|
||||
else
|
||||
std_success = 50
|
||||
if(zvalue > 0)
|
||||
prob_success = 50 + std_success
|
||||
else if(zvalue == 0)
|
||||
prob_success = 50
|
||||
else
|
||||
prob_success = 50 - std_success
|
||||
|
||||
if(use_power == ACTIVE_POWER_USE)
|
||||
powered = TRUE
|
||||
data["account_owner"] = account_name
|
||||
data["amount"] = banking_amount
|
||||
data["stored_cash"] = banked_cash
|
||||
data["mean_value"] = (major_threshold - positive_cash_offset - negative_cash_offset)
|
||||
data["error_name"] = error_cause
|
||||
data["power_saver"] = power_saver
|
||||
data["accuracy_percentage"] = inaccuracy_percentage * 100
|
||||
data["positive_cash_offset"] = positive_cash_offset
|
||||
data["negative_cash_offset"] = negative_cash_offset
|
||||
data["manual_power"] = powered ? FALSE : TRUE
|
||||
data["silicon_check"] = issilicon(user)
|
||||
data["success_estimate"] = prob_success
|
||||
return data
|
||||
|
||||
/obj/machinery/rnd/bepis/ui_act(action,params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("deposit_cash")
|
||||
if(use_power == IDLE_POWER_USE)
|
||||
return
|
||||
depositcash()
|
||||
if("withdraw_cash")
|
||||
if(use_power == IDLE_POWER_USE)
|
||||
return
|
||||
withdrawcash()
|
||||
if("begin_experiment")
|
||||
if(use_power == IDLE_POWER_USE)
|
||||
return
|
||||
if(banked_cash == 0)
|
||||
say("Please deposit funds to begin testing.")
|
||||
return
|
||||
calcsuccess()
|
||||
use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful.
|
||||
use_power = IDLE_POWER_USE //Machine shuts off after use to prevent spam and look better visually.
|
||||
update_icon_state()
|
||||
if("amount")
|
||||
var/input = text2num(params["amount"])
|
||||
if(input)
|
||||
banking_amount = input
|
||||
if("toggle_power")
|
||||
if(use_power == ACTIVE_POWER_USE)
|
||||
use_power = IDLE_POWER_USE
|
||||
else
|
||||
use_power = ACTIVE_POWER_USE
|
||||
update_icon_state()
|
||||
if("account_reset")
|
||||
if(use_power == IDLE_POWER_USE)
|
||||
return
|
||||
account_name = ""
|
||||
account = null
|
||||
say("Account settings reset.")
|
||||
. = TRUE
|
||||
@@ -122,3 +122,11 @@
|
||||
build_path = /obj/item/circuitboard/machine/autolathe/toy
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
category = list("Misc. Machinery")
|
||||
|
||||
/datum/design/board/hypnochair
|
||||
name = "Machine Design (Enhanced Interrogation Chamber)"
|
||||
desc = "Allows for the construction of circuit boards used to build an Enhanced Interrogation Chamber."
|
||||
id = "hypnochair"
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
build_path = /obj/item/circuitboard/machine/hypnochair
|
||||
category = list("Misc. Machinery")
|
||||
|
||||
@@ -66,6 +66,14 @@
|
||||
category = list("Research Machinery")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/board/bepis
|
||||
name = "Machine Design (B.E.P.I.S. Board)"
|
||||
desc = "The circuit board for a B.E.P.I.S."
|
||||
id = "bepis"
|
||||
build_path = /obj/item/circuitboard/machine/bepis
|
||||
category = list("Research Machinery")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/board/protolathe
|
||||
name = "Machine Design (Protolathe Board)"
|
||||
desc = "The circuit board for a protolathe."
|
||||
|
||||
@@ -206,6 +206,35 @@
|
||||
category = list("Equipment")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/datum/design/bright_helmet
|
||||
name = "Workplace-Ready Firefighter Helmet"
|
||||
desc = "By applying state of the art lighting technology to a fire helmet with industry standard photo-chemical hardening methods, this hardhat will protect you from robust workplace hazards."
|
||||
id = "bright_helmet"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/plastic = 3000, /datum/material/silver = 500)
|
||||
build_path = /obj/item/clothing/head/hardhat/red/upgraded
|
||||
category = list("Equipment")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
/datum/design/mauna_mug
|
||||
name = "Mauna Mug"
|
||||
desc = "This awesome mug will ensure your coffee never stays cold!"
|
||||
id = "mauna_mug"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 1000, /datum/material/glass = 100)
|
||||
build_path = /obj/item/reagent_containers/glass/maunamug
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/rolling_table
|
||||
name = "Rolly poly"
|
||||
desc = "We duct-taped some wheels to the bottom of a table. It's goddamn science alright?"
|
||||
id = "rolling_table"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 4000)
|
||||
build_path = /obj/structure/table/rolling
|
||||
category = list("Equipment")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/portaseeder
|
||||
name = "Portable Seed Extractor"
|
||||
desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant."
|
||||
@@ -285,6 +314,25 @@
|
||||
build_path = /obj/item/vending_refill/donksoft
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/eng_gloves
|
||||
name = "Tinkers Gloves"
|
||||
desc = "Overdesigned engineering gloves that have automated construction subroutines dialed in, allowing for faster construction while worn."
|
||||
id = "eng_gloves"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000)
|
||||
build_path = /obj/item/clothing/gloves/color/latex/engineering
|
||||
category = list("Equipment")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/datum/design/lavarods
|
||||
name = "Lava-Resistant Metal Rods"
|
||||
id = "lava_rods"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000)
|
||||
build_path = /obj/item/stack/rods/lava
|
||||
category = list("initial", "Stock Parts")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/////////////////////////////////////////
|
||||
////////////Janitor Designs//////////////
|
||||
/////////////////////////////////////////
|
||||
|
||||
@@ -72,6 +72,16 @@
|
||||
category = list("Tool Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/datum/design/rld_mini
|
||||
name = "Mini Rapid Light Device (MRLD)"
|
||||
desc = "A tool that can portable and standing lighting orbs and glowsticks."
|
||||
id = "rld_mini"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 20000, /datum/material/glass = 10000, /datum/material/plastic = 8000, /datum/material/gold = 2000)
|
||||
build_path = /obj/item/construction/rld/mini
|
||||
category = list("Tool Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
/////////////////////////////////////////
|
||||
//////////////Alien Tools////////////////
|
||||
/////////////////////////////////////////
|
||||
|
||||
@@ -234,13 +234,13 @@
|
||||
category = list("Firing Pins")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
/datum/design/pin_away
|
||||
name = "Station Locked Pin"
|
||||
desc = "This is a security firing pin which only authorizes users who are off station."
|
||||
id = "pin_away"
|
||||
/datum/design/pin_explorer
|
||||
name = "Outback Firing Pin"
|
||||
desc = "This firing pin only shoots while ya ain't on station, fair dinkum!"
|
||||
id = "pin_explorer"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 1500, /datum/material/glass = 2000)
|
||||
build_path = /obj/item/firing_pin/away
|
||||
materials = list(/datum/material/silver = 1000, /datum/material/gold = 1000, /datum/material/iron = 500)
|
||||
build_path = /obj/item/firing_pin/explorer
|
||||
category = list("Firing Pins")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
@@ -500,3 +500,13 @@
|
||||
materials = list(MAT_CATEGORY_RIGID = 12000)
|
||||
build_path = /obj/item/melee/cleric_mace
|
||||
category = list("Imported")
|
||||
|
||||
/datum/design/stun_boomerang
|
||||
name = "OZtek Boomerang"
|
||||
desc = "Uses reverse flow gravitodynamics to flip its personal gravity back to the thrower mid-flight. Also functions similar to a stun baton."
|
||||
id = "stun_boomerang"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000)
|
||||
build_path = /obj/item/melee/baton/boomerang
|
||||
category = list("Weapons")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
@@ -21,6 +21,16 @@
|
||||
. = ..()
|
||||
stored_research = new /datum/techweb/admin
|
||||
|
||||
/obj/item/disk/tech_disk/major
|
||||
name = "Reformatted technology disk"
|
||||
desc = "A disk containing a new, completed tech from the B.E.P.I.S. Upload the disk to an R&D Console to redeem the tech."
|
||||
icon_state = "rndmajordisk"
|
||||
custom_materials = list(/datum/material/iron=300, /datum/material/glass=100)
|
||||
|
||||
/obj/item/disk/tech_disk/major/Initialize()
|
||||
. = ..()
|
||||
stored_research = new /datum/techweb/bepis
|
||||
|
||||
/obj/item/disk/tech_disk/illegal
|
||||
name = "Illegal technology disk"
|
||||
desc = "A technology disk containing schematics for syndicate inspired equipment."
|
||||
|
||||
@@ -63,6 +63,19 @@
|
||||
id = "SCIENCE"
|
||||
organization = "Nanotrasen"
|
||||
|
||||
/datum/techweb/bepis //Should contain only 1 BEPIS tech selected at random.
|
||||
id = "EXPERIMENTAL"
|
||||
organization = "Nanotrasen R&D"
|
||||
|
||||
/datum/techweb/bepis/New()
|
||||
. = ..()
|
||||
var/bepis_id = pick(SSresearch.techweb_nodes_experimental) //To add a new tech to the BEPIS, add the ID to this pick list.
|
||||
var/datum/techweb_node/BN = (SSresearch.techweb_node_by_id(bepis_id))
|
||||
hidden_nodes -= BN.id //Has to be removed from hidden nodes
|
||||
research_node(BN, TRUE, FALSE, FALSE)
|
||||
update_node_status(BN)
|
||||
SSresearch.techweb_nodes_experimental -= bepis_id
|
||||
|
||||
/datum/techweb/Destroy()
|
||||
researched_nodes = null
|
||||
researched_designs = null
|
||||
@@ -126,17 +139,17 @@
|
||||
modify_point_list(l)
|
||||
|
||||
/datum/techweb/proc/copy_research_to(datum/techweb/receiver, unlock_hidden = TRUE) //Adds any missing research to theirs.
|
||||
if(unlock_hidden)
|
||||
for(var/i in receiver.hidden_nodes)
|
||||
CHECK_TICK
|
||||
if(!hidden_nodes[i])
|
||||
receiver.hidden_nodes -= i //We can see it so let them see it too.
|
||||
for(var/i in researched_nodes)
|
||||
CHECK_TICK
|
||||
receiver.research_node_id(i, TRUE, FALSE)
|
||||
for(var/i in researched_designs)
|
||||
CHECK_TICK
|
||||
receiver.add_design_by_id(i)
|
||||
if(unlock_hidden)
|
||||
for(var/i in receiver.hidden_nodes)
|
||||
CHECK_TICK
|
||||
if(!hidden_nodes[i])
|
||||
receiver.hidden_nodes -= i //We can see it so let them see it too.
|
||||
receiver.recalculate_nodes()
|
||||
|
||||
/datum/techweb/proc/copy()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
var/display_name = "Errored Node"
|
||||
var/description = "Why are you seeing this?"
|
||||
var/hidden = FALSE //Whether it starts off hidden.
|
||||
var/experimental = FALSE //If the tech can be randomly granted by the BEPIS as a reward. Meant to be fully given in tech disks, not researched.
|
||||
var/starting_node = FALSE //Whether it's available without any research.
|
||||
var/list/prereq_ids = list()
|
||||
var/list/design_ids = list()
|
||||
@@ -102,6 +103,6 @@
|
||||
description = "NT default research technologies."
|
||||
// Default research tech, prevents bricking
|
||||
design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "desttagger", "handlabel", "packagewrap",
|
||||
"destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand",
|
||||
"destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand",
|
||||
"space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal",
|
||||
"rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass")
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
////////////////////////B.E.P.I.S. Locked Techs////////////////////////
|
||||
|
||||
/datum/techweb_node/light_apps
|
||||
id = "light_apps"
|
||||
display_name = "Illumination Applications"
|
||||
description = "Applications of lighting and vision technology not originally thought to be commercially viable."
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("bright_helmet", "rld_mini")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/aus_security
|
||||
id = "aus_security"
|
||||
display_name = "Australicus Security Protocols"
|
||||
description = "It is said that security in the Australicus sector is tight, so we took some pointers from their equipment. Thankfully, our sector lacks any signs of these, 'dropbears'."
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("pin_explorer", "stun_boomerang")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/spec_eng
|
||||
id = "spec_eng"
|
||||
display_name = "Specialized Engineering"
|
||||
description = "Conventional wisdom has deemed these engineering products 'technically' safe, but far too dangerous to traditionally condone."
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("lava_rods", "eng_gloves")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/rolling_table
|
||||
id = "rolling_table"
|
||||
display_name = "Advanced Wheel Applications"
|
||||
description = "Adding wheels to things can lead to extremely beneficial outcomes."
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("rolling_table")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/Mauna_Mug
|
||||
id = "mauna_mug"
|
||||
display_name = "Mauna Mug"
|
||||
description = "A bored scientist was thinking to himself for very long...and then realized his coffee got cold! He made this invention to solve this extreme problem."
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("mauna_mug")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/nanite_replication_protocols
|
||||
id = "nanite_replication_protocols"
|
||||
display_name = "Nanite Replication Protocols"
|
||||
description = "Advanced behaviours that allow nanites to exploit certain circumstances to replicate faster."
|
||||
prereq_ids = list("nanite_smart")
|
||||
design_ids = list("kickstart_nanites","factory_nanites","tinker_nanites","offline_nanites","synergy_nanites")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/interrogation
|
||||
id = "interrogation"
|
||||
display_name = "Enhanced Interrogation Technology"
|
||||
description = "By cross-referencing several declassified documents from past dictatorial regimes, we were able to develop an incredibly effective interrogation device. \
|
||||
Ethical concerns about loss of free will may still apply, according to galactic law."
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("hypnochair")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
|
||||
/datum/techweb_node/tackle_advanced
|
||||
id = "tackle_advanced"
|
||||
display_name = "Advanced Grapple Technology"
|
||||
description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject \
|
||||
will no longer be accepted in its academic journals."
|
||||
design_ids = list("tackle_dolphin", "tackle_rocket")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
hidden = TRUE
|
||||
experimental = TRUE
|
||||
@@ -74,11 +74,3 @@
|
||||
prereq_ids = list("nanite_harmonic", "alientech")
|
||||
design_ids = list("spreading_nanites","mindcontrol_nanites","mitosis_nanites")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
|
||||
|
||||
/datum/techweb_node/nanite_replication_protocols
|
||||
id = "nanite_replication_protocols"
|
||||
display_name = "Nanite Replication Protocols"
|
||||
description = "Advanced behaviours that allow nanites to exploit certain circumstances to replicate faster."
|
||||
prereq_ids = list("nanite_smart")
|
||||
design_ids = list("kickstart_nanites","factory_nanites","tinker_nanites","offline_nanites","synergy_nanites")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
display_name = "Weapon Development Technology"
|
||||
description = "Our researchers have found new to weaponize just about everything now."
|
||||
prereq_ids = list("engineering")
|
||||
design_ids = list("pin_testing", "tele_shield", "lasercarbine", "pin_away")
|
||||
design_ids = list("pin_testing", "tele_shield", "lasercarbine")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500)
|
||||
|
||||
/datum/techweb_node/adv_weaponry
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
return FALSE
|
||||
if(istype(tool, /obj/item/melee/baton))
|
||||
var/obj/item/melee/baton/B = tool
|
||||
if(!B.status)
|
||||
if(!B.turned_on)
|
||||
to_chat(user, "<span class='warning'>[B] needs to be active!</span>")
|
||||
return FALSE
|
||||
if(istype(tool, /obj/item/gun/energy))
|
||||
|
||||
Reference in New Issue
Block a user