Merge branch 'master' of https://github.com/VOREStation/VOREStation into Kates-Taur-Clothes

This commit is contained in:
lbnesquik
2019-12-26 07:25:05 +01:00
772 changed files with 273143 additions and 193272 deletions
+102 -7
View File
@@ -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
+6
View File
@@ -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")
+48 -12
View File
@@ -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)
+6
View File
@@ -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)
+6
View File
@@ -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)
+11 -1
View File
@@ -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."
+2
View File
@@ -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
+8 -2
View File
@@ -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
+2 -2
View File
@@ -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
..()
+2 -2
View File
@@ -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"
+51 -11
View File
@@ -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
+7
View File
@@ -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]!")
+119 -86
View File
@@ -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"
+1 -1
View File
@@ -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)
+34 -4
View File
@@ -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
+6
View File
@@ -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")
+6
View File
@@ -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
+9 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+7 -7
View File
@@ -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
+150
View File
@@ -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)