Merge remote-tracking branch 'upstream/master' into psych+paramedic

This commit is contained in:
Detective Google
2020-02-20 22:17:55 -06:00
1946 changed files with 70382 additions and 24703 deletions

View File

@@ -57,6 +57,7 @@
var/poster_item_name = "hypothetical poster"
var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here."
var/poster_item_icon_state = "rolled_poster"
var/poster_item_type = /obj/item/poster
/obj/structure/sign/poster/Initialize()
. = ..()
@@ -114,7 +115,7 @@
/obj/structure/sign/poster/proc/roll_and_drop(loc)
pixel_x = 0
pixel_y = 0
var/obj/item/poster/P = new(loc, src)
var/obj/item/poster/P = new poster_item_type(loc, src)
forceMove(P)
return P
@@ -128,7 +129,7 @@
if (smooth & SMOOTH_DIAGONAL)
for (var/O in overlays)
var/image/I = O
if (copytext(I.icon_state, 1, 3) == "d-")
if(copytext(I.icon_state, 1, 3) == "d-") //3 == length("d-") + 1
return
var/stuff_on_wall = 0

View File

@@ -11,7 +11,7 @@
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
create_reagents(300)
create_reagents(300, NONE, NO_REAGENTS_VALUE)
if(loc && isturf(loc))
for(var/obj/effect/decal/cleanable/C in loc)
if(C != src && C.type == type && !QDELETED(C))

View File

@@ -29,13 +29,19 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
sleep(2)
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")

View File

@@ -5,6 +5,7 @@
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
bloodiness = 0 //This isn't supposed to be bloody.
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = /datum/reagent/liquidgibs
var/gibs_bloodtype = "A+"
@@ -19,7 +20,6 @@
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
@@ -44,13 +44,18 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")

View File

@@ -5,12 +5,12 @@
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_state = BLOOD_STATE_BLOOD
bloodiness = MAX_SHOE_BLOODINESS
bloodiness = BLOOD_AMOUNT_PER_DECAL
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
blood_DNA |= C.blood_DNA.Copy()
blood_DNA |= C.blood_DNA
update_icon()
..()

View File

@@ -48,6 +48,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
holder = atom
/datum/effect_system/proc/start()
if(QDELETED(src))
return
for(var/i in 1 to number)
if(total_effects > 20)
return
@@ -69,7 +71,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
for(var/j in 1 to steps_amt)
sleep(5)
step(E,direction)
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
if(!QDELETED(src))
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
/datum/effect_system/proc/decrement_total_effect()
total_effects--

View File

@@ -94,7 +94,7 @@
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
create_reagents(1000, NONE, NO_REAGENTS_VALUE) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
@@ -126,7 +126,7 @@
T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR)
for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction)
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
if(get_base_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)

View File

@@ -32,7 +32,7 @@
/obj/effect/particle_effect/smoke/Initialize()
. = ..()
create_reagents(500)
create_reagents(500, NONE, NO_REAGENTS_VALUE)
START_PROCESSING(SSobj, src)

View File

@@ -277,6 +277,27 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.newplayer_start += loc
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/start/nuclear_equipment
name = "bomb or clown beacon spawner"
var/nukie_path = /obj/item/sbeacondrop/bomb
var/clown_path = /obj/item/sbeacondrop/clownbomb
/obj/effect/landmark/start/nuclear_equipment/after_round_start()
var/npath = nukie_path
if(istype(SSticker.mode, /datum/game_mode/nuclear/clown_ops))
npath = clown_path
else if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/D = SSticker.mode
if(locate(/datum/dynamic_ruleset/roundstart/nuclear/clown_ops) in D.current_rules)
npath = clown_path
new npath(loc)
return ..()
/obj/effect/landmark/start/nuclear_equipment/minibomb
name = "minibomb or bombanana spawner"
nukie_path = /obj/item/storage/box/minibombs
clown_path = /obj/item/storage/box/bombananas
/obj/effect/landmark/latejoin
name = "JoinLate"
@@ -460,7 +481,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
if(!SSmapping.station_room_templates[t])
log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list")
templates -= t
template_name = pickweight(templates)
template_name = pickweightAllowZero(templates)
if(!template_name)
GLOB.stationroom_landmarks -= src
qdel(src)

View File

@@ -109,4 +109,4 @@
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
set waitfor = FALSE
monitor.hasprox_receiver.HasProximity(AM)
monitor?.hasprox_receiver.HasProximity(AM)

View File

@@ -10,7 +10,7 @@
var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn.
var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards.
/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases)
/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases, list/blood_dna)
. = ..()
if(gibtypes.len != gibamounts.len)
stack_trace("Gib list amount length mismatch!")
@@ -33,7 +33,7 @@
var/body_coloring = ""
if(source_mob)
if(!issilicon(source_mob))
dna_to_add = source_mob.get_blood_dna_list() //ez pz
dna_to_add = blood_dna || source_mob.get_blood_dna_list() //ez pz
if(ishuman(source_mob))
var/mob/living/carbon/human/H = source_mob
if(H.dna.species.use_skintones)

View File

@@ -163,6 +163,10 @@ again.
icon_state = "plastitaniumwindow_spawner"
spawn_list = list(/obj/structure/grille, /obj/structure/window/plastitanium)
//plastitanium pirate window
/obj/effect/spawner/structure/window/plastitanium/pirate
spawn_list = list(/obj/structure/grille, /obj/structure/window/plastitanium/pirate)
//ice window

View File

@@ -8,6 +8,7 @@
/obj/structure/sign/poster/wanted
var/wanted_name
poster_item_type = /obj/item/poster/wanted
/obj/structure/sign/poster/wanted/Initialize(mapload, icon/person_icon, person_name, description)
. = ..()

View File

@@ -400,12 +400,14 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return usr.client.Click(src, src_location, src_control, params)
var/list/directaccess = usr.DirectAccess() //This, specifically, is what requires the copypaste. If this were after the adjacency check, then it'd be impossible to use items in your inventory, among other things.
//If this were before the above checks, then trying to click on items would act a little funky and signal overrides wouldn't work.
if((usr.CanReach(src) || (src in directaccess)) && (usr.CanReach(over) || (over in directaccess)))
if(!usr.get_active_held_item())
usr.UnarmedAttack(src, TRUE)
if(usr.get_active_held_item() == src)
melee_attack_chain(usr, over)
return TRUE //returning TRUE as a "is this overridden?" flag
if(iscarbon(usr))
var/mob/living/carbon/C = usr
if(C.combatmode && ((C.CanReach(src) || (src in directaccess)) && (C.CanReach(over) || (over in directaccess))))
if(!C.get_active_held_item())
C.UnarmedAttack(src, TRUE)
if(C.get_active_held_item() == src)
melee_attack_chain(C, over)
return TRUE //returning TRUE as a "is this overridden?" flag
if(!Adjacent(usr) || !over.Adjacent(usr))
return // should stop you from dragging through windows

View File

@@ -369,7 +369,7 @@ AI MODULES
if(!targName)
return
subject = targName
laws = list("You may not injure a [subject] or, through inaction, allow a [subject] to come to harm.",\
laws = list("You may not injure a [subject] or cause one to come to harm.",\
"You must obey orders given to you by [subject]s, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
..()

View File

@@ -196,7 +196,7 @@ RLD
/obj/item/construction/rcd/verb/change_airlock_access(mob/user)
if (!ishuman(user) && !user.has_unlimited_silicon_privilege)
if (!ishuman(user) && !user.silicon_privileges)
return
var/t1 = ""

View File

@@ -7,35 +7,35 @@ RPD
#define DISPOSALS_CATEGORY 1
#define TRANSIT_CATEGORY 2
#define BUILD_MODE 1
#define WRENCH_MODE 2
#define DESTROY_MODE 4
#define PAINT_MODE 8
#define BUILD_MODE (1<<0)
#define WRENCH_MODE (1<<1)
#define DESTROY_MODE (1<<2)
#define PAINT_MODE (1<<3)
GLOBAL_LIST_INIT(atmos_pipe_recipes, list(
"Pipes" = list(
new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple),
new /datum/pipe_info/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold),
new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve),
new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital),
new /datum/pipe_info/pipe("Relief Valve", /obj/machinery/atmospherics/components/binary/relief_valve),
new /datum/pipe_info/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w),
new /datum/pipe_info/pipe("Layer Manifold", /obj/machinery/atmospherics/pipe/layer_manifold),
),
"Devices" = list(
new /datum/pipe_info/pipe("Connector", /obj/machinery/atmospherics/components/unary/portables_connector),
new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump),
new /datum/pipe_info/pipe("Relief Valve", /obj/machinery/atmospherics/components/unary/relief_valve),
new /datum/pipe_info/pipe("Gas Pump", /obj/machinery/atmospherics/components/binary/pump),
new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate),
new /datum/pipe_info/pipe("Volume Pump", /obj/machinery/atmospherics/components/binary/volume_pump),
new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber),
new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector),
new /datum/pipe_info/meter("Meter"),
new /datum/pipe_info/pipe("Gas Filter", /obj/machinery/atmospherics/components/trinary/filter),
new /datum/pipe_info/pipe("Gas Mixer", /obj/machinery/atmospherics/components/trinary/mixer),
new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate),
new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector),
new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber),
new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump),
new /datum/pipe_info/pipe("Passive Vent", /obj/machinery/atmospherics/components/unary/passive_vent),
new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve),
new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital),
new /datum/pipe_info/pipe("Relief Valve (Binary)", /obj/machinery/atmospherics/components/binary/relief_valve),
new /datum/pipe_info/pipe("Relief Valve (Unary)", /obj/machinery/atmospherics/components/unary/relief_valve),
new /datum/pipe_info/meter("Meter"),
),
"Heat Exchange" = list(
new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/heat_exchanging/simple),
@@ -102,22 +102,22 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
dirs = list("[NORTH]" = "Vertical", "[EAST]" = "Horizontal")
if(dirtype == PIPE_BENDABLE)
dirs += list("[NORTHWEST]" = "West to North", "[NORTHEAST]" = "North to East",
"[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South")
"[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South")
if(PIPE_TRINARY)
dirs = list("[NORTH]" = "West South East", "[EAST]" = "North West South",
"[SOUTH]" = "East North West", "[WEST]" = "South East North")
dirs = list("[NORTH]" = "West South East", "[SOUTH]" = "East North West",
"[EAST]" = "North West South", "[WEST]" = "South East North")
if(PIPE_TRIN_M)
dirs = list("[NORTH]" = "North East South", "[EAST]" = "East South West",
"[SOUTH]" = "South West North", "[WEST]" = "West North East",
"[SOUTHEAST]" = "West South East", "[NORTHEAST]" = "South East North",
"[NORTHWEST]" = "East North West", "[SOUTHWEST]" = "North West South")
dirs = list("[NORTH]" = "North East South", "[SOUTHWEST]" = "North West South",
"[NORTHEAST]" = "South East North", "[SOUTH]" = "South West North",
"[WEST]" = "West North East", "[SOUTHEAST]" = "West South East",
"[NORTHWEST]" = "East North West", "[EAST]" = "East South West",)
if(PIPE_UNARY)
dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West")
dirs = list("[NORTH]" = "North", "[SOUTH]" = "South", "[WEST]" = "West", "[EAST]" = "East")
if(PIPE_ONEDIR)
dirs = list("[SOUTH]" = name)
if(PIPE_UNARY_FLIPPABLE)
dirs = list("[NORTH]" = "North", "[NORTHEAST]" = "North Flipped", "[EAST]" = "East", "[SOUTHEAST]" = "East Flipped",
"[SOUTH]" = "South", "[SOUTHWEST]" = "South Flipped", "[WEST]" = "West", "[NORTHWEST]" = "West Flipped")
dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West",
"[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped")
var/list/rows = list()
@@ -208,7 +208,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/static/datum/pipe_info/first_atmos
var/static/datum/pipe_info/first_disposal
var/static/datum/pipe_info/first_transit
var/mode = BUILD_MODE | PAINT_MODE | DESTROY_MODE | WRENCH_MODE
var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE
/obj/item/pipe_dispenser/New()
. = ..()
@@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
assets.send(user)
ui = new(user, src, ui_key, "rpd", name, 300, 550, master_ui, state)
ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state)
ui.open()
/obj/item/pipe_dispenser/ui_data(mob/user)
@@ -316,9 +316,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
playeffect = FALSE
if("mode")
var/n = text2num(params["mode"])
if(n == 2 && !(mode&1) && !(mode&2))
mode |= 3
else if(mode&n)
if(mode & n)
mode &= ~n
else
mode |= n
@@ -327,6 +325,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
spark_system.start()
effectcooldown = world.time + 100
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
return TRUE
/obj/item/pipe_dispenser/pre_attack(atom/A, mob/user)
var/turf/T = get_turf(A)
@@ -342,11 +341,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/static/list/make_pipe_whitelist
if(!make_pipe_whitelist)
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille))
if(istype(A, /obj/machinery/atmospherics) && (mode & BUILD_MODE && !(mode & PAINT_MODE))) //Reduces pixelhunt when coloring is off.
A = get_turf(A)
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
. = FALSE
. = TRUE
if((mode&DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, destroy_speed, target = A))
@@ -354,7 +355,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
qdel(A)
return
if((mode&PAINT_MODE))
if((mode & PAINT_MODE))
if(istype(A, /obj/machinery/atmospherics/pipe) && !istype(A, /obj/machinery/atmospherics/pipe/layer_manifold))
var/obj/machinery/atmospherics/pipe/P = A
to_chat(user, "<span class='notice'>You start painting \the [P] [paint_color]...</span>")
@@ -372,7 +373,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
user.visible_message("<span class='notice'>[user] paints \the [A] [paint_color].</span>","<span class='notice'>You paint \the [A] [paint_color].</span>")
return
if(mode&BUILD_MODE)
if(mode & BUILD_MODE)
switch(category) //if we've gotten this var, the target is valid
if(ATMOS_CATEGORY) //Making pipes
if(!can_make_pipe)
@@ -388,7 +389,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(A)
PM.setAttachLayer(piping_layer)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
PM.wrench_act(user, src)
else
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
@@ -407,7 +408,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
P.setPipingLayer(piping_layer)
if(findtext("[queued_p_type]", "/obj/machinery/atmospherics/pipe") && !findtext("[queued_p_type]", "layer_manifold"))
P.add_atom_colour(GLOB.pipe_paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
P.wrench_act(user, src)
if(DISPOSALS_CATEGORY) //Making disposals pipes
@@ -431,7 +432,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
C.add_fingerprint(usr)
C.update_icon()
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
C.wrench_act(user, src)
return
@@ -453,7 +454,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
if(queued_p_type == /obj/structure/c_transit_tube_pod)
var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(A)
pod.add_fingerprint(usr)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
pod.wrench_act(user, src)
else
@@ -465,7 +466,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
tube.simple_rotate_flip()
tube.add_fingerprint(usr)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
tube.wrench_act(user, src)
return

View File

@@ -64,10 +64,10 @@
if(!L)
return OXYLOSS
L.Remove(user)
L.Remove()
// make some colorful reagent, and apply it to the lungs
L.create_reagents(10)
L.create_reagents(10, NONE, NO_REAGENTS_VALUE)
L.reagents.add_reagent(/datum/reagent/colorful_reagent, 10)
L.reagents.reaction(L, TOUCH, 1)

View File

@@ -20,7 +20,7 @@
throw_range = 14
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/tennis/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
/obj/item/toy/tennis/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE

View File

@@ -20,12 +20,12 @@
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
if(owner)
/obj/item/organ/body_egg/Remove(special = FALSE)
if(!QDELETED(owner))
REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
..()
return ..()
/obj/item/organ/body_egg/on_death()
. = ..()

View File

@@ -23,7 +23,7 @@
if(!boomingandboxing)
var/list/tracklist = list()
for(var/datum/track/S in SSjukeboxes.songs)
if(istype(S) && S.song_associated_id in availabletrackids)
if(istype(S) && (S.song_associated_id in availabletrackids))
tracklist[S.song_name] = S
var/selected = input(user, "Play song", "Track:") as null|anything in tracklist
if(QDELETED(src) || !selected || !istype(tracklist[selected], /datum/track))

View File

@@ -128,6 +128,9 @@
return
. = ..()
/obj/item/card/emag/empty
uses = 0
/obj/item/emagrecharge
name = "electromagnet charging device"
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
@@ -247,6 +250,7 @@ update_label("John Doe", "Clowny")
name = "agent card"
access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE)
var/anyone = FALSE //Can anyone forge the ID or just syndicate?
var/forged = FALSE //have we set a custom name and job assignment, or will we use what we're given when we chameleon change?
/obj/item/card/id/syndicate/Initialize()
. = ..()
@@ -262,29 +266,52 @@ update_label("John Doe", "Clowny")
var/obj/item/card/id/I = O
src.access |= I.access
if(isliving(user) && user.mind)
if(user.mind.special_role)
if(user.mind.special_role || anyone)
to_chat(usr, "<span class='notice'>The card's microscanners activate as you pass it over the ID, copying its access.</span>")
/obj/item/card/id/syndicate/attack_self(mob/user)
if(isliving(user) && user.mind)
if(user.mind.special_role || anyone)
if(alert(user, "Action", "Agent ID", "Show", "Forge") == "Forge")
var/t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name))as text | null),1,26)
if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/dead/new_player/prefrences.dm
if (t)
alert("Invalid name.")
return
registered_name = t
var/first_use = registered_name ? FALSE : TRUE
if(!(user.mind.special_role || anyone)) //Unless anyone is allowed, only syndies can use the card, to stop metagaming.
if(first_use) //If a non-syndie is the first to forge an unassigned agent ID, then anyone can forge it.
anyone = TRUE
else
return ..()
var/u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")as text | null),1,MAX_MESSAGE_LEN)
if(!u)
registered_name = ""
return
assignment = u
update_label()
to_chat(user, "<span class='notice'>You successfully forge the ID card.</span>")
var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset")
if(user.incapacitated())
return
if(popup_input == "Forge/Reset" && !forged)
var/input_name = stripped_input(user, "What name would you like to put on this card? Leave blank to randomise.", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN)
input_name = reject_bad_name(input_name)
if(!input_name)
// Invalid/blank names give a randomly generated one.
if(user.gender == MALE)
input_name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]"
else if(user.gender == FEMALE)
input_name = "[pick(GLOB.first_names_female)] [pick(GLOB.last_names)]"
else
input_name = "[pick(GLOB.first_names)] [pick(GLOB.last_names)]"
var/target_occupation = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", assignment ? assignment : "Assistant", MAX_MESSAGE_LEN)
if(!target_occupation)
return
..()
registered_name = input_name
assignment = target_occupation
update_label()
forged = TRUE
to_chat(user, "<span class='notice'>You successfully forge the ID card.</span>")
log_game("[key_name(user)] has forged \the [initial(name)] with name \"[registered_name]\" and occupation \"[assignment]\".")
return
else if (popup_input == "Forge/Reset" && forged)
registered_name = initial(registered_name)
assignment = initial(assignment)
log_game("[key_name(user)] has reset \the [initial(name)] named \"[src]\" to default.")
update_label()
forged = FALSE
to_chat(user, "<span class='notice'>You successfully reset the ID card.</span>")
return
return ..()
/obj/item/card/id/syndicate/anyone
anyone = TRUE
@@ -541,4 +568,15 @@ update_label("John Doe", "Clowny")
id_color = "#0000FF"
/obj/item/card/id/knight/captain
id_color = "#FFD700"
id_color = "#FFD700"
/obj/item/card/id/debug
name = "\improper Debug ID"
desc = "A debug ID card. Has ALL the all access, you really shouldn't have this."
icon_state = "ert_janitor"
assignment = "Jannie"
/obj/item/card/id/debug/Initialize()
access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
. = ..()

View File

@@ -122,7 +122,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/Initialize()
. = ..()
create_reagents(chem_volume, INJECTABLE | NO_REACT) // so it doesn't react until you light it
create_reagents(chem_volume, INJECTABLE | NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
if(list_reagents)
reagents.add_reagent_list(list_reagents)
if(starts_lit)
@@ -146,7 +146,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead)
return
if(istype(glass)) //you can dip cigarettes into beakers
if(glass.reagents.trans_to(src, chem_volume)) //if reagents were transfered, show the message
if(glass.reagents.trans_to(src, chem_volume, log = "cigar fill: dip cigarette")) //if reagents were transfered, show the message
to_chat(user, "<span class='notice'>You dip \the [src] into \the [glass].</span>")
else //if not, either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
@@ -154,7 +154,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
/obj/item/clothing/mask/cigarette/proc/light(flavor_text = null)
if(lit)
return
@@ -438,7 +437,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
packeditem = 1
name = "[O.name]-packed [initial(name)]"
if(O.reagents)
O.reagents.trans_to(src, O.reagents.total_volume)
O.reagents.trans_to(src, O.reagents.total_volume, log = "cigar fill: pipe pack")
qdel(O)
else
to_chat(user, "<span class='warning'>It has to be dried first!</span>")
@@ -687,7 +686,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(O.dry)
var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc)
R.chem_volume = target.reagents.total_volume
target.reagents.trans_to(R, R.chem_volume)
target.reagents.trans_to(R, R.chem_volume, log = "cigar fill: rolling paper afterattack")
qdel(target)
qdel(src)
user.put_in_active_hand(R)
@@ -718,7 +717,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
. = ..()
create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
create_reagents(chem_volume, NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
reagents.add_reagent(/datum/reagent/drug/nicotine, 50)
if(!icon_state)
if(!param_color)
@@ -903,7 +902,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
//Transfer reagents and remove the plant
user.show_message("<span class='notice'>You stuff the [DP] into the [src]'s bowl.</span>", MSG_VISUAL)
DP.reagents.trans_to(src, 100)
DP.reagents.trans_to(src, 100, log = "cigar fill: bong")
qdel(DP)
return
else

View File

@@ -35,6 +35,10 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/machine/autolathe/secure
name = "Secure Autolathe (Machine Board)"
build_path = /obj/machinery/autolathe/secure
/obj/item/circuitboard/machine/bloodbankgen
name = "Blood Bank Generator (Machine Board)"
build_path = /obj/machinery/bloodbankgen
@@ -238,6 +242,14 @@
/obj/machinery/vending/cigarette = "ShadyCigs Deluxe",
/obj/machinery/vending/games = "\improper Good Clean Fun",
/obj/machinery/vending/autodrobe = "AutoDrobe",
/obj/machinery/vending/assist = "\improper Vendomat",
/obj/machinery/vending/engivend = "\improper Engi-Vend",
/obj/machinery/vending/engivend = "\improper YouTool",
/obj/machinery/vending/sustenance = "\improper Sustenance Vendor",
/obj/machinery/vending/dinnerware = "\improper Plasteel Chef's Dinnerware Vendor",
/obj/machinery/vending/cart = "\improper PTech",
/obj/machinery/vending/hydronutrients = "\improper NutriMax",
/obj/machinery/vending/hydroseeds = "\improper MegaSeed Servitor",
/obj/machinery/vending/wardrobe/sec_wardrobe = "SecDrobe",
/obj/machinery/vending/wardrobe/medi_wardrobe = "MediDrobe",
/obj/machinery/vending/wardrobe/engi_wardrobe = "EngiDrobe",

View File

@@ -96,7 +96,7 @@
charges_left = charges
if(!reagents)
create_reagents(charges_left * volume_multiplier)
create_reagents(charges_left * volume_multiplier, NONE, NO_REAGENTS_VALUE)
reagents.clear_reagents()
var/total_weight = 0
@@ -407,7 +407,7 @@
to_chat(user, "<span class='notice'>You spray a [temp] on \the [target.name]</span>")
if(length(text_buffer) > 1)
text_buffer = copytext(text_buffer,2)
text_buffer = copytext(text_buffer, length(text_buffer[1]) + 1)
SStgui.update_uis(src)
if(post_noise)
@@ -427,7 +427,7 @@
/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target)
// Check area validity.
// Reject space, player-created areas, and non-station z-levels.
var/area/A = get_area(target)
var/area/A = get_base_area(target)
if(!A || (!is_station_level(A.z)) || !A.valid_territory)
to_chat(user, "<span class='warning'>[A] is unsuitable for tagging.</span>")
return FALSE
@@ -461,7 +461,7 @@
qdel(old_marking)
var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang)
var/area/territory = get_area(target)
var/area/territory = get_base_area(target)
new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag.
to_chat(user, "<span class='notice'>You tagged [territory] for your gang!</span>")
@@ -619,7 +619,6 @@
is_capped = TRUE
self_contained = FALSE // Don't disappear when they're empty
can_change_colour = TRUE
gang = TRUE //Gang check is true for all things upon the honored hierarchy of spraycans, except those that are FALSE.
reagent_contents = list(/datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol = 1)
@@ -711,7 +710,8 @@
if(isobj(target))
if(actually_paints)
if(color_hex2num(paint_color) < 350 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
var/list/hsl = rgb2hsl(hex2num(copytext(paint_color,2,4)),hex2num(copytext(paint_color,4,6)),hex2num(copytext(paint_color,6,8)))
if(hsl[3] < 0.25 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
return FALSE
@@ -774,7 +774,6 @@
icon_capped = "deathcan2_cap"
icon_uncapped = "deathcan2"
use_overlays = FALSE
gang = FALSE
volume_multiplier = 25
charges = 100
@@ -789,7 +788,6 @@
icon_capped = "clowncan2_cap"
icon_uncapped = "clowncan2"
use_overlays = FALSE
gang = FALSE
reagent_contents = list(/datum/reagent/lube = 1, /datum/reagent/consumable/banana = 1)
volume_multiplier = 5
@@ -804,7 +802,6 @@
icon_capped = "mimecan_cap"
icon_uncapped = "mimecan"
use_overlays = FALSE
gang = FALSE
can_change_colour = FALSE
paint_color = "#FFFFFF" //RGB

View File

@@ -0,0 +1,102 @@
/* This file contains standalone items for debug purposes. */
/obj/item/debug/human_spawner
name = "human spawner"
desc = "Spawn a human by aiming at a turf and clicking. Use in hand to change type."
icon = 'icons/obj/guns/magic.dmi'
icon_state = "nothingwand"
item_state = "wand"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
var/datum/species/selected_species
var/valid_species = list()
/obj/item/debug/human_spawner/afterattack(atom/target, mob/user, proximity)
..()
if(isturf(target))
var/mob/living/carbon/human/H = new /mob/living/carbon/human(target)
if(selected_species)
H.set_species(selected_species)
/obj/item/debug/human_spawner/attack_self(mob/user)
..()
var/choice = input("Select a species", "Human Spawner", null) in GLOB.species_list
selected_species = GLOB.species_list[choice]
/* Revive this once we purge all the istype checks for tools for tool_behaviour
/obj/item/debug/omnitool
name = "omnitool"
desc = "The original hypertool, born before them all. Use it in hand to unleash it's true power."
icon = 'icons/obj/device.dmi'
icon_state = "hypertool"
item_state = "hypertool"
toolspeed = 0.1
tool_behaviour = null
/obj/item/debug/omnitool/examine()
. = ..()
. += " The mode is: [tool_behaviour]"
/obj/item/debug/omnitool/proc/check_menu(mob/user)
if(!istype(user))
return FALSE
if(user.incapacitated() || !user.Adjacent(src))
return FALSE
return TRUE
/obj/item/debug/omnitool/attack_self(mob/user)
if(!user)
return
var/list/tool_list = list(
"Crowbar" = image(icon = 'icons/obj/tools.dmi', icon_state = "crowbar"),
"Multitool" = image(icon = 'icons/obj/device.dmi', icon_state = "multitool"),
"Screwdriver" = image(icon = 'icons/obj/tools.dmi', icon_state = "screwdriver_map"),
"Wirecutters" = image(icon = 'icons/obj/tools.dmi', icon_state = "cutters_map"),
"Wrench" = image(icon = 'icons/obj/tools.dmi', icon_state = "wrench"),
"Welding Tool" = image(icon = 'icons/obj/tools.dmi', icon_state = "miniwelder"),
"Analyzer" = image(icon = 'icons/obj/device.dmi', icon_state = "analyzer"),
"Mining Tool" = image(icon = 'icons/obj/mining.dmi', icon_state = "minipick"),
"Shovel" = image(icon = 'icons/obj/mining.dmi', icon_state = "spade"),
"Retractor" = image(icon = 'icons/obj/surgery.dmi', icon_state = "retractor"),
"Hemostat" = image(icon = 'icons/obj/surgery.dmi', icon_state = "hemostat"),
"Cautery" = image(icon = 'icons/obj/surgery.dmi', icon_state = "cautery"),
"Drill" = image(icon = 'icons/obj/surgery.dmi', icon_state = "drill"),
"Scalpel" = image(icon = 'icons/obj/surgery.dmi', icon_state = "scalpel"),
"Saw" = image(icon = 'icons/obj/surgery.dmi', icon_state = "saw")
)
var/tool_result = show_radial_menu(user, src, tool_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
return
switch(tool_result)
if("Crowbar")
tool_behaviour = TOOL_CROWBAR
if("Multitool")
tool_behaviour = TOOL_MULTITOOL
if("Screwdriver")
tool_behaviour = TOOL_SCREWDRIVER
if("Wirecutters")
tool_behaviour = TOOL_WIRECUTTER
if("Wrench")
tool_behaviour = TOOL_WRENCH
if("Welding Tool")
tool_behaviour = TOOL_WELDER
if("Analyzer")
tool_behaviour = TOOL_ANALYZER
if("Mining Tool")
tool_behaviour = TOOL_MINING
if("Shovel")
tool_behaviour = TOOL_SHOVEL
if("Retractor")
tool_behaviour = TOOL_RETRACTOR
if("Hemostat")
tool_behaviour = TOOL_HEMOSTAT
if("Cautery")
tool_behaviour = TOOL_CAUTERY
if("Drill")
tool_behaviour = TOOL_DRILL
if("Scalpel")
tool_behaviour = TOOL_SCALPEL
if("Saw")
tool_behaviour = TOOL_SAW
*/

View File

@@ -431,35 +431,21 @@
if((!req_defib && grab_ghost) || (req_defib && defib.grab_ghost))
H.notify_ghost_cloning("Your heart is being defibrillated!")
H.grab_ghost() // Shove them back in their body.
else if(can_defib(H))
else if(H.can_defib())
H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src)
do_help(H, user)
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H) //Our code here is different than tg, if it breaks in testing; BUG_PROBABLE_CAUSE
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
if(H.suiciding || H.hellbound || HAS_TRAIT(H, TRAIT_HUSK))
return
if((world.time - H.timeofdeath) > tlimit)
return
if((H.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (H.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
return
if(!heart || (heart.organ_flags & ORGAN_FAILING))
return
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || H.suiciding)
return
return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(req_defib)
if(defib.pullshocksafely && isliving(H.pulledby))
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
else
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, src))
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
M.emote("scream")
if(!H.pulledby || !isliving(H.pulledby))
return
if(req_defib && defib.pullshocksafely)
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
return
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, src))
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
M.emote("scream")
/obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)

View File

@@ -8,6 +8,7 @@
var/mob/owner = null //Carp doesn't attack owner, set when using in hand
var/owned = 0 //Boolean, no owner to begin with
var/mobtype = /mob/living/simple_animal/hostile/carp //So admins can change what mob spawns via var fuckery
can_random_spawn = FALSE
//Attack self
/obj/item/toy/plush/carpplushie/dehy_carp/attack_self(mob/user)

View File

@@ -1,4 +1,3 @@
//The advanced pea-green monochrome lcd of tomorrow.
GLOBAL_LIST_EMPTY(PDAs)
@@ -77,6 +76,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/hidden = FALSE // Is the PDA hidden from the PDA list?
var/emped = FALSE
var/equipped = FALSE //used here to determine if this is the first time its been picked up
var/allow_emojis = TRUE //if the pda can send emojis and actually have them parsed as such
var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both.
var/ownjob = null //related to above
@@ -255,10 +255,14 @@ GLOBAL_LIST_EMPTY(PDAs)
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda)
assets.send(user)
var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/goonchat)
emoji_s.send(user) //Already sent by chat but no harm doing this
user.set_machine(src)
var/dat = "<!DOCTYPE html><html><head><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
dat += assets.css_tag()
dat += emoji_s.css_tag()
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'>[PDAIMG(refresh)]Refresh</a>"
@@ -288,7 +292,7 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += text("ID: <a href='?src=[REF(src)];choice=Authenticate'>[id ? "[id.registered_name], [id.assignment]" : "----------"]")
dat += text("<br><a href='?src=[REF(src)];choice=UpdateInfo'>[id ? "Update PDA Info" : ""]</A><br><br>")
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss")]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]"
dat += "<br><br>"
@@ -338,6 +342,8 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "<li><a href='byond://?src=[REF(src)];choice=54'>[PDAIMG(medbot)]Bots Access</a></li>"
if (cartridge.access & CART_JANITOR)
dat += "<li><a href='byond://?src=[REF(src)];choice=49'>[PDAIMG(bucket)]Custodial Locator</a></li>"
if(cartridge.access & CART_MIME)
dat += "<li><a href='byond://?src=[REF(src)];choice=55'>[PDAIMG(emoji)]Emoji Guidebook</a></li>"
if (istype(cartridge.radio))
dat += "<li><a href='byond://?src=[REF(src)];choice=40'>[PDAIMG(signaler)]Signaler System</a></li>"
if (cartridge.access & CART_NEWSCASTER)
@@ -635,13 +641,13 @@ GLOBAL_LIST_EMPTY(PDAs)
if("Clear")//Clears messages
tnote = null
if("Ringtone")
var/t = input(U, "Please enter new ringtone", name, ttone) as text
var/t = stripped_input(U, "Please enter new ringtone", name, ttone, 20)
if(in_range(src, U) && loc == U && t)
if(SEND_SIGNAL(src, COMSIG_PDA_CHANGE_RINGTONE, U, t) & COMPONENT_STOP_RINGTONE_CHANGE)
U << browse(null, "window=pda")
return
else
ttone = copytext(sanitize(t), 1, 20)
ttone = t
else
U << browse(null, "window=pda")
return
@@ -715,7 +721,7 @@ GLOBAL_LIST_EMPTY(PDAs)
return
/obj/item/pda/proc/remove_id(mob/user)
if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
if(hasSiliconAccessInArea(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
do_remove_id(user)
@@ -753,7 +759,6 @@ GLOBAL_LIST_EMPTY(PDAs)
return
if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY))
return
var/emoji_message = emoji_parse(message)
if(prob(1))
message += "\nSent from my PDA"
// Send the signal
@@ -782,7 +787,7 @@ GLOBAL_LIST_EMPTY(PDAs)
"job" = "[ownjob]",
"message" = message,
"targets" = string_targets,
"emoji_message" = emoji_message
"emojis" = allow_emojis
))
if (picture)
signal.data["photo"] = picture
@@ -796,15 +801,18 @@ GLOBAL_LIST_EMPTY(PDAs)
playsound(src, 'sound/machines/terminal_error.ogg', 15, 1)
var/target_text = signal.format_target()
if(allow_emojis)
message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat
signal.data["message"] = emoji_parse(signal.data["message"])
// Log it in our logs
tnote += "<i><b>&rarr; To [target_text]:</b></i><br>[signal.format_message()]<br>"
// Show it to ghosts
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message(TRUE)]</span>"
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message()]</span>"
for(var/i in GLOB.dead_mob_list)
var/mob/M = i
if(M?.client && M.client.prefs.chat_toggles & CHAT_GHOSTPDA)
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[emoji_message]\"</span>")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[message]\"</span>")
// Log in the talk log
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text] (BLOCKED:[string_blocked])")
if (!silent)
@@ -835,7 +843,11 @@ GLOBAL_LIST_EMPTY(PDAs)
hrefstart = "<a href='?src=[REF(L)];track=[html_encode(signal.data["name"])]'>"
hrefend = "</a>"
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[signal.format_message(TRUE)] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>) <a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>(BLOCK/UNBLOCK)</a>")
var/inbound_message = signal.format_message()
if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis
inbound_message = emoji_parse(inbound_message)
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[inbound_message] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>) (<a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>BLOCK/UNBLOCK</a>)")
update_icon(TRUE)
@@ -904,7 +916,7 @@ GLOBAL_LIST_EMPTY(PDAs)
remove_pen()
/obj/item/pda/proc/toggle_light()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE))
return
if(fon)
fon = FALSE
@@ -916,7 +928,7 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda/proc/remove_pen()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(inserted_item)

View File

@@ -19,6 +19,26 @@
if(istype(cart) && cart.charges < 5)
cart.charges++
//Mime PDA sends "silent" messages.
/obj/item/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
desc = "A portable microcomputer by Thinktronic Systems, LTD. The hardware has been modified for compliance with the vows of silence."
silent = TRUE
ttone = "silence"
/obj/item/pda/mime/msg_input(mob/living/U = usr)
if(emped || toff)
return
var/emojis = emoji_sanitize(stripped_input(U, "Please enter emojis", name))
if(!emojis)
return
if(!U.canUseTopic(src, BE_CLOSE))
return
return emojis
// Special AI/pAI PDAs that cannot explode.
/obj/item/pda/ai
icon = null
@@ -79,14 +99,6 @@
icon_state = "pda-science"
ttone = "boom"
/obj/item/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
silent = TRUE
ttone = "silence"
/obj/item/pda/heads
default_cartridge = /obj/item/cartridge/head
icon_state = "pda-hop"

View File

@@ -100,7 +100,8 @@
bot_access_flags = CLEAN_BOT
/obj/item/cartridge/lawyer
name = "\improper P.R.O.V.E. cartridge"
name = "\improper S.P.A.M. cartridge"
desc = "Introducing the Station Public Announcement Messenger cartridge, featuring the unique ability to broadcast-mark messages, designed for lawyers across Nanotrasen to advertise their useful and important services."
icon_state = "cart-law"
access = CART_SECURITY
spam_enabled = 1
@@ -309,9 +310,14 @@ Code:
var/list/S = list(" Off","AOff"," On", " AOn")
var/list/chg = list("N","C","F")
//Neither copytext nor copytext_char is appropriate here; neither 30 UTF-8 code units nor 30 code points equates to 30 columns of output.
//Some glyphs are very tall or very wide while others are small or even take up no space at all.
//Emojis can take modifiers which are many characters but render as only one glyph.
//A proper solution here (as far as Unicode goes, maybe not ideal as far as markup goes, a table would be better)
//would be to use <span style="width: NNNpx; overflow: none;">[A.area.name]</span>
for(var/obj/machinery/power/apc/A in L)
menu += copytext(add_tspace(A.area.name, 30), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(DisplayPower(A.lastused_total), 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += copytext_char(add_trailing(A.area.name, 30, " "), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_leading(DisplayPower(A.lastused_total), 6, " ")] [A.cell ? "[add_leading(round(A.cell.percent()), 3, " ")]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += "</FONT></PRE>"
@@ -326,7 +332,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Sex: [active1.fields["gender"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
@@ -370,7 +376,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Sex: [active1.fields["gender"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
@@ -557,28 +563,44 @@ Code:
if (53) // Newscaster
menu = "<h4>[PDAIMG(notes)] Newscaster Access</h4>"
menu += "<br> Current Newsfeed: <A href='byond://?src=[REF(src)];choice=Newscaster Switch Channel'>[current_channel ? current_channel : "None"]</a> <br>"
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
var/datum/news/feed_channel/current
for(var/datum/news/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(!current)
menu += "<h5> ERROR : NO CHANNEL FOUND </h5>"
return
var/i = 1
for(var/datum/newscaster/feed_message/msg in current.messages)
for(var/datum/news/feed_message/msg in current.messages)
menu +="-[msg.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[msg.returnAuthor(-1)]</FONT>\]</FONT><BR>"
menu +="<b><font size=1>[msg.comments.len] comment[msg.comments.len > 1 ? "s" : ""]</font></b><br>"
if(msg.img)
user << browse_rsc(msg.img, "tmp_photo[i].png")
menu +="<img src='tmp_photo[i].png' width = '180'><BR>"
i++
for(var/datum/newscaster/feed_comment/comment in msg.comments)
for(var/datum/news/feed_comment/comment in msg.comments)
menu +="<font size=1><small>[comment.body]</font><br><font size=1><small><small><small>[comment.author] [comment.time_stamp]</small></small></small></small></font><br>"
menu += "<br> <A href='byond://?src=[REF(src)];choice=Newscaster Message'>Post Message</a>"
if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access
menu = "<h4>[PDAIMG(medbot)] Bots Interlink</h4>"
bot_control()
if (55) // Emoji Guidebook for mimes
menu = "<h4>[PDAIMG(emoji)] Emoji Guidebook</h4>"
var/static/list/emoji_icon_states
var/static/emoji_table
if(!emoji_table)
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
var/list/collate = list("<br><table>")
for(var/emoji in sortList(icon_states(icon('icons/emoji.dmi'))))
var/tag = sheet.icon_tag("emoji-[emoji]")
collate += "<tr><td>[emoji]</td><td>[tag]</td></tr>"
collate += "</table><br>"
emoji_table = collate.Join()
menu += "<br> To use an emoji in a pda message, refer to the guide and add \":\" around the emoji. Your PDA supports the following emoji:<br>"
menu += emoji_table
if (99) //Newscaster message permission error
menu = "<h5> ERROR : NOT AUTHORIZED [host_pda.id ? "" : "- ID SLOT EMPTY"] </h5>"
@@ -587,7 +609,7 @@ Code:
/obj/item/cartridge/Topic(href, href_list)
..()
if(!usr.canUseTopic(src, !issilicon(usr)))
if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
usr.unset_machine()
usr << browse(null, "window=pda")
return
@@ -660,8 +682,8 @@ Code:
if("Newscaster Message")
var/host_pda_owner_name = host_pda.id ? "[host_pda.id.registered_name] ([host_pda.id.assignment])" : "Unknown"
var/message = host_pda.msg_input()
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
var/datum/news/feed_channel/current
for(var/datum/news/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(current.locked && current.author != host_pda_owner_name)
@@ -679,6 +701,11 @@ Code:
return
playsound(src, 'sound/machines/terminal_select.ogg', 50, 1)
//emoji previews
if(href_list["emoji"])
var/parse = emoji_parse(":[href_list["emoji"]]:")
to_chat(usr, parse)
//Bot control section! Viciously ripped from radios for being laggy and terrible.
if(href_list["op"])
switch(href_list["op"])

View File

@@ -49,6 +49,10 @@
return
if(istype(target, /obj/structure/falsewall))
return
if(target.alpha != 255)
return
if(target.invisibility != 0)
return
if(iseffect(target))
if(!(istype(target, /obj/effect/decal))) //be a footprint
return

View File

@@ -46,7 +46,7 @@
var/list/organs = M.getorganszone("head") + M.getorganszone("eyes") + M.getorganszone("mouth")
for(var/internal_organ in organs)
var/obj/item/organ/I = internal_organ
I.Remove(M)
I.Remove()
I.forceMove(T)
head.drop_limb()
qdel(head)
@@ -89,25 +89,6 @@
else
to_chat(user, "<span class='notice'>Anomalous error. Summon a coder.</span>")
else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_GROIN)
var/mob/living/carbon/human/H = target
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
return
playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
H.visible_message("<span class='warning'>[user] is preparing to shrink [H]\'s [P.name] with their bluespace compression kit!</span>")
if(do_mob(user, H, 40) && charges > 0 && P.length > 0)
H.visible_message("<span class='warning'>[user] has shrunk [H]\'s [P.name]!</span>")
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
sparks()
flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
charges -= 1
var/p_name = P.name
P.modify_size(-5)
if(QDELETED(P))
H.visible_message("<span class='warning'>[H]\'s [p_name] vanishes!</span>")
/obj/item/compressionkit/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/ore/bluespace_crystal))
@@ -117,4 +98,4 @@
if(B.amount > 1)
B.amount -= 1
else
qdel(I)
qdel(I)

View File

@@ -14,6 +14,7 @@
var/last_use = 0
var/next_use = 0
var/obj/effect/abstract/sync_holder/sync_holder
var/resync_timer
/obj/item/desynchronizer/attack_self(mob/living/user)
if(world.time < next_use)
@@ -56,16 +57,20 @@
SEND_SIGNAL(AM, COMSIG_MOVABLE_SECLUDED_LOCATION)
last_use = world.time
icon_state = "desynchronizer-on"
addtimer(CALLBACK(src, .proc/resync), duration)
resync_timer = addtimer(CALLBACK(src, .proc/resync), duration , TIMER_STOPPABLE)
/obj/item/desynchronizer/proc/resync()
new /obj/effect/temp_visual/desynchronizer(sync_holder.drop_location())
QDEL_NULL(sync_holder)
if(resync_timer)
deltimer(resync_timer)
resync_timer = null
icon_state = initial(icon_state)
next_use = world.time + (world.time - last_use) // Could be 2*world.time-last_use but that would just be confusing
/obj/item/desynchronizer/Destroy()
resync()
if(sync_holder)
resync()
return ..()
/obj/effect/abstract/sync_holder

View File

@@ -51,7 +51,7 @@
/obj/item/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))
if(istype(M) && on && (user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)))
if((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
@@ -390,7 +390,7 @@
return TRUE
/obj/item/flashlight/emp/attack(mob/living/M, mob/living/user)
if(on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)) // call original attack when examining organs
if(on && (user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))) // call original attack when examining organs
..()
return

View File

@@ -38,6 +38,7 @@
/obj/item/geiger_counter/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(soundloop)
return ..()
/obj/item/geiger_counter/process()

View File

@@ -73,8 +73,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
// Variable window height, depending on how many GPS units there are
// to show, clamped to relatively safe range.
var/gps_window_height = CLAMP(325 + GLOB.GPS_list.len * 14, 325, 700)
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(state = updating)
@@ -91,6 +93,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
var/turf/curr = get_turf(src)
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
data["currentArea"] = "[get_area_name(curr, TRUE)]"
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
var/list/signals = list()
data["signals"] = list()
@@ -104,16 +108,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
continue
var/list/signal = list()
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
signal["area"] = get_area_name(G, TRUE)
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
if(!direction)
direction = "CENTER"
signal["degrees"] = "N/A"
signal["direction"] = direction
signals += list(signal) //Add this signal to the list of signals
data["signals"] = signals

View File

@@ -101,7 +101,7 @@
if(href_list["reset_radio_short"])
pai.unshort_radio()
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
var/newlaws = stripped_multiline_input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
if(href_list["toggle_holo"])

View File

@@ -61,7 +61,7 @@
var/mob/living/carbon/C = usr
if(usr.stat || usr.restrained() || C.back == src)
return
if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=radio")
onclose(usr, "radio")
@@ -127,7 +127,7 @@
/obj/item/electropack/ui_interact(mob/user)
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"
<TT>
@@ -200,14 +200,14 @@ Code:
/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad
if(istype(W, /obj/item/pen))
var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
var/t = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot", MAX_NAME_LEN)
if(t)
tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
name = "[initial(name)] - [tagname]"
tagname = t
name = "[initial(name)] - [t]"
else
return ..()
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
var/dat = {"
<TT>
<B>Frequency/Code</B> for shock collar:<BR>

View File

@@ -112,7 +112,14 @@
. = ..()
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio", name, 370, 220 + channels.len * 22, master_ui, state)
var/ui_width = 360
var/ui_height = 106
if(subspace_transmission)
if(channels.len > 0)
ui_height += 6 + channels.len * 21
else
ui_height += 24
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/radio/ui_data(mob/user)

View File

@@ -28,7 +28,7 @@ SLIME SCANNER
/obj/item/t_scanner/attack_self(mob/user)
on = !on
icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"
icon_state = copytext_char(icon_state, 1, -1) + "[on]"
if(on)
START_PROCESSING(SSobj, src)
@@ -407,19 +407,17 @@ SLIME SCANNER
// Blood Level
if(M.has_dna())
var/mob/living/carbon/C = M
var/blood_id = C.get_blood_id()
if(blood_id)
var/blood_typepath = C.get_blood_id()
if(blood_typepath)
if(ishuman(C))
if(H.bleed_rate)
msg += "<span class='danger'>Subject is bleeding!</span>\n"
var/blood_percent = round((C.scan_blood_volume() / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
if(blood_id != ("blood" || "jellyblood"))//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(!(blood_typepath in GLOB.blood_reagent_types))
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_typepath]
if(R)
blood_type = R.name
else
blood_type = blood_id
if(C.scan_blood_volume() <= (BLOOD_VOLUME_SAFE*C.blood_ratio) && C.scan_blood_volume() > (BLOOD_VOLUME_OKAY*C.blood_ratio))
msg += "<span class='danger'>LOW blood level [blood_percent] %, [C.scan_blood_volume()] cl,</span> <span class='info'>type: [blood_type]</span>\n"
else if(C.scan_blood_volume() <= (BLOOD_VOLUME_OKAY*C.blood_ratio))

View File

@@ -54,7 +54,7 @@
to_chat(user, "<span class='warning'>[src] was shaken recently, it needs time to settle.</span>")
return
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='italics'>You hear shaking and sloshing.</span>")
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='hear'>You hear shaking and sloshing.</span>")
shaking = TRUE
@@ -95,16 +95,47 @@
// except it actually ASKS THE DEAD (wooooo)
/obj/item/toy/eightball/haunted
shake_time = 150
cooldown_time = 1800
shake_time = 30 SECONDS
cooldown_time = 3 MINUTES
flags_1 = HEAR_1
var/last_message
var/selected_message
var/list/votes
//these kind of store the same thing but one is easier to work with.
var/list/votes = list()
var/list/voted = list()
var/static/list/haunted_answers = list(
"yes" = list(
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes"
),
"maybe" = list(
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again"
),
"no" = list(
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful"
)
)
/obj/item/toy/eightball/haunted/Initialize(mapload)
. = ..()
votes = list()
for (var/answer in haunted_answers)
votes[answer] = 0
GLOB.poi_list |= src
/obj/item/toy/eightball/haunted/Destroy()
@@ -122,7 +153,7 @@
interact(user)
return ..()
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode, atom/movable/source)
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
. = ..()
last_message = raw_message
@@ -137,38 +168,31 @@
if(isobserver(usr))
interact(usr)
/obj/item/toy/eightball/haunted/proc/get_vote_tallies()
var/list/answers = list()
for(var/ckey in votes)
var/selected = votes[ckey]
if(selected in answers)
answers[selected]++
else
answers[selected] = 1
return answers
/obj/item/toy/eightball/haunted/get_answer()
if(!votes.len)
return pick(possible_answers)
var/top_amount = 0
var/top_vote
var/list/tallied_votes = get_vote_tallies()
for(var/vote in votes)
var/amount_of_votes = length(votes[vote])
if(amount_of_votes > top_amount)
top_vote = vote
top_amount = amount_of_votes
//If one option actually has votes and there's a tie, pick between them 50/50
else if(top_amount && amount_of_votes == top_amount && prob(50))
top_vote = vote
top_amount = amount_of_votes
// I miss python sorting, then I wouldn't have to muck about with
// all this
var/most_popular_answer
var/most_amount = 0
// yes, if there is a tie, there is an arbitary decision
// but we never said the spirit world was fair
for(var/A in tallied_votes)
var/amount = tallied_votes[A]
if(amount > most_amount)
most_popular_answer = A
if(isnull(top_vote))
top_vote = pick(votes)
return most_popular_answer
for(var/vote in votes)
votes[vote] = 0
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.observer_state)
voted.Cut()
return top_vote
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.always_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -179,21 +203,13 @@
var/list/data = list()
data["shaking"] = shaking
data["question"] = selected_message
var/list/tallied_votes = get_vote_tallies()
data["answers"] = list()
for(var/pa in possible_answers)
for(var/pa in haunted_answers)
var/list/L = list()
L["answer"] = pa
var/amount = 0
if(pa in tallied_votes)
amount = tallied_votes[pa]
L["amount"] = amount
var/selected = FALSE
if(votes[user.ckey] == pa)
selected = TRUE
L["selected"] = selected
L["amount"] = votes[pa]
L["selected"] = voted[user.ckey]
data["answers"] += list(L)
return data
@@ -206,8 +222,11 @@
switch(action)
if("vote")
var/selected_answer = params["answer"]
if(!(selected_answer in possible_answers))
if(!(selected_answer in haunted_answers))
return
if(user.ckey in voted)
return
else
votes[user.ckey] = selected_answer
. = TRUE
votes[selected_answer] += 1
voted[user.ckey] = selected_answer
. = TRUE

View File

@@ -490,7 +490,13 @@
oneuse = FALSE
remarks = list("Looks like these would sell much better in a plasma fire...", "Using glass bowls rather then cones?", "Mixing soda and ice-cream?", "Tall glasses with of liquids and solids...", "Just add a bit of icecream and cherry on top?")
//Later content when I have free time - Trilby Date:24-Aug-2019
/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers
name = "Sandstone manual on bows"
desc = "A standstone slab with everything you need to know for making bows and arrows just like an ashwalker would."
crafting_recipe_types = list(/datum/crafting_recipe/bone_arrow, /datum/crafting_recipe/bone_bow, /datum/crafting_recipe/ashen_arrow, /datum/crafting_recipe/quiver, /datum/crafting_recipe/bow_tablet)
icon_state = "stone_tablet"
oneuse = FALSE
remarks = list("Sticking burning arrows into the sand makes them stronger?", "Breaking the bone apart to get shards, not sharpening the bone.", "Sinew is just like rope?")
/obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book
name = "Under The Oven"

View File

@@ -117,7 +117,7 @@
if(!O.reagents)
continue
var/reagent_list = pretty_string_from_reagent_list(O.reagents)
user.log_message("removed [O] ([reagent_list]) from [src]")
user.log_message("removed [O] ([reagent_list]) from [src]", LOG_GAME)
beakers = list()
to_chat(user, "<span class='notice'>You open the [initial(name)] assembly and remove the payload.</span>")
return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
@@ -177,7 +177,7 @@
/obj/item/grenade/chem_grenade/prime()
if(stage != READY)
return
return FALSE
var/list/datum/reagents/reactants = list()
for(var/obj/item/reagent_containers/glass/G in beakers)
@@ -192,7 +192,7 @@
O.forceMove(drop_location())
beakers = list()
stage_change(EMPTY)
return
return FALSE
if(nadeassembly)
var/mob/M = get_mob_by_ckey(assemblyattacher)
@@ -205,6 +205,7 @@
update_mob()
qdel(src)
return TRUE
//Large chem grenades accept slime cores and use the appropriately.
/obj/item/grenade/chem_grenade/large
@@ -219,7 +220,7 @@
/obj/item/grenade/chem_grenade/large/prime()
if(stage != READY)
return
return FALSE
for(var/obj/item/slime_extract/S in beakers)
if(S.Uses)
@@ -237,7 +238,7 @@
else
S.forceMove(get_turf(src))
no_splash = TRUE
..()
return ..()
//I tried to just put it in the allowed_containers list but
//if you do that it must have reagents. If you're going to
@@ -288,7 +289,7 @@
/obj/item/grenade/chem_grenade/adv_release/prime()
if(stage != READY)
return
return FALSE
var/total_volume = 0
for(var/obj/item/reagent_containers/RC in beakers)
@@ -296,7 +297,7 @@
if(!total_volume)
qdel(src)
qdel(nadeassembly)
return
return FALSE
var/fraction = unit_spread/total_volume
var/datum/reagents/reactants = new(unit_spread)
reactants.my_atom = src
@@ -313,6 +314,7 @@
else
addtimer(CALLBACK(src, .proc/prime), det_time)
log_game("A grenade detonated at [AREACOORD(DT)]")
return TRUE

View File

@@ -34,12 +34,12 @@
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE))
if(prob(50))
if(clumsy)
if(clumsy_check == GRENADE_CLUMSY_FUMBLE && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
else if(!clumsy && (clumsy_check == GRENADE_NONCLUMSY_FUMBLE))
else if(clumsy_check == GRENADE_NONCLUMSY_FUMBLE && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)))
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
preprime(user, 5, FALSE)
return FALSE

View File

@@ -92,6 +92,14 @@
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/combifan
name = "ATMOS holo-combifan projector"
desc = "A holographic projector that creates holographic combi-fans that prevent changes in atmosphere and temperature conditions. Somehow."
icon_state = "signmaker_atmos"
holosign_type = /obj/structure/holosign/barrier/combifan
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/medical
name = "\improper PENLITE barrier projector"
desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases."

View File

@@ -72,20 +72,21 @@
display_names += list(initial(A.name) = A)
var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
var/turf/T = get_turf(M)
if(!T || QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
return
var/index = display_names.Find(choice)
var/A = holy_armor_list[index]
GLOB.holy_armor_type = A
var/holy_armor_box = new A
var/holy_armor_box = new A(T)
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
if(holy_armor_box)
qdel(src)
M.put_in_active_hand(holy_armor_box)///YOU COMPILED
M.put_in_hands(holy_armor_box)
/obj/item/storage/box/holy
name = "Templar Kit"

View File

@@ -82,8 +82,9 @@
/obj/item/implant/explosive/proc/boom_goes_the_weasel()
explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
imp_in?.gib(TRUE)
qdel(src)
if(!QDELETED(imp_in))
imp_in.gib(TRUE)
qdel(src)
/obj/item/implant/explosive/macro
name = "macrobomb implant"

View File

@@ -0,0 +1,121 @@
#define HIJACK_APC_MAX_AMOUNT 5
/obj/item/implant/hijack
name = "hijack implant"
desc = "Allows you to control the machinery in a room by hacking into the APC."
actions_types = list(/datum/action/item_action/hands_free/activate, /datum/action/item_action/removeAPCs, /datum/action/item_action/accessAPCs, /datum/action/item_action/stealthmodetoggle)
activated = 1
var/toggled = FALSE
icon_state = "hijack"
var/eye_color
var/stealthmode = FALSE
var/stealthcooldown = 0
var/hijacking = FALSE
/obj/item/implant/hijack/activate()
. = ..()
toggled = !toggled
imp_in.click_intercept = toggled ? src : null
imp_in.siliconaccesstoggle = toggled ? TRUE : FALSE
to_chat(imp_in,"<span class='notice'>You turn [toggled ? "on" : "off"] [src]'s silicon interactions.</span>")
toggle_eyes()
/obj/item/implant/hijack/proc/toggle_eyes()
if (!ishuman(imp_in))
return
var/on = toggled && !stealthmode
var/mob/living/carbon/human/H = imp_in
H.eye_color = on ? "ff0" : eye_color
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.update_body()
/obj/item/implant/hijack/implant(mob/living/target, mob/user, silent = FALSE)
if(..())
ADD_TRAIT(target, TRAIT_HIJACKER, "implant")
if (ishuman(target))
var/mob/living/carbon/human/H = target
eye_color = H.eye_color
return TRUE
/obj/item/implant/hijack/removed(mob/living/source, silent = FALSE, special = 0)
if(..())
REMOVE_TRAIT(source, TRAIT_HIJACKER, "implant")
for (var/area/area in source.siliconaccessareas)
source.toggleSiliconAccessArea(area)
var/obj/machinery/power/apc/apc = area.get_apc()
if (apc)
apc.hijacker = null
apc.set_hijacked_lighting()
apc.update_icon()
if (ishuman(source))
var/mob/living/carbon/human/H = source
H.eye_color = eye_color
return TRUE
/obj/item/implant/hijack/proc/InterceptClickOn(mob/living/user,params,atom/object)
if (isitem(object) || !toggled || user.incapacitated())
return
if (stealthmode == FALSE && istype(object,/obj/machinery/power/apc) && !user.CanReach(object))
if (hijack_remotely(object))
return
if (stealthmode && !user.CanReach(object))
return
if (!object.hasSiliconAccessInArea(imp_in))
return
var/list/modifiers = params2list(params)
imp_in.face_atom(object)
if (modifiers["shift"] && modifiers["ctrl"])
object.AICtrlShiftClick(imp_in)
return TRUE
if (modifiers["shift"])
object.AIShiftClick(imp_in)
return TRUE
if (modifiers["ctrl"])
object.AICtrlClick(imp_in)
return TRUE
if (modifiers["alt"])
object.AIAltClick(imp_in)
return TRUE
if (user.get_active_held_item())
return
if (user.CanReach(object))
object.attack_robot(imp_in)
else
object.attack_ai(imp_in)
return TRUE
/obj/item/implant/hijack/proc/hijack_remotely(obj/machinery/power/apc/apc)
if (apc.hijacker || hijacking)
return FALSE //can't remotely hijack an already hijacked APC
hijacking = TRUE
to_chat(imp_in, "<span class='notice'>Establishing remote connection with APC.</span>")
if (!do_after(imp_in, 4 SECONDS,target=apc))
to_chat(imp_in, "<span class='warning'>Aborting.</span>")
hijacking = FALSE
return TRUE
if (LAZYLEN(imp_in.siliconaccessareas) >= HIJACK_APC_MAX_AMOUNT)
to_chat(src,"<span class='warning'>You are connected to too many APCs! Too many more will fry your brain.</span>")
hijacking = FALSE
return TRUE
imp_in.light_power = 2
imp_in.light_range = 2
imp_in.light_color = COLOR_YELLOW
imp_in.update_light()
imp_in.visible_message("<span class='warning'>[imp_in] starts glowing a with a hollow yellow light!</span>")
to_chat(imp_in, "<span class='notice'>Beginning hijack of APC.</span>")
if (do_after(imp_in, 21 SECONDS,target=apc))
apc.hijacker = imp_in
stealthmode = FALSE
apc.set_hijacked_lighting()
imp_in.toggleSiliconAccessArea(apc.area)
apc.update_icon()
stealthcooldown = world.time + 1 MINUTES + 30 SECONDS
toggle_eyes()
else
to_chat(imp_in, "<span class='warning'>Aborting.</span>")
hijacking = FALSE
imp_in.light_power = 0
imp_in.light_range = 0
imp_in.light_color = COLOR_YELLOW
imp_in.update_light()
return TRUE

View File

@@ -74,4 +74,8 @@
/obj/item/implanter/stealth
name = "implanter (stealth)"
imp_type = /obj/item/implant/stealth
imp_type = /obj/item/implant/stealth
/obj/item/implanter/hijack
name = "implanter (hijack)"
imp_type = /obj/item/implant/hijack

View File

@@ -259,7 +259,7 @@
light_color = "#37FFF7"
actions_types = list()
/obj/item/melee/transforming/energy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
/obj/item/melee/transforming/energy/sword/cx/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE

View File

@@ -19,3 +19,11 @@
icon_state = "skub"
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("skubbed")
/obj/item/supermatterspray
name = "supermatter spray"
desc = "A spray bottle containing some kind of magical spray to fix the SM. \"Do not inhale.\" is written on the side. Unless aimed at the supermatter, it does nothing."
icon = 'icons/obj/supermatter.dmi'
icon_state = "supermatterspray"
w_class = WEIGHT_CLASS_SMALL
var/usesleft = 2

View File

@@ -21,7 +21,7 @@
/obj/item/mop/New()
..()
create_reagents(mopcap)
create_reagents(mopcap, NONE, NO_REAGENTS_VALUE)
/obj/item/mop/proc/clean(turf/A)

View File

@@ -26,6 +26,7 @@
/obj/item/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
target = null
return ..()
/obj/item/pinpointer/attack_self(mob/living/user)
@@ -57,7 +58,7 @@
return
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
if(here.z != there.z)
if(!here || !there || here.z != there.z)
add_overlay("pinon[alert ? "alert" : ""]null")
return
if(get_dist_euclidian(here,there) <= minimum_range)
@@ -143,3 +144,34 @@
target = null
if(!target) //target can be set to null from above code, or elsewhere
active = FALSE
/obj/item/pinpointer/pair
name = "pair pinpointer"
desc = "A handheld tracking device that locks onto its other half of the matching pair."
var/other_pair
/obj/item/pinpointer/pair/Destroy()
other_pair = null
. = ..()
/obj/item/pinpointer/pair/scan_for_target()
target = other_pair
/obj/item/pinpointer/pair/examine(mob/user)
. = ..()
if(!active || !target)
return
var/mob/mob_holder = get(target, /mob)
if(istype(mob_holder))
to_chat(user, "Its pair is being held by [mob_holder].")
return
/obj/item/storage/box/pinpointer_pairs
name = "pinpointer pair box"
/obj/item/storage/box/pinpointer_pairs/PopulateContents()
var/obj/item/pinpointer/pair/A = new(src)
var/obj/item/pinpointer/pair/B = new(src)
A.other_pair = B
B.other_pair = A

View File

@@ -31,7 +31,16 @@
var/normal_desc
//--end of love :'(--
/obj/item/toy/plush/Initialize()
var/snowflake_id //if we set from a config snowflake plushie.
var/can_random_spawn = TRUE //if this is FALSE, don't spawn this for random plushies.
/obj/item/toy/plush/random_snowflake/Initialize(mapload, set_snowflake_id)
. = ..()
var/list/configlist = CONFIG_GET(keyed_list/snowflake_plushies)
var/id = pick(configlist)
set_snowflake_from_config(id)
/obj/item/toy/plush/Initialize(mapload, set_snowflake_id)
. = ..()
AddComponent(/datum/component/squeak, squeak_override)
@@ -50,6 +59,9 @@
normal_desc = desc
if(set_snowflake_id)
set_snowflake_from_config(set_snowflake_id)
/obj/item/toy/plush/Destroy()
QDEL_NULL(grenade)
@@ -97,6 +109,44 @@
return ..()
/obj/item/toy/plush/proc/set_snowflake_from_config(id)
var/list/configlist = CONFIG_GET(keyed_list/snowflake_plushies)
var/list/jsonlist = configlist[id]
ASSERT(jsonlist)
jsonlist = json_decode(jsonlist)
if(jsonlist["inherit_from"])
var/path = text2path(jsonlist["inherit_from"])
if(!ispath(path, /obj/item/toy/plush))
stack_trace("Invalid path for inheritance")
else
var/obj/item/toy/plush/P = new path //can't initial() lists
name = P.name
desc = P.desc
icon_state = P.icon_state
item_state = P.item_state
icon = P.icon
squeak_override = P.squeak_override
attack_verb = P.attack_verb
gender = P.gender
qdel(P)
if(jsonlist["name"])
name = jsonlist["name"]
if(jsonlist["desc"])
desc = jsonlist["desc"]
if(jsonlist["gender"])
gender = jsonlist["gender"]
if(jsonlist["icon_state"])
icon_state = jsonlist["icon_state"]
item_state = jsonlist["item_state"]
icon = 'config/plushies/sprites.dmi'
if(jsonlist["attack_verb"])
attack_verb = jsonlist["attack_verb"]
if(jsonlist["squeak_override"])
squeak_override = jsonlist["squeak_override"]
if(squeak_override)
var/datum/component/squeak/S = GetComponent(/datum/component/squeak)
S?.override_squeak_sounds = squeak_override
/obj/item/toy/plush/handle_atom_del(atom/A)
if(A == grenade)
grenade = null
@@ -367,13 +417,22 @@
if(mood_message)
desc += mood_message
GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
/proc/valid_plushie_paths()
. = list()
for(var/i in subtypesof(/obj/item/toy/plush))
var/obj/item/toy/plush/abstract = i
if(!initial(abstract.can_random_spawn))
continue
. += i
/obj/item/toy/plush/random
name = "Illegal plushie"
desc = "Something fucked up"
var/blacklisted_plushes = list(/obj/item/toy/plush/carpplushie/dehy_carp, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random)
can_random_spawn = FALSE
/obj/item/toy/plush/random/Initialize()
var/newtype = pick(subtypesof(/obj/item/toy/plush) - typecacheof(blacklisted_plushes))
var/newtype = prob(CONFIG_GET(number/snowflake_plushie_prob))? /obj/item/toy/plush/random_snowflake : pick(GLOB.valid_plushie_paths)
new newtype(loc)
return INITIALIZE_HINT_QDEL
@@ -504,115 +563,12 @@
attack_verb = list("clawed", "hissed", "tail slapped")
squeak_override = list('sound/weapons/slash.ogg' = 1)
/obj/item/toy/plush/lizardplushie/durgit
icon_state = "durgit"
item_state = "durgit"
squeak_override = list('modular_citadel/sound/voice/weh.ogg' = 1) //Durgit's the origin of the sound
/obj/item/toy/plush/lizardplushie/rio
icon_state = "rio"
item_state = "rio"
/obj/item/toy/plush/lizardplushie/dan
icon_state = "dan"
item_state = "dan"
/obj/item/toy/plush/lizardplushie/urinsu
icon_state = "urinsu"
item_state = "urinsu"
/obj/item/toy/plush/lizardplushie/arfrehn
icon_state = "arfrehn"
item_state = "arfrehn"
/obj/item/toy/plush/lizardplushie/soars
icon_state = "soars"
item_state = "soars"
/obj/item/toy/plush/lizardplushie/ghostie
icon_state = "ghostie"
item_state = "ghostie"
/obj/item/toy/plush/lizardplushie/amber
icon_state = "amber"
item_state = "amber"
/obj/item/toy/plush/lizardplushie/cyan
icon_state = "cyan"
item_state = "cyan"
/obj/item/toy/plush/lizardplushie/meena
icon_state = "meena"
item_state = "meena"
/obj/item/toy/plush/lizardplushie/stalks
icon_state = "stalks"
item_state = "stalks"
/obj/item/toy/plush/lizardplushie/kobold
name = "kobold plushie"
desc = "An adorable stuffed toy that resembles a kobold."
icon_state = "kobold"
item_state = "kobold"
/obj/item/toy/plush/lizardplushie/gorgi
icon_state = "gorgi"
item_state = "gorgi"
/obj/item/toy/plush/lizardplushie/almaz
icon_state = "almaz"
item_state = "almaz"
squeak_override = list('modular_citadel/sound/voice/raptor_purr.ogg' = 1)
/obj/item/toy/plush/lizardplushie/garou
icon_state = "garou"
item_state = "garou"
/obj/item/toy/plush/lizardplushie/augments
icon_state = "augments"
item_state = "augments"
squeak_override = list('modular_citadel/sound/voice/weh.ogg' = 1) //I have no mouth and I must weh
attack_verb = list("hugged", "patted", "snugged", "booped")
/obj/item/toy/plush/lizardplushie/xekov
icon_state = "xekov"
item_state = "xekov"
/obj/item/toy/plush/lizardplushie/greg
icon_state = "greg"
item_state = "greg"
/obj/item/toy/plush/lizardplushie/sin
icon_state = "sin"
item_state = "sin"
desc = "An adorable stuffed toy that resembles a lizardperson.. It faintly smells of sulfur."
/obj/item/toy/plush/lizardplushie/ends
icon_state = "ends"
item_state = "ends"
/obj/item/toy/plush/lizardplushie/lyssa
icon_state = "lyssa"
item_state = "lyssa"
/obj/item/toy/plush/snakeplushie
name = "snake plushie"
desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing."
icon_state = "plushie_snake"
item_state = "plushie_snake"
attack_verb = list("bitten", "hissed", "tail slapped")
squeak_override = list('modular_citadel/sound/voice/hiss.ogg' = 1)
/obj/item/toy/plush/snakeplushie/sasha
icon_state = "sasha"
item_state = "sasha"
/obj/item/toy/plush/snakeplushie/shay
icon_state = "shay"
item_state = "shay"
/obj/item/toy/plush/snakeplushie/vulken
icon_state = "vulken"
item_state = "vulken"
/obj/item/toy/plush/nukeplushie
name = "operative plushie"
desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
@@ -630,29 +586,17 @@
squeak_override = list('sound/effects/blobattack.ogg' = 1)
gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy
/obj/item/toy/plush/slimeplushie/annie
desc = "An adorable stuffed toy that resembles a slimey crewmember."
icon_state = "annie"
item_state = "annie"
/obj/item/toy/plush/slimeplushie/paxton
desc = "An adorable stuffed toy that resembles a slimey crewmember."
icon_state = "paxton"
item_state = "paxton"
attack_verb = list("CQC'd", "jabroni'd", "powergamed", "robusted", "cakehatted")
gender = MALE
/obj/item/toy/plush/awakenedplushie
name = "awakened plushie"
desc = "An ancient plushie that has grown enlightened to the true nature of reality."
icon_state = "plushie_awake"
item_state = "plushie_awake"
can_random_spawn = FALSE
/obj/item/toy/plush/awakenedplushie/ComponentInitialize()
. = ..()
AddComponent(/datum/component/edit_complainer)
/obj/item/toy/plush/beeplushie
name = "bee plushie"
desc = "A cute toy that resembles an even cuter bee."
@@ -668,21 +612,7 @@
icon_state = "bumble"
item_state = "bumble"
squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1)
/obj/item/toy/plush/mothplushie/nameko
icon_state = "nameko"
item_state = "nameko"
/obj/item/toy/plush/mothplushie/suru
icon_state = "suru"
item_state = "suru"
/obj/item/toy/plush/xeno
name = "xenohybrid plushie"
desc = "An adorable stuffed toy that resmembles a xenomorphic crewmember."
icon_state = "seras"
item_state = "seras"
squeak_override = list('sound/voice/hiss2.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/lampplushie
name = "lamp plushie"
@@ -736,20 +666,6 @@
icon_state = "scrubpuppy"
item_state = "scrubpuppy"
/obj/item/toy/plush/borgplushie/seeking
icon_state = "seeking"
item_state = "seeking"
/obj/item/toy/plush/borgplushie/neeb
icon_state = "neeb"
item_state = "neeb"
/obj/item/toy/plush/borgplushie/bhijn
desc = "An adorable stuffed toy of a IPC."
icon_state = "bhijn"
item_state = "bhijn"
attack_verb = list("closed", "reworked", "merged")
/obj/item/toy/plush/aiplush
name = "AI plushie"
desc = "A little stuffed toy AI core... it appears to be malfunctioning."
@@ -758,246 +674,22 @@
attack_verb = list("hacked", "detonated", "overloaded")
squeak_override = list('sound/machines/beep.ogg' = 9, 'sound/machines/buzz-two.ogg' = 1)
/obj/item/toy/plush/bird
name = "bird plushie"
desc = "An adorable stuffed plushie that resembles an avian."
icon_state = "sylas"
item_state = "sylas"
attack_verb = list("peeped", "beeped", "poofed")
squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1)
/obj/item/toy/plush/bird/esela
icon_state = "esela"
item_state = "esela"
/obj/item/toy/plush/bird/jahonna
icon_state = "jahonna"
item_state = "jahonna"
/obj/item/toy/plush/bird/krick
icon_state = "krick"
item_state = "krick"
/obj/item/toy/plush/bird/birddi
icon_state = "birddi"
item_state = "birddi"
/obj/item/toy/plush/bird/jewel
icon_state = "jewel"
item_state = "jewel"
/obj/item/toy/plush/sergal
name = "sergal plushie"
desc = "An adorable stuffed plushie that resembles a sagaru."
icon_state = "faux"
item_state = "faux"
squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1)
/obj/item/toy/plush/sergal/gladwyn
icon_state = "gladwyn"
item_state = "gladwyn"
/obj/item/toy/plush/sergal/jermaine
icon_state = "jermaine"
item_state = "jermaine"
/obj/item/toy/plush/mammal
name = "mammal plushie"
desc = "An adorable stuffed toy resembling some sort of crew member."
icon_state = "dubious"
item_state = "dubious"
/obj/item/toy/plush/mammal/gavin
icon_state = "gavin"
item_state = "gavin"
/obj/item/toy/plush/mammal/blep
icon_state = "blep"
item_state = "blep"
/obj/item/toy/plush/mammal/circe
desc = "A luxuriously soft toy that resembles a nine-tailed kitsune."
icon_state = "circe"
item_state = "circe"
attack_verb = list("medicated", "tailhugged", "kissed")
/obj/item/toy/plush/mammal/robin
icon_state = "robin"
item_state = "robin"
/obj/item/toy/plush/mammal/pavel
icon_state = "pavel"
item_state = "pavel"
/obj/item/toy/plush/mammal/mason
icon_state = "mason"
item_state = "mason"
/obj/item/toy/plush/mammal/oten
icon_state = "oten"
item_state = "oten"
/obj/item/toy/plush/mammal/ray
icon_state = "ray"
item_state = "ray"
/obj/item/toy/plush/mammal/redtail
icon_state = "redtail"
item_state = "redtail"
/obj/item/toy/plush/mammal/dawud
icon_state = "dawud"
item_state = "dawud"
/obj/item/toy/plush/mammal/edgar
icon_state = "edgar"
item_state = "edgar"
attack_verb = list("collared", "tricked", "headpatted")
/obj/item/toy/plush/mammal/frank
icon_state = "frank"
item_state = "frank"
/obj/item/toy/plush/mammal/poojawa
icon_state = "poojawa"
item_state = "poojawa"
/obj/item/toy/plush/mammal/hazel
icon_state = "hazel"
item_state = "hazel"
/obj/item/toy/plush/mammal/joker
icon_state = "joker"
item_state = "joker"
/obj/item/toy/plush/mammal/gunther
icon_state = "gunther"
item_state = "gunther"
/obj/item/toy/plush/mammal/fox
icon_state = "fox"
item_state = "fox"
/obj/item/toy/plush/mammal/rae
desc = "An adorable stuffed toy of an artic fox."
icon_state = "rae"
item_state = "rae"
/obj/item/toy/plush/snakeplushie
name = "snake plushie"
desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing."
icon_state = "plushie_snake"
item_state = "plushie_snake"
attack_verb = list("bitten", "hissed", "tail slapped")
squeak_override = list('modular_citadel/sound/voice/hiss.ogg' = 1)
/obj/item/toy/plush/mammal/zed
desc = "A masked stuffed toy that resembles a fierce miner. He even comes with his own little crusher!"
icon_state = "zed"
item_state = "zed"
attack_verb = list("ENDED", "CRUSHED", "GNOMED")
/obj/item/toy/plush/mammal/justin
icon_state = "justin"
item_state = "justin"
attack_verb = list("buttslapped", "fixed")
/obj/item/toy/plush/mammal/reece
icon_state = "reece"
item_state = "reece"
attack_verb = list("healed", "cured", "demoted")
/obj/item/toy/plush/mammal/redwood
desc = "An adorable stuffed toy resembling a Nanotrasen Captain. That just happens to be a bunny."
icon_state = "redwood"
item_state = "redwood"
attack_verb = list("ordered", "bapped", "reprimanded")
/obj/item/toy/plush/mammal/marisol
desc = "An adorable stuffed toy resembling a demi-wolf security officer."
icon_state = "marisol"
item_state = "marisol"
attack_verb = list("arrested", "harmbattoned", "lasered")
/obj/item/toy/plush/mammal/minty
desc = "An adorable stuffed toy resembling some sort of crew member. It smells like mint.."
icon_state = "minty"
item_state = "minty"
attack_verb = list("freshened", "brushed")
/obj/item/toy/plush/mammal/dog
desc = "An adorable stuffed toy that resembles a canine."
icon_state = "katlin"
item_state = "katlin"
attack_verb = list("barked", "boofed", "borked")
squeak_override = list(
'modular_citadel/sound/voice/bark1.ogg' = 1,
'modular_citadel/sound/voice/bark2.ogg' = 1
)
/obj/item/toy/plush/mammal/dog/frost
icon_state = "frost"
item_state = "frost"
/obj/item/toy/plush/mammal/dog/atticus
icon_state = "atticus"
item_state = "atticus"
/obj/item/toy/plush/mammal/dog/fletch
icon_state = "fletch"
item_state = "fletch"
/obj/item/toy/plush/mammal/dog/vincent
icon_state = "vincent"
item_state = "vincent"
/obj/item/toy/plush/mammal/dog/zigfried
desc = "An adorable stuffed toy of a very good boy."
icon_state = "zigfried"
item_state = "zigfried"
/obj/item/toy/plush/mammal/dog/nikolai
icon_state = "nikolai"
item_state = "nikolai"
/obj/item/toy/plush/mammal/dog/flynn
icon_state = "flynn"
item_state = "flynn"
/obj/item/toy/plush/mammal/dog/fritz
icon_state = "fritz"
item_state = "fritz"
attack_verb = list("barked", "boofed", "shotgun'd")
obj_flags = UNIQUE_RENAME
unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad")
/obj/item/toy/plush/mammal/dog/jesse
desc = "An adorable wolf toy that resembles a cream-colored wolf. He has a little pride flag!"
icon_state = "jesse"
item_state = "jesse"
attack_verb = list("greeted", "merc'd", "howdy'd")
/obj/item/toy/plush/catgirl
name = "feline plushie"
desc = "An adorable stuffed toy that resembles a feline."
icon_state = "bailey"
item_state = "bailey"
attack_verb = list("headbutt", "scritched", "bit")
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
/obj/item/toy/plush/catgirl/mikeel
desc = "An adorable stuffed toy of some tauric cat person."
icon_state = "mikeel"
item_state = "mikeel"
/obj/item/toy/plush/catgirl/skylar
desc = "An adorable stuffed toy that resembles a degenerate."
icon_state = "skylar2"
item_state = "skylar2"
attack_verb = list("powergamed", "merged", "tabled")
squeak_override = list('sound/effects/meow1.ogg' = 1)
/obj/item/toy/plush/catgirl/drew
icon_state = "drew"
item_state = "drew"
/obj/item/toy/plush/catgirl/trilby
desc = "A masked stuffed toy that resembles a feline scientist."
icon_state = "trilby"
item_state = "trilby"
attack_verb = list("PR'd", "coded", "remembered")
/obj/item/toy/plush/mammal
name = "mammal plushie"
desc = "An adorable stuffed toy resembling some sort of crew member."
can_random_spawn = FALSE
/obj/item/toy/plush/catgirl/fermis
name = "medcat plushie"
@@ -1007,20 +699,36 @@
attack_verb = list("cuddled", "petpatted", "wigglepurred")
squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1)
/obj/item/toy/plush/catgirl/mariaf
desc = "An adorable stuffed toy that resembles a very tall cat girl."
icon_state = "mariaf"
item_state = "mariaf"
attack_verb = list("hugged", "stabbed", "licked")
/obj/item/toy/plush/xeno
name = "xenohybrid plushie"
desc = "An adorable stuffed toy that resmembles a xenomorphic crewmember."
squeak_override = list('sound/voice/hiss2.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/catgirl/maya
desc = "An adorable stuffed toy that resembles an angry cat girl. She has her own tiny nuke disk!"
icon_state = "maya"
item_state = "maya"
attack_verb = list("nuked", "arrested", "harmbatonned")
/obj/item/toy/plush/bird
name = "bird plushie"
desc = "An adorable stuffed plushie that resembles an avian."
attack_verb = list("peeped", "beeped", "poofed")
squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/catgirl/marisa
desc = "An adorable stuffed toy that resembles a crew member, or maybe a witch. Having it makes you feel you can win."
icon_state = "marisa"
item_state = "marisa"
attack_verb = list("blasted", "sparked", "dazzled")
/obj/item/toy/plush/sergal
name = "sergal plushie"
desc = "An adorable stuffed plushie that resembles a sagaru."
squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/mammal/dog
desc = "An adorable stuffed toy that resembles a canine."
attack_verb = list("barked", "boofed", "borked")
squeak_override = list(
'modular_citadel/sound/voice/bark1.ogg' = 1,
'modular_citadel/sound/voice/bark2.ogg' = 1
)
/obj/item/toy/plush/catgirl
name = "feline plushie"
desc = "An adorable stuffed toy that resembles a feline."
attack_verb = list("headbutt", "scritched", "bit")
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
can_random_spawn = FALSE

View File

@@ -44,9 +44,9 @@
if(H.stat == DEAD || H == user)
continue
if(H.mind && (has_job_loyalties || has_role_loyalties))
if(has_job_loyalties && H.mind.assigned_role in job_loyalties)
if(has_job_loyalties && (H.mind.assigned_role in job_loyalties))
inspired += H
else if(has_role_loyalties && H.mind.special_role in role_loyalties)
else if(has_role_loyalties && (H.mind.special_role in role_loyalties))
inspired += H
else if(check_inspiration(H))
inspired += H

View File

@@ -203,7 +203,7 @@
var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA = new (R.module)
R.module.basic_modules += KA
R.module.add_module(KA, FALSE, TRUE)
/obj/item/borg/upgrade/advcutter
name = "mining cyborg advanced plasma cutter"
@@ -335,7 +335,6 @@
var/msg_cooldown = 0
var/on = FALSE
var/powercost = 10
var/mob/living/silicon/robot/cyborg
var/datum/action/toggle_action
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R, user = usr)
@@ -346,7 +345,6 @@
to_chat(user, "<span class='warning'>This unit is already equipped with a self-repair module.</span>")
return FALSE
cyborg = R
icon_state = "selfrepair_off"
toggle_action = new /datum/action/item_action/toggle(src)
toggle_action.Grant(R)
@@ -354,34 +352,20 @@
/obj/item/borg/upgrade/selfrepair/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
if (.)
toggle_action.Remove(cyborg)
toggle_action.Remove(R)
QDEL_NULL(toggle_action)
cyborg = null
deactivate_sr()
/obj/item/borg/upgrade/selfrepair/dropped()
. = ..()
addtimer(CALLBACK(src, .proc/check_dropped), 1)
/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
if(loc != cyborg)
toggle_action.Remove(cyborg)
QDEL_NULL(toggle_action)
cyborg = null
deactivate_sr()
/obj/item/borg/upgrade/selfrepair/ui_action_click()
on = !on
if(on)
to_chat(cyborg, "<span class='notice'>You activate the self-repair module.</span>")
START_PROCESSING(SSobj, src)
to_chat(toggle_action.owner, "<span class='notice'>You deactivate the self-repair module.</span>")
deactivate_sr()
else
to_chat(cyborg, "<span class='notice'>You deactivate the self-repair module.</span>")
STOP_PROCESSING(SSobj, src)
update_icon()
to_chat(toggle_action.owner, "<span class='notice'>You activate the self-repair module.</span>")
activate_sr()
/obj/item/borg/upgrade/selfrepair/update_icon()
if(cyborg)
if(toggle_action)
icon_state = "selfrepair_[on ? "on" : "off"]"
for(var/X in actions)
var/datum/action/A = X
@@ -389,6 +373,11 @@
else
icon_state = "cyborg_upgrade5"
/obj/item/borg/upgrade/selfrepair/proc/activate_sr()
START_PROCESSING(SSobj, src)
on = TRUE
update_icon()
/obj/item/borg/upgrade/selfrepair/proc/deactivate_sr()
STOP_PROCESSING(SSobj, src)
on = FALSE
@@ -399,7 +388,9 @@
repair_tick = 1
return
if(cyborg && (cyborg.stat != DEAD) && on)
var/mob/living/silicon/robot/cyborg = toggle_action.owner
if(istype(cyborg) && (cyborg.stat != DEAD) && on)
if(!cyborg.cell)
to_chat(cyborg, "<span class='warning'>Self-repair module deactivated. Please, insert the power cell.</span>")
deactivate_sr()

View File

@@ -1,12 +1,16 @@
/obj/item/shield
name = "shield"
icon = 'icons/obj/items_and_weapons.dmi'
block_chance = 50
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
var/transparent = FALSE // makes beam projectiles pass through the shield
/obj/item/shield/proc/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK)
return TRUE
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "riot"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
@@ -19,6 +23,19 @@
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
transparent = TRUE
max_integrity = 75
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(transparent && (hitby.pass_flags & PASSGLASS))
return FALSE
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
final_block_chance = 100
. = ..()
if(.)
on_shield_block(owner, hitby, attack_text, damage, attack_type)
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
@@ -26,14 +43,40 @@
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else if(istype(W, /obj/item/stack/sheet/mineral/titanium))
if(obj_integrity >= max_integrity)
to_chat(user, "<span class='warning'>[src] is already in perfect condition.</span>")
else
var/obj/item/stack/sheet/mineral/titanium/T = W
T.use(1)
obj_integrity = max_integrity
to_chat(user, "<span class='notice'>You repair [src] with [T].</span>")
else
return ..()
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
final_block_chance = 100
/obj/item/shield/riot/examine(mob/user)
. = ..()
var/healthpercent = round((obj_integrity/max_integrity) * 100, 1)
switch(healthpercent)
if(50 to 99)
. += "<span class='info'>It looks slightly damaged.</span>"
if(25 to 50)
. += "<span class='info'>It appears heavily damaged.</span>"
if(0 to 25)
. += "<span class='warning'>It's falling apart!</span>"
/obj/item/shield/riot/proc/shatter(mob/living/carbon/human/owner)
playsound(owner, 'sound/effects/glassbr3.ogg', 100)
new /obj/item/shard((get_turf(src)))
/obj/item/shield/riot/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK)
if(obj_integrity <= damage)
var/turf/T = get_turf(owner)
T.visible_message("<span class='warning'>[hitby] destroys [src]!</span>")
shatter(owner)
qdel(src)
return FALSE
take_damage(damage)
return ..()
/obj/item/shield/riot/roman
@@ -43,11 +86,18 @@
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
transparent = FALSE
max_integrity = 65
/obj/item/shield/riot/roman/fake
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
block_chance = 0
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
max_integrity = 30
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
playsound(owner, 'sound/effects/grillehit.ogg', 100)
new /obj/item/stack/sheet/metal(get_turf(src))
/obj/item/shield/riot/buckler
name = "wooden buckler"
@@ -59,11 +109,17 @@
materials = list()
resistance_flags = FLAMMABLE
block_chance = 30
transparent = FALSE
max_integrity = 55
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
playsound(owner, 'sound/effects/bang.ogg', 50)
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
icon = 'icons/obj/items_and_weapons.dmi'
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
@@ -91,7 +147,7 @@
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "[base_icon_state][active]"
@@ -101,21 +157,20 @@
throwforce = on_throwforce
throw_speed = on_throw_speed
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = initial(force)
throwforce = initial(throwforce)
throw_speed = initial(throw_speed)
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "teleriot0"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
@@ -135,7 +190,7 @@
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
icon_state = "teleriot[active]"
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
if(active)
force = 8
@@ -181,3 +236,4 @@
throwforce = 15 //Massive pice of metal
w_class = WEIGHT_CLASS_HUGE
item_flags = SLOWS_WHILE_IN_HAND
transparent = FALSE

View File

@@ -1,7 +1,11 @@
/* Glass stack types
* Contains:
* Glass sheets
* Plasma glass
* Reinforced glass sheets
* Reinforced plasma glass
* Titanium glass
* Plastitanium glass
* Glass shards - TODO: Move this into code/game/object/item/weapons
*/
@@ -254,6 +258,9 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
merge_type = /obj/item/stack/sheet/plastitaniumglass
shard_type = /obj/item/shard
/obj/item/stack/sheet/plastitaniumglass/fifty
amount = 50
/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plastitaniumglass_recipes
return ..()
@@ -373,4 +380,8 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
throwforce = 11
icon_state = "plasmalarge"
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
icon_prefix = "plasma"
icon_prefix = "plasma"
/obj/item/shard/plasma/alien
name = "alien shard"
desc = "A nasty looking shard of advanced alloy glass."

View File

@@ -323,6 +323,9 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
point_value = 45
merge_type = /obj/item/stack/sheet/mineral/plastitanium
/obj/item/stack/sheet/mineral/plastitanium/fifty
amount = 50
GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
new/datum/stack_recipe("plastitanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20), \
))
@@ -401,6 +404,8 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 2, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien bar stool", /obj/item/chair/stool/bar/alien, 1, time = 20, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien stool", /obj/item/chair/stool/alien, 1, time = 20, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 20, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \

View File

@@ -51,6 +51,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
null, \
new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("trash bin", /obj/structure/closet/crate/bin, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE),\
null, \
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), \
@@ -154,6 +155,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
new/datum/stack_recipe("crate", /obj/structure/closet/crate, 5, time = 90, one_per_turf = TRUE), \
null, \
new /datum/stack_recipe_list("airlock assemblies", list( \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \
@@ -309,6 +311,15 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
recipes = GLOB.bamboo_recipes
return ..()
/obj/item/stack/sheet/mineral/bamboo/ten
amount = 10
/obj/item/stack/sheet/mineral/bamboo/twenty
amount = 20
/obj/item/stack/sheet/mineral/bamboo/fifty
amount = 50
/*
* Cloth
*/
@@ -365,6 +376,14 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
/*
* Silk
*/
GLOBAL_LIST_INIT(silk_recipes, list ( \
new/datum/stack_recipe("white jumpsuit", /obj/item/clothing/under/color/white, 4, time = 40), \
new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 2, time = 40), \
null, \
new/datum/stack_recipe("silk string", /obj/item/weaponcrafting/silkstring, 2, time = 40), \
))
/obj/item/stack/sheet/silk
name = "silk"
desc = "A long soft material. This one is just made out of cotton rather then any spiders or wyrms"
@@ -374,14 +393,14 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
novariants = TRUE
merge_type = /obj/item/stack/sheet/silk
//obj/item/stack/sheet/silk/Initialize(mapload, new_amount, merge = TRUE)
// recipes = GLOB.silk_recipes
// return ..()
/obj/item/stack/sheet/silk/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.silk_recipes
return ..()
/*
* Durathread
*/
GLOBAL_LIST_INIT(durathread_recipes, list ( \
GLOBAL_LIST_INIT(durathread_recipes, list ( \
new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/durathread, 4, time = 40),
new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \
new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \
@@ -688,6 +707,16 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
/*
* Bones
*/
GLOBAL_LIST_INIT(bone_recipes, list(
new /datum/stack_recipe("Bone Dagger", /obj/item/kitchen/knife/combat/bone, 2, time = 20), \
new /datum/stack_recipe("Skull Helmet", /obj/item/clothing/head/helmet/skull, 4, time = 30), \
new /datum/stack_recipe("Bone Armor", /obj/item/clothing/suit/armor/bone, 6, time = 30)))
/obj/item/stack/sheet/bone/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.bone_recipes
. = ..()
/obj/item/stack/sheet/bone
name = "bones"
icon = 'icons/obj/mining.dmi'
@@ -704,12 +733,15 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
grind_results = list(/datum/reagent/carbon = 10)
merge_type = /obj/item/stack/sheet/bone
/*
* Plastic
*/
GLOBAL_LIST_INIT(plastic_recipes, list(
new /datum/stack_recipe("see-through plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
new /datum/stack_recipe("opaque plastic flaps", /obj/structure/plasticflaps/opaque, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
new /datum/stack_recipe("water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/empty), \
new /datum/stack_recipe("large water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/large/empty,3), \
new /datum/stack_recipe("large trash cart", /obj/structure/closet/crate/bin,50),\
new /datum/stack_recipe("wet floor sign", /obj/item/caution, 2)))
/obj/item/stack/sheet/plastic

View File

@@ -399,11 +399,14 @@
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
blood_DNA = from.blood_DNA
fingerprints = from.fingerprints
fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
if(from.blood_DNA)
blood_DNA = from.blood_DNA.Copy()
if(from.fingerprints)
fingerprints = from.fingerprints.Copy()
if(from.fingerprintshidden)
fingerprintshidden = from.fingerprintshidden.Copy()
if(from.fingerprintslast)
fingerprintslast = from.fingerprintslast
/obj/item/stack/microwave_act(obj/machinery/microwave/M)
if(istype(M) && M.dirty < 100)

View File

@@ -528,6 +528,31 @@
for(var/i in 1 to 9)
new /obj/item/ammo_box/magazine/smgm45(src)
/obj/item/storage/backpack/duffelbag/syndie/ammo/dark_gygax
desc = "A large duffel bag, packed to the brim with various exosuit ammo."
/obj/item/storage/backpack/duffelbag/syndie/ammo/dark_gygax/PopulateContents()
new /obj/item/mecha_ammo/incendiary(src)
new /obj/item/mecha_ammo/incendiary(src)
new /obj/item/mecha_ammo/incendiary(src)
new /obj/item/mecha_ammo/flashbang(src)
new /obj/item/mecha_ammo/flashbang(src)
new /obj/item/mecha_ammo/flashbang(src)
/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler
desc = "A large duffel bag, packed to the brim with various exosuit ammo."
/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler/PopulateContents()
new /obj/item/mecha_ammo/lmg(src)
new /obj/item/mecha_ammo/lmg(src)
new /obj/item/mecha_ammo/lmg(src)
new /obj/item/mecha_ammo/scattershot(src)
new /obj/item/mecha_ammo/scattershot(src)
new /obj/item/mecha_ammo/scattershot(src)
new /obj/item/mecha_ammo/missiles_he(src)
new /obj/item/mecha_ammo/missiles_he(src)
new /obj/item/mecha_ammo/missiles_he(src)
/obj/item/storage/backpack/duffelbag/syndie/c20rbundle
desc = "A large duffel bag containing a C-20r, some magazines, and a cheap looking suppressor."

View File

@@ -399,10 +399,12 @@
/obj/item/storage/bag/bio/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL //Allows you to pick up Lungs, Liver, and Stomach
STR.max_combined_w_class = 200
STR.max_items = 25
STR.insert_preposition = "in"
STR.can_hold = typecacheof(list(/obj/item/slime_extract, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/blood, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/reagent_containers/food/snacks/monkeycube))
STR.can_hold = typecacheof(list(/obj/item/slime_extract, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/blood, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/reagent_containers/food/snacks/monkeycube, /obj/item/organ, /obj/item/reagent_containers/food/snacks/meat/slab, /obj/item/bodypart))
STR.cant_hold = typecacheof(list(/obj/item/organ/brain, /obj/item/organ/liver/cybernetic, /obj/item/organ/heart/cybernetic, /obj/item/organ/lungs/cybernetic, /obj/item/organ/tongue/cybernetic, /obj/item/organ/ears/cybernetic, /obj/item/organ/eyes/robotic, /obj/item/organ/cyberimp))
/obj/item/storage/bag/bio/holding
name = "bio bag of holding"

View File

@@ -179,17 +179,23 @@
/obj/item/pinpointer/crew
))
/obj/item/storage/belt/medical/surgery_belt_adv
name = "surgical supply belt"
desc = "A specialized belt designed for holding surgical equipment. It seems to have specific pockets for each and every surgical tool you can think of."
content_overlays = FALSE
var/advanced_drapes = FALSE
/obj/item/storage/belt/medical/surgery_belt_adv/PopulateContents()
new /obj/item/scalpel/advanced(src)
new /obj/item/retractor/advanced(src)
new /obj/item/surgicaldrill/advanced(src)
new /obj/item/surgical_drapes(src)
if(advanced_drapes)
new /obj/item/surgical_drapes/advanced(src)
else
new /obj/item/surgical_drapes(src)
/obj/item/storage/belt/medical/surgery_belt_adv/cmo
advanced_drapes = TRUE
/obj/item/storage/belt/security
name = "security belt"
@@ -575,6 +581,7 @@
/obj/item/key/janitor,
/obj/item/clothing/gloves,
/obj/item/melee/flyswatter,
/obj/item/twohanded/broom,
/obj/item/paint/paint_remover,
/obj/item/assembly/mousetrap,
/obj/item/screwdriver,
@@ -612,6 +619,21 @@
/obj/item/ammo_casing
))
/obj/item/storage/belt/quiver
name = "leather quiver"
desc = "A quiver made from the hide of some animal. Used to hold arrows."
icon_state = "quiver"
item_state = "quiver"
/obj/item/storage/belt/quiver/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 15
STR.display_numerical_stacking = TRUE
STR.can_hold = typecacheof(list(
/obj/item/ammo_casing/caseless/arrow
))
/obj/item/storage/belt/medolier
name = "medolier"
desc = "A medical bandolier for holding smartdarts."

View File

@@ -173,23 +173,25 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/unholy2clean = A.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
A.reagents.del_reagent(/datum/reagent/fuel/unholywater)
A.reagents.add_reagent(/datum/reagent/water/holywater,unholy2clean)
if(istype(A, /obj/item/twohanded/required/cult_bastard) && !iscultist(user))
var/obj/item/twohanded/required/cult_bastard/sword = A
to_chat(user, "<span class='notice'>You begin to exorcise [sword].</span>")
if(istype(A, /obj/item/twohanded/required/cult_bastard) || istype(A, /obj/item/melee/cultblade) && !iscultist(user))
to_chat(user, "<span class='notice'>You begin to exorcise [A].</span>")
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
if(do_after(user, 40, target = sword))
if(do_after(user, 40, target = A))
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
for(var/obj/item/soulstone/SS in sword.contents)
SS.usability = TRUE
for(var/mob/living/simple_animal/shade/EX in SS)
SSticker.mode.remove_cultist(EX.mind, 1, 0)
EX.icon_state = "ghost1"
EX.name = "Purified [EX.name]"
SS.release_shades(user)
qdel(SS)
new /obj/item/nullrod/claymore(get_turf(sword))
user.visible_message("<span class='notice'>[user] has purified the [sword]!</span>")
qdel(sword)
if(istype(A, /obj/item/twohanded/required/cult_bastard))
for(var/obj/item/soulstone/SS in A.contents)
SS.usability = TRUE
for(var/mob/living/simple_animal/shade/EX in SS)
SSticker.mode.remove_cultist(EX.mind, 1, 0)
EX.icon_state = "ghost1"
EX.name = "Purified [EX.name]"
SS.release_shades(user)
qdel(SS)
new /obj/item/nullrod/claymore(get_turf(A))
else
new /obj/item/claymore/purified(get_turf(A))
user.visible_message("<span class='notice'>[user] has purified [A]!</span>")
qdel(A)
else if(istype(A, /obj/item/soulstone) && !iscultist(user))
var/obj/item/soulstone/SS = A
@@ -244,3 +246,6 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
/obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna)
return FALSE
/obj/item/storage/book/bible/syndicate/empty
uses = 0

View File

@@ -322,6 +322,26 @@
for(var/i in 1 to 5)
new /obj/item/grenade/empgrenade(src)
/obj/item/storage/box/minibombs
name = "box of syndicate minibombs"
desc = "A box containing 2 highly explosive syndicate minibombs."
icon_state = "syndiebox"
illustration = "frag"
/obj/item/storage/box/minibombs/PopulateContents()
new /obj/item/grenade/syndieminibomb(src)
new /obj/item/grenade/syndieminibomb(src)
/obj/item/storage/box/bombananas
name = "box of bombananas"
desc = "A box containing 2 highly explosive bombananas. Discard peel at enemy after consumption."
icon_state = "syndiebox"
illustration = "frag"
/obj/item/storage/box/bombananas/PopulateContents()
new /obj/item/reagent_containers/food/snacks/grown/banana/bombanana(src)
new /obj/item/reagent_containers/food/snacks/grown/banana/bombanana(src)
/obj/item/storage/box/trackimp
name = "boxed tracking implant kit"
desc = "Box full of scum-bag tracking utensils."
@@ -1267,4 +1287,63 @@
/obj/item/storage/box/marshmallow/PopulateContents()
for (var/i in 1 to 5)
new /obj/item/reagent_containers/food/snacks/marshmallow(src)
new /obj/item/reagent_containers/food/snacks/marshmallow(src)
/obj/item/storage/box/material/PopulateContents() //less uranium because radioactive
var/static/items_inside = list(
/obj/item/stack/sheet/metal/fifty=1,\
/obj/item/stack/sheet/glass/fifty=1,\
/obj/item/stack/sheet/rglass=50,\
/obj/item/stack/sheet/plasmaglass=50,\
/obj/item/stack/sheet/titaniumglass=50,\
/obj/item/stack/sheet/plastitaniumglass=50,\
/obj/item/stack/sheet/plasteel=50,\
/obj/item/stack/sheet/mineral/plastitanium=50,\
/obj/item/stack/sheet/mineral/titanium=50,\
/obj/item/stack/sheet/mineral/gold=50,\
/obj/item/stack/sheet/mineral/silver=50,\
/obj/item/stack/sheet/mineral/plasma=50,\
/obj/item/stack/sheet/mineral/uranium=50,\
/obj/item/stack/sheet/mineral/diamond=50,\
/obj/item/stack/sheet/bluespace_crystal=50,\
/obj/item/stack/sheet/mineral/bananium=50,\
/obj/item/stack/sheet/mineral/wood=50,\
/obj/item/stack/sheet/plastic/fifty=1,\
/obj/item/stack/sheet/runed_metal/fifty=1
)
generate_items_inside(items_inside, src)
/obj/item/storage/box/debugtools
name = "box of debug tools"
icon_state = "syndiebox"
/obj/item/storage/box/debugtools/PopulateContents()
var/static/items_inside = list(
/obj/item/flashlight/emp/debug=1,\
/obj/item/pda=1,\
/obj/item/modular_computer/tablet/preset/advanced=1,\
/obj/item/geiger_counter=1,\
/obj/item/construction/rcd/combat/admin=1,\
/obj/item/pipe_dispenser=1,\
/obj/item/card/emag=1,\
/obj/item/healthanalyzer/advanced=1,\
/obj/item/disk/tech_disk/debug=1,\
/obj/item/uplink/debug=1,\
/obj/item/uplink/nuclear/debug=1,\
/obj/item/storage/box/beakers/bluespace=1,\
/obj/item/storage/box/beakers/variety=1,\
/obj/item/storage/box/material=1,\
/obj/item/storage/belt/medical/surgery_belt_adv
)
generate_items_inside(items_inside, src)
/obj/item/storage/box/beakers/variety
name = "beaker variety box"
/obj/item/storage/box/beakers/variety/PopulateContents()
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/glass/beaker/large(src)
new /obj/item/reagent_containers/glass/beaker/plastic(src)
new /obj/item/reagent_containers/glass/beaker/meta(src)
new /obj/item/reagent_containers/glass/beaker/noreact(src)
new /obj/item/reagent_containers/glass/beaker/bluespace(src)

View File

@@ -12,6 +12,7 @@
* Cigarette Box
* Cigar Case
* Heart Shaped Box w/ Chocolates
* Ring Box
*/
/obj/item/storage/fancy
@@ -352,3 +353,33 @@
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 8
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/tinychocolate))
/*
* Ring Box
*/
/obj/item/storage/fancy/ringbox
name = "ring box"
desc = "A tiny box covered in soft red felt made for holding rings."
icon = 'icons/obj/ring.dmi'
icon_state = "gold ringbox"
icon_type = "gold ring"
w_class = WEIGHT_CLASS_TINY
spawn_type = /obj/item/clothing/gloves/ring
/obj/item/storage/fancy/ringbox/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
STR.can_hold = typecacheof(list(/obj/item/clothing/gloves/ring))
/obj/item/storage/fancy/ringbox/diamond
icon_state = "diamond ringbox"
icon_type = "diamond ring"
spawn_type = /obj/item/clothing/gloves/ring/diamond
/obj/item/storage/fancy/ringbox/silver
icon_state = "silver ringbox"
icon_type = "silver ring"
spawn_type = /obj/item/clothing/gloves/ring/silver

View File

@@ -35,7 +35,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/update_icon()
..()
cut_overlays()
if(blood_DNA && blood_DNA.len)
if(length(blood_DNA))
add_blood_overlay()
if(has_latches)
var/icon/I = icon('icons/obj/storage.dmi', latches)
@@ -251,16 +251,12 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
new /obj/item/ammo_box/a762(src)
new /obj/item/ammo_box/a762(src)
/obj/item/storage/toolbox/gold_real
/obj/item/storage/toolbox/plastitanium/gold_real
name = "golden toolbox"
desc = "A larger then normal toolbox made of gold plated plastitanium."
icon_state = "gold"
item_state = "toolbox_gold"
has_latches = FALSE
force = 16 // Less then a spear
throwforce = 14
throw_speed = 5
throw_range = 10
/obj/item/storage/toolbox/gold_real/PopulateContents()
new /obj/item/screwdriver/nuke(src)

View File

@@ -343,7 +343,7 @@
new /obj/item/implanter/radio/syndicate(src)
/obj/item/storage/box/syndie_kit/centcom_costume/PopulateContents()
new /obj/item/clothing/under/rank/centcom_officer(src)
new /obj/item/clothing/under/rank/centcom_officer/syndicate(src)
new /obj/item/clothing/shoes/sneakers/black(src)
new /obj/item/clothing/gloves/color/black(src)
new /obj/item/radio/headset/headset_cent/empty(src)

View File

@@ -15,13 +15,18 @@
attack_verb = list("beaten")
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
var/stunforce = 140
var/stamforce = 25
var/status = FALSE
var/knockdown = TRUE
var/obj/item/stock_parts/cell/cell
var/hitcost = 1000
var/hitcost = 750
var/throw_hit_chance = 35
var/preload_cell_type //if not empty the baton starts with this type of cell
/obj/item/melee/baton/examine(mob/user)
. = ..()
. += "<span class='notice'>Right click attack while in combat mode to disarm instead of stun.</span>"
/obj/item/melee/baton/get_cell()
. = cell
if(iscyborg(loc))
@@ -32,7 +37,7 @@
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
/obj/item/melee/baton/Initialize()
/obj/item/melee/baton/Initialize(mapload)
. = ..()
if(preload_cell_type)
if(!ispath(preload_cell_type,/obj/item/stock_parts/cell))
@@ -48,7 +53,7 @@
baton_stun(hit_atom)
/obj/item/melee/baton/loaded //this one starts with a cell pre-installed.
preload_cell_type = /obj/item/stock_parts/cell/high
preload_cell_type = /obj/item/stock_parts/cell/high/plus
/obj/item/melee/baton/proc/deductcharge(chrgdeductamt, chargecheck = TRUE, explode = TRUE)
var/obj/item/stock_parts/cell/copper_top = get_cell()
@@ -134,44 +139,41 @@
add_fingerprint(user)
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
var/interrupt = common_baton_melee(M, user, FALSE)
if(!interrupt)
..()
/obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params)
. = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-disarming.
user.changeNext_move(CLICK_CD_MELEE)
//return TRUE to interrupt attack chain.
/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))
clowning_around(user)
return
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)//CIT CHANGE - makes it impossible to baton in stamina softcrit
to_chat(user, "<span class='danger'>You're too exhausted for that.</span>")//CIT CHANGE - ditto
return //CIT CHANGE - ditto
if(iscyborg(M))
..()
return
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //CIT CHANGE - makes it impossible to baton in stamina softcrit
to_chat(user, "<span class='danger'>You're too exhausted for that.</span>")
return TRUE
if(ishuman(M))
var/mob/living/carbon/human/L = M
if(check_martial_counter(L, user))
return
return TRUE
if(status)
if(baton_stun(M, user, disarming))
user.do_attack_animation(M)
user.adjustStaminaLossBuffered(getweight()) //CIT CHANGE - makes stunbatonning others cost stamina
else if(user.a_intent != INTENT_HARM) //they'll try to bash in the last proc.
M.visible_message("<span class='warning'>[user] has prodded [M] with [src]. Luckily it was off.</span>", \
"<span class='warning'>[user] has prodded you with [src]. Luckily it was off</span>")
return disarming || (user.a_intent != INTENT_HARM)
if(user.a_intent != INTENT_HARM)
if(status)
if(baton_stun(M, user))
user.do_attack_animation(M)
user.adjustStaminaLossBuffered(getweight())//CIT CHANGE - makes stunbatonning others cost stamina
return
else
M.visible_message("<span class='warning'>[user] has prodded [M] with [src]. Luckily it was off.</span>", \
"<span class='warning'>[user] has prodded you with [src]. Luckily it was off</span>")
else
if(status)
baton_stun(M, user)
..()
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user)
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user, disarming = FALSE)
if(L.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
var/stunpwr = stunforce
var/stunpwr = stamforce
var/obj/item/stock_parts/cell/our_cell = get_cell()
if(!our_cell)
switch_status(FALSE)
@@ -187,17 +189,21 @@
return FALSE
stunpwr *= round(stuncharge/hitcost, 0.1)
L.Knockdown(stunpwr)
L.adjustStaminaLoss(stunpwr*0.1)//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented.
L.apply_effect(EFFECT_STUTTER, stunforce)
if(!disarming)
if(knockdown)
L.Knockdown(50, override_stamdmg = 0) //knockdown
L.adjustStaminaLoss(stunpwr)
else
L.drop_all_held_items() //no knockdown/stamina damage, instead disarm.
L.apply_effect(EFFECT_STUTTER, stamforce)
SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK)
if(user)
L.lastattacker = user.real_name
L.lastattackerckey = user.ckey
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>", \
"<span class='userdanger'>[user] has stunned you with [src]!</span>")
log_combat(user, L, "stunned")
L.visible_message("<span class='danger'>[user] has [disarming? "disarmed" : "stunned"] [L] with [src]!</span>", \
"<span class='userdanger'>[user] has [disarming? "disarmed" : "stunned"] you with [src]!</span>")
log_combat(user, L, disarming? "disarmed" : "stunned")
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
@@ -212,7 +218,7 @@
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
user.Knockdown(stamforce*6)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
deductcharge(hitcost)
@@ -274,8 +280,9 @@
w_class = WEIGHT_CLASS_BULKY
force = 3
throwforce = 5
stunforce = 100
hitcost = 2000
stamforce = 25
hitcost = 1000
knockdown = FALSE
throw_hit_chance = 10
slot_flags = ITEM_SLOT_BACK
var/obj/item/assembly/igniter/sparkler

View File

@@ -33,6 +33,9 @@
H.update_internals_hud_icon(0)
else
if(!H.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
if(HAS_TRAIT(H, TRAIT_NO_INTERNALS))
to_chat(H, "<span class='warning'>Due to cumbersome equipment or anatomy, you are currently unable to use internals!</span>")
return
var/obj/item/clothing/check
var/internals = FALSE
@@ -156,7 +159,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tanks", name, 420, 200, master_ui, state)
ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state)
ui.open()
/obj/item/tank/ui_data(mob/user)

View File

@@ -138,14 +138,17 @@
/obj/item/hand_tele/pre_attack(atom/target, mob/user, params)
if(try_dispel_portal(target, user))
return FALSE
return TRUE
return ..()
/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user)
if(is_parent_of_portal(target))
/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user, delay = 30)
var/datum/beam/B = user.Beam(target)
if(is_parent_of_portal(target) && (!delay || do_after(user, delay, target = target)))
qdel(target)
to_chat(user, "<span class='notice'>You dispel [target] with \the [src]!</span>")
qdel(B)
return TRUE
qdel(B)
return FALSE
/obj/item/hand_tele/afterattack(atom/target, mob/user)

View File

@@ -16,7 +16,7 @@
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
user.Knockdown(stamforce * 6)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE))
deductcharge(hitcost)

View File

@@ -289,7 +289,7 @@
var/light_brightness = 3
actions_types = list()
/obj/item/toy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
/obj/item/toy/sword/cx/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE
@@ -453,6 +453,7 @@
force_wielded = 0
attack_verb = list("attacked", "struck", "hit")
total_mass_on = TOTAL_MASS_TOY_SWORD
sharpness = IS_BLUNT
/obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return FALSE
@@ -472,6 +473,7 @@
attack_verb = list("attacked", "struck", "hit")
total_mass_on = TOTAL_MASS_TOY_SWORD
slowdown_wielded = 0
sharpness = IS_BLUNT
/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return FALSE
@@ -1012,6 +1014,7 @@
/obj/item/toy/cards/singlecard/examine(mob/user)
. = ..()
if(ishuman(user))
var/mob/living/carbon/human/cardUser = user
if(cardUser.is_holding(src))
@@ -1244,7 +1247,7 @@
/obj/item/toy/clockwork_watch/examine(mob/user)
. = ..()
. += "<span class='info'>Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]"
. += "<span class='info'>Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]"
/*
* Toy Dagger

View File

@@ -38,9 +38,9 @@
wielded = 0
if(!isnull(force_unwielded))
force = force_unwielded
var/sf = findtext(name," (Wielded)")
var/sf = findtext(name, " (Wielded)", -10)//10 == length(" (Wielded)")
if(sf)
name = copytext(name,1,sf)
name = copytext(name, 1, sf)
else //something wrong
name = "[initial(name)]"
update_icon()
@@ -347,7 +347,6 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
clean_blood()
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
@@ -511,7 +510,7 @@
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
return FALSE
/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
/obj/item/twohanded/dualsaber/hypereutactic/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE
@@ -1017,3 +1016,66 @@
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
/obj/item/twohanded/broom
name = "broom"
desc = "This is my BROOMSTICK! It can be used manually or braced with two hands to sweep items as you move. It has a telescopic handle for compact storage." //LIES
icon = 'icons/obj/janitor.dmi'
icon_state = "broom0"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
force = 8
throwforce = 10
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_NORMAL
force_unwielded = 8
force_wielded = 12
attack_verb = list("swept", "brushed off", "bludgeoned", "whacked")
resistance_flags = FLAMMABLE
/obj/item/twohanded/broom/update_icon_state()
icon_state = "broom[wielded]"
/obj/item/twohanded/broom/wield(mob/user)
. = ..()
if(!wielded)
return
to_chat(user, "<span class='notice'>You brace the [src] against the ground in a firm sweeping stance.</span>")
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/sweep)
/obj/item/twohanded/broom/unwield(mob/user)
. = ..()
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
/obj/item/twohanded/broom/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!proximity)
return
sweep(user, A, FALSE)
/obj/item/twohanded/broom/proc/sweep(mob/user, atom/A, moving = TRUE)
var/turf/target
if (!moving)
if (isturf(A))
target = A
else
target = A.loc
else
target = user.loc
if (locate(/obj/structure/table) in target.contents)
return
var/i = 0
for(var/obj/item/garbage in target.contents)
if(!garbage.anchored)
garbage.Move(get_step(target, user.dir), user.dir)
i++
if(i >= 20)
break
if(i >= 1)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 5, TRUE, -1)
/obj/item/twohanded/broom/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) //bless you whoever fixes this copypasta
J.put_in_cart(src, user)
J.mybroom=src
J.update_icon()

View File

@@ -79,6 +79,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
user.visible_message("<span class='suicide'>[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return(BRUTELOSS)
/obj/item/claymore/purified
name = "purified longsword"
desc = "A hastily-purified longsword. While not as holy as it could be, it's still a formidable weapon against those who would rather see you dead."
force = 25
/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
desc = "<b><i>THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!</i></b>\nActivate it in your hand to point to the nearest victim."
flags_1 = CONDUCT_1
@@ -312,23 +317,27 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb = list("stubbed", "poked")
resistance_flags = FIRE_PROOF
var/extended = 0
var/extended_force = 20
var/extended_throwforce = 23
var/extended_icon_state = "switchblade_ext"
var/retracted_icon_state = "switchblade"
/obj/item/switchblade/attack_self(mob/user)
extended = !extended
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
if(extended)
force = 20
force = extended_force
w_class = WEIGHT_CLASS_NORMAL
throwforce = 23
icon_state = "switchblade_ext"
throwforce = extended_throwforce
icon_state = extended_icon_state
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
else
force = 3
force = initial(force)
w_class = WEIGHT_CLASS_SMALL
throwforce = 5
icon_state = "switchblade"
throwforce = initial(throwforce)
icon_state = retracted_icon_state
attack_verb = list("stubbed", "poked")
hitsound = 'sound/weapons/genhit.ogg'
sharpness = IS_BLUNT
@@ -337,6 +346,25 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS)
/obj/item/switchblade/crafted
icon_state = "switchblade_ms"
desc = "A concealable spring-loaded knife."
force = 2
throwforce = 3
extended_force = 15
extended_throwforce = 18
extended_icon_state = "switchblade_ext_ms"
retracted_icon_state = "switchblade_ms"
/obj/item/switchblade/crafted/attackby(obj/item/I, mob/user, params)
. = ..()
if(istype(I, /obj/item/stack/sheet/mineral/silver))
icon_state = extended ? "switchblade_ext_msf" : "switchblade_msf"
extended_icon_state = "switchblade_ext_msf"
retracted_icon_state = "switchblade_msf"
icon_state = "switchblade_msf"
to_chat(user, "<span class='notice'>You use part of the silver to improve your Switchblade. Stylish!</span>")
/obj/item/phone
name = "red phone"
desc = "Should anything ever go wrong..."

View File

@@ -60,8 +60,8 @@
var/flagslist = splittext(set_obj_flags,";")
var/list/string_to_objflag = GLOB.bitfields["obj_flags"]
for (var/flag in flagslist)
if (findtext(flag,"!",1,2))
flag = copytext(flag,1-(length(flag))) // Get all but the initial !
if(flag[1] == "!")
flag = copytext(flag, length(flag[1]) + 1) // Get all but the initial !
obj_flags &= ~string_to_objflag[flag]
else
obj_flags |= string_to_objflag[flag]
@@ -125,7 +125,7 @@
if ((M.client && M.machine == src))
is_in_use = TRUE
ui_interact(M)
if(isAI(usr) || iscyborg(usr) || IsAdminGhost(usr))
if(isAI(usr) || iscyborg(usr) || IsAdminGhost(usr) || hasSiliconAccessInArea(usr))
if (!(usr in nearby))
if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
is_in_use = TRUE
@@ -178,7 +178,7 @@
machine = null
//called when the user unsets the machine.
/atom/movable/proc/on_unset_machine(mob/user)
/atom/proc/on_unset_machine(mob/user)
return
/mob/proc/set_machine(obj/O)

View File

@@ -37,7 +37,7 @@
structureclimber.visible_message("<span class='warning'>[structureclimber] has been knocked off [src].", "You're knocked off [src]!", "You see [structureclimber] get knocked off [src].</span>")
/obj/structure/ui_act(action, params)
..()
. = ..()
add_fingerprint(usr)
/obj/structure/MouseDrop_T(atom/movable/O, mob/user)

View File

@@ -52,7 +52,7 @@
var/area/A = get_area(src)
if(!A.blob_allowed)
return FALSE
if(!A.power_equip)
if(!A.powered(EQUIP))
return FALSE
if(!SSmapping.level_trait(T.z,ZTRAIT_STATION))
return FALSE

View File

@@ -305,7 +305,7 @@
/datum/barsign/meow_mix
name = "Meow Mix"
icon = "meow_mix"
icon = "Meow Mix"
desc = "No, we don't serve catnip, officer!"
/datum/barsign/hiddensigns

View File

@@ -370,6 +370,43 @@
item_state = "stool_bar"
origin_type = /obj/structure/chair/stool/bar
//////////////////////////
//Alien(Disco) Stools!////
//////////////////////////
/obj/structure/chair/stool/alien
name = "alien stool"
desc = "A hard stool made of advanced alien alloy."
icon_state = "stoolalien"
icon = 'icons/obj/abductor.dmi'
item_chair = /obj/item/chair/stool/alien
buildstacktype = /obj/item/stack/sheet/mineral/abductor
buildstackamount = 1
/obj/structure/chair/stool/bar/alien
name = "bronze bar stool"
desc = "A hard bar stool made of advanced alien alloy."
icon_state = "baralien"
icon = 'icons/obj/abductor.dmi'
item_chair = /obj/item/chair/stool/bar/alien
buildstacktype = /obj/item/stack/sheet/mineral/abductor
buildstackamount = 1
/obj/item/chair/stool/alien
name = "stool"
icon_state = "stoolalien_toppled"
item_state = "stoolalien"
icon = 'icons/obj/abductor.dmi'
origin_type = /obj/structure/chair/stool/alien
break_chance = 0 //It's too sturdy.
/obj/item/chair/stool/bar/alien
name = "bar stool"
icon_state = "baralien_toppled"
item_state = "baralien"
icon = 'icons/obj/abductor.dmi'
origin_type = /obj/structure/chair/stool/bar/alien
//////////////////////////
//Brass & Bronze stools!//
//////////////////////////

View File

@@ -532,7 +532,7 @@
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
return ..()
if(!user.canUseTopic(src) || !isturf(user.loc))
if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
return
dive_into(user)

View File

@@ -95,7 +95,7 @@
if(user.lying && get_dist(src, user) > 0)
return
if(!broken && registered_id != null && registered_id in user.held_items)
if(!broken && registered_id != null && (registered_id in user.held_items))
handle_prisoner_id(user)
return

View File

@@ -76,7 +76,7 @@
new /obj/item/door_remote/chief_medical_officer(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/pet_carrier(src)
new /obj/item/storage/belt/medical/surgery_belt_adv(src)
new /obj/item/storage/belt/medical/surgery_belt_adv/cmo(src)
new /obj/item/wallframe/defib_mount(src)
new /obj/item/circuitboard/machine/techfab/department/medical(src)
new /obj/item/storage/photo_album/CMO(src)

View File

@@ -2,38 +2,21 @@
name = "\proper captain's locker"
req_access = list(ACCESS_CAPTAIN)
icon_state = "cap"
/obj/structure/closet/secure_closet/captains/PopulateContents()
/obj/structure/closet/secure_closet/captains/PopulateContents() //Excess clothing and such can be found in the Captain's Wardrobe. You can also find this file in code/modules/vending/wardrobes.
..()
new /obj/item/clothing/suit/hooded/wintercoat/captain(src)
new /obj/item/storage/backpack/captain(src)
new /obj/item/storage/backpack/satchel/cap(src)
new /obj/item/storage/backpack/duffelbag/captain(src)
new /obj/item/clothing/neck/cloak/cap(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/clothing/neck/petcollar(src) //I considered removing the pet stuff too but eh, who knows. We might get Renault back. Plus I guess you could use that collar for... other means. Aren't you supposed to be guarding the disk?
new /obj/item/pet_carrier(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/clothing/under/rank/captain(src)
new /obj/item/clothing/under/rank/captain/skirt(src)
new /obj/item/clothing/suit/armor/vest/capcarapace(src)
new /obj/item/clothing/head/caphat(src)
new /obj/item/clothing/under/captainparade(src)
new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src)
new /obj/item/clothing/head/caphat/parade(src)
new /obj/item/clothing/head/caphat/beret(src)
new /obj/item/clothing/suit/captunic(src)
new /obj/item/clothing/under/rank/captain/femformal(src) //citadel edit
new /obj/item/clothing/head/crown/fancy(src)
new /obj/item/cartridge/captain(src)
new /obj/item/storage/box/silver_ids(src)
new /obj/item/radio/headset/heads/captain/alt(src)
new /obj/item/radio/headset/heads/captain(src)
new /obj/item/clothing/glasses/sunglasses/gar/supergar(src)
new /obj/item/clothing/gloves/color/captain(src)
new /obj/item/storage/belt/sabre(src)
new /obj/item/gun/energy/e_gun(src)
new /obj/item/door_remote/captain(src)
new /obj/item/storage/photo_album/Captain(src)
new /obj/item/clothing/head/caphat/beret/white(src)
/obj/structure/closet/secure_closet/hop
name = "\proper head of personnel's locker"

View File

@@ -126,8 +126,10 @@
new /obj/item/clothing/mask/bandana/black(src)
if(prob(40))
new /obj/item/clothing/under/assistantformal(src)
new /obj/item/clothing/suit/hooded/wintercoat/aformal(src)
if(prob(40))
new /obj/item/clothing/under/assistantformal(src)
new /obj/item/clothing/suit/hooded/wintercoat/aformal(src)
if(prob(30))
new /obj/item/clothing/suit/hooded/wintercoat(src)
new /obj/item/clothing/shoes/winterboots(src)
@@ -169,4 +171,6 @@
if(prob(30))
new /obj/item/clothing/suit/hooded/wintercoat(src)
new /obj/item/clothing/shoes/winterboots(src)
if (prob(30))
new /obj/item/clothing/suit/hooded/wintercoat/polychromic(src)
return

View File

@@ -13,6 +13,8 @@
climb_time = 10 //real fast, because let's be honest stepping into or onto a crate is easy
climb_stun = 0 //climbing onto crates isn't hard, guys
delivery_icon = "deliverycrate"
material_drop = /obj/item/stack/sheet/plasteel
material_drop_amount = 5
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest
/obj/structure/closet/crate/New()
@@ -45,6 +47,12 @@
if(manifest)
tear_manifest(user)
/obj/structure/closet/crate/tool_interact(obj/item/W, mob/user)
if(W.tool_behaviour == TOOL_WIRECUTTER && manifest)
tear_manifest(user)
return TRUE
return ..()
/obj/structure/closet/crate/open(mob/living/user)
. = ..()
if(. && manifest)
@@ -81,7 +89,7 @@
/obj/structure/closet/crate/coffin/examine(mob/user)
. = ..()
if(user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
if(user.mind?.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
. += {"<span class='cult'>This is a coffin which you can use to regenerate your burns and other wounds faster.</span>"}
. += {"<span class='cult'>You can also thicken your blood if you survive the day, and hide from the sun safely while inside.</span>"}
/* if(user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
@@ -142,6 +150,9 @@
new /obj/item/reagent_containers/blood/OMinus(src)
new /obj/item/reagent_containers/blood/OPlus(src)
new /obj/item/reagent_containers/blood/lizard(src)
new /obj/item/reagent_containers/blood/jellyblood(src)
new /obj/item/reagent_containers/blood/insect(src)
new /obj/item/reagent_containers/blood/synthetics(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/blood/random(src)

View File

@@ -4,8 +4,8 @@
icon_state = "largebins"
open_sound = 'sound/effects/bin_open.ogg'
close_sound = 'sound/effects/bin_close.ogg'
material_drop = /obj/item/stack/sheet/plastic
material_drop_amount = 40
material_drop = /obj/item/stack/sheet/metal
material_drop_amount = 10
anchored = TRUE
horizontal = FALSE
delivery_icon = null

View File

@@ -70,3 +70,8 @@
name = "secure science crate"
desc = "A crate with a lock on it, painted in the scheme of the station's scientists."
icon_state = "scisecurecrate"
/obj/structure/closet/crate/secure/medical
desc = "A secure medical crate."
name = "medical crate"
icon_state = "medical_secure_crate"

View File

@@ -80,7 +80,7 @@
/obj/structure/displaycase/proc/trigger_alarm()
//Activate Anti-theft
if(alert)
var/area/alarmed = get_area(src)
var/area/alarmed = get_base_area(src)
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)

View File

@@ -205,6 +205,9 @@
if(!mineral)
if(istype(G, /obj/item/stack/sheet/mineral) && G.sheettype)
var/M = G.sheettype
var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
if(!mineralassembly)
return
if(G.get_amount() >= 2)
playsound(src, 'sound/items/crowbar.ogg', 100, 1)
user.visible_message("[user] adds [G.name] to the airlock assembly.", \
@@ -214,7 +217,6 @@
return
to_chat(user, "<span class='notice'>You install [M] plating into the airlock assembly.</span>")
G.use(2)
var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
var/obj/structure/door_assembly/MA = new mineralassembly(loc)
transfer_assembly_vars(src, MA, TRUE)
else

View File

@@ -7,7 +7,7 @@
anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
layer = CLOSED_TURF_LAYER
layer = LOW_OBJ_LAYER
density = TRUE
opacity = 1
max_integrity = 100

View File

@@ -12,26 +12,27 @@
roundstart = FALSE
death = FALSE
mob_species = /datum/species/pod
flavour_text = "<span class='big bold'>You are a sentient ecosystem,</span><b> an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \
seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \
for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago.</b>"
short_desc = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed."
flavour_text = "Your masters, benevolent as they were, created uncounted seed vaults and spread them across \
the universe to every planet they could chart. You are in one such seed vault. \
Your goal is to cultivate and spread life wherever it will go while waiting for contact from your creators. \
Estimated time of last contact: Deployment, 5000 millennia ago."
assignedrole = "Lifebringer"
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn)
var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
"Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
new_spawn.real_name = plant_name
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.underwear = "Nude" //You're a plant, partner
H.update_body()
/obj/effect/mob_spawn/human/seed_vault/Destroy()
new/obj/structure/fluff/empty_terrarium(get_turf(src))
return ..()
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/carbon/human/new_spawn)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
"Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
new_spawn.real_name = plant_name //why this works when moving it from one function to another is beyond me
new_spawn.underwear = "Nude" //You're a plant, partner
new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere?
new_spawn.socks = "Nude"
new_spawn.update_body()
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
/obj/effect/mob_spawn/human/ash_walker
@@ -48,18 +49,31 @@
anchored = FALSE
move_resist = MOVE_FORCE_NORMAL
density = FALSE
flavour_text = "<span class='big bold'>You are an ash walker.</span><b> Your tribe worships <span class='danger'>the Necropolis</span>. The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest.</b>"
short_desc = "You are an ash walker. Your tribe worships the Necropolis."
flavour_text = "The wastes are sacred ground, its monsters a blessed bounty. You would never willingly leave your homeland behind. \
You have seen lights in the distance... they foreshadow the arrival of outsiders to your domain. \
Ensure your nest remains protected at all costs."
assignedrole = "Ash Walker"
/obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn)
new_spawn.real_name = random_unique_lizard_name(gender)
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>")
if(is_mining_level(z))
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>")
else
to_chat(new_spawn, "<span class='userdanger'>You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.</span>")
new_spawn.grant_language(/datum/language/draconic)
var/datum/language_holder/holder = new_spawn.get_language_holder()
holder.selected_default_language = /datum/language/draconic
//Ash walkers on birth understand how to make bone bows, bone arrows and ashen arrows
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_arrow)
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_bow)
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/ashen_arrow)
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/quiver)
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bow_tablet)
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.underwear = "Nude"
@@ -88,8 +102,9 @@
roundstart = FALSE
death = FALSE
mob_species = /datum/species/shadow
flavour_text = "<span class='big bold'>You are cursed.</span><b> Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland.</b>"
short_desc = "You are cursed."
flavour_text = "Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland."
assignedrole = "Exile"
/obj/effect/mob_spawn/human/exile/Destroy()
@@ -126,9 +141,10 @@
var/has_owner = FALSE
var/can_transfer = TRUE //if golems can switch bodies to this new shell
var/mob/living/owner = null //golem's owner if it has one
flavour_text = "<span class='big bold'>You are a Free Golem.</span><b> Your family worships <span class='danger'>The Liberator</span>. In his infinite and divine wisdom, he set your clan free to \
short_desc = "You are a Free Golem. Your family worships The Liberator."
flavour_text = "In his infinite and divine wisdom, he set your clan free to \
travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \
golems, so that no golem may ever be forced to serve again.</b>"
golems, so that no golem may ever be forced to serve again."
/obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null)
if(species) //spawners list uses object name to register so this goes before ..()
@@ -139,8 +155,9 @@
if(!mapload && A)
notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM, ignore_dnr_observers = TRUE)
if(has_owner && creator)
flavour_text = "<span class='big bold'>You are a Golem.</span><b> You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \
Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost.</b>"
short_desc = "You are a golem."
flavour_text = "You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools."
important_info = "Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost."
owner = creator
/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name)
@@ -213,8 +230,9 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You've been stranded in this godless prison of a planet for longer than you can remember.</span><b> Each day you barely scrape by, and between the terrible \
conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
short_desc = "You've been stranded in this godless prison of a planet for longer than you can remember."
flavour_text = "Each day you barely scrape by, and between the terrible conditions of your makeshift shelter, \
the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
assignedrole = "Hermit"
@@ -225,20 +243,20 @@
if(1)
flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \
only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \
life and sent you to this hell are forever branded into your memory.</b>"
life and sent you to this hell are forever branded into your memory."
outfit.uniform = /obj/item/clothing/under/assistantformal
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
if(2)
flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \
heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.</b>"
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since."
outfit.uniform = /obj/item/clothing/under/rank/prisoner
outfit.shoes = /obj/item/clothing/shoes/sneakers/orange
outfit.back = /obj/item/storage/backpack
if(3)
flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.</b>"
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there."
outfit.uniform = /obj/item/clothing/under/rank/medical
outfit.suit = /obj/item/clothing/suit/toggle/labcoat
outfit.back = /obj/item/storage/backpack/medic
@@ -246,7 +264,7 @@
if(4)
flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so <i>kindly</i> put it. It seems that they were right when you, on a tour \
at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now.</b>"
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now."
outfit.uniform = /obj/item/clothing/under/color/grey/glorf
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
@@ -264,9 +282,10 @@
desc = "A small sleeper typically used to instantly restore minor wounds. This one seems broken, and its occupant is comatose."
job_description = "Lavaland Veterinarian"
mob_name = "a translocated vet"
flavour_text = "<span class='big bold'>What...?</span><b> Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they can tell you what happened.</b>"
short_desc = "You are a animal doctor who just woke up in lavaland"
flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they c everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; an tell you what happened."
assignedrole = "Translocated Vet"
/obj/effect/mob_spawn/human/doctor/alive/lavaland/Destroy()
@@ -285,8 +304,9 @@
outfit = /datum/outfit/lavalandprisoner
roundstart = FALSE
death = FALSE
flavour_text = "<b>Good. It seems as though your ship crashed. <span class='big bold'>You're a prisoner,</span> sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you. You remember that you were convicted of "
short_desc = "You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you."
flavour_text = "Good. It seems as though your ship crashed. You remember that you were convicted of "
assignedrole = "Escaped Prisoner"
/obj/effect/mob_spawn/human/prisoner_transport/special(mob/living/L)
@@ -298,7 +318,7 @@
var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \
"worship of a forbidden deity", "interspecies relations", "mutiny")
flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]</b>."
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]."
/datum/outfit/lavalandprisoner
name = "Lavaland Prisoner"
@@ -325,8 +345,9 @@
roundstart = FALSE
random = TRUE
outfit = /datum/outfit/hotelstaff
flavour_text = "<span class='big bold'>You are a staff member of a top-of-the-line space hotel!</span><b> Cater to guests and <font size=6><b>DON'T</b></font> leave the hotel, lest the manager fire you for\
dereliction of duty!</b>"
short_desc = "You are a staff member of a top-of-the-line space hotel!"
flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and make sure the manager doesn't fire you."
important_info = "DON'T leave the hotel"
assignedrole = "Hotel Staff"
/datum/outfit/hotelstaff
@@ -343,8 +364,10 @@
mob_name = "hotel security member"
job_description = "Hotel Security"
outfit = /datum/outfit/hotelstaff/security
flavour_text = "<span class='big bold'>You are a peacekeeper</span><b> assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff. Do <font size=6>NOT</font> leave the hotel, as that is grounds for contract termination.</b>"
short_desc = "You are a peacekeeper."
flavour_text = "You have been assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff."
important_info = "Do NOT leave the hotel, as that is grounds for contract termination."
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
/datum/outfit/hotelstaff/security
@@ -383,7 +406,8 @@
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
. = ..()
owner = owner_mind
flavour_text = "<span class='big bold'>You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil.</span><b> Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell.</b>"
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil."
important_info = "Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
@@ -441,9 +465,9 @@
/obj/effect/mob_spawn/human/syndicate/battlecruiser
name = "Syndicate Battlecruiser Ship Operative"
flavour_text = "<span class='big bold'>You are a crewmember aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, maintain the ship, and keep the engine running.</b></span> If you are not familiar with how the supermatter engine functions: <b>do not attempt to start it.</b><br>\
<br>\
<span class='danger'><b>The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives.</b></span></font>"
short_desc = "You are a crewmember aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to follow your captain's orders, maintain the ship, and keep the engine running. If you are not familiar with how the supermatter engine functions: do not attempt to start it."
important_info = "The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives."
outfit = /datum/outfit/syndicate_empty/SBC
/datum/outfit/syndicate_empty/SBC
@@ -453,10 +477,9 @@
belt = /obj/item/storage/belt/military/assault
/obj/effect/mob_spawn/human/syndicate/battlecruiser/assault
name = "Syndicate Battlecruiser Assault Operative"
flavour_text = "<span class='big bold'>You are an assault operative aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13.</b></span> There is an armory, multiple assault ships, and beam cannons to attack the station with.<br>\
<br>\
<span class='danger'><b>Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!</b></span></span>"
short_desc = "You are an assault operative aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13. There is an armory, multiple assault ships, and beam cannons to attack the station with."
important_info = "Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!"
outfit = /datum/outfit/syndicate_empty/SBC/assault
/datum/outfit/syndicate_empty/SBC/assault
@@ -472,9 +495,9 @@
/obj/effect/mob_spawn/human/syndicate/battlecruiser/captain
name = "Syndicate Battlecruiser Captain"
flavour_text = "<span class='big bold'>You are the captain aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to oversee your crew, defend the ship, and destroy Space Station 13.</b></span> The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal.<br>\
<br>\
<span class='danger'><b>As the captain, this whole operation falls on your shoulders.</b></span> You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough.</span>"
short_desc = "You are the captain aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to oversee your crew, defend the ship, and destroy Space Station 13. The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal."
important_info = "As the captain, this whole operation falls on your shoulders. You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough."
outfit = /datum/outfit/syndicate_empty/SBC/assault/captain
id_access_list = list(150,151)
@@ -500,10 +523,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a security officer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \
The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/security
shoes = /obj/item/clothing/shoes/jackboots
id = /obj/item/card/id/away/old/sec
@@ -527,10 +551,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are an engineer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. The last thing \
you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/engineer
shoes = /obj/item/clothing/shoes/workboots
id = /obj/item/card/id/away/old/eng
@@ -552,10 +577,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a scientist working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \
The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/scientist
shoes = /obj/item/clothing/shoes/laceup
id = /obj/item/card/id/away/old/sci
@@ -582,7 +608,8 @@
anchored = TRUE
density = FALSE
show_flavour = FALSE //Flavour only exists for spawners menu
flavour_text = "<span class='big bold'>You are a space pirate.</span><b> The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</b>"
short_desc = "You are a space pirate."
flavour_text = "The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot."
assignedrole = "Space Pirate"
var/rank = "Mate"
@@ -617,9 +644,10 @@
density = FALSE
death = FALSE
assignedrole = "Ghost Cafe Visitor"
flavour_text = "Is this what life after death is like?"
short_desc = "You are a Ghost Cafe Visitor!"
flavour_text = "You know one thing for sure. You arent actually alive. Are you in a simulation?"
skip_reentry_check = TRUE
banType = "ghostcafe"
banType = ROLE_GHOSTCAFE
/datum/action/toggle_dead_chat_mob
icon_icon = 'icons/mob/mob.dmi'
@@ -642,12 +670,14 @@
/obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn)
if(new_spawn.client)
new_spawn.client.prefs.copy_to(new_spawn)
var/area/A = get_area(src)
var/datum/outfit/O = new /datum/outfit/ghostcafe()
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel))
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT)

View File

@@ -166,6 +166,9 @@
if(S.sheettype && S.sheettype != "runed")
var/M = S.sheettype
if(state == GIRDER_DISPLACED)
var/F = text2path("/obj/structure/falsewall/[M]")
if(!F)
return
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
return
@@ -174,11 +177,13 @@
return
S.use(2)
to_chat(user, "<span class='notice'>You create a false wall. Push on it to open or close the passage.</span>")
var/F = text2path("/obj/structure/falsewall/[M]")
var/obj/structure/FW = new F (loc)
transfer_fingerprints_to(FW)
qdel(src)
else
var/F = text2path("/turf/closed/wall/mineral/[M]")
if(!F)
return
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to add plating!</span>")
return
@@ -189,7 +194,7 @@
S.use(2)
to_chat(user, "<span class='notice'>You add the plating.</span>")
var/turf/T = get_turf(src)
T.PlaceOnTop(text2path("/turf/closed/wall/mineral/[M]"))
T.PlaceOnTop(F)
transfer_fingerprints_to(T)
qdel(src)
return

View File

@@ -97,7 +97,7 @@
icon_state = "guillotine_raised"
/obj/structure/guillotine/proc/drop_blade(mob/user)
if (buckled_mobs.len && blade_sharpness)
if (has_buckled_mobs() && blade_sharpness)
var/mob/living/carbon/human/H = buckled_mobs[1]
if (!H)

View File

@@ -42,8 +42,9 @@
if(.)
return
to_chat(user, "<span class='notice'>You take down [src].</span>")
victim.forceMove(drop_location())
victim = null
if(victim)
victim.forceMove(drop_location())
victim = null
spear.forceMove(drop_location())
spear = null
qdel(src)

View File

@@ -8,14 +8,16 @@
max_integrity = 1
armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20)
var/obj/item/holosign_creator/projector
var/init_vis_overlay = TRUE
/obj/structure/holosign/Initialize(mapload, source_projector)
. = ..()
if(source_projector)
projector = source_projector
projector.signs += src
SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, alpha, RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
alpha = 0
if(init_vis_overlay)
SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, alpha, RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
alpha = 0
/obj/structure/holosign/Destroy()
if(projector)
@@ -74,8 +76,10 @@
icon_state = "holo_fan"
density = FALSE
anchored = TRUE
layer = ABOVE_NORMAL_TURF_LAYER
CanAtmosPass = ATMOS_PASS_NO
alpha = 150
init_vis_overlay = FALSE
/obj/structure/holosign/barrier/atmos/Initialize()
. = ..()
@@ -93,6 +97,26 @@
/obj/structure/holosign/barrier/firelock/blocksTemperature()
return TRUE
/obj/structure/holosign/barrier/combifan
name = "holo combifan"
desc = "A holographic barrier resembling a blue-accented tiny fan. Though it does not prevent solid objects from passing through, gas and temperature changes are kept out."
icon_state = "holo_combifan"
max_integrity = 30
density = FALSE
anchored = TRUE
layer = ABOVE_NORMAL_TURF_LAYER
alpha = 150
init_vis_overlay = FALSE
CanAtmosPass = ATMOS_PASS_NO
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/combolock/blocksTemperature()
return TRUE
/obj/structure/holosign/barrier/combolock/Initialize()
. = ..()
air_update_turf(TRUE)
/obj/structure/holosign/barrier/cyborg
name = "Energy Field"
desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles."

View File

@@ -6,11 +6,11 @@
anchored = FALSE
density = TRUE
//copypaste sorry
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
var/obj/item/storage/bag/trash/mybag = null
var/obj/item/mop/mymop = null
var/obj/item/reagent_containers/spray/cleaner/myspray = null
var/obj/item/lightreplacer/myreplacer = null
var/obj/item/storage/bag/trash/mybag
var/obj/item/mop/mymop
var/obj/item/twohanded/broom/mybroom
var/obj/item/reagent_containers/spray/cleaner/myspray
var/obj/item/lightreplacer/myreplacer
var/signs = 0
var/const/max_signs = 4
@@ -49,7 +49,12 @@
m.janicart_insert(user, src)
else
to_chat(user, fail_msg)
else if(istype(I, /obj/item/twohanded/broom))
if(!mybroom)
var/obj/item/twohanded/broom/b=I
b.janicart_insert(user,src)
else
to_chat(user, fail_msg)
else if(istype(I, /obj/item/storage/bag/trash))
if(!mybag)
var/obj/item/storage/bag/trash/t=I
@@ -97,6 +102,8 @@
dat += "<a href='?src=[REF(src)];garbage=1'>[mybag.name]</a><br>"
if(mymop)
dat += "<a href='?src=[REF(src)];mop=1'>[mymop.name]</a><br>"
if(mybroom)
dat += "<a href='?src=[REF(src)];broom=1'>[mybroom.name]</a><br>"
if(myspray)
dat += "<a href='?src=[REF(src)];spray=1'>[myspray.name]</a><br>"
if(myreplacer)
@@ -124,6 +131,11 @@
user.put_in_hands(mymop)
to_chat(user, "<span class='notice'>You take [mymop] from [src].</span>")
mymop = null
if(href_list["broom"])
if(mybroom)
user.put_in_hands(mybroom)
to_chat(user, "<span class='notice'>You take [mybroom] from [src].</span>")
mybroom = null
if(href_list["spray"])
if(myspray)
user.put_in_hands(myspray)
@@ -155,6 +167,8 @@
add_overlay("cart_garbage")
if(mymop)
add_overlay("cart_mop")
if(mybroom)
add_overlay("cart_broom")
if(myspray)
add_overlay("cart_spray")
if(myreplacer)

View File

@@ -20,14 +20,14 @@
return
if(broken || !Adjacent(user))
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
//see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
//this is largely copypasted from there.
//handle facial hair (if necessary)
if(H.gender == MALE)
if(H.gender != FEMALE)
var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return //no tele-grooming
@@ -133,7 +133,7 @@
switch(choice)
if("name")
var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN)
var/newname = reject_bad_name(stripped_input(H, "Who are we again?", "Name change", H.name, MAX_NAME_LEN))
if(!newname)
return

Some files were not shown because too many files have changed in this diff Show More