mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-29 15:08:34 +01:00
Merge branch 'master' of https://github.com/VOREStation/VOREStation into Kates-Taur-Clothes
This commit is contained in:
@@ -152,6 +152,12 @@
|
||||
* Weeds
|
||||
*/
|
||||
#define NODERANGE 3
|
||||
#define WEED_NORTH_EDGING "north"
|
||||
#define WEED_SOUTH_EDGING "south"
|
||||
#define WEED_EAST_EDGING "east"
|
||||
#define WEED_WEST_EDGING "west"
|
||||
#define WEED_NODE_GLOW "glow"
|
||||
#define WEED_NODE_BASE "nodebase"
|
||||
|
||||
/obj/effect/alien/weeds
|
||||
name = "weeds"
|
||||
@@ -164,6 +170,18 @@
|
||||
layer = ABOVE_TURF_LAYER
|
||||
var/health = 15
|
||||
var/obj/effect/alien/weeds/node/linked_node = null
|
||||
var/static/list/weedImageCache
|
||||
|
||||
/obj/effect/alien/weeds/Destroy()
|
||||
var/turf/T = get_turf(src)
|
||||
// To not mess up the overlay updates.
|
||||
loc = null
|
||||
|
||||
for (var/obj/effect/alien/weeds/W in range(1,T))
|
||||
W.updateWeedOverlays()
|
||||
|
||||
linked_node = null
|
||||
..()
|
||||
|
||||
/obj/effect/alien/weeds/node
|
||||
icon_state = "weednode"
|
||||
@@ -173,9 +191,22 @@
|
||||
light_range = NODERANGE
|
||||
var/node_range = NODERANGE
|
||||
|
||||
var/set_color = null
|
||||
|
||||
/obj/effect/alien/weeds/node/New()
|
||||
..(src.loc, src)
|
||||
|
||||
/obj/effect/alien/weeds/node/Initialize()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
spawn(1 SECOND)
|
||||
if(color)
|
||||
set_color = color
|
||||
|
||||
/obj/effect/alien/weeds/node/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/effect/alien/weeds/New(pos, node)
|
||||
..()
|
||||
@@ -184,12 +215,45 @@
|
||||
return
|
||||
linked_node = node
|
||||
if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
|
||||
spawn(rand(150, 200))
|
||||
if(src)
|
||||
Life()
|
||||
|
||||
fullUpdateWeedOverlays()
|
||||
|
||||
/obj/effect/alien/weeds/proc/updateWeedOverlays()
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
if(!weedImageCache || !weedImageCache.len)
|
||||
weedImageCache = list()
|
||||
// weedImageCache.len = 4
|
||||
weedImageCache[WEED_NORTH_EDGING] = image('icons/mob/alien.dmi', "weeds_side_n", layer=2.11, pixel_y = -32)
|
||||
weedImageCache[WEED_SOUTH_EDGING] = image('icons/mob/alien.dmi', "weeds_side_s", layer=2.11, pixel_y = 32)
|
||||
weedImageCache[WEED_EAST_EDGING] = image('icons/mob/alien.dmi', "weeds_side_e", layer=2.11, pixel_x = -32)
|
||||
weedImageCache[WEED_WEST_EDGING] = image('icons/mob/alien.dmi', "weeds_side_w", layer=2.11, pixel_x = 32)
|
||||
|
||||
var/turf/N = get_step(src, NORTH)
|
||||
var/turf/S = get_step(src, SOUTH)
|
||||
var/turf/E = get_step(src, EAST)
|
||||
var/turf/W = get_step(src, WEST)
|
||||
if(!locate(/obj/effect/alien) in N.contents)
|
||||
if(istype(N, /turf/simulated/floor))
|
||||
overlays += weedImageCache[WEED_SOUTH_EDGING]
|
||||
if(!locate(/obj/effect/alien) in S.contents)
|
||||
if(istype(S, /turf/simulated/floor))
|
||||
overlays += weedImageCache[WEED_NORTH_EDGING]
|
||||
if(!locate(/obj/effect/alien) in E.contents)
|
||||
if(istype(E, /turf/simulated/floor))
|
||||
overlays += weedImageCache[WEED_WEST_EDGING]
|
||||
if(!locate(/obj/effect/alien) in W.contents)
|
||||
if(istype(W, /turf/simulated/floor))
|
||||
overlays += weedImageCache[WEED_EAST_EDGING]
|
||||
|
||||
/obj/effect/alien/weeds/proc/fullUpdateWeedOverlays()
|
||||
for (var/obj/effect/alien/weeds/W in range(1,src))
|
||||
W.updateWeedOverlays()
|
||||
|
||||
return
|
||||
|
||||
/obj/effect/alien/weeds/proc/Life()
|
||||
/obj/effect/alien/weeds/process()
|
||||
set background = 1
|
||||
var/turf/U = get_turf(src)
|
||||
/*
|
||||
@@ -211,6 +275,9 @@ Alien plants should do something if theres a lot of poison
|
||||
if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
|
||||
return
|
||||
|
||||
if(linked_node != src)
|
||||
color = linked_node.set_color
|
||||
|
||||
direction_loop:
|
||||
for(var/dirn in cardinal)
|
||||
var/turf/T = get_step(src, dirn)
|
||||
@@ -222,10 +289,33 @@ Alien plants should do something if theres a lot of poison
|
||||
// continue
|
||||
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
if(!O.CanZASPass(U))
|
||||
continue direction_loop
|
||||
|
||||
new /obj/effect/alien/weeds(T, linked_node)
|
||||
var/obj/effect/E = new /obj/effect/alien/weeds(T, linked_node)
|
||||
|
||||
E.color = color
|
||||
|
||||
if(istype(src, /obj/effect/alien/weeds/node))
|
||||
var/obj/effect/alien/weeds/node/N = src
|
||||
var/list/nearby_weeds = list()
|
||||
for(var/obj/effect/alien/weeds/W in range(N.node_range,src))
|
||||
nearby_weeds |= W
|
||||
|
||||
for(var/obj/effect/alien/weeds/W in nearby_weeds)
|
||||
if(!W)
|
||||
continue
|
||||
|
||||
if(!W.linked_node)
|
||||
W.linked_node = src
|
||||
|
||||
W.color = W.linked_node.set_color
|
||||
|
||||
if(W == src)
|
||||
continue
|
||||
|
||||
if(prob(max(10, 40 - (5 * nearby_weeds.len))))
|
||||
W.process()
|
||||
|
||||
|
||||
/obj/effect/alien/weeds/ex_act(severity)
|
||||
@@ -282,7 +372,12 @@ Alien plants should do something if theres a lot of poison
|
||||
healthcheck()
|
||||
|
||||
#undef NODERANGE
|
||||
|
||||
#undef WEED_NORTH_EDGING
|
||||
#undef WEED_SOUTH_EDGING
|
||||
#undef WEED_EAST_EDGING
|
||||
#undef WEED_WEST_EDGING
|
||||
#undef WEED_NODE_GLOW
|
||||
#undef WEED_NODE_BASE
|
||||
|
||||
/*
|
||||
* Acid
|
||||
|
||||
@@ -74,6 +74,12 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if(metal)
|
||||
return
|
||||
if(istype(AM, /mob/living))
|
||||
|
||||
@@ -70,6 +70,12 @@ var/global/list/image/splatter_cache=list()
|
||||
desc = initial(desc)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/Crossed(mob/living/carbon/human/perp)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = perp
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if (!istype(perp))
|
||||
return
|
||||
if(amount < 1)
|
||||
@@ -199,10 +205,10 @@ var/global/list/image/splatter_cache=list()
|
||||
overlays += giblets
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/up
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6","gibup1","gibup1","gibup1")
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/down
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/body
|
||||
random_icon_states = list("gibhead", "gibtorso")
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
name = "rolled-up poster"
|
||||
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface."
|
||||
icon_state = "rolled_poster"
|
||||
var/serial_number = 0
|
||||
var/serial_number = null
|
||||
|
||||
var/poster_type = /obj/structure/sign/poster
|
||||
|
||||
/obj/item/weapon/contraband/poster/New(turf/loc, var/given_serial = 0)
|
||||
if(given_serial == 0)
|
||||
serial_number = rand(1, poster_designs.len)
|
||||
else
|
||||
serial_number = given_serial
|
||||
if(!serial_number)
|
||||
if(given_serial == 0)
|
||||
serial_number = rand(1, poster_designs.len)
|
||||
else
|
||||
serial_number = given_serial
|
||||
name += " - No. [serial_number]"
|
||||
..(loc)
|
||||
|
||||
@@ -57,7 +59,7 @@
|
||||
|
||||
user << "<span class='notice'>You start placing the poster on the wall...</span>" //Looks like it's uncluttered enough. Place the poster.
|
||||
|
||||
var/obj/structure/sign/poster/P = new(user.loc, placement_dir=get_dir(user, W), serial=serial_number)
|
||||
var/obj/structure/sign/poster/P = new poster_type(user.loc, placement_dir=get_dir(user, W), serial=serial_number, itemtype = src.type)
|
||||
|
||||
flick("poster_being_set", P)
|
||||
//playsound(W, 'sound/items/poster_being_created.ogg', 100, 1) //why the hell does placing a poster make printer sounds?
|
||||
@@ -74,6 +76,18 @@
|
||||
|
||||
qdel(oldsrc) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway
|
||||
|
||||
//NT subtype
|
||||
/obj/item/weapon/contraband/poster/nanotrasen
|
||||
icon_state = "rolled_poster_nt"
|
||||
poster_type = /obj/structure/sign/poster/nanotrasen
|
||||
|
||||
/obj/item/weapon/contraband/poster/nanotrasen/New(turf/loc, var/given_serial = 0)
|
||||
if(given_serial == 0)
|
||||
serial_number = rand(1, NT_poster_designs.len)
|
||||
else
|
||||
serial_number = given_serial
|
||||
..(loc)
|
||||
|
||||
//############################## THE ACTUAL DECALS ###########################
|
||||
|
||||
/obj/structure/sign/poster
|
||||
@@ -85,15 +99,22 @@
|
||||
var/poster_type //So mappers can specify a desired poster
|
||||
var/ruined = 0
|
||||
|
||||
/obj/structure/sign/poster/New(var/newloc, var/placement_dir=null, var/serial=null)
|
||||
var/roll_type
|
||||
var/poster_set = FALSE
|
||||
|
||||
/obj/structure/sign/poster/New(var/newloc, var/placement_dir=null, var/serial=null, var/itemtype = /obj/item/weapon/contraband/poster)
|
||||
..(newloc)
|
||||
|
||||
if(!serial)
|
||||
serial = rand(1, poster_designs.len) //use a random serial if none is given
|
||||
|
||||
serial_number = serial
|
||||
var/datum/poster/design = poster_designs[serial_number]
|
||||
set_poster(design)
|
||||
if(!poster_set)
|
||||
serial_number = serial
|
||||
var/datum/poster/design = poster_designs[serial_number]
|
||||
set_poster(design)
|
||||
|
||||
if(itemtype || !roll_type)
|
||||
roll_type = itemtype
|
||||
|
||||
switch (placement_dir)
|
||||
if (NORTH)
|
||||
@@ -121,6 +142,8 @@
|
||||
desc = "[initial(desc)] [design.desc]"
|
||||
icon_state = design.icon_state // poster[serial_number]
|
||||
|
||||
poster_set = TRUE
|
||||
|
||||
/obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_wirecutter())
|
||||
playsound(src.loc, W.usesound, 100, 1)
|
||||
@@ -132,7 +155,6 @@
|
||||
roll_and_drop(user.loc)
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/sign/poster/attack_hand(mob/user as mob)
|
||||
|
||||
if(ruined)
|
||||
@@ -152,7 +174,7 @@
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/structure/sign/poster/proc/roll_and_drop(turf/newloc)
|
||||
var/obj/item/weapon/contraband/poster/P = new(src, serial_number)
|
||||
var/obj/item/weapon/contraband/poster/P = new roll_type(src, serial_number)
|
||||
P.loc = newloc
|
||||
src.loc = P
|
||||
qdel(src)
|
||||
@@ -163,3 +185,17 @@
|
||||
// Description suffix
|
||||
var/desc=""
|
||||
var/icon_state=""
|
||||
|
||||
// NT poster subtype.
|
||||
/obj/structure/sign/poster/nanotrasen
|
||||
roll_type = /obj/item/weapon/contraband/poster/nanotrasen
|
||||
|
||||
/obj/structure/sign/poster/nanotrasen/New(var/newloc, var/placement_dir=null, var/serial=null, var/itemtype = /obj/item/weapon/contraband/poster/nanotrasen)
|
||||
if(!serial)
|
||||
serial = rand(1, NT_poster_designs.len)
|
||||
|
||||
serial_number = serial
|
||||
var/datum/poster/design = NT_poster_designs[serial_number]
|
||||
set_poster(design)
|
||||
|
||||
..(newloc, placement_dir, serial, itemtype)
|
||||
|
||||
@@ -43,4 +43,175 @@
|
||||
name = "Airlock Maintenance Reference"
|
||||
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
|
||||
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
|
||||
wire codes."
|
||||
wire codes."
|
||||
|
||||
/datum/poster/pol_10
|
||||
icon_state="polposter9"
|
||||
name = "orchid"
|
||||
desc = "This poster appears strangely familiar, depicting the flower of a tree native to the planet Earth."
|
||||
|
||||
// A new subset of poster datum for Security posters.
|
||||
/datum/poster/nanotrasen
|
||||
icon_state = "polposter1"
|
||||
name = "Safety!"
|
||||
desc = "A poster advising you to learn how to put on your internals at a moment's notice."
|
||||
|
||||
/datum/poster/nanotrasen/pol_2
|
||||
icon_state="polposter2"
|
||||
name = "Safety!"
|
||||
desc = "A blue and white colored poster. This one advises you to wear your safety goggles when handling chemicals."
|
||||
|
||||
/datum/poster/nanotrasen/pol_3
|
||||
icon_state="polposter3"
|
||||
name = "Safety!"
|
||||
desc = "A safety poster instructing you to comply with the authorities, especially in an emergency."
|
||||
|
||||
/datum/poster/nanotrasen/pol_4
|
||||
icon_state="polposter4"
|
||||
name = "Clean Hands Save Lives"
|
||||
desc = "A safety poster reminding you to wash your hands."
|
||||
|
||||
/datum/poster/nanotrasen/pol_5
|
||||
icon_state="polposter5"
|
||||
name = "Help!"
|
||||
desc = "This poster depicts a man helping another man get up."
|
||||
|
||||
/datum/poster/nanotrasen/pol_6
|
||||
icon_state="polposter6"
|
||||
name = "Walk!"
|
||||
desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls."
|
||||
|
||||
/datum/poster/nanotrasen/pol_7
|
||||
icon_state="polposter7"
|
||||
name = "Place your signs!"
|
||||
desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded."
|
||||
|
||||
/datum/poster/nanotrasen/pol_8
|
||||
icon_state="polposter8"
|
||||
name = "Safety!"
|
||||
desc = "An advertisement / safety poster for EVA training and certification. Training is available at your local Central Command."
|
||||
|
||||
/datum/poster/nanotrasen/pol_9
|
||||
icon_state="poster10"
|
||||
name = "Airlock Maintenance Reference"
|
||||
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
|
||||
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
|
||||
wire codes."
|
||||
|
||||
/datum/poster/nanotrasen/pol_10
|
||||
icon_state="polposter9"
|
||||
name = "orchid"
|
||||
desc = "This poster suggests a feeling of peace. It depicts the flower of a tree native to the planet Earth."
|
||||
|
||||
/datum/poster/nanotrasen/bay_9
|
||||
icon_state="bsposter9"
|
||||
name = "Pinup Girl Amy"
|
||||
desc = "This particular one is of Amy, the nymphomaniac urban legend of deep space. How this photograph came to be is not known."
|
||||
|
||||
/datum/poster/nanotrasen/bay_21
|
||||
icon_state="bsposter21"
|
||||
name = "Join the Fuzz!"
|
||||
desc = "It's a nice recruitment poster of a white haired Chinese woman that says; \"Big Guns, Hot Women, Good Times. Security. We get it done.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_22
|
||||
icon_state="bsposter22"
|
||||
name = "Looking for a career with excitement?"
|
||||
desc = "A recruitment poster starring a dark haired woman with glasses and a purple shirt that has \"Got Brains? Got Talent? Not afraid of electric flying monsters that want to suck the soul out of you? Then Xenobiology could use someone like you!\" written on the bottom."
|
||||
|
||||
/datum/poster/nanotrasen/bay_23
|
||||
icon_state="bsposter23"
|
||||
name = "Safety first: because electricity doesn't wait!"
|
||||
desc = "A safety poster starring a clueless looking redhead with frazzled hair. \"Every year, hundreds of NT employees expose themselves to electric shock. Play it safe. Avoid suspicious doors after electrical storms, and always wear protection when doing electric maintenance.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_24
|
||||
icon_state="bsposter24"
|
||||
name = "Responsible medbay habits, No #259"
|
||||
desc = "A poster with a nervous looking geneticist on it states; \"Friends Tell Friends They're Clones. It can cause severe and irreparable emotional trauma if a person is not properly informed of their recent demise. Always follow your contractual obligation and inform them of their recent rejuvenation.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_25
|
||||
icon_state="bsposter25"
|
||||
name = "Irresponsible medbay habits, No #2"
|
||||
desc = "This is a safety poster starring a perverted looking naked doctor. \"Sexual harassment is never okay. REPORT any acts of sexual deviance or harassment that disrupt a healthy working environment.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_49
|
||||
icon_state="bsposter49"
|
||||
name = "Engineering recruitment"
|
||||
desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_52
|
||||
icon_state="bsposter52"
|
||||
name = "fire safety poster"
|
||||
desc = "This is a poster reminding you of what you should do if you are on fire, or if you are at a dance party."
|
||||
|
||||
/datum/poster/nanotrasen/bay_53
|
||||
icon_state="bsposter53"
|
||||
name = "fire extinguisher poster"
|
||||
desc = "This is a poster reminding you of what you should use to put out a fire."
|
||||
|
||||
/datum/poster/nanotrasen/bay_54
|
||||
icon_state="bsposter54"
|
||||
name = "firefighter poster"
|
||||
desc = "This is a poster of a particularly stern looking firefighter. The caption reads, \"Only you can prevent space fires.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_57
|
||||
icon_state="bsposter57"
|
||||
name = "space carp warning poster"
|
||||
desc = "This poster tells of the dangers of space carp infestations."
|
||||
|
||||
/datum/poster/nanotrasen/bay_58
|
||||
icon_state="bsposter58"
|
||||
name = "space carp information poster"
|
||||
desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
|
||||
|
||||
/datum/poster/nanotrasen/nt_1
|
||||
icon_state = "ntposter01"
|
||||
name = "Security recruitment"
|
||||
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about the importance of Security."
|
||||
|
||||
/datum/poster/nanotrasen/nt_2
|
||||
icon_state = "ntposter02"
|
||||
name = "Security recruitment"
|
||||
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about Security Employee benefits."
|
||||
|
||||
/datum/poster/nanotrasen/nt_3
|
||||
icon_state = "ntposter03"
|
||||
name = "Mechatronic Safety"
|
||||
desc = "This poster displays three cutting-edge gygaxes standing in line in front of a man in plain clothes.\
|
||||
The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
|
||||
The image seems important."
|
||||
|
||||
//VOREStation Removal Start TFF 17/12/19 - lore not used in our station's own lore.
|
||||
/*
|
||||
/datum/poster/nanotrasen/nt_4
|
||||
icon_state = "ntposter04"
|
||||
name = "Beware Aetotheans"
|
||||
desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
|
||||
*/
|
||||
//VOREstation Removal End
|
||||
|
||||
/datum/poster/nanotrasen/nt_5
|
||||
icon_state = "ntposter05"
|
||||
name = "Promethean"
|
||||
desc = "This poster displays a friendly-looking green Promethean in a labcoat. The fine-print around the edges talks about the benefits Prometheans give in laboratories."
|
||||
|
||||
/datum/poster/nanotrasen/nt_6
|
||||
icon_state = "ntposter06"
|
||||
name = "NanoTrasen"
|
||||
desc = "This poster showcases an NT emblem. There is writing in the ring around the inner points, probably some sort of slogan no one bothers to memorize."
|
||||
|
||||
/datum/poster/nanotrasen/nt_7
|
||||
icon_state = "ntposter07"
|
||||
name = "SolGov"
|
||||
desc = "This poster showcases an SCG emblem. The outer ring reads,\
|
||||
\"<font face='times new roman ms'>NIL MORTALIBUS ARDUI EST</font>\".\
|
||||
Solar Confederate Government."
|
||||
|
||||
/datum/poster/nanotrasen/nt_8
|
||||
icon_state = "ntposter08"
|
||||
name = "wildlife hazard"
|
||||
desc = "This poster warns against attempting to kill a fully grown giant spider or other hostile life-form alone."
|
||||
|
||||
/datum/poster/nanotrasen/nt_9
|
||||
icon_state = "ntposter09"
|
||||
name = "Regulations and You"
|
||||
desc = "This poster showcases an NT security guard reading from her PDA. The blurb advocates for the reader to keep corporate regulations in mind at all times, as an emergency can occur at any time."
|
||||
|
||||
@@ -185,6 +185,12 @@ steam.start() -- spawns the effect
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/effect/smoke/Crossed(mob/living/carbon/M as mob )
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = M
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
..()
|
||||
if(istype(M))
|
||||
affect(M)
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
..()
|
||||
|
||||
/obj/effect/mine/Crossed(AM as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
Bumped(AM)
|
||||
|
||||
/obj/effect/mine/Bumped(mob/M as mob|obj)
|
||||
|
||||
@@ -21,6 +21,12 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
|
||||
return
|
||||
|
||||
/obj/effect/portal/Crossed(AM as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if(istype(AM,/mob) && !(istype(AM,/mob/living)))
|
||||
return //do not send ghosts, zshadows, ai eyes, etc
|
||||
spawn(0)
|
||||
|
||||
@@ -134,6 +134,8 @@
|
||||
var/travelling_in_vent = 0
|
||||
var/list/grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/nurse, /mob/living/simple_mob/animal/giant_spider/hunter)
|
||||
|
||||
var/stunted = FALSE
|
||||
|
||||
/obj/effect/spider/spiderling/frost
|
||||
grow_as = list(/mob/living/simple_mob/animal/giant_spider/frost)
|
||||
|
||||
@@ -261,9 +263,17 @@
|
||||
break
|
||||
if(amount_grown >= 100)
|
||||
var/spawn_type = pick(grow_as)
|
||||
new spawn_type(src.loc, src)
|
||||
var/mob/living/simple_mob/animal/giant_spider/GS = new spawn_type(src.loc, src)
|
||||
if(stunted)
|
||||
spawn(2)
|
||||
GS.make_spiderling()
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spider/spiderling/stunted
|
||||
stunted = TRUE
|
||||
|
||||
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "spiderling remains"
|
||||
desc = "Green squishy mess."
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/obj/effect/spider/spiderling/virgo
|
||||
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
|
||||
@@ -13,6 +13,12 @@
|
||||
return 0
|
||||
|
||||
/obj/effect/step_trigger/Crossed(H as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = H
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
..()
|
||||
if(!H)
|
||||
return
|
||||
|
||||
@@ -74,16 +74,22 @@
|
||||
switch(drawtype)
|
||||
if("letter")
|
||||
drawtype = input("Choose the letter.", "Crayon scribbles") in list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
|
||||
if(get_dist(target, user) > 1 || !(user.z == target.z))
|
||||
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
|
||||
return
|
||||
to_chat(user, "You start drawing a letter on the [target.name].")
|
||||
if("graffiti")
|
||||
drawtype = input("Choose the graffiti.", "Crayon scribbles") in list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa")
|
||||
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
|
||||
return
|
||||
to_chat(user, "You start drawing graffiti on the [target.name].")
|
||||
if("rune")
|
||||
drawtype = input("Choose the rune.", "Crayon scribbles") in list("rune1", "rune2", "rune3", "rune4", "rune5", "rune6")
|
||||
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
|
||||
return
|
||||
to_chat(user, "You start drawing a rune on the [target.name].")
|
||||
if("arrow")
|
||||
drawtype = input("Choose the arrow.", "Crayon scribbles") in list("left", "right", "up", "down")
|
||||
if(get_dist(target, user) > 1 || !(user.z == target.z))
|
||||
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
|
||||
return
|
||||
to_chat(user, "You start drawing an arrow on the [target.name].")
|
||||
if(instant || do_after(user, 50))
|
||||
|
||||
@@ -1456,6 +1456,12 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/pda/clown/Crossed(AM as mob|obj) //Clown PDA is slippery.
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if (istype(AM, /mob/living))
|
||||
var/mob/living/M = AM
|
||||
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
if(ghost.exonet)
|
||||
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]")
|
||||
|
||||
for(var/obj/item/integrated_circuit/input/EPv2/CIRC in im_contacts)
|
||||
if(CIRC.exonet && CIRC.assembly)
|
||||
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(CIRC.assembly.name), "address" = CIRC.exonet.address, "ref" = "\ref[CIRC]")
|
||||
|
||||
|
||||
//Actual messages.
|
||||
for(var/I in im_list)
|
||||
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
|
||||
|
||||
@@ -1,162 +1,166 @@
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 4 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received,
|
||||
// text - message text to send if message is of type "text")
|
||||
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response and IM function.
|
||||
/obj/item/device/communicator/receive_exonet_message(var/atom/origin_atom, origin_address, message, text)
|
||||
if(message == "voice")
|
||||
if(isobserver(origin_atom) || istype(origin_atom, /obj/item/device/communicator))
|
||||
if(origin_atom in voice_invites)
|
||||
var/user = null
|
||||
if(ismob(origin_atom.loc))
|
||||
user = origin_atom.loc
|
||||
open_connection(user, origin_atom)
|
||||
return
|
||||
else if(origin_atom in voice_requests)
|
||||
return //Spam prevention
|
||||
else
|
||||
request(origin_atom)
|
||||
if(message == "ping")
|
||||
if(network_visibility)
|
||||
var/random = rand(200,350)
|
||||
random = random / 10
|
||||
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
|
||||
if(message == "text")
|
||||
request_im(origin_atom, origin_address, text)
|
||||
return
|
||||
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
|
||||
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
|
||||
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
|
||||
if(message == "voice")
|
||||
if(istype(origin_atom, /obj/item/device/communicator))
|
||||
var/obj/item/device/communicator/comm = origin_atom
|
||||
if(src in comm.voice_invites)
|
||||
comm.open_connection(src)
|
||||
return
|
||||
to_chat(src, "<span class='notice'>\icon[origin_atom] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
|
||||
verb, and select that name to answer the call.</span>")
|
||||
src << 'sound/machines/defib_SafetyOn.ogg'
|
||||
comm.voice_invites |= src
|
||||
if(message == "ping")
|
||||
if(client && client.prefs.communicator_visibility)
|
||||
var/random = rand(450,700)
|
||||
random = random / 10
|
||||
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
|
||||
if(message == "text")
|
||||
to_chat(src, "<span class='notice'>\icon[origin_atom] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
|
||||
src << 'sound/machines/defib_safetyOff.ogg'
|
||||
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
|
||||
return
|
||||
|
||||
// Proc: request_im()
|
||||
// Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message)
|
||||
// Description: Response to a communicator trying to message the device.
|
||||
// Adds them to the list of people that have messaged this device and adds the message to the message list.
|
||||
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
|
||||
var/who = null
|
||||
if(isobserver(candidate))
|
||||
var/mob/observer/dead/ghost = candidate
|
||||
who = ghost
|
||||
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
|
||||
else if(istype(candidate, /obj/item/device/communicator))
|
||||
var/obj/item/device/communicator/comm = candidate
|
||||
who = comm.owner
|
||||
comm.im_contacts |= src
|
||||
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
|
||||
else return
|
||||
|
||||
im_contacts |= candidate
|
||||
|
||||
if(!who)
|
||||
return
|
||||
|
||||
if(ringer)
|
||||
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(2, loc))
|
||||
O.show_message(text("\icon[src] *beep*"))
|
||||
|
||||
alert_called = 1
|
||||
update_icon()
|
||||
|
||||
//Search for holder of the device.
|
||||
var/mob/living/L = null
|
||||
if(loc && isliving(loc))
|
||||
L = loc
|
||||
|
||||
if(L)
|
||||
to_chat(L, "<span class='notice'>\icon[src] Message from [who].</span>")
|
||||
|
||||
// Verb: text_communicator()
|
||||
// Parameters: None
|
||||
// Description: Allows a ghost to send a text message to a communicator.
|
||||
/mob/observer/dead/verb/text_communicator()
|
||||
set category = "Ghost"
|
||||
set name = "Text Communicator"
|
||||
set desc = "If there is a communicator available, send a text message to it."
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
|
||||
return
|
||||
|
||||
if (!src.stat)
|
||||
return
|
||||
|
||||
if (usr != src)
|
||||
return //something is terribly wrong
|
||||
|
||||
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
|
||||
if(src.client.prefs.real_name == L.real_name)
|
||||
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
|
||||
return
|
||||
|
||||
var/obj/machinery/exonet_node/E = get_exonet_node()
|
||||
if(!E || !E.on || !E.allow_external_communicators)
|
||||
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
|
||||
so your call can't go through.</span>")
|
||||
return
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/obj/item/device/communicator/comm in all_communicators)
|
||||
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
|
||||
continue
|
||||
choices.Add(comm)
|
||||
|
||||
if(!choices.len)
|
||||
to_chat(src, "<span class='danger'>There are no available communicators, sorry.</span>")
|
||||
return
|
||||
|
||||
var/choice = input(src,"Send a text message to whom?") as null|anything in choices
|
||||
if(choice)
|
||||
var/obj/item/device/communicator/chosen_communicator = choice
|
||||
var/mob/observer/dead/O = src
|
||||
var/text_message = sanitize(input(src, "What do you want the message to say?")) as message
|
||||
if(text_message && O.exonet)
|
||||
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
|
||||
|
||||
to_chat(src, "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>")
|
||||
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
|
||||
log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
|
||||
continue
|
||||
if(M == src)
|
||||
continue
|
||||
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
|
||||
|
||||
|
||||
|
||||
// Verb: show_text_messages()
|
||||
// Parameters: None
|
||||
// Description: Lets ghosts review messages they've sent or received.
|
||||
/mob/observer/dead/verb/show_text_messages()
|
||||
set category = "Ghost"
|
||||
set name = "Show Text Messages"
|
||||
set desc = "Allows you to see exonet text messages you've sent and received."
|
||||
|
||||
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
|
||||
for(var/line in exonet_messages)
|
||||
HTML += line + "<br>"
|
||||
HTML +="</body></html>"
|
||||
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 4 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received,
|
||||
// text - message text to send if message is of type "text")
|
||||
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response and IM function.
|
||||
/obj/item/device/communicator/receive_exonet_message(var/atom/origin_atom, origin_address, message, text)
|
||||
if(message == "voice")
|
||||
if(isobserver(origin_atom) || istype(origin_atom, /obj/item/device/communicator))
|
||||
if(origin_atom in voice_invites)
|
||||
var/user = null
|
||||
if(ismob(origin_atom.loc))
|
||||
user = origin_atom.loc
|
||||
open_connection(user, origin_atom)
|
||||
return
|
||||
else if(origin_atom in voice_requests)
|
||||
return //Spam prevention
|
||||
else
|
||||
request(origin_atom)
|
||||
if(message == "ping")
|
||||
if(network_visibility)
|
||||
var/random = rand(200,350)
|
||||
random = random / 10
|
||||
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
|
||||
if(message == "text")
|
||||
request_im(origin_atom, origin_address, text)
|
||||
return
|
||||
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
|
||||
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
|
||||
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
|
||||
if(message == "voice")
|
||||
if(istype(origin_atom, /obj/item/device/communicator))
|
||||
var/obj/item/device/communicator/comm = origin_atom
|
||||
if(src in comm.voice_invites)
|
||||
comm.open_connection(src)
|
||||
return
|
||||
to_chat(src, "<span class='notice'>\icon[origin_atom] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
|
||||
verb, and select that name to answer the call.</span>")
|
||||
src << 'sound/machines/defib_SafetyOn.ogg'
|
||||
comm.voice_invites |= src
|
||||
if(message == "ping")
|
||||
if(client && client.prefs.communicator_visibility)
|
||||
var/random = rand(450,700)
|
||||
random = random / 10
|
||||
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
|
||||
if(message == "text")
|
||||
to_chat(src, "<span class='notice'>\icon[origin_atom] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
|
||||
src << 'sound/machines/defib_safetyOff.ogg'
|
||||
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
|
||||
return
|
||||
|
||||
// Proc: request_im()
|
||||
// Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message)
|
||||
// Description: Response to a communicator trying to message the device.
|
||||
// Adds them to the list of people that have messaged this device and adds the message to the message list.
|
||||
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
|
||||
var/who = null
|
||||
if(isobserver(candidate))
|
||||
var/mob/observer/dead/ghost = candidate
|
||||
who = ghost
|
||||
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
|
||||
else if(istype(candidate, /obj/item/device/communicator))
|
||||
var/obj/item/device/communicator/comm = candidate
|
||||
who = comm.owner
|
||||
comm.im_contacts |= src
|
||||
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
|
||||
else if(istype(candidate, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/CIRC = candidate
|
||||
who = CIRC
|
||||
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
|
||||
else return
|
||||
|
||||
im_contacts |= candidate
|
||||
|
||||
if(!who)
|
||||
return
|
||||
|
||||
if(ringer)
|
||||
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(2, loc))
|
||||
O.show_message(text("\icon[src] *beep*"))
|
||||
|
||||
alert_called = 1
|
||||
update_icon()
|
||||
|
||||
//Search for holder of the device.
|
||||
var/mob/living/L = null
|
||||
if(loc && isliving(loc))
|
||||
L = loc
|
||||
|
||||
if(L)
|
||||
to_chat(L, "<span class='notice'>\icon[src] Message from [who].</span>")
|
||||
|
||||
// Verb: text_communicator()
|
||||
// Parameters: None
|
||||
// Description: Allows a ghost to send a text message to a communicator.
|
||||
/mob/observer/dead/verb/text_communicator()
|
||||
set category = "Ghost"
|
||||
set name = "Text Communicator"
|
||||
set desc = "If there is a communicator available, send a text message to it."
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
|
||||
return
|
||||
|
||||
if (!src.stat)
|
||||
return
|
||||
|
||||
if (usr != src)
|
||||
return //something is terribly wrong
|
||||
|
||||
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
|
||||
if(src.client.prefs.real_name == L.real_name)
|
||||
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
|
||||
return
|
||||
|
||||
var/obj/machinery/exonet_node/E = get_exonet_node()
|
||||
if(!E || !E.on || !E.allow_external_communicators)
|
||||
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
|
||||
so your call can't go through.</span>")
|
||||
return
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/obj/item/device/communicator/comm in all_communicators)
|
||||
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
|
||||
continue
|
||||
choices.Add(comm)
|
||||
|
||||
if(!choices.len)
|
||||
to_chat(src, "<span class='danger'>There are no available communicators, sorry.</span>")
|
||||
return
|
||||
|
||||
var/choice = input(src,"Send a text message to whom?") as null|anything in choices
|
||||
if(choice)
|
||||
var/obj/item/device/communicator/chosen_communicator = choice
|
||||
var/mob/observer/dead/O = src
|
||||
var/text_message = sanitize(input(src, "What do you want the message to say?")) as message
|
||||
if(text_message && O.exonet)
|
||||
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
|
||||
|
||||
to_chat(src, "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>")
|
||||
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
|
||||
log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
|
||||
continue
|
||||
if(M == src)
|
||||
continue
|
||||
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
|
||||
|
||||
|
||||
|
||||
// Verb: show_text_messages()
|
||||
// Parameters: None
|
||||
// Description: Lets ghosts review messages they've sent or received.
|
||||
/mob/observer/dead/verb/show_text_messages()
|
||||
set category = "Ghost"
|
||||
set name = "Show Text Messages"
|
||||
set desc = "Allows you to see exonet text messages you've sent and received."
|
||||
|
||||
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
|
||||
for(var/line in exonet_messages)
|
||||
HTML += line + "<br>"
|
||||
HTML +="</body></html>"
|
||||
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
desc = "A desk lamp with an adjustable mount."
|
||||
icon_state = "lamp"
|
||||
force = 10
|
||||
brightness_on = 5
|
||||
brightness_on = 10 //TFF 27/11/19 - post refactor fix for intensity levels.
|
||||
w_class = ITEMSIZE_LARGE
|
||||
power_use = 0
|
||||
on = 1
|
||||
|
||||
@@ -54,6 +54,11 @@
|
||||
var/failmsg = ""
|
||||
var/charge = 0
|
||||
|
||||
// Eating used bulbs gives us bulb shards
|
||||
var/bulb_shards = 0
|
||||
// when we get this many shards, we get a free bulb.
|
||||
var/shards_required = 4
|
||||
|
||||
/obj/item/device/lightreplacer/New()
|
||||
failmsg = "The [name]'s refill light blinks red."
|
||||
..()
|
||||
@@ -76,18 +81,55 @@
|
||||
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights.</span>")
|
||||
|
||||
if(istype(W, /obj/item/weapon/light))
|
||||
var/new_bulbs = 0
|
||||
var/obj/item/weapon/light/L = W
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
add_uses(1)
|
||||
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
|
||||
user.drop_item()
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
to_chat(user, "You need a working light.")
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
new_bulbs += AddShards(1)
|
||||
qdel(L)
|
||||
if(new_bulbs != 0)
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = W
|
||||
var/found_lightbulbs = FALSE
|
||||
var/replaced_something = TRUE
|
||||
|
||||
for(var/obj/item/I in S.contents)
|
||||
if(istype(I,/obj/item/weapon/light))
|
||||
var/obj/item/weapon/light/L = I
|
||||
found_lightbulbs = TRUE
|
||||
if(src.uses >= max_uses)
|
||||
break
|
||||
if(L.status == LIGHT_OK)
|
||||
replaced_something = TRUE
|
||||
add_uses(1)
|
||||
qdel(L)
|
||||
|
||||
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
|
||||
replaced_something = TRUE
|
||||
AddShards(1)
|
||||
qdel(L)
|
||||
|
||||
if(!found_lightbulbs)
|
||||
to_chat(user, "<span class='warning'>\The [S] contains no bulbs.</span>")
|
||||
return
|
||||
|
||||
if(!replaced_something && src.uses == max_uses)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You fill \the [src] with lights from \the [S].</span>")
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
/* // This would probably be a bit OP. If you want it though, uncomment the code.
|
||||
if(isrobot(user))
|
||||
@@ -113,6 +155,15 @@
|
||||
/obj/item/device/lightreplacer/proc/add_uses(var/amount = 1)
|
||||
uses = min(max(uses + amount, 0), max_uses)
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
|
||||
bulb_shards += amount
|
||||
var/new_bulbs = round(bulb_shards / shards_required)
|
||||
if(new_bulbs > 0)
|
||||
add_uses(new_bulbs)
|
||||
bulb_shards = bulb_shards % shards_required
|
||||
return new_bulbs
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1)
|
||||
charge += amount
|
||||
if(charge > 6)
|
||||
@@ -121,18 +172,41 @@
|
||||
|
||||
/obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U)
|
||||
|
||||
if(target.status == LIGHT_OK)
|
||||
if(target.status != LIGHT_OK)
|
||||
if(CanUse(U))
|
||||
if(!Use(U)) return
|
||||
to_chat(U, "<span class='notice'>You replace the [target.get_fitting_name()] with the [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
var/new_bulbs = AddShards(1)
|
||||
if(new_bulbs != 0)
|
||||
to_chat(U, "<span class='notice'>\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.</span>")
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
|
||||
var/obj/item/weapon/light/L2 = new target.light_type()
|
||||
|
||||
target.status = L2.status
|
||||
target.switchcount = L2.switchcount
|
||||
target.rigged = emagged
|
||||
target.brightness_range = L2.brightness_range
|
||||
target.brightness_power = L2.brightness_power
|
||||
target.brightness_color = L2.brightness_color
|
||||
target.on = target.has_power()
|
||||
target.update()
|
||||
qdel(L2)
|
||||
|
||||
if(target.on && target.rigged)
|
||||
target.explode()
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(U, failmsg)
|
||||
return
|
||||
else
|
||||
to_chat(U, "There is a working [target.get_fitting_name()] already inserted.")
|
||||
else if(!CanUse(U))
|
||||
to_chat(U, failmsg)
|
||||
else if(Use(U))
|
||||
to_chat(U, "<span class='notice'>You replace the [target.get_fitting_name()] with the [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
target.remove_bulb()
|
||||
|
||||
var/obj/item/weapon/light/L = new target.light_type()
|
||||
target.insert_bulb(L)
|
||||
return
|
||||
|
||||
/obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user)
|
||||
emagged = !emagged
|
||||
@@ -153,4 +227,4 @@
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
#undef LIGHT_BURNED
|
||||
@@ -51,10 +51,10 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/device/multitool/proc/mode_switch(mob/living/user)
|
||||
if(++mode_index > modes.len) mode_index = 1
|
||||
if(mode_index + 1 > modes.len) mode_index = 1
|
||||
|
||||
else
|
||||
mode_index++
|
||||
mode_index += 1
|
||||
|
||||
toolmode = modes[mode_index]
|
||||
to_chat(user,"<span class='notice'>\The [src] is now set to [toolmode].</span>")
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/obj/item/device/encryptionkey/heads/captain
|
||||
name = "colony director's encryption key"
|
||||
icon_state = "cap_cypherkey"
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0)
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/ai_integrated
|
||||
name = "ai integrated encryption key"
|
||||
@@ -99,7 +99,7 @@
|
||||
/obj/item/device/encryptionkey/heads/hop
|
||||
name = "head of personnel's encryption key"
|
||||
icon_state = "hop_cypherkey"
|
||||
channels = list("Supply" = 1, "Service" = 1, "Command" = 1, "Security" = 0)
|
||||
channels = list("Supply" = 1, "Service" = 1, "Command" = 1, "Security" = 1)
|
||||
/*
|
||||
/obj/item/device/encryptionkey/headset_mine
|
||||
name = "mining radio encryption key"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/device/encryptionkey/heads/hop
|
||||
name = "head of personnel's encryption key"
|
||||
icon_state = "hop_cypherkey"
|
||||
channels = list("Supply" = 1, "Service" = 1, "Command" = 1, "Security" = 0, "Explorer" = 0)
|
||||
channels = list("Supply" = 1, "Service" = 1, "Command" = 1, "Security" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/ai_integrated
|
||||
name = "ai integrated encryption key"
|
||||
@@ -12,7 +12,7 @@
|
||||
/obj/item/device/encryptionkey/heads/captain
|
||||
name = "colony director's encryption key"
|
||||
icon_state = "cap_cypherkey"
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0, "Explorer" = 0)
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/rd
|
||||
name = "research director's encryption key"
|
||||
|
||||
@@ -46,10 +46,10 @@
|
||||
/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel)
|
||||
if (channel == "special")
|
||||
if (translate_binary)
|
||||
var/datum/language/binary = all_languages["Robot Talk"]
|
||||
var/datum/language/binary = GLOB.all_languages["Robot Talk"]
|
||||
binary.broadcast(M, message)
|
||||
if (translate_hive)
|
||||
var/datum/language/hivemind = all_languages["Hivemind"]
|
||||
var/datum/language/hivemind = GLOB.all_languages["Hivemind"]
|
||||
hivemind.broadcast(M, message)
|
||||
return null
|
||||
|
||||
|
||||
@@ -19,4 +19,29 @@
|
||||
|
||||
/obj/item/device/radio/headset
|
||||
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ears.dmi',
|
||||
SPECIES_WEREBEAST = 'icons/mob/species/werebeast/ears.dmi')
|
||||
SPECIES_WEREBEAST = 'icons/mob/species/werebeast/ears.dmi')
|
||||
|
||||
/obj/item/device/radio/headset/mob_headset //Adminbus headset for simplemob shenanigans.
|
||||
name = "nonhuman radio receiver"
|
||||
desc = "An updated, self-adhesive modular intercom that requires no hands to operate or ears to hold, just stick it on. Takes encryption keys"
|
||||
|
||||
/obj/item/device/radio/headset/mob_headset/receive_range(freq, level)
|
||||
if(ismob(src.loc))
|
||||
return ..(freq, level, 1)
|
||||
return -1
|
||||
|
||||
/obj/item/device/radio/headset/mob_headset/afterattack(var/atom/movable/target, mob/living/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(istype(target,/mob/living/simple_mob))
|
||||
var/mob/living/simple_mob/M = target
|
||||
if(!M.mob_radio)
|
||||
user.drop_item()
|
||||
forceMove(M)
|
||||
M.mob_radio = src
|
||||
return
|
||||
if(M.mob_radio)
|
||||
M.mob_radio.forceMove(M.loc)
|
||||
M.mob_radio = null
|
||||
return
|
||||
..()
|
||||
@@ -60,7 +60,7 @@
|
||||
name = "broken bug"
|
||||
desc = "" //Even when it's broken it's inconspicuous
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "eshield0"
|
||||
icon_state = "eshield"
|
||||
item_state = "nothing"
|
||||
layer = TURF_LAYER+0.2
|
||||
w_class = ITEMSIZE_TINY
|
||||
@@ -75,7 +75,7 @@
|
||||
name = "bug"
|
||||
desc = "" //Nothing to see here
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "eshield0"
|
||||
icon_state = "eshield"
|
||||
item_state = "nothing"
|
||||
layer = TURF_LAYER+0.2
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
//The perfect adminboos device?
|
||||
/obj/item/device/perfect_tele
|
||||
name = "personal translocator"
|
||||
desc = "Seems absurd, doesn't it? Yet, here we are. Generally considered dangerous contraband unless the user has permission from Central Command."
|
||||
icon = 'icons/obj/device_alt.dmi'
|
||||
icon_state = "hand_tele"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
origin_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_ILLEGAL = 7)
|
||||
|
||||
var/cell_type = /obj/item/weapon/cell/device/weapon
|
||||
var/obj/item/weapon/cell/power_source
|
||||
var/charge_cost = 800 // cell/device/weapon has 2400
|
||||
var/battery_lock = 0 //If set, weapon cannot switch batteries
|
||||
|
||||
var/longrange = 0 //Can teleport very long distances
|
||||
var/abductor = 0 //Can be used on teleportation blocking turfs
|
||||
|
||||
var/list/beacons = list()
|
||||
var/ready = 1
|
||||
var/beacons_left = 3
|
||||
var/failure_chance = 5 //Percent
|
||||
var/obj/item/device/perfect_tele_beacon/destination
|
||||
var/datum/effect/effect/system/spark_spread/spk
|
||||
var/list/warned_users = list()
|
||||
var/list/logged_events = list()
|
||||
|
||||
/obj/item/device/perfect_tele/New()
|
||||
..()
|
||||
flags |= NOBLUDGEON
|
||||
if(cell_type)
|
||||
power_source = new cell_type(src)
|
||||
else
|
||||
power_source = new /obj/item/weapon/cell/device(src)
|
||||
spk = new(src)
|
||||
spk.set_up(5, 0, src)
|
||||
spk.attach(src)
|
||||
|
||||
/obj/item/device/perfect_tele/Destroy()
|
||||
// Must clear the beacon's backpointer or we won't GC. Someday maybe do something nicer even.
|
||||
for(var/obj/item/device/perfect_tele_beacon/B in beacons)
|
||||
B.tele_hand = null
|
||||
beacons.Cut()
|
||||
QDEL_NULL(power_source)
|
||||
QDEL_NULL(spk)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/perfect_tele/update_icon()
|
||||
if(!power_source)
|
||||
icon_state = "[initial(icon_state)]_o"
|
||||
else if(ready && (power_source.check_charge(charge_cost) || power_source.fully_charged()))
|
||||
icon_state = "[initial(icon_state)]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_w"
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele/attack_hand(mob/user)
|
||||
if(user.get_inactive_hand() == src)
|
||||
unload_ammo(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/perfect_tele/proc/unload_ammo(mob/user)
|
||||
if(battery_lock)
|
||||
to_chat(user,"<span class='notice'>[src] does not have a battery port.</span>")
|
||||
return
|
||||
if(user.get_inactive_hand() == src && power_source)
|
||||
to_chat(user,"<span class='notice'>You eject \the [power_source] from \the [src].</span>")
|
||||
user.put_in_hands(power_source)
|
||||
power_source = null
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user,"<span class='notice'>[src] does not have a power cell.</span>")
|
||||
|
||||
/obj/item/device/perfect_tele/attack_self(mob/user)
|
||||
if(!(user.ckey in warned_users))
|
||||
warned_users |= user.ckey
|
||||
alert(user,"This device can be easily used to break ERP preferences due to the nature of teleporting \
|
||||
and tele-vore. Make sure you carefully examine someone's OOC prefs before teleporting them if you are \
|
||||
going to use this device for ERP purposes. This device records all warnings given and teleport events for \
|
||||
admin review in case of pref-breaking, so just don't do it.","OOC WARNING")
|
||||
|
||||
var/choice = alert(user,"What do you want to do?","[src]","Create Beacon","Cancel","Target Beacon")
|
||||
switch(choice)
|
||||
if("Create Beacon")
|
||||
if(beacons_left <= 0)
|
||||
alert("The translocator can't support any more beacons!","Error")
|
||||
return
|
||||
|
||||
var/new_name = html_encode(input(user,"New beacon's name (2-20 char):","[src]") as text|null)
|
||||
|
||||
if(length(new_name) > 20 || length(new_name) < 2)
|
||||
alert("Entered name length invalid (must be longer than 2, no more than than 20).","Error")
|
||||
return
|
||||
if(new_name in beacons)
|
||||
alert("No duplicate names, please. '[new_name]' exists already.","Error")
|
||||
return
|
||||
|
||||
var/obj/item/device/perfect_tele_beacon/nb = new(get_turf(src))
|
||||
nb.tele_name = new_name
|
||||
nb.tele_hand = src
|
||||
nb.creator = user.ckey
|
||||
beacons[new_name] = nb
|
||||
beacons_left--
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
L.put_in_any_hand_if_possible(nb)
|
||||
|
||||
if("Target Beacon")
|
||||
if(!beacons.len)
|
||||
to_chat(user,"<span class='warning'>\The [src] doesn't have any beacons!</span>")
|
||||
else
|
||||
var/target = input("Which beacon do you target?","[src]") in beacons|null
|
||||
if(target && (target in beacons))
|
||||
destination = beacons[target]
|
||||
to_chat(user,"<span class='notice'>Destination set to '[target]'.</span>")
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/device/perfect_tele/attackby(obj/W, mob/user)
|
||||
if(istype(W,cell_type) && !power_source)
|
||||
power_source = W
|
||||
power_source.update_icon() //Why doesn't a cell do this already? :|
|
||||
user.unEquip(power_source)
|
||||
power_source.forceMove(src)
|
||||
to_chat(user,"<span class='notice'>You insert \the [power_source] into \the [src].</span>")
|
||||
update_icon()
|
||||
|
||||
else if(istype(W,/obj/item/device/perfect_tele_beacon))
|
||||
var/obj/item/device/perfect_tele_beacon/tb = W
|
||||
if(tb.tele_name in beacons)
|
||||
to_chat(user,"<span class='notice'>You re-insert \the [tb] into \the [src].</span>")
|
||||
beacons -= tb.tele_name
|
||||
user.unEquip(tb)
|
||||
qdel(tb)
|
||||
beacons_left++
|
||||
else
|
||||
to_chat(user,"<span class='notice'>\The [tb] doesn't belong to \the [src].</span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele/proc/teleport_checks(mob/living/target,mob/living/user)
|
||||
//Uhhuh, need that power source
|
||||
if(!power_source)
|
||||
to_chat(user,"<span class='warning'>\The [src] has no power source!</span>")
|
||||
return FALSE
|
||||
|
||||
//Check for charge
|
||||
if((!power_source.check_charge(charge_cost)) && (!power_source.fully_charged()))
|
||||
to_chat(user,"<span class='warning'>\The [src] does not have enough power left!</span>")
|
||||
return FALSE
|
||||
|
||||
//Only mob/living need apply.
|
||||
if(!istype(user) || !istype(target))
|
||||
return FALSE
|
||||
|
||||
//No, you can't teleport buckled people.
|
||||
if(target.buckled)
|
||||
to_chat(user,"<span class='warning'>The target appears to be attached to something...</span>")
|
||||
return FALSE
|
||||
|
||||
//No, you can't teleport if it's not ready yet.
|
||||
if(!ready)
|
||||
to_chat(user,"<span class='warning'>\The [src] is still recharging!</span>")
|
||||
return FALSE
|
||||
|
||||
//No, you can't teleport if there's no destination.
|
||||
if(!destination)
|
||||
to_chat(user,"<span class='warning'>\The [src] doesn't have a current valid destination set!</span>")
|
||||
return FALSE
|
||||
|
||||
//No, you can't teleport if there's a jammer.
|
||||
if(is_jammed(src) || is_jammed(destination))
|
||||
to_chat(user,"<span class='warning'>\The [src] refuses to teleport you, due to strong interference!</span>")
|
||||
return FALSE
|
||||
|
||||
//No, you can't port to or from away missions. Stupidly complicated check.
|
||||
var/turf/uT = get_turf(user)
|
||||
var/turf/dT = get_turf(destination)
|
||||
var/list/dat = list()
|
||||
dat["z_level_detection"] = using_map.get_map_levels(uT.z)
|
||||
|
||||
if(!uT || !dT)
|
||||
return FALSE
|
||||
|
||||
if(!longrange)
|
||||
if( (uT.z != dT.z) && (!(dT.z in dat["z_level_detection"])) )
|
||||
to_chat(user,"<span class='warning'>\The [src] can't teleport you that far!</span>")
|
||||
return FALSE
|
||||
|
||||
if(!abductor)
|
||||
if(uT.block_tele || dT.block_tele)
|
||||
to_chat(user,"<span class='warning'>Something is interfering with \the [src]!</span>")
|
||||
return FALSE
|
||||
|
||||
//Seems okay to me!
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/perfect_tele/afterattack(mob/living/target, mob/living/user, proximity)
|
||||
//No, you can't teleport people from over there.
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
if(!teleport_checks(target,user))
|
||||
return //The checks proc can send them a message if it wants.
|
||||
|
||||
//Bzzt.
|
||||
ready = 0
|
||||
power_source.use(charge_cost)
|
||||
|
||||
//Failure chance
|
||||
if(prob(failure_chance) && beacons.len >= 2)
|
||||
var/list/wrong_choices = beacons - destination.tele_name
|
||||
var/wrong_name = pick(wrong_choices)
|
||||
destination = beacons[wrong_name]
|
||||
to_chat(user,"<span class='warning'>\The [src] malfunctions and sends you to the wrong beacon!</span>")
|
||||
|
||||
//Destination beacon vore checking
|
||||
var/turf/dT = get_turf(destination)
|
||||
var/atom/real_dest = dT
|
||||
|
||||
var/atom/real_loc = destination.loc
|
||||
if(isbelly(real_loc))
|
||||
real_dest = real_loc
|
||||
if(isliving(real_loc))
|
||||
var/mob/living/L = real_loc
|
||||
if(L.vore_selected)
|
||||
real_dest = L.vore_selected
|
||||
else if(L.vore_organs.len)
|
||||
real_dest = pick(L.vore_organs)
|
||||
|
||||
//Confirm televore
|
||||
var/televored = FALSE
|
||||
if(isbelly(real_dest))
|
||||
var/obj/belly/B = real_dest
|
||||
if(!target.can_be_drop_prey && B.owner != user)
|
||||
to_chat(target,"<span class='warning'>\The [src] narrowly avoids teleporting you right into \a [lowertext(real_dest.name)]!</span>")
|
||||
real_dest = dT //Nevermind!
|
||||
else
|
||||
televored = TRUE
|
||||
to_chat(target,"<span class='warning'>\The [src] teleports you right into \a [lowertext(real_dest.name)]!</span>")
|
||||
|
||||
//Phase-out effect
|
||||
phase_out(target,get_turf(target))
|
||||
|
||||
//Move them
|
||||
target.forceMove(real_dest)
|
||||
|
||||
//Phase-in effect
|
||||
phase_in(target,get_turf(target))
|
||||
|
||||
//And any friends!
|
||||
for(var/obj/item/weapon/grab/G in target.contents)
|
||||
if(G.affecting && (G.state >= GRAB_AGGRESSIVE))
|
||||
|
||||
//Phase-out effect for grabbed person
|
||||
phase_out(G.affecting,get_turf(G.affecting))
|
||||
|
||||
//Move them, and televore if necessary
|
||||
G.affecting.forceMove(real_dest)
|
||||
if(televored)
|
||||
to_chat(target,"<span class='warning'>\The [src] teleports you right into \a [lowertext(real_dest.name)]!</span>")
|
||||
|
||||
//Phase-in effect for grabbed person
|
||||
phase_in(G.affecting,get_turf(G.affecting))
|
||||
|
||||
update_icon()
|
||||
spawn(30 SECONDS)
|
||||
ready = 1
|
||||
update_icon()
|
||||
|
||||
logged_events["[world.time]"] = "[user] teleported [target] to [real_dest] [televored ? "(Belly: [lowertext(real_dest.name)])" : null]"
|
||||
|
||||
/obj/item/device/perfect_tele/proc/phase_out(var/mob/M,var/turf/T)
|
||||
|
||||
if(!M || !T)
|
||||
return
|
||||
|
||||
spk.set_up(5, 0, M)
|
||||
spk.attach(M)
|
||||
playsound(T, "sparks", 50, 1)
|
||||
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
|
||||
|
||||
/obj/item/device/perfect_tele/proc/phase_in(var/mob/M,var/turf/T)
|
||||
|
||||
if(!M || !T)
|
||||
return
|
||||
|
||||
spk.start()
|
||||
playsound(T, 'sound/effects/phasein.ogg', 25, 1)
|
||||
playsound(T, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
anim(T,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
|
||||
spk.set_up(5, 0, src)
|
||||
spk.attach(src)
|
||||
|
||||
/obj/item/device/perfect_tele_beacon
|
||||
name = "translocator beacon"
|
||||
desc = "That's unusual."
|
||||
icon = 'icons/obj/device_alt.dmi'
|
||||
icon_state = "motion2"
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
var/tele_name
|
||||
var/obj/item/device/perfect_tele/tele_hand
|
||||
var/creator
|
||||
var/warned_users = list()
|
||||
var/tele_network = null
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/New()
|
||||
..()
|
||||
flags |= NOBLUDGEON
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/Destroy()
|
||||
tele_name = null
|
||||
tele_hand = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/attack_hand(mob/user)
|
||||
if((user.ckey != creator) && !(user.ckey in warned_users))
|
||||
warned_users |= user.ckey
|
||||
var/choice = alert(user,"This device is a translocator beacon. Having it on your person may mean that anyone \
|
||||
who teleports to this beacon gets teleported into your selected vore-belly. If you are prey-only \
|
||||
or don't wish to potentially have a random person teleported into you, it's suggested that you \
|
||||
not carry this around.","OOC WARNING","Take It","Leave It")
|
||||
if(choice == "Leave It")
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/stationary
|
||||
name = "stationary translocator beacon"
|
||||
icon = 'icons/obj/radio_vr.dmi'
|
||||
icon_state = "floor_beacon"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
anchored = 1
|
||||
|
||||
GLOBAL_LIST_BOILERPLATE(premade_tele_beacons, /obj/item/device/perfect_tele_beacon/stationary)
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/attack_self(mob/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
var/confirm = alert(user, "You COULD eat the beacon...", "Eat beacon?", "Eat it!", "No, thanks.")
|
||||
if(confirm == "Eat it!")
|
||||
var/obj/belly/bellychoice = input("Which belly?","Select A Belly") as null|anything in L.vore_organs
|
||||
if(bellychoice)
|
||||
user.visible_message("<span class='warning'>[user] is trying to stuff \the [src] into [user.gender == MALE ? "his" : user.gender == FEMALE ? "her" : "their"] [bellychoice]!</span>","<span class='notice'>You begin putting \the [src] into your [bellychoice]!</span>")
|
||||
if(do_after(user,5 SECONDS,src))
|
||||
user.unEquip(src)
|
||||
forceMove(bellychoice)
|
||||
user.visible_message("<span class='warning'>[user] eats a telebeacon!</span>","You eat the the beacon!")
|
||||
|
||||
// A single-beacon variant for use by miners (or whatever)
|
||||
/obj/item/device/perfect_tele/one_beacon
|
||||
name = "mini-translocator"
|
||||
desc = "A more limited translocator with a single beacon, useful for some things, like setting the mining department on fire accidentally. Legal for use in the pursuit of NanoTrasen interests, namely mining and exploration."
|
||||
icon_state = "minitrans"
|
||||
beacons_left = 1 //Just one
|
||||
cell_type = /obj/item/weapon/cell/device
|
||||
origin_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5)
|
||||
|
||||
/*
|
||||
/obj/item/device/perfect_tele/one_beacon/teleport_checks(mob/living/target,mob/living/user)
|
||||
var/turf/T = get_turf(destination)
|
||||
if(T && user.z != T.z)
|
||||
to_chat(user,"<span class='warning'>\The [src] is too far away from the beacon. Try getting closer first!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/obj/item/device/perfect_tele/alien
|
||||
name = "alien translocator"
|
||||
desc = "This strange device allows one to teleport people and objects across large distances."
|
||||
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge/alien
|
||||
charge_cost = 400
|
||||
beacons_left = 6
|
||||
failure_chance = 0 //Percent
|
||||
longrange = 1
|
||||
abductor = 1
|
||||
|
||||
/obj/item/device/perfect_tele/frontier
|
||||
icon_state = "minitrans"
|
||||
beacons_left = 1 //Just one
|
||||
battery_lock = 1
|
||||
unacidable = 1
|
||||
failure_chance = 0 //Percent
|
||||
var/loc_network = null
|
||||
var/phase_power = 75
|
||||
var/recharging = 0
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/unload_ammo(var/mob/user)
|
||||
if(recharging)
|
||||
return
|
||||
recharging = 1
|
||||
update_icon()
|
||||
user.visible_message("<span class='notice'>[user] opens \the [src] and starts pumping the handle.</span>", \
|
||||
"<span class='notice'>You open \the [src] and start pumping the handle.</span>")
|
||||
while(recharging)
|
||||
if(!do_after(user, 10, src))
|
||||
break
|
||||
playsound(get_turf(src),'sound/items/change_drill.ogg',25,1)
|
||||
if(power_source.give(phase_power) < phase_power)
|
||||
break
|
||||
|
||||
recharging = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/update_icon()
|
||||
if(recharging)
|
||||
icon_state = "[initial(icon_state)]_o"
|
||||
update_held_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/staff
|
||||
name = "centcom translocator"
|
||||
desc = "Similar to translocator technology, however, most of its destinations are hardcoded."
|
||||
charge_cost = 1200 // Enough for one person and their partner
|
||||
loc_network = "centcom"
|
||||
longrange = 1
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/staff/New()
|
||||
..()
|
||||
for(var/obj/item/device/perfect_tele_beacon/stationary/nb in premade_tele_beacons)
|
||||
if(nb.tele_network == loc_network)
|
||||
beacons[nb.tele_name] = nb
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/unknown
|
||||
name = "modified translocator"
|
||||
desc = "This crank-charged translocator has only one beacon, but it already has a destination preprogrammed into it."
|
||||
charge_cost = 1200 // Enough for one person and their partner
|
||||
longrange = 1
|
||||
abductor = 1
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/unknown/New()
|
||||
..()
|
||||
for(var/obj/item/device/perfect_tele_beacon/stationary/nb in premade_tele_beacons)
|
||||
if(nb.tele_network == loc_network)
|
||||
beacons[nb.tele_name] = nb
|
||||
|
||||
/obj/item/device/perfect_tele/frontier/unknown/one
|
||||
loc_network = "unkone"
|
||||
/obj/item/device/perfect_tele/frontier/unknown/two
|
||||
loc_network = "unktwo"
|
||||
/obj/item/device/perfect_tele/frontier/unknown/three
|
||||
loc_network = "unkthree"
|
||||
/obj/item/device/perfect_tele/frontier/unknown/four
|
||||
loc_network = "unkfour"
|
||||
@@ -255,12 +255,14 @@
|
||||
name = "toy sword"
|
||||
desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "sword0"
|
||||
icon_state = "esword"
|
||||
var/lcolor
|
||||
var/rainbow = FALSE
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
|
||||
)
|
||||
var/active = 0.0
|
||||
var/active = 0
|
||||
w_class = ITEMSIZE_SMALL
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
|
||||
@@ -269,22 +271,54 @@
|
||||
if (src.active)
|
||||
user << "<span class='notice'>You extend the plastic blade with a quick flick of your wrist.</span>"
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 50, 1)
|
||||
src.icon_state = "swordblue"
|
||||
src.item_state = "[icon_state]_blade"
|
||||
src.w_class = ITEMSIZE_LARGE
|
||||
else
|
||||
user << "<span class='notice'>You push the plastic blade back down into the handle.</span>"
|
||||
playsound(user, 'sound/weapons/saberoff.ogg', 50, 1)
|
||||
src.icon_state = "sword0"
|
||||
src.item_state = "[icon_state]"
|
||||
src.w_class = ITEMSIZE_SMALL
|
||||
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
|
||||
update_icon()
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/toy/sword/update_icon()
|
||||
. = ..()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade")
|
||||
blade_overlay.color = lcolor
|
||||
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
|
||||
if(active)
|
||||
add_overlay(blade_overlay)
|
||||
if(istype(usr,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
|
||||
/obj/item/toy/sword/AltClick(mob/living/user)
|
||||
if(!in_range(src, user)) //Basic checks to prevent abuse
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Recolor", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null
|
||||
if(energy_color_input)
|
||||
lcolor = sanitize_hexcolor(energy_color_input)
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/sword/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W, /obj/item/device/multitool) && !active)
|
||||
if(!rainbow)
|
||||
rainbow = TRUE
|
||||
else
|
||||
rainbow = FALSE
|
||||
to_chat(user, "<span class='notice'>You manipulate the color controller in [src].</span>")
|
||||
update_icon()
|
||||
/obj/item/toy/katana
|
||||
name = "replica katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
@@ -322,6 +356,12 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/toy/snappop/Crossed(H as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = H
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if((ishuman(H))) //i guess carp and shit shouldn't set them off
|
||||
var/mob/living/carbon/M = H
|
||||
if(M.m_intent == "run")
|
||||
@@ -938,7 +978,7 @@
|
||||
/obj/item/toy/plushie/mouse
|
||||
name = "mouse plush"
|
||||
desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend."
|
||||
icon_state = "mouseplushie"
|
||||
icon_state = "mouseplushie" //TFF 12/11/19 - updated icon to show a sprite that doesn't replicate a dead mouse. Heck you for that! >:C
|
||||
pokephrase = "Squeak!"
|
||||
|
||||
/obj/item/toy/plushie/kitten
|
||||
|
||||
@@ -243,6 +243,13 @@
|
||||
electric_cost_coefficent = 41.66 // Twice as efficent, out of pity.
|
||||
toolspeed = 0.5 // Twice as fast, since borg versions typically have this.
|
||||
|
||||
/obj/item/weapon/rcd/electric/mounted/borg/swarm
|
||||
can_remove_rwalls = FALSE
|
||||
name = "Rapid Assimilation Device"
|
||||
ranged = TRUE
|
||||
toolspeed = 0.7
|
||||
material_to_use = MAT_STEELHULL
|
||||
|
||||
/obj/item/weapon/rcd/electric/mounted/borg/lesser
|
||||
can_remove_rwalls = FALSE
|
||||
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
* Banana Peals
|
||||
*/
|
||||
/obj/item/weapon/bananapeel/Crossed(AM as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if (istype(AM, /mob/living))
|
||||
var/mob/living/M = AM
|
||||
M.slip("the [src.name]",4)
|
||||
@@ -24,6 +30,12 @@
|
||||
reagents.add_reagent("cleaner", 5)
|
||||
|
||||
/obj/item/weapon/soap/Crossed(AM as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if (istype(AM, /mob/living))
|
||||
var/mob/living/M = AM
|
||||
M.slip("the [src.name]",3)
|
||||
|
||||
@@ -197,6 +197,9 @@ var/last_chew = 0
|
||||
breakouttime = 200
|
||||
cuff_type = "duct tape"
|
||||
|
||||
/obj/item/weapon/handcuffs/cable/tape/cyborg
|
||||
dispenser = TRUE
|
||||
|
||||
//Legcuffs. Not /really/ handcuffs, but its close enough.
|
||||
/obj/item/weapon/handcuffs/legcuffs
|
||||
name = "legcuffs"
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
var/primary_color = rgb(0,0,0) // Obtained by eyedroppering the stripe in the middle of the card
|
||||
var/secondary_color = rgb(0,0,0) // Likewise for the oval in the top-left corner
|
||||
|
||||
var/datum/job/job_access_type = /datum/job/assistant // Job type to acquire access rights from, if any
|
||||
|
||||
//alt titles are handled a bit weirdly in order to unobtrusively integrate into existing ID system
|
||||
var/assignment = null //can be alt title or the actual job
|
||||
var/rank = null //actual job
|
||||
@@ -134,16 +132,6 @@
|
||||
icon_state = "silver"
|
||||
item_state = "silver_id"
|
||||
|
||||
/obj/item/weapon/card/id/silver/secretary
|
||||
assignment = "Command Secretary"
|
||||
rank = "Command Secretary"
|
||||
job_access_type = /datum/job/secretary
|
||||
|
||||
/obj/item/weapon/card/id/silver/hop
|
||||
assignment = "Head of Personnel"
|
||||
rank = "Head of Personnel"
|
||||
job_access_type = /datum/job/hop
|
||||
|
||||
/obj/item/weapon/card/id/gold
|
||||
name = "identification card"
|
||||
desc = "A golden card which shows power and might."
|
||||
@@ -154,13 +142,11 @@
|
||||
/obj/item/weapon/card/id/gold/captain
|
||||
assignment = "Colony Director"
|
||||
rank = "Colony Director"
|
||||
job_access_type = /datum/job/captain
|
||||
|
||||
/obj/item/weapon/card/id/gold/captain/spare
|
||||
name = "\improper Colony Director's spare ID"
|
||||
desc = "The spare ID of the High Lord himself."
|
||||
registered_name = "Colony Director"
|
||||
job_access_type = /datum/job/captain
|
||||
|
||||
/obj/item/weapon/card/id/synthetic
|
||||
name = "\improper Synthetic ID"
|
||||
@@ -205,31 +191,6 @@
|
||||
primary_color = rgb(189,237,237)
|
||||
secondary_color = rgb(223,255,255)
|
||||
|
||||
/obj/item/weapon/card/id/medical/doctor
|
||||
assignment = "Medical Doctor"
|
||||
rank = "Medical Doctor"
|
||||
job_access_type = /datum/job/doctor
|
||||
|
||||
/obj/item/weapon/card/id/medical/chemist
|
||||
assignment = "Chemist"
|
||||
rank = "Chemist"
|
||||
job_access_type = /datum/job/chemist
|
||||
|
||||
/obj/item/weapon/card/id/medical/geneticist
|
||||
assignment = "Geneticist"
|
||||
rank = "Geneticist"
|
||||
job_access_type = /datum/job/doctor //geneticist
|
||||
|
||||
/obj/item/weapon/card/id/medical/psychiatrist
|
||||
assignment = "Psychiatrist"
|
||||
rank = "Psychiatrist"
|
||||
job_access_type = /datum/job/psychiatrist
|
||||
|
||||
/obj/item/weapon/card/id/medical/paramedic
|
||||
assignment = "Paramedic"
|
||||
rank = "Paramedic"
|
||||
job_access_type = /datum/job/paramedic
|
||||
|
||||
/obj/item/weapon/card/id/medical/head
|
||||
name = "identification card"
|
||||
desc = "A card which represents care and compassion."
|
||||
@@ -238,7 +199,6 @@
|
||||
secondary_color = rgb(255,223,127)
|
||||
assignment = "Chief Medical Officer"
|
||||
rank = "Chief Medical Officer"
|
||||
job_access_type = /datum/job/cmo
|
||||
|
||||
/obj/item/weapon/card/id/security
|
||||
name = "identification card"
|
||||
@@ -247,21 +207,6 @@
|
||||
primary_color = rgb(189,47,0)
|
||||
secondary_color = rgb(223,127,95)
|
||||
|
||||
/obj/item/weapon/card/id/security/officer
|
||||
assignment = "Security Officer"
|
||||
rank = "Security Officer"
|
||||
job_access_type = /datum/job/officer
|
||||
|
||||
/obj/item/weapon/card/id/security/detective
|
||||
assignment = "Detective"
|
||||
rank = "Detective"
|
||||
job_access_type = /datum/job/detective
|
||||
|
||||
/obj/item/weapon/card/id/security/warden
|
||||
assignment = "Warden"
|
||||
rank = "Warden"
|
||||
job_access_type = /datum/job/warden
|
||||
|
||||
/obj/item/weapon/card/id/security/head
|
||||
name = "identification card"
|
||||
desc = "A card which represents honor and protection."
|
||||
@@ -270,7 +215,6 @@
|
||||
secondary_color = rgb(255,223,127)
|
||||
assignment = "Head of Security"
|
||||
rank = "Head of Security"
|
||||
job_access_type = /datum/job/hos
|
||||
|
||||
/obj/item/weapon/card/id/engineering
|
||||
name = "identification card"
|
||||
@@ -279,16 +223,6 @@
|
||||
primary_color = rgb(189,94,0)
|
||||
secondary_color = rgb(223,159,95)
|
||||
|
||||
/obj/item/weapon/card/id/engineering/engineer
|
||||
assignment = "Station Engineer"
|
||||
rank = "Station Engineer"
|
||||
job_access_type = /datum/job/engineer
|
||||
|
||||
/obj/item/weapon/card/id/engineering/atmos
|
||||
assignment = "Atmospheric Technician"
|
||||
rank = "Atmospheric Technician"
|
||||
job_access_type = /datum/job/atmos
|
||||
|
||||
/obj/item/weapon/card/id/engineering/head
|
||||
name = "identification card"
|
||||
desc = "A card which represents creativity and ingenuity."
|
||||
@@ -297,7 +231,6 @@
|
||||
secondary_color = rgb(255,223,127)
|
||||
assignment = "Chief Engineer"
|
||||
rank = "Chief Engineer"
|
||||
job_access_type = /datum/job/chief_engineer
|
||||
|
||||
/obj/item/weapon/card/id/science
|
||||
name = "identification card"
|
||||
@@ -306,21 +239,6 @@
|
||||
primary_color = rgb(142,47,142)
|
||||
secondary_color = rgb(191,127,191)
|
||||
|
||||
/obj/item/weapon/card/id/science/scientist
|
||||
assignment = "Scientist"
|
||||
rank = "Scientist"
|
||||
job_access_type = /datum/job/scientist
|
||||
|
||||
/obj/item/weapon/card/id/science/xenobiologist
|
||||
assignment = "Xenobiologist"
|
||||
rank = "Xenobiologist"
|
||||
job_access_type = /datum/job/xenobiologist
|
||||
|
||||
/obj/item/weapon/card/id/science/roboticist
|
||||
assignment = "Roboticist"
|
||||
rank = "Roboticist"
|
||||
job_access_type = /datum/job/roboticist
|
||||
|
||||
/obj/item/weapon/card/id/science/head
|
||||
name = "identification card"
|
||||
desc = "A card which represents knowledge and reasoning."
|
||||
@@ -329,7 +247,6 @@
|
||||
secondary_color = rgb(255,223,127)
|
||||
assignment = "Research Director"
|
||||
rank = "Research Director"
|
||||
job_access_type = /datum/job/rd
|
||||
|
||||
/obj/item/weapon/card/id/cargo
|
||||
name = "identification card"
|
||||
@@ -338,16 +255,6 @@
|
||||
primary_color = rgb(142,94,0)
|
||||
secondary_color = rgb(191,159,95)
|
||||
|
||||
/obj/item/weapon/card/id/cargo/cargo_tech
|
||||
assignment = "Cargo Technician"
|
||||
rank = "Cargo Technician"
|
||||
job_access_type = /datum/job/cargo_tech
|
||||
|
||||
/obj/item/weapon/card/id/cargo/mining
|
||||
assignment = "Shaft Miner"
|
||||
rank = "Shaft Miner"
|
||||
job_access_type = /datum/job/mining
|
||||
|
||||
/obj/item/weapon/card/id/cargo/head
|
||||
name = "identification card"
|
||||
desc = "A card which represents service and planning."
|
||||
@@ -356,12 +263,10 @@
|
||||
secondary_color = rgb(255,223,127)
|
||||
assignment = "Quartermaster"
|
||||
rank = "Quartermaster"
|
||||
job_access_type = /datum/job/qm
|
||||
|
||||
/obj/item/weapon/card/id/assistant
|
||||
assignment = USELESS_JOB //VOREStation Edit - Visitor not Assistant
|
||||
rank = USELESS_JOB //VOREStation Edit - Visitor not Assistant
|
||||
job_access_type = /datum/job/assistant
|
||||
|
||||
/obj/item/weapon/card/id/civilian
|
||||
name = "identification card"
|
||||
@@ -371,42 +276,6 @@
|
||||
secondary_color = rgb(95,159,191)
|
||||
assignment = "Civilian"
|
||||
rank = "Assistant"
|
||||
job_access_type = /datum/job/assistant
|
||||
|
||||
/obj/item/weapon/card/id/civilian/bartender
|
||||
assignment = "Bartender"
|
||||
rank = "Bartender"
|
||||
job_access_type = /datum/job/bartender
|
||||
|
||||
/obj/item/weapon/card/id/civilian/botanist
|
||||
assignment = "Botanist"
|
||||
rank = "Botanist"
|
||||
job_access_type = /datum/job/hydro
|
||||
|
||||
/obj/item/weapon/card/id/civilian/chaplain
|
||||
assignment = "Chaplain"
|
||||
rank = "Chaplain"
|
||||
job_access_type = /datum/job/chaplain
|
||||
|
||||
/obj/item/weapon/card/id/civilian/chef
|
||||
assignment = "Chef"
|
||||
rank = "Chef"
|
||||
job_access_type = /datum/job/chef
|
||||
|
||||
/obj/item/weapon/card/id/civilian/internal_affairs_agent
|
||||
assignment = "Internal Affairs Agent"
|
||||
rank = "Internal Affairs Agent"
|
||||
job_access_type = /datum/job/lawyer
|
||||
|
||||
/obj/item/weapon/card/id/civilian/janitor
|
||||
assignment = "Janitor"
|
||||
rank = "Janitor"
|
||||
job_access_type = /datum/job/janitor
|
||||
|
||||
/obj/item/weapon/card/id/civilian/librarian
|
||||
assignment = "Librarian"
|
||||
rank = "Librarian"
|
||||
job_access_type = /datum/job/librarian
|
||||
|
||||
/obj/item/weapon/card/id/civilian/head //This is not the HoP. There's no position that uses this right now.
|
||||
name = "identification card"
|
||||
|
||||
@@ -66,8 +66,7 @@
|
||||
|
||||
/obj/item/weapon/implant/proc/implant_loadout(var/mob/living/carbon/human/H)
|
||||
if(H)
|
||||
var/obj/item/organ/external/affected = H.organs_by_name[initialize_loc]
|
||||
if(handle_implant(H, affected))
|
||||
if(handle_implant(H, initialize_loc))
|
||||
invisibility = initial(invisibility)
|
||||
post_implant(H)
|
||||
|
||||
|
||||
@@ -19,12 +19,3 @@
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "implant"
|
||||
roundstart = FALSE
|
||||
|
||||
/obj/item/weapon/implant/dud/Initialize()
|
||||
..()
|
||||
if(roundstart)
|
||||
invisibility = 100
|
||||
..()
|
||||
spawn(3)
|
||||
if(!ishuman(loc) && !QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
@@ -105,10 +105,3 @@ Implant Specifics:<BR>"}
|
||||
my_brain.take_damage(15)
|
||||
my_brain = null
|
||||
return
|
||||
|
||||
/obj/item/weapon/implant/neural/roundstart/Initialize()
|
||||
invisibility = 100
|
||||
..()
|
||||
spawn(3)
|
||||
if(!ishuman(loc) && !QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
@@ -86,10 +86,13 @@
|
||||
health--
|
||||
check_health()
|
||||
|
||||
/obj/item/weapon/material/attackby(obj/item/weapon/W, mob/user as mob)
|
||||
/obj/item/weapon/material/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/whetstone))
|
||||
var/obj/item/weapon/whetstone/whet = W
|
||||
repair(whet.repair_amount, whet.repair_time, user)
|
||||
if(istype(W, /obj/item/weapon/material/sharpeningkit))
|
||||
var/obj/item/weapon/material/sharpeningkit/SK = W
|
||||
repair(SK.repair_amount, SK.repair_time, user)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/material/proc/check_health(var/consumed)
|
||||
@@ -134,7 +137,19 @@
|
||||
to_chat(user, "<span class='warning'>You can't repair \the [src].</span>")
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/material/proc/sharpen(var/material, var/sharpen_time, var/kit, mob/living/M)
|
||||
if(!fragile)
|
||||
if(health < initial(health))
|
||||
to_chat(M, "You should repair [src] first. Try using [kit] on it.")
|
||||
return FALSE
|
||||
M.visible_message("[M] begins to replace parts of [src] with [kit].", "You begin to replace parts of [src] with [kit].")
|
||||
if(do_after(usr, sharpen_time))
|
||||
M.visible_message("[M] has finished replacing parts of [src].", "You finish replacing parts of [src].")
|
||||
src.set_material(material)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(M, "<span class = 'warning'>You can't sharpen and re-edge [src].</span>")
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
Commenting this out pending rebalancing of radiation based on small objects.
|
||||
@@ -162,4 +177,4 @@ Commenting this out pending rebalancing of radiation based on small objects.
|
||||
TemperatureAct(150)
|
||||
else
|
||||
return ..()
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -108,6 +108,12 @@
|
||||
|
||||
/obj/item/weapon/material/shard/Crossed(AM as mob|obj)
|
||||
..()
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if(isliving(AM))
|
||||
var/mob/M = AM
|
||||
|
||||
|
||||
@@ -8,4 +8,69 @@
|
||||
force = 3
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/repair_amount = 5
|
||||
var/repair_time = 40
|
||||
var/repair_time = 40
|
||||
|
||||
/obj/item/weapon/whetstone/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/stack/material))
|
||||
var/obj/item/stack/material/M = I
|
||||
if(M.amount >= 5)
|
||||
to_chat(user, "You begin to refine the [src] with [M]...")
|
||||
if(do_after(user, 70))
|
||||
M.use(5)
|
||||
var/obj/item/SK
|
||||
SK = new /obj/item/weapon/material/sharpeningkit(get_turf(user), M.material.name)
|
||||
to_chat(user, "You sharpen and refine the [src] into \a [SK].")
|
||||
qdel(src)
|
||||
if(SK)
|
||||
user.put_in_hands(SK)
|
||||
else
|
||||
to_chat(user, "You need 5 [src] to refine it into a sharpening kit.")
|
||||
|
||||
/obj/item/weapon/material/sharpeningkit
|
||||
name = "sharpening kit"
|
||||
desc = "A refined, fine grit whetstone, useful for sharpening dull edges, polishing out dents, and, with extra material, replacing an edge."
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "sharpener"
|
||||
hitsound = 'sound/weapons/genhit3.ogg'
|
||||
force_divisor = 0.7
|
||||
thrown_force_divisor = 1
|
||||
var/repair_amount = 5
|
||||
var/repair_time = 40
|
||||
var/sharpen_time = 100
|
||||
var/uses = 0
|
||||
|
||||
/obj/item/weapon/material/sharpeningkit/examine(mob/user, distance)
|
||||
. = ..()
|
||||
to_chat(user, "There [uses == 1 ? "is" : "are"] [uses] [material] [uses == 1 ? src.material.sheet_singular_name : src.material.sheet_plural_name] left for use.")
|
||||
/obj/item/weapon/material/sharpeningkit/Initialize()
|
||||
. = ..()
|
||||
setrepair()
|
||||
|
||||
/obj/item/weapon/material/sharpeningkit/proc/setrepair()
|
||||
repair_amount = material.hardness * 0.1
|
||||
repair_time = material.weight * 0.5
|
||||
sharpen_time = material.weight * 3
|
||||
|
||||
/obj/item/weapon/material/sharpeningkit/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W, /obj/item/stack/material))
|
||||
var/obj/item/stack/material/S = W
|
||||
if(S.material == material)
|
||||
S.use(1)
|
||||
uses += 1
|
||||
to_chat(user, "You add a [S.material.name] [S.material.sheet_singular_name] to [src].")
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/material))
|
||||
if(istype(W, /obj/item/weapon/material/sharpeningkit))
|
||||
to_chat(user, "Really? Sharpening a [W] with [src]? You goofball.")
|
||||
return
|
||||
var/obj/item/weapon/material/M = W
|
||||
if(uses >= M.w_class*2)
|
||||
if(M.sharpen(src.material.name, sharpen_time, src, user))
|
||||
uses -= M.w_class*2
|
||||
return
|
||||
else
|
||||
to_chat(user, "Not enough material to sharpen [M]. You need [M.w_class*2] [M.material.sheet_plural_name].")
|
||||
return
|
||||
else
|
||||
to_chat(user, "You can't sharpen [W] with [src]!")
|
||||
|
||||
@@ -11,17 +11,46 @@
|
||||
var/lrange = 2
|
||||
var/lpower = 2
|
||||
var/lcolor = "#0099FF"
|
||||
|
||||
var/colorable = FALSE
|
||||
var/rainbow = FALSE
|
||||
// If it uses energy.
|
||||
var/use_cell = FALSE
|
||||
var/hitcost = 120
|
||||
var/obj/item/weapon/cell/bcell = null
|
||||
var/cell_type = /obj/item/weapon/cell/device
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
|
||||
)
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/green/New()
|
||||
colorable = FALSE
|
||||
lcolor = "#008000"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/red/New()
|
||||
colorable = FALSE
|
||||
lcolor = "#FF0000"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/blue/New()
|
||||
colorable = FALSE
|
||||
lcolor = "#0000FF"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/purple/New()
|
||||
colorable = FALSE
|
||||
lcolor = "#800080"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/white/New()
|
||||
colorable = FALSE
|
||||
lcolor = "#FFFFFF"
|
||||
|
||||
/obj/item/weapon/melee/energy/proc/activate(mob/living/user)
|
||||
if(active)
|
||||
return
|
||||
active = 1
|
||||
if(rainbow)
|
||||
item_state = "[icon_state]_blade_rainbow"
|
||||
else
|
||||
item_state = "[icon_state]_blade"
|
||||
embed_chance = active_embed_chance
|
||||
force = active_force
|
||||
throwforce = active_throwforce
|
||||
@@ -29,12 +58,14 @@
|
||||
edge = 1
|
||||
w_class = active_w_class
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 50, 1)
|
||||
update_icon()
|
||||
set_light(lrange, lpower, lcolor)
|
||||
|
||||
/obj/item/weapon/melee/energy/proc/deactivate(mob/living/user)
|
||||
if(!active)
|
||||
return
|
||||
playsound(user, 'sound/weapons/saberoff.ogg', 50, 1)
|
||||
item_state = "[icon_state]"
|
||||
active = 0
|
||||
embed_chance = initial(embed_chance)
|
||||
force = initial(force)
|
||||
@@ -42,6 +73,7 @@
|
||||
sharp = initial(sharp)
|
||||
edge = initial(edge)
|
||||
w_class = initial(w_class)
|
||||
update_icon()
|
||||
set_light(0,0)
|
||||
|
||||
/obj/item/weapon/melee/energy/proc/use_charge(var/cost)
|
||||
@@ -102,6 +134,13 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/melee/energy/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W, /obj/item/device/multitool) && colorable && !active)
|
||||
if(!rainbow)
|
||||
rainbow = TRUE
|
||||
else
|
||||
rainbow = FALSE
|
||||
to_chat(user, "<span class='notice'>You manipulate the color controller in [src].</span>")
|
||||
update_icon()
|
||||
if(use_cell)
|
||||
if(istype(W, cell_type))
|
||||
if(!bcell)
|
||||
@@ -125,13 +164,53 @@
|
||||
/obj/item/weapon/melee/energy/get_cell()
|
||||
return bcell
|
||||
|
||||
/obj/item/weapon/melee/energy/update_icon()
|
||||
. = ..()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade")
|
||||
blade_overlay.color = lcolor
|
||||
color = lcolor
|
||||
if(rainbow)
|
||||
blade_overlay = mutable_appearance(icon, "[icon_state]_blade_rainbow")
|
||||
blade_overlay.color = "FFFFFF"
|
||||
color = "FFFFFF"
|
||||
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
|
||||
if(active)
|
||||
add_overlay(blade_overlay)
|
||||
if(istype(usr,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/melee/energy/AltClick(mob/living/user)
|
||||
if(!colorable) //checks if is not colorable
|
||||
return
|
||||
if(!in_range(src, user)) //Basic checks to prevent abuse
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Recolor", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null
|
||||
if(energy_color_input)
|
||||
lcolor = sanitize_hexcolor(energy_color_input)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/melee/energy/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/*
|
||||
* Energy Axe
|
||||
*/
|
||||
/obj/item/weapon/melee/energy/axe
|
||||
name = "energy axe"
|
||||
desc = "An energised battle axe."
|
||||
icon_state = "axe0"
|
||||
icon_state = "eaxe"
|
||||
item_state = "eaxe"
|
||||
//active_force = 150 //holy...
|
||||
active_force = 60
|
||||
active_throwforce = 35
|
||||
@@ -152,13 +231,11 @@
|
||||
/obj/item/weapon/melee/energy/axe/activate(mob/living/user)
|
||||
..()
|
||||
damtype = SEARING
|
||||
icon_state = "axe1"
|
||||
to_chat(user, "<span class='notice'>\The [src] is now energised.</span>")
|
||||
|
||||
/obj/item/weapon/melee/energy/axe/deactivate(mob/living/user)
|
||||
..()
|
||||
damtype = BRUTE
|
||||
icon_state = initial(icon_state)
|
||||
to_chat(user, "<span class='notice'>\The [src] is de-energised. It's just a regular axe now.</span>")
|
||||
|
||||
/obj/item/weapon/melee/energy/axe/suicide_act(mob/user)
|
||||
@@ -187,7 +264,8 @@
|
||||
color
|
||||
name = "energy sword"
|
||||
desc = "May the force be within you."
|
||||
icon_state = "sword0"
|
||||
icon_state = "esword"
|
||||
item_state = "esword"
|
||||
active_force = 30
|
||||
active_throwforce = 20
|
||||
active_w_class = ITEMSIZE_LARGE
|
||||
@@ -200,9 +278,8 @@
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_ILLEGAL = 4)
|
||||
sharp = 1
|
||||
edge = 1
|
||||
var/blade_color
|
||||
var/random_color = TRUE
|
||||
var/active_state = "sword"
|
||||
colorable = TRUE
|
||||
|
||||
|
||||
projectile_parry_chance = 65
|
||||
|
||||
@@ -211,30 +288,6 @@
|
||||
if(!istype(loc,/mob))
|
||||
deactivate(user)
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/New()
|
||||
if(random_color)
|
||||
blade_color = pick("red","blue","green","purple","white")
|
||||
lcolor = blade_color
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/green/New()
|
||||
blade_color = "green"
|
||||
lcolor = "#008000"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/red/New()
|
||||
blade_color = "red"
|
||||
lcolor = "#FF0000"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/blue/New()
|
||||
blade_color = "blue"
|
||||
lcolor = "#0000FF"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/purple/New()
|
||||
blade_color = "purple"
|
||||
lcolor = "#800080"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/white/New()
|
||||
blade_color = "white"
|
||||
lcolor = "#FFFFFF"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/activate(mob/living/user)
|
||||
if(!active)
|
||||
@@ -242,14 +295,13 @@
|
||||
|
||||
..()
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
icon_state = "[active_state][blade_color]"
|
||||
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/deactivate(mob/living/user)
|
||||
if(active)
|
||||
to_chat(user, "<span class='notice'>\The [src] deactivates!</span>")
|
||||
..()
|
||||
attack_verb = list()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(active && default_parry_check(user, attacker, damage_source) && prob(60))
|
||||
@@ -284,11 +336,10 @@
|
||||
/obj/item/weapon/melee/energy/sword/pirate
|
||||
name = "energy cutlass"
|
||||
desc = "Arrrr matey."
|
||||
icon_state = "cutlass0"
|
||||
icon_state = "cutlass"
|
||||
item_state = "cutlass"
|
||||
colorable = TRUE
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/pirate/activate(mob/living/user)
|
||||
..()
|
||||
icon_state = "cutlass1"
|
||||
|
||||
/*
|
||||
*Ionic Rapier
|
||||
@@ -300,8 +351,8 @@
|
||||
description_info = "This is a dangerous melee weapon that will deliver a moderately powerful electromagnetic pulse to whatever it strikes. \
|
||||
Striking a lesser robotic entity will compel it to attack you, as well. It also does extra burn damage to robotic entities, but it does \
|
||||
very little damage to purely organic targets."
|
||||
icon_state = "ionic_rapier0"
|
||||
random_color = FALSE
|
||||
icon_state = "ionrapier"
|
||||
item_state = "ionrapier"
|
||||
active_force = 5
|
||||
active_throwforce = 3
|
||||
active_embed_chance = 0
|
||||
@@ -312,7 +363,6 @@
|
||||
lrange = 2
|
||||
lpower = 2
|
||||
lcolor = "#0000FF"
|
||||
active_state = "ionic_rapier"
|
||||
projectile_parry_chance = 30 // It's not specifically designed for cutting and slashing, but it can still, maybe, save your life.
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/ionic_rapier/afterattack(var/atom/movable/AM, var/mob/living/user, var/proximity)
|
||||
@@ -339,6 +389,13 @@
|
||||
target.taunt(user)
|
||||
target.adjustFireLoss(force * 6) // 30 Burn, for 50 total.
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/ionic_rapier/lance
|
||||
name = "zero-point lance"
|
||||
desc = "Designed specifically for disrupting electronics at relatively close range, however it is still capable of dealing some damage to living beings."
|
||||
active_force = 20
|
||||
armor_penetration = 15
|
||||
reach = 2
|
||||
|
||||
/*
|
||||
* Charge blade. Uses a cell, and costs energy per strike.
|
||||
*/
|
||||
@@ -350,6 +407,7 @@
|
||||
active_force = 25
|
||||
armor_penetration = 25
|
||||
projectile_parry_chance = 40
|
||||
colorable = TRUE
|
||||
|
||||
hitcost = 75
|
||||
|
||||
@@ -357,15 +415,14 @@
|
||||
..()
|
||||
bcell = new/obj/item/weapon/cell/device/weapon(src)
|
||||
|
||||
/*
|
||||
*Energy Blade
|
||||
*/
|
||||
//Energy Blade (ninja uses this)
|
||||
|
||||
//Can't be activated or deactivated, so no reason to be a subtype of energy
|
||||
/obj/item/weapon/melee/energy/blade
|
||||
name = "energy blade"
|
||||
desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal."
|
||||
icon_state = "blade"
|
||||
item_state = "blade"
|
||||
force = 40 //Normal attacks deal very high damage - about the same as wielded fire axe
|
||||
armor_penetration = 100
|
||||
sharp = 1
|
||||
@@ -448,49 +505,27 @@
|
||||
|
||||
return 1
|
||||
|
||||
/*
|
||||
*Energy Spear
|
||||
*/
|
||||
//Energy Spear
|
||||
|
||||
/obj/item/weapon/melee/energy/spear
|
||||
name = "energy spear"
|
||||
desc = "Concentrated energy forming a sharp tip at the end of a long rod."
|
||||
icon_state = "espear0"
|
||||
armor_penetration = 75
|
||||
sharp = 1
|
||||
edge = 1
|
||||
force = 5
|
||||
throwforce = 10
|
||||
throw_speed = 7
|
||||
throw_range = 11
|
||||
reach = 2
|
||||
w_class = ITEMSIZE_LARGE
|
||||
active_force = 25
|
||||
active_throwforce = 30
|
||||
active_w_class = ITEMSIZE_HUGE
|
||||
var/random_color = TRUE
|
||||
var/tip_color = ""
|
||||
var/active_state = "espear"
|
||||
name = "energy spear"
|
||||
desc = "Concentrated energy forming a sharp tip at the end of a long rod."
|
||||
icon_state = "espear"
|
||||
armor_penetration = 75
|
||||
sharp = 1
|
||||
edge = 1
|
||||
force = 5
|
||||
throwforce = 10
|
||||
throw_speed = 7
|
||||
throw_range = 11
|
||||
reach = 2
|
||||
w_class = ITEMSIZE_LARGE
|
||||
active_force = 25
|
||||
active_throwforce = 30
|
||||
active_w_class = ITEMSIZE_HUGE
|
||||
colorable = TRUE
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/New()
|
||||
if(random_color)
|
||||
tip_color = pick("red","blue","green","purple")
|
||||
lcolor = tip_color
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/green/New()
|
||||
tip_color = "green"
|
||||
lcolor = "#008000"
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/red/New()
|
||||
tip_color = "red"
|
||||
lcolor = "#FF0000"
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/blue/New()
|
||||
tip_color = "blue"
|
||||
lcolor = "#0000FF"
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/purple/New()
|
||||
tip_color = "purple"
|
||||
lcolor = "#800080"
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/activate(mob/living/user)
|
||||
@@ -498,7 +533,6 @@
|
||||
to_chat(user, "<span class='notice'>\The [src] is now energised.</span>")
|
||||
..()
|
||||
attack_verb = list("jabbed", "stabbed", "impaled")
|
||||
icon_state = "[active_state]-[tip_color]"
|
||||
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/deactivate(mob/living/user)
|
||||
@@ -506,7 +540,6 @@
|
||||
to_chat(user, "<span class='notice'>\The [src] deactivates!</span>")
|
||||
..()
|
||||
attack_verb = list("whacked", "beat", "slapped", "thonked")
|
||||
icon_state = "espear0"
|
||||
|
||||
/obj/item/weapon/melee/energy/spear/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(active && default_parry_check(user, attacker, damage_source) && prob(50))
|
||||
@@ -516,4 +549,4 @@
|
||||
spark_system.start()
|
||||
playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
return 1
|
||||
return 0
|
||||
return 0
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/obj/item/weapon/melee/energy/sword/imperial
|
||||
name = "energy gladius"
|
||||
desc = "A broad, short energy blade. You'll be glad to have this in a fight."
|
||||
icon_state = "sword0"
|
||||
icon_state = "impsword"
|
||||
icon = 'icons/obj/weapons_vr.dmi'
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi')
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/imperial/activate(mob/living/user)
|
||||
..()
|
||||
icon_state = "sword1"
|
||||
colorable = FALSE
|
||||
lcolor = "#FFFFFF"
|
||||
@@ -27,7 +27,7 @@ var/global/list/cached_icons = list()
|
||||
return ..()
|
||||
|
||||
New()
|
||||
if(paint_type && lentext(paint_type) > 0)
|
||||
if(paint_type && length(paint_type) > 0)
|
||||
name = paint_type + " " + name
|
||||
..()
|
||||
reagents.add_reagent("water", volume*3/5)
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
name = "energy combat shield"
|
||||
desc = "A shield capable of stopping most projectile and melee attacks. It can be retracted, expanded, and stored anywhere."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "eshield0" // eshield1 for expanded
|
||||
icon_state = "eshield"
|
||||
item_state = "eshield"
|
||||
slot_flags = SLOT_EARS
|
||||
flags = NOCONDUCT
|
||||
force = 3.0
|
||||
@@ -123,9 +124,16 @@
|
||||
throw_speed = 1
|
||||
throw_range = 4
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/lrange = 1.5
|
||||
var/lpower = 1.5
|
||||
var/lcolor = "#006AFF"
|
||||
origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_ILLEGAL = 4)
|
||||
attack_verb = list("shoved", "bashed")
|
||||
var/active = 0
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
|
||||
)
|
||||
|
||||
/obj/item/weapon/shield/energy/handle_shield(mob/user)
|
||||
if(!active)
|
||||
@@ -175,11 +183,33 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/shield/energy/update_icon()
|
||||
icon_state = "eshield[active]"
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade")
|
||||
if(lcolor)
|
||||
blade_overlay.color = lcolor
|
||||
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
|
||||
if(active)
|
||||
set_light(1.5, 1.5, "#006AFF")
|
||||
add_overlay(blade_overlay)
|
||||
item_state = "[icon_state]_blade"
|
||||
set_light(lrange, lpower, lcolor)
|
||||
else
|
||||
set_light(0)
|
||||
item_state = "[icon_state]"
|
||||
|
||||
/obj/item/weapon/shield/energy/AltClick(mob/living/user)
|
||||
if(!in_range(src, user)) //Basic checks to prevent abuse
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(alert("Are you sure you want to recolor your shield?", "Confirm Recolor", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null
|
||||
if(energy_color_input)
|
||||
lcolor = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/shield/energy/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/obj/item/weapon/shield/riot/tele
|
||||
name = "telescopic shield"
|
||||
@@ -226,4 +256,4 @@
|
||||
H.update_inv_r_hand()
|
||||
|
||||
add_fingerprint(user)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "energy scutum"
|
||||
desc = "It's really easy to mispronounce the name of this shield if you've only read it in books."
|
||||
icon = 'icons/obj/weapons_vr.dmi'
|
||||
icon_state = "eshield0" // eshield1 for expanded
|
||||
icon_state = "impshield" // eshield1 for expanded
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi')
|
||||
|
||||
/obj/item/weapon/shield/fluff/wolfgirlshield
|
||||
|
||||
@@ -422,3 +422,10 @@
|
||||
H.visible_message("<span class='notice'>\The [src] decides not to unpack \the [src]!</span>", \
|
||||
"<span class='notice'>You decide not to unpack \the [src]!</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/backpack/satchel/ranger
|
||||
name = "ranger satchel"
|
||||
desc = "A satchel designed for the Go Go ERT Rangers series to allow for slightly bigger carry capacity for the ERT-Rangers.\
|
||||
Unlike the show claims, it is not a phoron-enhanced satchel of holding with plot-relevant content."
|
||||
icon = 'icons/obj/clothing/ranger.dmi'
|
||||
icon_state = "ranger_satchel"
|
||||
@@ -373,3 +373,17 @@
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
w_class = ITEMSIZE_SMALL
|
||||
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks,/obj/item/weapon/reagent_containers/food/condiment)
|
||||
|
||||
// -----------------------------
|
||||
// Evidence Bag
|
||||
// -----------------------------
|
||||
/obj/item/weapon/storage/bag/detective
|
||||
name = "secure satchel"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "detbag"
|
||||
desc = "A bag for storing investigation things. You know, securely."
|
||||
max_storage_space = ITEMSIZE_COST_NORMAL * 15
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
w_class = ITEMSIZE_SMALL
|
||||
can_hold = list(/obj/item/weapon/forensics/swab,/obj/item/weapon/sample/print,/obj/item/weapon/sample/fibers,/obj/item/weapon/evidencebag)
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/obj/item/weapon/storage/bag/chemistry
|
||||
slot_flags = null
|
||||
@@ -435,3 +435,8 @@
|
||||
icon_state = "fannypack_yellow"
|
||||
item_state = "fannypack_yellow"
|
||||
|
||||
/obj/item/weapon/storage/belt/ranger
|
||||
name = "ranger belt"
|
||||
desc = "The fancy utility-belt holding the tools, cuffs and gadgets of the Go Go ERT-Rangers. The belt buckle is not real phoron, but it is still surprisingly comfortable to wear."
|
||||
icon = 'icons/obj/clothing/ranger.dmi'
|
||||
icon_state = "ranger_belt"
|
||||
@@ -326,6 +326,13 @@
|
||||
icon_state = "donk_kit"
|
||||
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket = 7)
|
||||
|
||||
/obj/item/weapon/storage/box/buns
|
||||
name = "box of bread buns"
|
||||
desc = "Freshly baked at some point in the past few months."
|
||||
icon_state = "bun_box"
|
||||
max_storage_space = ITEMSIZE_COST_NORMAL * 5
|
||||
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/bun = 12)
|
||||
|
||||
/obj/item/weapon/storage/box/monkeycubes
|
||||
name = "monkey cube box"
|
||||
desc = "Drymate brand monkey cubes. Just add water!"
|
||||
@@ -346,7 +353,7 @@
|
||||
|
||||
/obj/item/weapon/storage/box/monkeycubes/neaeracubes
|
||||
name = "neaera cube box"
|
||||
desc = "Drymate brand neaera cubes, shipped from Jargon 4. Just add water!"
|
||||
desc = "Drymate brand neaera cubes, shipped from Qerr'balak. Just add water!"
|
||||
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube = 4)
|
||||
|
||||
/obj/item/weapon/storage/box/ids
|
||||
@@ -401,7 +408,7 @@
|
||||
W.lit = 1
|
||||
W.damtype = "burn"
|
||||
W.icon_state = "match_lit"
|
||||
START_PROCESSING(SSobj, W)
|
||||
START_PROCESSING(SSobj, W)
|
||||
W.update_icon()
|
||||
return
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
starts_with = list(/obj/item/device/encryptionkey/headset_com = 7)
|
||||
|
||||
/obj/item/weapon/storage/box/servicekeys
|
||||
name = "box of command keys"
|
||||
name = "box of service keys"
|
||||
desc = "A box full of service keys, for the HoP to give out as necessary."
|
||||
starts_with = list(/obj/item/device/encryptionkey/headset_service = 7)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ Frequency:
|
||||
direct = "very weak"
|
||||
src.temp += "[W.code]-[dir2text(get_dir(sr, tr))]-[direct]<BR>"
|
||||
|
||||
src.temp += "<B>Extranneous Signals:</B><BR>"
|
||||
src.temp += "<B>Extraneous Signals:</B><BR>"
|
||||
for (var/obj/item/weapon/implant/tracking/W in all_tracking_implants)
|
||||
if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc) || W.malfunction))
|
||||
continue
|
||||
|
||||
@@ -106,6 +106,12 @@
|
||||
can_buckle = initial(can_buckle)
|
||||
|
||||
/obj/item/weapon/beartrap/Crossed(AM as mob|obj)
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = AM
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
if(deployed && isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.m_intent == "run")
|
||||
|
||||
@@ -87,6 +87,12 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/catwalk/Crossed()
|
||||
//VOREStation Edit begin: SHADEKIN
|
||||
var/mob/SK = usr
|
||||
if(istype(SK))
|
||||
if(SK.shadekin_phasing_check())
|
||||
return
|
||||
//VOREStation Edit end: SHADEKIN
|
||||
. = ..()
|
||||
if(isliving(usr))
|
||||
playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/obj/structure/closet/secure_closet/freezer/kitchen
|
||||
name = "kitchen cabinet"
|
||||
req_access = list(access_kitchen)
|
||||
req_access = list()
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/reagent_containers/food/condiment/flour = 7,
|
||||
|
||||
@@ -4,14 +4,18 @@
|
||||
req_access = list(access_all_personal_lockers)
|
||||
var/registered_name = null
|
||||
|
||||
/* //VOREStation Removal
|
||||
starts_with = list(
|
||||
/obj/item/device/radio/headset)
|
||||
*/
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/Initialize()
|
||||
/* //VOREStation Removal
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
starts_with += /obj/item/weapon/storage/backpack/satchel/norm
|
||||
*/
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/patient
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
/obj/item/weapon/storage/belt/security,
|
||||
/obj/item/device/flash,
|
||||
/obj/item/weapon/melee/baton/loaded,
|
||||
/obj/item/weapon/gun/energy/gun,
|
||||
/obj/item/weapon/gun/magnetic/railgun/heater/pistol/hos,
|
||||
/obj/item/weapon/cell/device/weapon,
|
||||
/obj/item/clothing/accessory/holster/waist,
|
||||
/obj/item/weapon/melee/telebaton,
|
||||
@@ -223,6 +223,8 @@
|
||||
starts_with += /obj/item/weapon/storage/backpack/satchel/sec
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/dufflebag/sec
|
||||
if(prob(30))
|
||||
starts_with += /obj/item/weapon/contraband/poster/nanotrasen
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/security/cargo/Initialize()
|
||||
@@ -271,6 +273,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/flask/detflask,
|
||||
/obj/item/weapon/storage/briefcase/crimekit,
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/weapon/storage/bag/detective,
|
||||
/obj/item/device/tape/random = 3)
|
||||
|
||||
/obj/structure/closet/secure_closet/detective/update_icon()
|
||||
@@ -305,6 +308,17 @@ GLOBAL_LIST_BOILERPLATE(all_brig_closets, /obj/structure/closet/secure_closet/br
|
||||
/obj/item/clothing/under/color/prison,
|
||||
/obj/item/clothing/shoes/orange)
|
||||
|
||||
/obj/structure/closet/secure_closet/posters
|
||||
name = "morale storage"
|
||||
req_access = list(access_security)
|
||||
anchored = 1
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen)
|
||||
|
||||
/obj/structure/closet/secure_closet/courtroom
|
||||
name = "courtroom locker"
|
||||
|
||||
@@ -83,4 +83,13 @@
|
||||
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
|
||||
return
|
||||
|
||||
create_occupant(user)
|
||||
var/choice = input(user, "Are you certain you wish to activate this pod?", "Control Pod") as null|anything in list("Yes", "No")
|
||||
|
||||
if(!choice || choice == "No")
|
||||
return
|
||||
|
||||
else if(used)
|
||||
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
|
||||
return
|
||||
|
||||
create_occupant(user)
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
// Ghost variant.
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human
|
||||
name = "mysterious cryopod"
|
||||
desc = "This is a pod which appears to contain a body."
|
||||
description_info = "This contains a body, which may wake at any time. The external controls\
|
||||
seem to be malfunctioning."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper_1"
|
||||
icon_state_opened = "sleeper_0"
|
||||
density = TRUE
|
||||
ghost_query_type = /datum/ghost_query/stowaway
|
||||
anchored = FALSE
|
||||
|
||||
var/occupant_type = "stowaway"
|
||||
|
||||
var/allow_appearance_change = TRUE
|
||||
|
||||
var/make_antag = MODE_STOWAWAY
|
||||
|
||||
var/start_injured = FALSE
|
||||
var/spawn_with_emag = TRUE
|
||||
|
||||
var/list/clothing_possibilities
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/Initialize()
|
||||
..()
|
||||
|
||||
handle_clothing_setup()
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/proc/handle_clothing_setup()
|
||||
clothing_possibilities = list()
|
||||
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/under/color)
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/head/soft)
|
||||
clothing_possibilities |= /obj/item/clothing/shoes/black
|
||||
clothing_possibilities |= /obj/item/device/radio/headset
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/create_occupant(var/mob/M)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/carbon/human/H = new(src)
|
||||
|
||||
H.adjustCloneLoss(rand(1,5))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(H)
|
||||
to_chat(M, "<span class='notice'>You are a [occupant_type]!</span>")
|
||||
if(make_antag)
|
||||
to_chat(M, "<span class='warning'>Your intent may not be completely beneficial.</span>")
|
||||
H.ckey = M.ckey
|
||||
visible_message("<span class='warning'>As \the [src] opens, the pipes on \the [src] surge, before it grows dark.</span>")
|
||||
log_and_message_admins("successfully opened \a [src] and became a [occupant_type].")
|
||||
|
||||
var/list/uniform_options
|
||||
var/list/shoe_options
|
||||
var/list/head_options
|
||||
var/list/headset_options
|
||||
|
||||
if(clothing_possibilities && clothing_possibilities.len)
|
||||
for(var/path in clothing_possibilities)
|
||||
if(ispath(path, /obj/item/clothing/under))
|
||||
if(!uniform_options)
|
||||
uniform_options = list()
|
||||
uniform_options |= path
|
||||
if(ispath(path, /obj/item/clothing/shoes))
|
||||
if(!shoe_options)
|
||||
shoe_options = list()
|
||||
shoe_options |= path
|
||||
if(ispath(path, /obj/item/clothing/head))
|
||||
if(!head_options)
|
||||
head_options = list()
|
||||
head_options |= path
|
||||
if(ispath(path, /obj/item/device/radio/headset))
|
||||
if(!headset_options)
|
||||
headset_options = list()
|
||||
headset_options |= path
|
||||
|
||||
if(uniform_options && uniform_options.len)
|
||||
var/newpath = pick(uniform_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(shoe_options && shoe_options.len)
|
||||
var/newpath = pick(shoe_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(head_options && head_options.len)
|
||||
var/newpath = pick(head_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(headset_options && headset_options.len)
|
||||
var/newpath = pick(headset_options)
|
||||
var/obj/item/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(spawn_with_emag)
|
||||
var/obj/item/weapon/card/emag/E = new(H)
|
||||
E.name = "broken card"
|
||||
E.description_antag = "This is a 'disguised' emag, to make your escape from wherever you happen to be trapped."
|
||||
H.equip_to_appropriate_slot(E)
|
||||
|
||||
var/newname = sanitize(input(H, "Your mind feels foggy, and you recall your name might be [H.real_name]. Would you like to change your name?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
H.real_name = newname
|
||||
|
||||
icon_state = icon_state_opened
|
||||
|
||||
H.forceMove(T)
|
||||
|
||||
if(make_antag)
|
||||
var/datum/antagonist/antag = all_antag_types[make_antag]
|
||||
if(antag)
|
||||
if(antag.add_antagonist(H.mind, 1, 1, 0, 1, 1))
|
||||
log_admin("\The [src] made [key_name(src)] into a [antag.role_text].")
|
||||
|
||||
if(start_injured) // Done 3 different times to disperse damage.
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
|
||||
if(allow_appearance_change)
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
|
||||
visible_message("<span class='aliem'>\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!</span>")
|
||||
|
||||
// Manual Variant
|
||||
// This one lacks the emag option due to the fact someone has to activate it, and they will probably help the person.
|
||||
/obj/structure/ghost_pod/manual/human
|
||||
name = "mysterious cryopod"
|
||||
desc = "This is a pod which appears to contain a body."
|
||||
description_info = "This contains a body, which may wake at any time. The external controls\
|
||||
seem to be functioning, though the warning lights that flash give no solace.."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper_1"
|
||||
icon_state_opened = "sleeper_0"
|
||||
density = TRUE
|
||||
ghost_query_type = /datum/ghost_query/lost_passenger
|
||||
anchored = FALSE
|
||||
|
||||
var/occupant_type = "lost passenger"
|
||||
|
||||
var/allow_appearance_change = TRUE
|
||||
|
||||
var/make_antag = MODE_STOWAWAY
|
||||
|
||||
var/start_injured = TRUE
|
||||
|
||||
var/list/clothing_possibilities
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/Initialize()
|
||||
..()
|
||||
|
||||
handle_clothing_setup()
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/proc/handle_clothing_setup()
|
||||
clothing_possibilities = list()
|
||||
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/under/utility)
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/head/beret)
|
||||
clothing_possibilities |= /obj/item/clothing/shoes/black
|
||||
clothing_possibilities |= /obj/item/device/radio/headset
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/create_occupant(var/mob/M)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/carbon/human/H = new(src)
|
||||
|
||||
H.adjustCloneLoss(rand(1,5))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(H)
|
||||
to_chat(M, "<span class='notice'>You are a [occupant_type]!</span>")
|
||||
if(make_antag)
|
||||
to_chat(M, "<span class='warning'>Your intent may not be completely beneficial.</span>")
|
||||
H.ckey = M.ckey
|
||||
visible_message("<span class='warning'>As \the [src] opens, the pipes on \the [src] surge, before it grows dark.</span>")
|
||||
log_and_message_admins("successfully opened \a [src] and got a [occupant_type].")
|
||||
|
||||
var/list/uniform_options
|
||||
var/list/shoe_options
|
||||
var/list/head_options
|
||||
var/list/headset_options
|
||||
|
||||
if(clothing_possibilities && clothing_possibilities.len)
|
||||
for(var/path in clothing_possibilities)
|
||||
if(ispath(path, /obj/item/clothing/under))
|
||||
if(!uniform_options)
|
||||
uniform_options = list()
|
||||
uniform_options |= path
|
||||
if(ispath(path, /obj/item/clothing/shoes))
|
||||
if(!shoe_options)
|
||||
shoe_options = list()
|
||||
shoe_options |= path
|
||||
if(ispath(path, /obj/item/clothing/head))
|
||||
if(!head_options)
|
||||
head_options = list()
|
||||
head_options |= path
|
||||
if(ispath(path, /obj/item/device/radio/headset))
|
||||
if(!headset_options)
|
||||
headset_options = list()
|
||||
headset_options |= path
|
||||
|
||||
if(uniform_options && uniform_options.len)
|
||||
var/newpath = pick(uniform_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(shoe_options && shoe_options.len)
|
||||
var/newpath = pick(shoe_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(head_options && head_options.len)
|
||||
var/newpath = pick(head_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(headset_options && headset_options.len)
|
||||
var/newpath = pick(headset_options)
|
||||
var/obj/item/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
var/newname = sanitize(input(H, "Your mind feels foggy, and you recall your name might be [H.real_name]. Would you like to change your name?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
H.real_name = newname
|
||||
|
||||
icon_state = icon_state_opened
|
||||
|
||||
H.forceMove(T)
|
||||
|
||||
if(make_antag)
|
||||
var/datum/antagonist/antag = all_antag_types[make_antag]
|
||||
if(antag)
|
||||
if(antag.add_antagonist(H.mind, 1, 1, 0, 1, 1))
|
||||
log_admin("\The [src] made [key_name(src)] into a [antag.role_text].")
|
||||
|
||||
if(start_injured) // Done 3 different times to disperse damage.
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
|
||||
if(allow_appearance_change)
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
|
||||
visible_message("<span class='aliem'>\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!</span>")
|
||||
@@ -58,4 +58,50 @@
|
||||
R.ckey = M.ckey
|
||||
visible_message("<span class='warning'>As \the [src] opens, the eyes of the robot flicker as it is activated.</span>")
|
||||
R.Namepick()
|
||||
..()
|
||||
..()
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone
|
||||
name = "drone shell"
|
||||
desc = "A heavy metallic ball."
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer_unactivated"
|
||||
density = FALSE
|
||||
anchored = FALSE
|
||||
|
||||
var/drone_class = "general"
|
||||
var/drone_type = /mob/living/silicon/robot/drone/swarm
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/create_occupant(var/mob/M)
|
||||
var/mob/living/silicon/robot/drone/swarm/R = new drone_type(get_turf(src))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(R)
|
||||
to_chat(M, "<span class='cult'>You are <b>[R]</b>, the remnant of some distant species, mechanical or flesh, living or dead.</span>")
|
||||
R.ckey = M.ckey
|
||||
visible_message("<span class='cult'>As \the [src] shudders, it glows before lifting itself with three shimmering limbs!</span>")
|
||||
spawn(3 SECONDS)
|
||||
to_chat(R,"<span class='notice'>Many of your tools are standard drone devices, however others provide you with particular benefits.</span>")
|
||||
to_chat(R,"<span class='notice'>Unlike standard drones, you are capable of utilizing 'zero point wells', found in your 'spells' tab.</span>")
|
||||
to_chat(R,"<span class='notice'>Here you will also find your replication ability(s), depending on the type of drone you are.</span>")
|
||||
to_chat(R,"<span class='notice'>Gunners have a special anti-personnel gun capable of shocking or punching through armor with low damage.</span>")
|
||||
to_chat(R,"<span class='notice'>Impalers have an energy-lance.</span>")
|
||||
to_chat(R,"<span class='notice'>General drones have the unique ability to produce one of each of these two types of shells per generation.</span>")
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/Initialize()
|
||||
..()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
say_dead_object("A <span class='notice'>[drone_class] swarm drone</span> shell is now available in \the [T.loc].", src)
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/gunner
|
||||
name = "gunner shell"
|
||||
|
||||
drone_class = "gunner"
|
||||
drone_type = /mob/living/silicon/robot/drone/swarm/gunner
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/melee
|
||||
name = "impaler shell"
|
||||
|
||||
drone_class = "impaler"
|
||||
drone_type = /mob/living/silicon/robot/drone/swarm/melee
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
/obj/structure/girder/update_icon()
|
||||
if(anchored)
|
||||
icon_state = "girder"
|
||||
icon_state = initial(icon_state)
|
||||
else
|
||||
icon_state = "displaced"
|
||||
|
||||
@@ -320,6 +320,7 @@
|
||||
name = "column"
|
||||
icon= 'icons/obj/cult.dmi'
|
||||
icon_state= "cultgirder"
|
||||
max_health = 250
|
||||
health = 250
|
||||
cover = 70
|
||||
girder_material = "cult"
|
||||
@@ -354,6 +355,13 @@
|
||||
new /obj/effect/decal/remains/human(get_turf(src))
|
||||
dismantle()
|
||||
|
||||
/obj/structure/girder/resin
|
||||
name = "soft girder"
|
||||
icon_state = "girder_resin"
|
||||
max_health = 225
|
||||
health = 225
|
||||
cover = 60
|
||||
girder_material = "resin"
|
||||
|
||||
/obj/structure/girder/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
|
||||
@@ -680,7 +680,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
)
|
||||
|
||||
uncommon_loot = list(
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/safety_clamp,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser,
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid,
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
spawn(1)
|
||||
var/newname = sanitizeSafe(input(vox,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
|
||||
if(!newname || newname == "")
|
||||
var/datum/language/L = all_languages[vox.species.default_language]
|
||||
var/datum/language/L = GLOB.all_languages[vox.species.default_language]
|
||||
newname = L.get_random_name()
|
||||
vox.real_name = newname
|
||||
vox.name = vox.real_name
|
||||
|
||||
@@ -103,12 +103,12 @@
|
||||
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
|
||||
playing = 0
|
||||
return
|
||||
if(lentext(note) == 0)
|
||||
if(length(note) == 0)
|
||||
continue
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
for(var/i=2 to lentext(note))
|
||||
for(var/i=2 to length(note))
|
||||
var/ni = copytext(note,i,i+1)
|
||||
if(!text2num(ni))
|
||||
if(ni == "#" || ni == "b" || ni == "n")
|
||||
@@ -196,11 +196,11 @@
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lentext(t) >= INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
|
||||
if(length(t) >= INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
|
||||
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
|
||||
if(cont == "no")
|
||||
break
|
||||
while(lentext(t) > INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
|
||||
while(length(t) > INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
|
||||
//split into lines
|
||||
spawn()
|
||||
lines = splittext(t, "\n")
|
||||
@@ -214,7 +214,7 @@
|
||||
lines.Cut(INSTRUMENT_MAX_LINE_NUMBER+1)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
if(length(l) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
to_chat(usr, "Line [linenum] too long!")
|
||||
lines.Remove(l)
|
||||
else
|
||||
@@ -244,7 +244,7 @@
|
||||
return
|
||||
if(lines.len > INSTRUMENT_MAX_LINE_NUMBER)
|
||||
return
|
||||
if(lentext(newline) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
if(length(newline) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
newline = copytext(newline, 1, INSTRUMENT_MAX_LINE_LENGTH)
|
||||
lines.Add(newline)
|
||||
else if(href_list["deleteline"])
|
||||
@@ -257,7 +257,7 @@
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lentext(content) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
if(length(content) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
content = copytext(content, 1, INSTRUMENT_MAX_LINE_LENGTH)
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/obj/structure/cult/pylon/swarm
|
||||
name = "Swarm Construct"
|
||||
desc = "A small pod."
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "pod"
|
||||
light_color = "#00B2B2"
|
||||
|
||||
shatter_message = "The energetic field shatters!"
|
||||
impact_sound = 'sound/effects/Glasshit.ogg'
|
||||
shatter_sound = 'sound/effects/phasein.ogg'
|
||||
|
||||
var/list/active_beams
|
||||
|
||||
/obj/structure/cult/pylon/swarm/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover, /mob/living))
|
||||
var/mob/living/L = mover
|
||||
if(L.faction == "swarmer")
|
||||
return TRUE
|
||||
else if(istype(mover, /obj/item/projectile))
|
||||
var/obj/item/projectile/P = mover
|
||||
if(istype(P.firer) && P.firer.faction == "swarmer")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/Initialize()
|
||||
..()
|
||||
active_beams = list()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/Destroy()
|
||||
for(var/datum/beam/B in active_beams)
|
||||
QDEL_NULL(B)
|
||||
active_beams = null
|
||||
..()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/pylonhit(var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3))
|
||||
visible_message("<span class='danger'>[shatter_message]</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/cult/pylon/swarm/attackpylon(mob/user as mob, var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3))
|
||||
user.visible_message(
|
||||
"<span class='danger'>[user] smashed \the [src]!</span>",
|
||||
"<span class='warning'>You hit \the [src], and its crystal breaks apart!</span>",
|
||||
"You hear a tinkle of crystalline shards."
|
||||
)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
user.do_attack_animation(src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
else
|
||||
if(prob(damage * 2))
|
||||
to_chat(user, "You pulverize what was left of \the [src]!")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
|
||||
/obj/structure/cult/pylon/swarm/pylon_unique()
|
||||
. = ..()
|
||||
|
||||
return .
|
||||
|
||||
/obj/structure/cult/pylon/swarm/zp_well
|
||||
name = "Zero Point Well"
|
||||
desc = "Infinite cosmic power, itty bitty usability."
|
||||
|
||||
icon_state = "trap"
|
||||
|
||||
description_info = "An infinitely small point in space that may or may not be used to supply power to some form of advanced machine."
|
||||
|
||||
activation_cooldown = 0 // These things run constantly.
|
||||
|
||||
/obj/structure/cult/pylon/swarm/zp_well/pylon_unique()
|
||||
. = ..()
|
||||
|
||||
for(var/mob/living/silicon/robot/drone/swarm/S in view(3, src))
|
||||
var/has_beam = FALSE
|
||||
for(var/datum/beam/B in active_beams)
|
||||
if(B.target == S)
|
||||
has_beam = TRUE
|
||||
break
|
||||
|
||||
if(!has_beam)
|
||||
active_beams |= Beam(S,icon='icons/effects/beam.dmi',icon_state="holo_beam",time=3 SECONDS,maxdistance=3,beam_type = /obj/effect/ebeam,beam_sleep_time=2)
|
||||
|
||||
if(S.cell)
|
||||
S.cell.give(rand(5, 30))
|
||||
|
||||
. = TRUE
|
||||
|
||||
return .
|
||||
|
||||
/obj/structure/cult/pylon/swarm/defender
|
||||
name = "Zero Point Wall"
|
||||
desc = "Infinite cosmic power, itty bitty passability."
|
||||
|
||||
icon_state = "barricade"
|
||||
|
||||
description_info = "An infinitely small point in space spread upon infinitely many finitely-bounded points in space. Nice."
|
||||
|
||||
/obj/structure/cult/pylon/swarm/defender/pylonhit(var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3) && round(damage * 0.8) >= 30)
|
||||
visible_message("<span class='danger'>[shatter_message]</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/cult/pylon/swarm/defender/attackpylon(mob/user as mob, var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3) && round(damage * 0.8) >= 25)
|
||||
user.visible_message(
|
||||
"<span class='danger'>[user] smashed \the [src]!</span>",
|
||||
"<span class='warning'>You hit \the [src], and its crystal breaks apart!</span>",
|
||||
"You hear a tinkle of crystalline shards."
|
||||
)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
user.do_attack_animation(src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
else
|
||||
if(prob(damage * 2))
|
||||
to_chat(user, "You pulverize what was left of \the [src]!")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
Reference in New Issue
Block a user