diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index a1ed1bf3648..84cfa9a8264 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -15,26 +15,38 @@ Pipelines + Other Objects -> Pipe network
active_power_usage = 0
power_channel = ENVIRON
var/nodealert = 0
-
- layer = 2.4 //under wires with their 2.44
+
+ layer = 2.4 //under wires with their 2.44
var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber
var/connected_to = 1 //same as above, currently not used for anything
var/icon_connect_type = "" //"-supply" or "-scrubbers"
-
+
var/initialize_directions = 0
var/pipe_color
-
+
var/global/datum/pipe_icon_manager/icon_manager
+/obj/machinery/atmospherics/Destroy()
+ for(var/mob/living/M in src) //ventcrawling is serious business
+ M.remove_ventcrawl()
+ M.loc = src.loc
+ ..()
+
+// Find a connecting /obj/machinery/atmospherics in specified direction.
+/obj/machinery/atmospherics/proc/findConnecting(var/direction)
+ for(var/obj/machinery/atmospherics/target in get_step(src,direction))
+ if(target.initialize_directions & get_dir(target,src))
+ return target
+
/obj/machinery/atmospherics/New()
if(!icon_manager)
icon_manager = new()
-
+
if(!pipe_color)
pipe_color = color
color = null
-
+
if(!pipe_color_check(pipe_color))
pipe_color = null
..()
@@ -84,22 +96,22 @@ obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/a
if(list1[i] == list2[j])
var/n = list1[i]
return n
- return 0
-
+ return 0
+
/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
if(!istype(icon_manager))
if(!safety) //to prevent infinite loops
icon_manager = new()
check_icon_cache(1)
return 0
-
+
return 1
/obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node)
//Don't use this for standard pipes
if(!istype(node))
return null
-
+
return node.pipe_color
/obj/machinery/atmospherics/process()
@@ -134,4 +146,34 @@ obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/a
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
/obj/machinery/atmospherics/update_icon()
- return null
\ No newline at end of file
+ return null
+
+#define VENT_SOUND_DELAY 30
+
+/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
+ if(!(direction & initialize_directions)) //can't go in a way we aren't connecting to
+ return
+
+ var/obj/machinery/atmospherics/target_move = findConnecting(direction)
+ if(target_move)
+ if(is_type_in_list(target_move, ventcrawl_machinery) && target_move.can_crawl_through())
+ user.remove_ventcrawl()
+ user.forceMove(target_move.loc) //handles entering and so on
+ user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.")
+ else if(target_move.can_crawl_through())
+ user.loc = target_move
+ user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement
+ if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
+ user.last_played_vent = world.time
+ playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
+ else
+ if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery) && target_move.can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
+ user.remove_ventcrawl()
+ user.forceMove(src.loc)
+ user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.")
+ user.canmove = 0
+ spawn(1)
+ user.canmove = 1
+
+/obj/machinery/atmospherics/proc/can_crawl_through()
+ return 1
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index d2092ce7e54..4c6a529e3bb 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -39,7 +39,7 @@
var/radio_filter_out
var/radio_filter_in
-
+
connect_types = list(1,2) //connects to regular and supply pipes
/obj/machinery/atmospherics/unary/vent_pump/on
@@ -80,7 +80,7 @@
return
overlays.Cut()
-
+
var/vent_icon = "vent"
var/turf/T = get_turf(src)
@@ -89,7 +89,7 @@
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
vent_icon += "h"
-
+
if(welded)
vent_icon += "weld"
else if(!powered())
@@ -307,6 +307,9 @@
update_icon()
return
+/obj/machinery/atmospherics/unary/vent_pump/can_crawl_through()
+ return !welded
+
/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
@@ -375,16 +378,3 @@
initial_loc.air_vent_names -= id_tag
..()
return
-
-/*
- Alt-click to ventcrawl - Monkeys, aliens, slimes and mice.
- This is a little buggy but somehow that just seems to plague ventcrawl.
- I am sorry, I don't know why.
-*/
-/obj/machinery/atmospherics/unary/vent_pump/AltClick(var/mob/living/ML)
- if(istype(ML))
- var/list/ventcrawl_verbs = list(/mob/living/carbon/monkey/verb/ventcrawl, /mob/living/carbon/alien/verb/alien_ventcrawl, /mob/living/carbon/slime/verb/ventcrawl,/mob/living/simple_animal/mouse/verb/ventcrawl)
- if(length(ML.verbs & ventcrawl_verbs)) // alien queens have this removed, an istype would be complicated
- ML.handle_ventcrawl(src)
- return
- ..()
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 05d60c80c96..23b1f7899de 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -23,13 +23,14 @@
var/volume_rate = 120
var/panic = 0 //is this scrubber panicked?
+ var/welded = 0
var/area_uid
var/radio_filter_out
var/radio_filter_in
connect_types = list(1,3) //connects to regular and scrubber pipes
-
+
/obj/machinery/atmospherics/unary/vent_scrubber/New()
icon = null
@@ -50,7 +51,7 @@
return
overlays.Cut()
-
+
var/scrubber_icon = "scrubber"
var/turf/T = get_turf(src)
@@ -61,6 +62,8 @@
scrubber_icon += "off"
else
scrubber_icon += "[on ? "[scrubbing ? "on" : "in"]" : "off"]"
+ if(welded)
+ scrubber_icon = "scrubberweld"
overlays += icon_manager.get_atmos_icon("device", , , scrubber_icon)
@@ -127,6 +130,8 @@
return
if (!node)
on = 0
+ if(welded)
+ return 0
//broadcast_status()
if(!on)
return 0
@@ -151,7 +156,7 @@
removed.oxygen = 0
if(scrub_N2)
filtered_out.nitrogen = removed.nitrogen
- removed.nitrogen = 0
+ removed.nitrogen = 0
if(scrub_Toxins)
filtered_out.toxins = removed.toxins
removed.toxins = 0
@@ -229,7 +234,7 @@
scrubbing = text2num(signal.data["scrubbing"])
if(signal.data["toggle_scrubbing"])
scrubbing = !scrubbing
-
+
if(signal.data["o2_scrub"] != null)
scrub_O2 = text2num(signal.data["o2_scrub"])
if(signal.data["toggle_o2_scrub"])
@@ -276,7 +281,30 @@
if(old_stat != stat)
update_icon()
+/obj/machinery/atmospherics/unary/vent_scrubber/can_crawl_through()
+ return !welded
+
/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params)
+ if(istype(W, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = W
+ if (WT.remove_fuel(0,user))
+ user << "Now welding the scrubber."
+ if(do_after(user, 20))
+ if(!src || !WT.isOn()) return
+ playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ if(!welded)
+ user.visible_message("[user] welds the scrubber shut.", "You weld the vent scrubber.", "You hear welding.")
+ welded = 1
+ update_icon()
+ else
+ user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.")
+ welded = 0
+ update_icon()
+ else
+ user << "The welding tool needs to be on to start this task."
+ else
+ user << "You need more welding fuel to complete this task."
+ return 1
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!(stat & NOPOWER) && on)
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 0e721d87c87..32bd4f9a823 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -38,6 +38,33 @@ var/global/list/language_keys[0] // Table of say codes for all languages
var/global/list/all_nations[0]
var/global/list/whitelisted_species = list()
+//global var of unsafe-to-spawn-on-reaction mobs
+var/global/list/blocked_mobs = list(/mob/living/simple_animal/hostile,
+ /mob/living/simple_animal/hostile/pirate,
+ /mob/living/simple_animal/hostile/pirate/ranged,
+ /mob/living/simple_animal/hostile/russian,
+ /mob/living/simple_animal/hostile/russian/ranged,
+ /mob/living/simple_animal/hostile/syndicate,
+ /mob/living/simple_animal/hostile/syndicate/melee,
+ /mob/living/simple_animal/hostile/syndicate/melee/space,
+ /mob/living/simple_animal/hostile/syndicate/ranged,
+ /mob/living/simple_animal/hostile/syndicate/ranged/space,
+ /mob/living/simple_animal/hostile/alien/queen/large,
+ /mob/living/simple_animal/hostile/retaliate,
+ /mob/living/simple_animal/hostile/retaliate/clown,
+ /mob/living/simple_animal/hostile/mushroom,
+ /mob/living/simple_animal/hostile/asteroid,
+ /mob/living/simple_animal/hostile/asteroid/basilisk,
+ /mob/living/simple_animal/hostile/asteroid/goldgrub,
+ /mob/living/simple_animal/hostile/asteroid/goliath,
+ /mob/living/simple_animal/hostile/asteroid/hivelord,
+ /mob/living/simple_animal/hostile/asteroid/hivelordbrood,
+ /mob/living/simple_animal/hostile/carp/holocarp,
+ /mob/living/simple_animal/hostile/mining_drone,
+ /mob/living/simple_animal/hostile/spaceWorm,
+ /mob/living/simple_animal/hostile/spaceWorm/wormHead
+ )
+
//Preferences stuff
//Hairstyles
var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name
@@ -56,9 +83,6 @@ var/global/list/undershirt_t = list("White Shirt", "White Tank top", "Black shir
var/global/list/undershirt_list = undershirt_t
//Backpacks
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
- //Slime Colors
-var/global/slime_colorh = list("grey", "gold", "silver", "metal", "purple", "darkpurple", "orange", "yellow", "red", "blue", "darkblue", "pink", "green", "lightpink", "black", "oil", "adamantine")
-
//////////////////////////
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 81ed859a7e5..77489174db4 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -61,7 +61,7 @@ proc/random_name(gender, species = "Human")
else
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
else
- return current_species.get_random_name(gender)
+ return current_species.get_random_name(gender)
proc/random_skin_tone()
switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino"))
@@ -130,7 +130,7 @@ Proc for attack log creation, because really why not
5 is additional information, anything that needs to be added
*/
-proc/add_logs(mob/target, mob/user, what_done, var/object=null, var/addition=null)
+proc/add_logs(mob/target, mob/user, what_done, var/object=null, var/addition=null) //Victim : Attacker : what they did : what they did it with : extra notes
var/list/ignore=list("shaked","CPRed","grabbed","punched")
if(!user)
return
@@ -142,5 +142,5 @@ proc/add_logs(mob/target, mob/user, what_done, var/object=null, var/addition=nul
if(target.client)
if(what_done in ignore) return
if(target == user)return
- msg_admin_attack("[user.name][ismob(user) ? "([user.ckey])" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition](JMP)")
+ msg_admin_attack("[user.name][ismob(user) ? "([user.ckey])" : ""][isAntag(user) ? "(ANTAG)" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition](JMP)")
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 9462083757e..43f4808a076 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1511,7 +1511,8 @@ var/list/WALLITEMS = list(
"/obj/machinery/newscaster", "/obj/machinery/firealarm", "/obj/structure/noticeboard", "/obj/machinery/door_control",
"/obj/machinery/computer/security/telescreen", "/obj/machinery/embedded_controller/radio/simple_vent_controller",
"/obj/item/weapon/storage/secure/safe", "/obj/machinery/door_timer", "/obj/machinery/flasher", "/obj/machinery/keycard_auth",
- "/obj/structure/mirror", "/obj/structure/closet/fireaxecabinet", "/obj/machinery/computer/security/telescreen/entertainment"
+ "/obj/structure/mirror", "/obj/structure/closet/fireaxecabinet", "/obj/machinery/computer/security/telescreen/entertainment",
+ "/obj/structure/sign"
)
/proc/gotwallitem(loc, dir)
for(var/obj/O in loc)
@@ -1541,7 +1542,7 @@ var/list/WALLITEMS = list(
for(var/obj/O in get_step(loc, dir))
for(var/item in WALLITEMS)
if(istype(O, text2path(item)))
- if(O.pixel_x == 0 && O.pixel_y == 0)
+ if(abs(O.pixel_x) <= 10 && abs(O.pixel_y) <= 10)
return 1
return 0
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 2bbe14bea42..38aae40c51b 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -470,13 +470,13 @@
//mymob.item_use_icon.color = ui_color
mymob.item_use_icon.alpha = ui_alpha
- mymob.gun_move_icon = new /obj/screen/gun/move(null)
+ /*mymob.gun_move_icon = new /obj/screen/gun/move(null)
//mymob.gun_move_icon.color = ui_color
mymob.gun_move_icon.alpha = ui_alpha
mymob.gun_run_icon = new /obj/screen/gun/run(null)
//mymob.gun_run_icon.color = ui_color
- mymob.gun_run_icon.alpha = ui_alpha
+ mymob.gun_run_icon.alpha = ui_alpha*/
if (mymob.client)
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
@@ -560,4 +560,4 @@
A.screen_loc = ui_action_slot5
break //5 slots available, so no more can be added.
num++
- src.client.screen += src.hud_used.item_action_list
\ No newline at end of file
+ src.client.screen += src.hud_used.item_action_list
diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm
index bfbbc589ab2..095de121300 100644
--- a/code/_onclick/hud/monkey.dm
+++ b/code/_onclick/hud/monkey.dm
@@ -231,14 +231,14 @@
if (mymob.client.target_can_click)
mymob.item_use_icon.dir = 1
src.adding += mymob.item_use_icon
- mymob.gun_move_icon = new /obj/screen/gun/move(null)
+ /*mymob.gun_move_icon = new /obj/screen/gun/move(null)
if (mymob.client.target_can_move)
mymob.gun_move_icon.dir = 1
mymob.gun_run_icon = new /obj/screen/gun/run(null)
if (mymob.client.target_can_run)
mymob.gun_run_icon.dir = 1
src.adding += mymob.gun_run_icon
- src.adding += mymob.gun_move_icon
+ src.adding += mymob.gun_move_icon*/
mymob.client.screen = null
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index 1495714e51c..e91cfb50f78 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -154,14 +154,14 @@
if (mymob.client.target_can_click)
mymob.item_use_icon.dir = 1
src.adding += mymob.item_use_icon
- mymob.gun_move_icon = new /obj/screen/gun/move(null)
+ /*mymob.gun_move_icon = new /obj/screen/gun/move(null)
if (mymob.client.target_can_move)
mymob.gun_move_icon.dir = 1
mymob.gun_run_icon = new /obj/screen/gun/run(null)
if (mymob.client.target_can_run)
mymob.gun_run_icon.dir = 1
src.adding += mymob.gun_run_icon
- src.adding += mymob.gun_move_icon
+ src.adding += mymob.gun_move_icon*/
mymob.client.screen = null
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 7406307c632..813cc9f3f46 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -105,7 +105,7 @@
master = null
dir = 2
- move
+ /*move
name = "Allow Walking"
icon_state = "no_walk0"
screen_loc = ui_gun2
@@ -113,7 +113,7 @@
run
name = "Allow Running"
icon_state = "no_run0"
- screen_loc = ui_gun3
+ screen_loc = ui_gun3*/
item
name = "Allow Item Use"
@@ -421,7 +421,7 @@
if(istype(usr, /mob/living/silicon/robot))
usr:toggle_module(3)
- if("Allow Walking")
+ /*if("Allow Walking")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
return
if(!istype(usr.equipped(),/obj/item/weapon/gun))
@@ -455,7 +455,7 @@
usr << "You need your gun in your active hand to do that!"
return
usr.client.AllowTargetRun()
- gun_click_time = world.time
+ gun_click_time = world.time*/
if("Allow Item Use")
if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes.
diff --git a/code/_onclick/ventcrawl.dm b/code/_onclick/ventcrawl.dm
new file mode 100644
index 00000000000..f80b0933a71
--- /dev/null
+++ b/code/_onclick/ventcrawl.dm
@@ -0,0 +1,37 @@
+var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /obj/machinery/atmospherics/unary/vent_scrubber)
+
+/mob/living/carbon/slime/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/carbon/monkey/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/simple_animal/borer/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/simple_animal/mouse/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/simple_animal/spiderbot/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/carbon/alien/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
\ No newline at end of file
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index d7b995cdf2c..d99a17e7ab5 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -179,9 +179,6 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD)
eyes_s.Blend(facial_s, ICON_OVERLAY)
- if(H.species.bloodflags & BLOOD_SLIME)
- var/icon/blendingslime = new/icon("icon" = 'icons/effects/slimemutant.dmi', "icon_state" = "[H.slime_color]_slime_[H.gender]_s")
- preview_icon.Blend(blendingslime, ICON_OVERLAY)
var/icon/clothes_s = null
switch(H.mind.assigned_role)
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index f6a415912dc..1320ca0a855 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -262,7 +262,6 @@ client
body += ""
if(ishuman(D))
body += ""
- body += ""
body += ""
body += ""
body += ""
@@ -790,27 +789,6 @@ client
holder.Topic(href, list("makemask"=href_list["makemask"]))
- else if(href_list["setmutantrace"])
- if(!check_rights(R_SPAWN)) return
-
- var/mob/living/carbon/human/H = locate(href_list["setmutantrace"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- var/new_mutantrace = input("Please choose a new mutantrace","Mutantrace",null) as null|anything in list("NONE","golem","lizard","slime","plant","shadow","tajaran","skrell","vox")
- switch(new_mutantrace)
- if(null)
- return
- if("NONE")
- new_mutantrace = ""
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- if(H.dna)
- H.dna.mutantrace = new_mutantrace
- H.update_mutantrace()
-
else if(href_list["setspecies"])
if(!check_rights(R_SPAWN)) return
diff --git a/code/datums/martial.dm b/code/datums/martial.dm
new file mode 100644
index 00000000000..6fbe984e6ad
--- /dev/null
+++ b/code/datums/martial.dm
@@ -0,0 +1,366 @@
+/datum/martial_art
+ var/name = "Martial Art"
+ var/streak = ""
+ var/max_streak_length = 6
+ var/current_target = null
+ var/temporary = 0
+ var/datum/martial_art/base = null // The permanent style
+
+/datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ return 0
+
+/datum/martial_art/proc/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ return 0
+
+/datum/martial_art/proc/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ return 0
+
+/datum/martial_art/proc/add_to_streak(var/element,var/mob/living/carbon/human/D)
+ if(D != current_target)
+ current_target = D
+ streak = ""
+ streak = streak+element
+ if(length(streak) > max_streak_length)
+ streak = copytext(streak,2)
+ return
+
+/datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D)
+ add_logs(A, D, "punched")
+ A.do_attack_animation(D)
+ var/damage = rand(0,9)
+
+ var/atk_verb = "punch"
+ if(D.lying)
+ atk_verb = "kick"
+
+ if(!damage)
+ playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ D.visible_message("[A] has attempted to [atk_verb] [D]!")
+ return 0
+
+ var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting))
+ var/armor_block = D.run_armor_check(affecting, "melee")
+
+ playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)
+
+ D.visible_message("[A] has [atk_verb]ed [D]!", \
+ "[A] has [atk_verb]ed [D]!")
+
+ D.apply_damage(damage, BRUTE, affecting, armor_block)
+ if((D.stat != DEAD) && damage >= 9)
+ D.visible_message("[A] has weakened [D]!!", \
+ "[A] has weakened [D]!")
+ D.apply_effect(4, WEAKEN, armor_block)
+ D.forcesay(hit_appends)
+ else if(D.lying)
+ D.forcesay(hit_appends)
+ return 1
+
+/datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0)
+ if(make_temporary)
+ temporary = 1
+ if(H.martial_art && H.martial_art.temporary)
+ if(temporary)
+ base = H.martial_art.base
+ else
+ H.martial_art.base = src //temporary styles have priority
+ return
+ H.martial_art = src
+
+/datum/martial_art/proc/remove(var/mob/living/carbon/human/H)
+ if(H.martial_art != src)
+ return
+ H.martial_art = base
+
+
+/datum/martial_art/boxing
+ name = "Boxing"
+
+/datum/martial_art/boxing/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ A << " Can't disarm while boxing!"
+ return 1
+
+/datum/martial_art/boxing/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ A << " Can't grab while boxing!"
+ return 1
+
+/datum/martial_art/boxing/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ add_logs(A, D, "punched")
+ A.do_attack_animation(D)
+
+ var/atk_verb = pick("left hook","right hook","straight punch")
+
+ var/damage = rand(5,8)
+
+ if(!damage)
+ playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!")
+ return 0
+
+
+ var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting))
+ var/armor_block = D.run_armor_check(affecting, "melee")
+
+ playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)
+
+
+ D.visible_message("[A] has hit [D] with a [atk_verb]!", \
+ "[A] has hit [D] with a [atk_verb]!")
+
+ D.apply_damage(damage, STAMINA, affecting, armor_block)
+ if(D.getStaminaLoss() > 50)
+ var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
+ if((D.stat != DEAD) && prob(knockout_prob))
+ D.visible_message("[A] has knocked [D] out with a haymaker!", \
+ "[A] has knocked [D] out with a haymaker!")
+ D.apply_effect(10,WEAKEN,armor_block)
+ D.SetSleeping(5)
+ D.forcesay(hit_appends)
+ else if(D.lying)
+ D.forcesay(hit_appends)
+ return 1
+
+/datum/martial_art/drunk_brawling
+ name = "Drunken Brawling"
+
+/datum/martial_art/drunk_brawling/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ if(prob(70))
+ A.visible_message("[A] tries to grab ahold of [D], but fails!", \
+ "You fail to grab ahold of [D]!")
+ return 1
+ D.grabbedby(A,1)
+ var/obj/item/weapon/grab/G = A.get_active_hand()
+ if(G)
+ D.visible_message("[A] grabs ahold of [D] drunkenly!", \
+ "[A] grabs ahold of [D] drunkenly!")
+ return 1
+
+/datum/martial_art/drunk_brawling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ add_logs(A, D, "punched")
+ A.do_attack_animation(D)
+
+ var/atk_verb = pick("jab","uppercut","overhand punch","drunken right hook","drunken left hook")
+
+ var/damage = rand(0,6)
+
+ if(atk_verb == "uppercut")
+ if(prob(90))
+ damage = 0
+ else //10% chance to do a massive amount of damage
+ damage = 14
+
+ if(prob(50)) //they are drunk, they aren't going to land half of their hits
+ damage = 0
+
+ if(!damage)
+ playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!")
+ return 1 //returns 1 so that they actually miss and don't switch to attackhand damage
+
+ var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting))
+ var/armor_block = D.run_armor_check(affecting, "melee")
+
+ playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)
+
+
+ D.visible_message("[A] has hit [D] with a [atk_verb]!", \
+ "[A] has hit [D] with a [atk_verb]!")
+
+ D.apply_damage(damage, BRUTE, null, armor_block)
+ D.apply_effect(damage, STAMINA, armor_block)
+ if(D.getStaminaLoss() > 50)
+ var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
+ if((D.stat != DEAD) && prob(knockout_prob))
+ D.visible_message("[A] has knocked [D] out with a haymaker!", \
+ "[A] has knocked [D] out with a haymaker!")
+ D.apply_effect(10,WEAKEN,armor_block)
+ D.Paralyse(5)
+ D.forcesay(hit_appends)
+ else if(D.lying)
+ D.forcesay(hit_appends)
+ return 1
+
+/datum/martial_art/wrestling
+ name = "Wrestling"
+
+/datum/martial_art/wrestling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ D.grabbedby(A,1)
+ var/obj/item/weapon/grab/G = A.get_active_hand()
+ if(G && prob(50))
+ G.state = GRAB_AGGRESSIVE
+ D.visible_message("[A] has [D] in a clinch!", \
+ "[A] has [D] in a clinch!")
+ else
+ D.visible_message("[A] fails to get [D] in a clinch!", \
+ "[A] fails to get [D] in a clinch!")
+ return 1
+
+
+/datum/martial_art/wrestling/proc/Suplex(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ add_logs(A, D, "suplexed")
+ D.visible_message("[A] suplexes [D]!", \
+ "[A] suplexes [D]!")
+ D.forceMove(A.loc)
+ var/armor_block = D.run_armor_check(null, "melee")
+ D.apply_damage(30, BRUTE, null, armor_block)
+ D.apply_effect(6, WEAKEN, armor_block)
+ A.SpinAnimation(10,1)
+
+ D.SpinAnimation(10,1)
+ spawn(3)
+ armor_block = A.run_armor_check(null, "melee")
+ A.apply_effect(4, WEAKEN, armor_block)
+ return
+
+/datum/martial_art/wrestling/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ if(istype(A.get_inactive_hand(),/obj/item/weapon/grab))
+ var/obj/item/weapon/grab/G = A.get_inactive_hand()
+ if(G.affecting == D)
+ Suplex(A,D)
+ return 1
+ harm_act(A,D)
+ return 1
+
+/datum/martial_art/wrestling/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ D.grabbedby(A,1)
+ D.visible_message("[A] holds [D] down!", \
+ "[A] holds [D] down!")
+ var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting))
+ var/armor_block = D.run_armor_check(affecting, "melee")
+ D.apply_damage(10, STAMINA, affecting, armor_block)
+ return 1
+
+#define TORNADO_COMBO "HHD"
+#define THROWBACK_COMBO "DHD"
+#define PLASMA_COMBO "HDDDH"
+
+/datum/martial_art/plasma_fist
+ name = "Plasma Fist"
+
+/datum/martial_art/plasma_fist/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ if(findtext(streak,TORNADO_COMBO))
+ streak = ""
+ Tornado(A,D)
+ return 1
+ if(findtext(streak,THROWBACK_COMBO))
+ streak = ""
+ Throwback(A,D)
+ return 1
+ if(findtext(streak,PLASMA_COMBO))
+ streak = ""
+ Plasma(A,D)
+ return 1
+ return 0
+
+/datum/martial_art/plasma_fist/proc/Tornado(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ A.say("TORNADO SWEEP!")
+ spawn(0)
+ for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
+ A.dir = i
+ playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1)
+ sleep(1)
+ var/obj/effect/proc_holder/spell/wizard/aoe_turf/repulse/R = new(null)
+ var/list/turfs = list()
+ for(var/turf/T in range(1,A))
+ turfs.Add(T)
+ R.cast(turfs)
+ return
+
+/datum/martial_art/plasma_fist/proc/Throwback(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ D.visible_message("[A] has hit [D] with Plasma Punch!", \
+ "[A] has hit [D] with Plasma Punch!")
+ playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
+ var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
+ D.throw_at(throw_target, 200, 4)
+ A.say("HYAH!")
+ return
+
+/datum/martial_art/plasma_fist/proc/Plasma(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ A.do_attack_animation(D)
+ playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
+ A.say("PLASMA FIST!")
+ D.visible_message("[A] has hit [D] with THE PLASMA FIST TECHNIQUE!", \
+ "[A] has hit [D] with THE PLASMA FIST TECHNIQUE!")
+ D.gib()
+ return
+
+/datum/martial_art/plasma_fist/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ add_to_streak("H")
+ if(check_streak(A,D))
+ return 1
+ basic_hit(A,D)
+ return 1
+
+/datum/martial_art/plasma_fist/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ add_to_streak("D")
+ if(check_streak(A,D))
+ return 1
+ basic_hit(A,D)
+ return 1
+
+/datum/martial_art/plasma_fist/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
+ add_to_streak("G")
+ if(check_streak(A,D))
+ return 1
+ basic_hit(A,D)
+ return 1
+
+
+//ITEMS
+
+/obj/item/clothing/gloves/boxing
+ var/datum/martial_art/boxing/style = new
+
+/obj/item/clothing/gloves/boxing/equipped(mob/user, slot)
+ if(!ishuman(user))
+ return
+ if(slot == slot_gloves)
+ var/mob/living/carbon/human/H = user
+ style.teach(H,1)
+ return
+
+/obj/item/clothing/gloves/boxing/dropped(mob/user)
+ if(!ishuman(user))
+ return
+ var/mob/living/carbon/human/H = user
+ if(H.get_item_by_slot(slot_gloves) == src)
+ style.remove(H)
+ return
+
+/obj/item/weapon/storage/belt/champion/wrestling
+ name = "Wrestling Belt"
+ var/datum/martial_art/wrestling/style = new
+
+/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot)
+ if(!ishuman(user))
+ return
+ if(slot == slot_belt)
+ var/mob/living/carbon/human/H = user
+ style.teach(H,1)
+ return
+
+/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user)
+ if(!ishuman(user))
+ return
+ var/mob/living/carbon/human/H = user
+ if(H.get_item_by_slot(slot_belt) == src)
+ style.remove(H)
+ return
+
+/obj/item/weapon/plasma_fist_scroll
+ name = "Plasma Fist Scroll"
+ desc = "Teaches the traditional wizard martial art."
+ icon = 'icons/obj/wizard.dmi'
+ icon_state ="scroll2"
+ var/used = 0
+
+/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user as mob)
+ if(!ishuman(user))
+ return
+ if(!used)
+ var/mob/living/carbon/human/H = user
+ var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null)
+ F.teach(H)
+ H << "You learn the PLASMA FIST style."
+ used = 1
+ desc += "It looks like it's magic was used up."
diff --git a/code/datums/pizza_bomb.dm b/code/datums/pizza_bomb.dm
new file mode 100644
index 00000000000..1ec911ccb72
--- /dev/null
+++ b/code/datums/pizza_bomb.dm
@@ -0,0 +1,101 @@
+/obj/item/device/pizza_bomb
+ name = "pizza box"
+ desc = "A box suited for pizzas."
+ icon = 'icons/obj/food.dmi'
+ icon_state = "pizzabox1"
+ var/timer = 10 //Adjustable timer
+ var/timer_set = 0
+ var/primed = 0
+ var/disarmed = 0
+ var/wires = list("orange", "green", "blue", "yellow", "aqua", "purple")
+ var/correct_wire
+ var/armer //Used for admin purposes
+
+/obj/item/device/pizza_bomb/attack_self(mob/user)
+ if(disarmed)
+ user << "\The [src] is disarmed."
+ return
+ if(!timer_set)
+ name = "pizza bomb"
+ desc = "It seems inactive."
+ icon_state = "pizzabox_bomb"
+ timer_set = 1
+ timer = (input(user, "Set a timer, from one second to ten seconds.", "Timer", "[timer]") as num) * 10
+ if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained())
+ timer_set = 0
+ name = "pizza box"
+ desc = "A box suited for pizzas."
+ icon_state = "pizzabox1"
+ return
+ timer = Clamp(timer, 10, 100)
+ icon_state = "pizzabox1"
+ user << "You set the timer to [timer / 10] before activating the payload and closing \the [src]."
+ message_admins("[key_name(usr)]? has set a timer on a pizza bomb to [timer/10] seconds at (JMP).")
+ log_game("[key_name(usr)] has set the timer on a pizza bomb to [timer/10] seconds ([loc.x],[loc.y],[loc.z]).")
+ armer = usr
+ name = "pizza box"
+ desc = "A box suited for pizzas."
+ return
+ if(!primed)
+ name = "pizza bomb"
+ desc = "OH GOD THAT'S NOT A PIZZA"
+ icon_state = "pizzabox_bomb"
+ audible_message("\icon[src] *beep* *beep*")
+ user << "That's no pizza! That's a bomb!"
+ message_admins("[key_name(usr)]? has triggered a pizza bomb armed by [armer] at (JMP).")
+ log_game("[key_name(usr)] has triggered a pizza bomb armed by [armer] ([loc.x],[loc.y],[loc.z]).")
+ primed = 1
+ sleep(timer)
+ return go_boom()
+
+/obj/item/device/pizza_bomb/proc/go_boom()
+ if(disarmed)
+ visible_message("\icon[src] Sparks briefly jump out of the [correct_wire] wire on \the [src], but it's disarmed!")
+ return
+ src.audible_message("\icon[src] [src] beeps, \"Enjoy the pizza!\"")
+ src.visible_message("\The [src] violently explodes!")
+ explosion(src.loc,1,2,4) //Identical to a minibomb
+ qdel(src)
+
+/obj/item/device/pizza_bomb/attackby(var/obj/item/I, var/mob/user, params)
+ if(istype(I, /obj/item/weapon/wirecutters) && primed)
+ user << "Oh God, what wire do you cut?!"
+ var/chosen_wire = input(user, "OH GOD OH GOD", "WHAT WIRE?!") in wires
+ if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained())
+ return
+ playsound(src, 'sound/items/Wirecutter.ogg', 50, 1, 1)
+ user.visible_message("[user] cuts the [chosen_wire] wire!", "You cut the [chosen_wire] wire!")
+ sleep(5)
+ if(chosen_wire == correct_wire)
+ src.audible_message("\icon[src] \The [src] suddenly stops beeping and seems lifeless.")
+ user << "You did it!"
+ icon_state = "pizzabox_bomb_[correct_wire]"
+ name = "pizza bomb"
+ desc = "A devious contraption, made of a small explosive payload hooked up to pressure-sensitive wires. It's disarmed."
+ disarmed = 1
+ primed = 0
+ return
+ else
+ user << "WRONG WIRE!"
+ go_boom()
+ return
+ if(istype(I, /obj/item/weapon/wirecutters) && disarmed)
+ if(!in_range(user, src))
+ user << "You can't see the box well enough to cut the wires out."
+ return
+ user.visible_message("[user] starts removing the payload and wires from \the [src].")
+ if(do_after(user, 40))
+ playsound(src, 'sound/items/Wirecutter.ogg', 50, 1, 1)
+ user.unEquip(src)
+ user.visible_message("[user] removes the insides of \the [src]!")
+ var/obj/item/stack/cable_coil/C = new /obj/item/stack/cable_coil(src.loc)
+ C.amount = 3
+ new /obj/item/weapon/bombcore/miniature(src.loc)
+ new /obj/item/pizzabox(src.loc)
+ qdel(src)
+ return
+ ..()
+
+/obj/item/device/pizza_bomb/New()
+ ..()
+ correct_wire = pick(wires)
\ No newline at end of file
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 6a6f2bd52e8..1db0e95da0d 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -48,6 +48,7 @@ var/list/uplink_items = list()
var/list/gamemodes = list() // Empty list means it is in all the gamemodes. Otherwise place the gamemode name here.
var/list/excludefrom = list() //Empty list does nothing. Place the name of gamemode you don't want this item to be available in here. This is so you dont have to list EVERY mode to exclude something.
var/list/job = null
+ var/surplus = 100 //Chance of being included in the surplus crate (when pick() selects it)
/datum/uplink_item/proc/spawn_item(var/turf/loc, var/obj/item/device/uplink/U)
if(item)
@@ -108,13 +109,6 @@ var/list/uplink_items = list()
cost = 8
job = list("Clown")
-/datum/uplink_item/jobspecific/conversionkit
- name = "Conversion Kit Bundle"
- desc = "A bundle that comes with a professional revolver conversion kit and 1 box of .357 ammo. The kit allows you to convert your revolver to fire lethal rounds or vice versa, modification is nearly perfect and will not result in catastrophic failure."
- item = /obj/item/weapon/storage/box/syndie_kit/conversion
- cost = 12
- job = list("Detective")
-
//Chef
/datum/uplink_item/jobspecific/specialsauce
name = "Chef Excellence's Special Sauce"
@@ -174,13 +168,6 @@ var/list/uplink_items = list()
cost = 6
job = list("Civilian")
-/*
-/datum/uplink_item/jobspecific/greytide
- name = "Greytide Implant"
- desc = "A box containing an implanter filled with a greytide implant when injected into another person makes them loyal to the greytide and your cause, unless of course they're already implanted by someone else. Loyalty ends if the implant is no longer in their system."
- item = /obj/item/weapon/storage/box/syndie_kit/greytide
- cost = 7
- job = list("Civilian") */
//Bartender
/datum/uplink_item/jobspecific/drunkbullets
@@ -244,6 +231,7 @@ var/list/uplink_items = list()
desc = "A brutally simple syndicate revolver that fires .357 Magnum cartridges and has 7 chambers."
item = /obj/item/weapon/gun/projectile/revolver
cost = 13
+ surplus = 50
/datum/uplink_item/dangerous/smg
name = "Syndicate SMG"
@@ -251,6 +239,15 @@ var/list/uplink_items = list()
item = /obj/item/weapon/gun/projectile/automatic/c20r
cost = 14
gamemodes = list("nuclear emergency")
+ surplus = 40
+
+/datum/uplink_item/dangerous/car
+ name = "C-90gl Compact Assault Rifle"
+ desc = "A fully-loaded Zashchita Industriya toploading bullpup assault rifle that uses 30-round 5.45x39mm magazines with a togglable underslung 40mm grenade launcher."
+ item = /obj/item/weapon/gun/projectile/automatic/c90gl
+ cost = 18
+ gamemodes = list("nuclear emergency")
+ surplus = 50
/datum/uplink_item/dangerous/machinegun
name = "Syndicate LMG"
@@ -258,6 +255,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/gun/projectile/automatic/l6_saw
cost = 40
gamemodes = list("nuclear emergency")
+ surplus = 0
/datum/uplink_item/dangerous/crossbow
name = "Energy Crossbow"
@@ -265,6 +263,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow
cost = 12
excludefrom = list("nuclear emergency")
+ surplus = 50
/datum/uplink_item/dangerous/sword
name = "Energy Sword"
@@ -272,12 +271,19 @@ var/list/uplink_items = list()
item = /obj/item/weapon/melee/energy/sword
cost = 8
+/datum/uplink_item/dangerous/chainsaw
+ name = "Chainsaw"
+ desc = "A high powered chainsaw for cutting up ...you know...."
+ item = /obj/item/weapon/twohanded/chainsaw
+ cost = 13
+
/datum/uplink_item/dangerous/manhacks
name = "Viscerator Delivery Grenade"
desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred any non-operatives in the area."
item = /obj/item/weapon/grenade/spawnergrenade/manhacks
cost = 8
gamemodes = list("nuclear emergency")
+ surplus = 35
/datum/uplink_item/dangerous/saringrenades
name = "Sarin Gas Grenades"
@@ -285,6 +291,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/storage/box/syndie_kit/sarin
cost = 15
gamemodes = list("nuclear emergency")
+ surplus = 0
/datum/uplink_item/dangerous/emp
name = "EMP Kit"
@@ -305,6 +312,7 @@ var/list/uplink_items = list()
item = /obj/mecha/combat/gygax/dark/loaded
cost = 90
gamemodes = list("nuclear emergency")
+ surplus = 0
/datum/uplink_item/dangerous/mauler
name = "Mauler Exosuit"
@@ -312,6 +320,7 @@ var/list/uplink_items = list()
item = /obj/mecha/combat/marauder/mauler/loaded
cost = 140
gamemodes = list("nuclear emergency")
+ surplus = 0
/datum/uplink_item/dangerous/syndieborg
name = "Syndicate Cyborg"
@@ -319,6 +328,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/antag_spawner/borg_tele
cost = 50
gamemodes = list("nuclear emergency")
+ surplus = 0
//for refunding the syndieborg teleporter
/datum/uplink_item/dangerous/syndieborg/spawn_item()
@@ -330,6 +340,7 @@ var/list/uplink_items = list()
/datum/uplink_item/ammo
category = "Ammunition"
+ surplus = 40
/datum/uplink_item/ammo/pistol
name = "Ammo-10mm"
@@ -350,13 +361,6 @@ var/list/uplink_items = list()
cost = 2
gamemodes = list("nuclear emergency")
-/datum/uplink_item/dangerous/car
- name = "C-90gl Compact Assault Rifle"
- desc = "A fully-loaded Zashchita Industriya toploading bullpup assault rifle that uses 30-round 5.45x39mm magazines with a togglable underslung 40mm grenade launcher."
- item = /obj/item/weapon/gun/projectile/automatic/c90gl
- cost = 18
- gamemodes = list("nuclear emergency")
-
/datum/uplink_item/ammo/bullbuck
name = "Drum Magazine - 12g buckshot"
desc = "An additional 8-round buckshot magazine for use in the Bulldog shotgun. Front towards enemy."
@@ -398,7 +402,7 @@ var/list/uplink_items = list()
item = /obj/item/ammo_box/magazine/m762
cost = 12
gamemodes = list("nuclear emergency")
-
+ surplus = 0
// STEALTHY WEAPONS
@@ -417,6 +421,7 @@ var/list/uplink_items = list()
desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. You can also drop it underfoot to slip people."
item = /obj/item/weapon/soap/syndie
cost = 1
+ surplus = 50
/datum/uplink_item/stealthy_weapons/detomatix
name = "Detomatix PDA Cartridge"
@@ -431,6 +436,20 @@ var/list/uplink_items = list()
desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the shots of the weapon for increased stealth and superior ambushing capability."
item = /obj/item/weapon/suppressor
cost = 3
+ surplus = 10
+
+/datum/uplink_item/stealthy_weapons/pizza_bomb
+ name = "Pizza Bomb"
+ desc = "A pizza box with a bomb taped inside of it. The timer needs to be set by opening the box; afterwards, opening the box again will trigger the detonation."
+ item = /obj/item/device/pizza_bomb
+ cost = 4
+ surplus = 8
+
+/datum/uplink_item/stealthy_weapons/dehy_carp
+ name = "Dehydrated Space Carp"
+ desc = "Just add water to make your very own hostile to everything space carp. It looks just like a plushie."
+ item = /obj/item/toy/carpplushie/dehy_carp
+ cost = 3
// STEALTHY TOOLS
@@ -449,6 +468,7 @@ var/list/uplink_items = list()
it can also be used in a washing machine to forge clothing."
item = /obj/item/weapon/stamp/chameleon
cost = 1
+ surplus = 35
/datum/uplink_item/stealthy_tools/syndigolashes
name = "No-Slip Syndicate Shoes"
@@ -479,6 +499,7 @@ var/list/uplink_items = list()
desc = "Enables you to bug cameras to view them remotely. Adding particular items to it alters its functions."
item = /obj/item/device/camera_bug
cost = 2
+ surplus = 90
/datum/uplink_item/stealthy_tools/dnascrambler
name = "DNA Scrambler"
@@ -491,6 +512,7 @@ var/list/uplink_items = list()
desc = "This satchel is thin enough to be hidden in the gap between plating and tiling, great for stashing your stolen goods. Comes with a crowbar and a floor tile inside."
item = /obj/item/weapon/storage/backpack/satchel_flat
cost = 2
+ surplus = 30
// DEVICE AND TOOLS
@@ -531,6 +553,14 @@ var/list/uplink_items = list()
item = /obj/item/weapon/storage/box/syndie_kit/space
cost = 5
+/datum/uplink_item/device_tools/hardsuit
+ name = "Blood-red Hardsuit"
+ desc = "The feared suit of a syndicate nuclear agent. Features slightly better armoring. When the helmet is deployed your identity will be protected. Toggling the suit into combat mode \
+ will allow you all the mobility of a loose fitting uniform without sacrificing armoring. Additionally the suit is collapsible, small enough to fit within a backpack. \
+ Nanotrasen crewmembers are trained to report red space suit sightings, these suits in particular are known to drive employees into a panic."
+ item = /obj/item/weapon/storage/box/syndie_kit/hardsuit
+ cost = 8
+
/datum/uplink_item/device_tools/thermal
name = "Thermal Imaging Glasses"
desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
@@ -542,12 +572,14 @@ var/list/uplink_items = list()
desc = "A key, that when inserted into a radio headset, allows you to listen to and talk with artificial intelligences and cybernetic organisms in binary."
item = /obj/item/device/encryptionkey/binary
cost = 5
+ surplus = 75
/datum/uplink_item/device_tools/cipherkey
name = "Syndicate Encryption Key"
desc = "A key, that when inserted into a radio headset, allows you to listen to all station department channels as well as talk on an encrypted Syndicate channel."
item = /obj/item/device/encryptionkey/syndicate
cost = 5
+ surplus = 75
/datum/uplink_item/device_tools/hacked_module
name = "Hacked AI Upload Module"
@@ -606,6 +638,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/circuitboard/teleporter
cost = 40
gamemodes = list("nuclear emergency")
+ surplus = 0
/datum/uplink_item/device_tools/shield
name = "Energy Shield"
@@ -613,6 +646,7 @@ var/list/uplink_items = list()
item = /obj/item/weapon/shield/energy
cost = 16
gamemodes = list("nuclear emergency")
+ surplus = 20
// IMPLANTS
@@ -630,6 +664,7 @@ var/list/uplink_items = list()
desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. The ability for an agent to open an uplink after their posessions have been stripped from them makes this implant excellent for escaping confinement."
item = /obj/item/weapon/implanter/uplink
cost = 20
+ surplus = 0
/datum/uplink_item/implants/explosive
name = "Explosive Implant"
@@ -659,6 +694,7 @@ var/list/uplink_items = list()
/datum/uplink_item/badass
category = "(Pointless) Badassery"
+ surplus = 0
/datum/uplink_item/badass/bundle
name = "Syndicate Bundle"
@@ -674,6 +710,14 @@ var/list/uplink_items = list()
item = /obj/item/toy/cards/deck/syndicate
cost = 1
excludefrom = list("nuclear emergency")
+ surplus = 40
+
+/datum/uplink_item/badass/syndiecash
+ name = "Syndicate Briefcase Full of Cash"
+ desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods and services at lucrative prices. \
+ The briefcase also feels a little heavier to hold; it has been manufactured to pack a little bit more of a punch if your client needs some convincing."
+ item = /obj/item/weapon/storage/secure/briefcase/syndie
+ cost = 1
/datum/uplink_item/badass/balloon
name = "For showing that you are The Boss"
@@ -705,3 +749,38 @@ var/list/uplink_items = list()
U.uses -= max(0, I.cost)
feedback_add_details("traitor_uplink_items_bought","RN")
return new I.item(loc)
+
+/datum/uplink_item/badass/surplus_crate
+ name = "Syndicate Surplus Crate"
+ desc = "A crate containing 50 telecrystals worth of random syndicate leftovers."
+ cost = 20
+ item = /obj/item/weapon/storage/box/syndicate
+ excludefrom = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/badass/surplus_crate/spawn_item(turf/loc, obj/item/device/uplink/U)
+ var/obj/structure/closet/crate/C = new(loc)
+ var/list/temp_uplink_list = get_uplink_items()
+ var/list/buyable_items = list()
+ for(var/category in temp_uplink_list)
+ buyable_items += temp_uplink_list[category]
+ var/list/bought_items = list()
+ U.uses -= cost
+ U.used_TC = 20
+ var/remaining_TC = 50
+
+ var/datum/uplink_item/I
+ while(remaining_TC)
+ I = pick(buyable_items)
+ if(!I.surplus)
+ continue
+ if(I.cost > remaining_TC)
+ continue
+ if((I.item in bought_items) && prob(33)) //To prevent people from being flooded with the same thing over and over again.
+ continue
+ bought_items += I.item
+ remaining_TC -= I.cost
+
+ U.purchase_log += "\icon[C]"
+ for(var/item in bought_items)
+ new item(C)
+ U.purchase_log += "\icon[item]"
\ No newline at end of file
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index c8e76fa8ac9..2462c13c2a7 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -485,6 +485,12 @@
icon_state = "wood_tableparts"
flags = null
+/obj/item/weapon/table_parts/glass
+ name = "glass table parts"
+ desc = "fragile!"
+ icon_state = "glass_tableparts"
+ flags = null
+
/obj/item/weapon/wire
desc = "This is just a simple piece of regular insulated wire."
name = "wire"
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index c24ea331bcd..cba9e44ecde 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -52,7 +52,7 @@
InitializeLighting()
-/area/proc/poweralert(var/state, var/obj/source as obj)
+/area/proc/poweralert(var/state, var/obj/source as obj)
if (state != poweralm)
poweralm = state
if(istype(source)) //Only report power alarms on the z-level where the source is located.
@@ -263,7 +263,7 @@
/area/proc/updateicon()
if(radalert) // always show the radiation alert, regardless of power
icon_state = "radiation"
- blend_mode = BLEND_MULTIPLY
+ blend_mode = BLEND_MULTIPLY
else if ((fire || eject || party) && ((!requires_power)?(!requires_power):power_environ))//If it doesn't require power, can still activate this proc.
if(fire && !radalert && !eject && !party)
icon_state = "red"
@@ -385,30 +385,30 @@
thunk(L)
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
- if(L && L.client && (L.client.prefs.sound & SOUND_AMBIENCE))
- if(!L.client.ambience_playing)
- L.client.ambience_playing = 1
- L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2)
+ if(!L.client.ambience_playing && L && L.client && (L.client.prefs.sound & SOUND_BUZZ)) //split off the white noise from the rest of the ambience because of annoyance complaints - Kluys
+ L.client.ambience_playing = 1
+ L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2)
+ else L.client.ambience_playing = 0
- if(prob(35) && !newarea.media_source)
- // TODO: This is dumb. - N3X
- if(istype(src, /area/chapel))
- sound = pick('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg','sound/music/traitor.ogg')
- else if(istype(src, /area/medical/morgue))
- sound = pick('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/music/main.ogg')
- else if(type == /area)
- sound = pick('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg')
- else if(istype(src, /area/engine))
- sound = pick('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg')
- else if(istype(src, /area/AIsattele) || istype(src, /area/turret_protected/ai) || istype(src, /area/turret_protected/ai_upload) || istype(src, /area/turret_protected/ai_upload_foyer))
- sound = pick('sound/ambience/ambimalf.ogg')
- else if(istype(src, /area/mine/explored) || istype(src, /area/mine/unexplored))
- sound = pick('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg')
- musVolume = 25
- else if(istype(src, /area/tcommsat) || istype(src, /area/turret_protected/tcomwest) || istype(src, /area/turret_protected/tcomeast) || istype(src, /area/turret_protected/tcomfoyer) || istype(src, /area/turret_protected/tcomsat))
- sound = pick('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
- else
- sound = pick('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
+ if(prob(35) && !newarea.media_source && L && L.client && (L.client.prefs.sound & SOUND_AMBIENCE))
+ // TODO: This is dumb. - N3X
+ if(istype(src, /area/chapel))
+ sound = pick('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg','sound/music/traitor.ogg')
+ else if(istype(src, /area/medical/morgue))
+ sound = pick('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/music/main.ogg')
+ else if(type == /area)
+ sound = pick('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg')
+ else if(istype(src, /area/engine))
+ sound = pick('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg')
+ else if(istype(src, /area/AIsattele) || istype(src, /area/turret_protected/ai) || istype(src, /area/turret_protected/ai_upload) || istype(src, /area/turret_protected/ai_upload_foyer))
+ sound = pick('sound/ambience/ambimalf.ogg')
+ else if(istype(src, /area/mine/explored) || istype(src, /area/mine/unexplored))
+ sound = pick('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg')
+ musVolume = 25
+ else if(istype(src, /area/tcommsat) || istype(src, /area/turret_protected/tcomwest) || istype(src, /area/turret_protected/tcomeast) || istype(src, /area/turret_protected/tcomfoyer) || istype(src, /area/turret_protected/tcomsat))
+ sound = pick('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
+ else
+ sound = pick('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
if(!L.client.played)
L << sound(sound, repeat = 0, wait = 0, volume = musVolume, channel = 1)
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index e028702a44e..0687b41e691 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -82,7 +82,6 @@ var/global/list/bad_blocks[0]
// From old dna.
var/b_type = "A+" // Should probably change to an integer => string map but I'm lazy.
- var/mutantrace = null // The type of mutant race the player is, if applicable (i.e. potato-man)
var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings,
// New stuff
@@ -95,7 +94,6 @@ var/global/list/bad_blocks[0]
new_dna.unique_enzymes=unique_enzymes
new_dna.struc_enzymes_original=struc_enzymes_original // will make clone's SE the same as the original, do we want this?
new_dna.b_type=b_type
- new_dna.mutantrace=mutantrace
new_dna.real_name=real_name
new_dna.species=species
for(var/b=1;b<=DNA_SE_LENGTH;b++)
diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm
index 4f8af67358b..3e355212d0e 100644
--- a/code/game/dna/genes/goon_disabilities.dm
+++ b/code/game/dna/genes/goon_disabilities.dm
@@ -336,7 +336,7 @@
if(L)
usr.attack_log += text("\[[time_stamp()]\] [usr.real_name] ([usr.ckey]) cast the spell [name] on [L.real_name] ([L.ckey]).")
- msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast the spell [name] on [L.real_name] ([L.ckey]) (JMP)")
+ msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast the spell [name] on [L.real_name] ([L.ckey]) (JMP)")
L.adjust_fire_stacks(0.5)
L.visible_message("\red [L.name] suddenly bursts into flames!")
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index 3a61aa0607c..687bf9c1bb1 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -164,12 +164,12 @@
H.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [H]!",
"[usr] sprays a cloud of fine ice crystals over your [H.head]'s visor.")
log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals yes, suit yes")
- msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
+ msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
else
H.visible_message("\red [usr] sprays a cloud of fine ice crystals engulfing, [H]!",
"[usr] sprays a cloud of fine ice crystals cover your [H.head]'s visor and make it into your air vents!.")
log_admin("[usr.real_name] ([ckey(usr.key)]) has used cryokinesis on [C.real_name] ([ckey(C.key)]), ()")
- msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
+ msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
H.bodytemperature = max(0, H.bodytemperature - 50)
H.adjustFireLoss(5)
if(!handle_suit)
@@ -179,7 +179,7 @@
C.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [C]!")
log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals no, suit no")
- msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
+ msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
//playsound(usr.loc, 'bamf.ogg', 50, 0)
diff --git a/code/game/gamemodes/changeling/powers/spiders.dm b/code/game/gamemodes/changeling/powers/spiders.dm
index 52f8ecd31bd..135fd92479c 100644
--- a/code/game/gamemodes/changeling/powers/spiders.dm
+++ b/code/game/gamemodes/changeling/powers/spiders.dm
@@ -8,9 +8,9 @@
//Makes some spiderlings. Good for setting traps and causing general trouble.
/obj/effect/proc_holder/changeling/spiders/sting_action(var/mob/user)
- for(var/i=0, i<4, i++)
+ for(var/i=0, i<2, i++)
var/obj/effect/spider/spiderling/S = new(user.loc)
- S.grow_as = /mob/living/simple_animal/hostile/giant_spider/hunter
+ S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter
feedback_add_details("changeling_powers","SI")
return 1
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 65310a6b250..adf28b1e8d2 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -332,7 +332,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on him by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used [name] on [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used [name] on [M.name] ([M.ckey]) (JMP)")
if(!iscarbon(M))
M.LAssailant = null
else
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 6b71348f054..16a452ac651 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -103,7 +103,6 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
vox.name = vox.real_name
newraider.name = vox.name
vox.age = rand(12,20)
- vox.dna.mutantrace = "vox"
vox.set_species("Vox")
vox.languages = list() // Removing language from chargen.
vox.flavor_text = ""
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 777268f0aef..a41fcc019f9 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -1014,10 +1014,9 @@
else if(istype(W, /obj/item/weapon/wrench))
user << "You remove the fire alarm assembly from the wall!"
- var/obj/item/alarm_frame/frame = new /obj/item/alarm_frame()
- frame.loc = user.loc
+ new /obj/item/mounted/frame/alarm_frame(get_turf(user))
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
- del(src)
+ qdel(src)
return 0
@@ -1049,50 +1048,6 @@ Just a object used in constructing air alarms
m_amt = 50
g_amt = 50
-
-/*
-AIR ALARM ITEM
-Handheld air alarm frame, for placing on walls
-Code shamelessly copied from apc_frame
-*/
-/obj/item/alarm_frame
- name = "air alarm frame"
- desc = "Used for building Air Alarms"
- icon = 'icons/obj/monitors.dmi'
- icon_state = "alarm_bitem"
- flags = CONDUCT
-
-/obj/item/alarm_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if (istype(W, /obj/item/weapon/wrench))
- new /obj/item/stack/sheet/metal( get_turf(src.loc), 2 )
- del(src)
- return
- ..()
-
-/obj/item/alarm_frame/proc/try_build(turf/on_wall)
- if (get_dist(on_wall,usr)>1)
- return
-
- var/ndir = get_dir(on_wall,usr)
- if (!(ndir in cardinal))
- return
-
- var/turf/loc = get_turf_loc(usr)
- var/area/A = loc.loc
- if (!istype(loc, /turf/simulated/floor))
- usr << "\red Air Alarm cannot be placed on this spot."
- return
- if (A.requires_power == 0 || A.name == "Space")
- usr << "\red Air Alarm cannot be placed in this area."
- return
-
- if(gotwallitem(loc, ndir))
- usr << "\red There's already an item on this wall!"
- return
-
- new /obj/machinery/alarm(loc, ndir, 1)
- del(src)
-
/*
FIRE ALARM
*/
@@ -1213,8 +1168,7 @@ FIRE ALARM
else if(istype(W, /obj/item/weapon/wrench))
user << "You remove the fire alarm assembly from the wall!"
- var/obj/item/firealarm_frame/frame = new /obj/item/firealarm_frame()
- frame.loc = user.loc
+ new /obj/item/mounted/frame/firealarm(get_turf(user))
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
del(src)
return
@@ -1385,52 +1339,6 @@ Just a object used in constructing fire alarms
m_amt = 50
g_amt = 50
-
-/*
-FIRE ALARM ITEM
-Handheld fire alarm frame, for placing on walls
-Code shamelessly copied from apc_frame
-*/
-/obj/item/firealarm_frame
- name = "fire alarm frame"
- desc = "Used for building Fire Alarms"
- icon = 'icons/obj/monitors.dmi'
- icon_state = "fire_bitem"
- flags = CONDUCT
-
-/obj/item/firealarm_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if (istype(W, /obj/item/weapon/wrench))
- new /obj/item/stack/sheet/metal( get_turf(src.loc), 2 )
- del(src)
- return
- ..()
-
-/obj/item/firealarm_frame/proc/try_build(turf/on_wall)
- if (get_dist(on_wall,usr)>1)
- return
-
- var/ndir = get_dir(on_wall,usr)
- if (!(ndir in cardinal))
- return
-
- var/turf/loc = get_turf_loc(usr)
- var/area/A = loc.loc
- if (!istype(loc, /turf/simulated/floor))
- usr << "\red Fire Alarm cannot be placed on this spot."
- return
- if (A.requires_power == 0 || A.name == "Space")
- usr << "\red Fire Alarm cannot be placed in this area."
- return
-
- if(gotwallitem(loc, ndir))
- usr << "\red There's already an item on this wall!"
- return
-
- new /obj/machinery/firealarm(loc, ndir, 1)
-
- del(src)
-
-
/obj/machinery/partyalarm
name = "\improper PARTY BUTTON"
desc = "Cuban Pete is in the house!"
diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm
index 41609e66d8e..d5fb43f4d97 100644
--- a/code/game/machinery/hydroponics.dm
+++ b/code/game/machinery/hydroponics.dm
@@ -806,12 +806,12 @@
user << "You plant the [S.seed.seed_name] [S.seed.seed_noun]."
if(S.seed.spread == 1)
- msg_admin_attack("[key_name(user)] has planted a creeper packet.")
+ msg_admin_attack("[key_name(user)][isAntag(user) ? "(ANTAG)" : ""] has planted a creeper packet.")
var/obj/effect/plant_controller/creeper/PC = new(get_turf(src))
if(PC)
PC.seed = S.seed
else if(S.seed.spread == 2)
- msg_admin_attack("[key_name(user)] has planted a spreading vine packet.")
+ msg_admin_attack("[key_name(user)][isAntag(user) ? "(ANTAG)" : ""] has planted a spreading vine packet.")
var/obj/effect/plant_controller/PC = new(get_turf(src))
if(PC)
PC.seed = S.seed
@@ -901,8 +901,8 @@
usr << "The plant looks \red unhealthy."
else
usr << "[src] is empty."
- usr << "Water: [round(waterlevel,0.1)]/100"
- usr << "Nutrient: [round(nutrilevel,0.1)]/10"
+ usr << "Water: [round(waterlevel,0.1)]/[maxwater]"
+ usr << "Nutrient: [round(nutrilevel,0.1)]/[maxnutri]"
if(weedlevel >= 5)
usr << "[src] is \red filled with weeds!"
if(pestlevel >= 5)
diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm
index b6349f454b6..60a4d3d094f 100644
--- a/code/game/machinery/kitchen/gibber.dm
+++ b/code/game/machinery/kitchen/gibber.dm
@@ -270,7 +270,7 @@
user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]"
if(src.occupant.ckey)
- msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] gibbed [src.occupant] ([src.occupant.ckey]) (JMP)")
if(!iscarbon(user))
src.occupant.LAssailant = null
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 248908ed824..5ce4008235f 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -40,7 +40,7 @@
src.backup_author = ""
src.censored = 0
src.is_admin_channel = 0
-
+
/datum/feed_channel/proc/announce_news()
return "Breaking news from [channel_name]!"
@@ -55,36 +55,6 @@ var/datum/feed_network/news_network = new /datum/feed_network //The global n
var/list/obj/machinery/newscaster/allCasters = list() //Global list that will contain reference to all newscasters in existence.
-/obj/item/newscaster_frame
- name = "newscaster frame"
- desc = "Used to build newscasters, just secure to the wall."
- icon_state = "newscaster"
- item_state = "syringe_kit"
- m_amt = 14000
- g_amt = 8000
-
-/obj/item/newscaster_frame/proc/try_build(turf/on_wall)
- if (get_dist(on_wall,usr)>1)
- return
- var/ndir = get_dir(usr,on_wall)
- if (!(ndir in cardinal))
- return
- var/turf/loc = get_turf(usr)
- var/area/A = loc.loc
- if (!istype(loc, /turf/simulated/floor))
- usr << "Newscaster cannot be placed on this spot."
- return
- if (A.requires_power == 0 || A.name == "Space")
- usr << "Newscaster cannot be placed in this area."
- return
- for(var/obj/machinery/newscaster/T in loc)
- usr << "There is another newscaster here."
- return
- var/obj/machinery/newscaster/N = new(loc)
- N.pixel_y -= (loc.y - on_wall.y) * 32
- N.pixel_x -= (loc.x - on_wall.x) * 32
- qdel(src)
-
/obj/machinery/newscaster
name = "newscaster"
desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
@@ -741,7 +711,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
user << "Now [anchored ? "un" : ""]securing [name]"
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
if(do_after(user, 60))
- new /obj/item/newscaster_frame(loc)
+ new /obj/item/mounted/frame/newscaster_frame(loc)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
qdel(src)
return
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 314f14e0ffa..fb6b23d17d1 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -138,7 +138,7 @@
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
if(payload && !istype(payload, /obj/item/weapon/bombcore/training))
- msg_admin_attack("[key_name(user)]? has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
+ msg_admin_attack("[key_name(user)][isAntag(user) ? "(ANTAG)" : ""]? has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
payload.adminlog = "The [src.name] that [key_name(user)] had primed detonated!"
@@ -273,6 +273,14 @@
/obj/item/weapon/bombcore/badmin/explosion/detonate()
explosion(get_turf(src),HeavyExplosion,MediumExplosion,LightExplosion)
+/obj/item/weapon/bombcore/miniature
+ name = "small bomb core"
+ w_class = 2
+
+/obj/item/weapon/bombcore/miniature/detonate()
+ explosion(src.loc,1,2,4) //Identical to a minibomb
+ qdel(src)
+
///Syndicate Detonator (aka the big red button)///
/obj/item/device/syndicatedetonator
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 1e5bb2a2a8e..007fc2f5f7e 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -768,9 +768,11 @@
icon_state = "coffee"
icon_vend = "coffee-vend"
vend_delay = 34
- products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
+ products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25,
+ /obj/item/weapon/reagent_containers/food/drinks/chocolate = 10, /obj/item/weapon/reagent_containers/food/drinks/chicken_soup = 10,/obj/item/weapon/reagent_containers/food/drinks/weightloss = 10)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10)
- prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
+ prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25, /obj/item/weapon/reagent_containers/food/drinks/chocolate = 25,
+ /obj/item/weapon/reagent_containers/food/drinks/chicken_soup = 30,/obj/item/weapon/reagent_containers/food/drinks/weightloss = 50)
refill_canister = /obj/item/weapon/vending_refill/coffee
/obj/machinery/vending/coffee/New()
@@ -786,16 +788,16 @@
/obj/machinery/vending/snack
name = "Getmore Chocolate Corp"
desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars"
- product_slogans = "Try our new nougat bar!;Twice the calories for half the price!"
+ product_slogans = "Try our new nougat bar!;Twice the calories for half the price!;Now featuring Discount Dan's food line!"
product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!"
icon_state = "snack"
- products = list(/obj/item/weapon/reagent_containers/food/snacks/candy/candybar = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/drinks/chicken_soup = 6,
- /obj/item/weapon/reagent_containers/food/snacks/chips =6,/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,
- /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6)
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/candy/candybar = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/snacks/chips =6,
+ /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,
+ /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6,/obj/item/weapon/reagent_containers/food/drinks/dansoup/random = 20,/obj/item/weapon/reagent_containers/food/snacks/danburrito/random = 20)
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
- prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy/candybar = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,/obj/item/weapon/reagent_containers/food/drinks/chicken_soup = 30,
+ prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy/candybar = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,
/obj/item/weapon/reagent_containers/food/snacks/chips =25,/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 30,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 20,
- /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30,/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25)
+ /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30,/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25,/obj/item/weapon/reagent_containers/food/drinks/dansoup/random = 10,/obj/item/weapon/reagent_containers/food/snacks/danburrito/random = 12)
refill_canister = /obj/item/weapon/vending_refill/snack
/obj/machinery/vending/snack/New()
@@ -843,6 +845,21 @@
component_parts += new /obj/item/weapon/vending_refill/cola(0)
component_parts += new /obj/item/weapon/vending_refill/cola(0)
+//New Cola Machine
+/obj/machinery/vending/soda
+ name = "Donk Co. Cola"
+ desc = "A cola vendor provided by Donk Company, Inc."
+ icon_state = "soda"
+ product_slogans = "Donk Co. Cola: Refreshing, delicious, and robust!"
+ product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space."
+ products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/robust = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/pubber = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/grifeo = 10,
+ /obj/item/weapon/reagent_containers/food/drinks/cans/grones = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/runoff = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/horror = 10,
+ /obj/item/weapon/reagent_containers/food/drinks/cans/orangeaid = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/limeaid = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/decirprevo = 10)
+ prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/robust = 35, /obj/item/weapon/reagent_containers/food/drinks/cans/pubber = 35, /obj/item/weapon/reagent_containers/food/drinks/cans/grifeo = 35,
+ /obj/item/weapon/reagent_containers/food/drinks/cans/grones = 35, /obj/item/weapon/reagent_containers/food/drinks/cans/runoff = 35, /obj/item/weapon/reagent_containers/food/drinks/cans/horror = 35,
+ /obj/item/weapon/reagent_containers/food/drinks/cans/orangeaid = 50, /obj/item/weapon/reagent_containers/food/drinks/cans/limeaid = 50, /obj/item/weapon/reagent_containers/food/drinks/cans/decirprevo = 60)
+
+
//This one's from bay12
/obj/machinery/vending/cart
name = "PTech"
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 24550898ec5..521716c44a5 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -264,8 +264,8 @@
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
if(target.reagents)
- if(target.reagents.get_reagent_amount("cryptobiolin") + force < force*2)
- target.reagents.add_reagent("cryptobiolin", force/2)
+ if(target.reagents.get_reagent_amount("atropine") + force < force*2)
+ target.reagents.add_reagent("atropine", force/2)
if(target.reagents.get_reagent_amount("toxin") + force < force*2)
target.reagents.add_reagent("toxin", force/2.5)
diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index 49deee27731..bc73b6689b4 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -16,6 +16,10 @@
icon_state = "ash"
anchored = 1
+/obj/effect/decal/cleanable/ash/New()
+ ..()
+ reagents.add_reagent("ash", 10)
+
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
@@ -27,6 +31,14 @@
icon_state = "dirt"
mouse_opacity = 0
+/obj/effect/decal/cleanable/dirt/blackpowder
+ name = "black powder"
+ mouse_opacity = 1
+ noscoop = 1
+
+/obj/effect/decal/cleanable/dirt/blackpowder/New()
+ ..()
+ reagents.add_reagent("blackpowder", 40) //size 2 explosion when activated
/obj/effect/decal/cleanable/flour
name = "flour"
@@ -103,6 +115,11 @@
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
var/list/datum/disease2/disease/virus2 = list()
+ noclear = 1
+
+/obj/effect/decal/cleanable/vomit/New()
+ ..()
+ reagents.add_reagent("vomit", 5)
/obj/effect/decal/cleanable/vomit/green
@@ -111,6 +128,11 @@
icon_state = "gvomit_1"
random_icon_states = list("gvomit_1", "gvomit_2", "gvomit_3", "gvomit_4")
+/obj/effect/decal/cleanable/vomit/green/New()
+ ..()
+ reagents.remove_reagent("vomit", 5)
+ reagents.add_reagent("green_vomit", 5)
+
/obj/effect/decal/cleanable/poop
name = "poop"
desc = "Gosh, how unpleasant."
@@ -148,3 +170,17 @@
layer = 2
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
+
+/obj/effect/decal/cleanable/fungus
+ name = "space fungus"
+ desc = "A fungal growth. Looks pretty nasty."
+ density = 0
+ anchored = 1
+ layer = 2
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "flour"
+ color = "#D5820B"
+
+/obj/effect/decal/cleanable/fungus/New()
+ ..()
+ reagents.add_reagent("fungus", 10)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 471a32a6c92..d64303e1267 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -1,7 +1,43 @@
/obj/effect/decal/cleanable
var/list/random_icon_states = list()
var/targeted_by = null // Used so cleanbots can't claim a mess.
+ var/noscoop = 0 //if it has this, don't let it be scooped up
+ var/noclear = 0 //if it has this, don't delete it when its' scooped up
+
/obj/effect/decal/cleanable/New()
if (random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
+ create_reagents(100)
+ ..()
+
+/obj/effect/decal/cleanable/attackby(obj/item/weapon/W as obj, mob/user as mob,)
+ if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food/drinks))
+ if(src.reagents && W.reagents && !noscoop)
+ if(!src.reagents.total_volume)
+ user << "There isn't enough [src] to scoop up!"
+ return
+ if(W.reagents.total_volume >= W.reagents.maximum_volume)
+ user << "[W] is full!"
+ return
+ user << "You scoop the [src] into [W]!"
+ reagents.trans_to(W, reagents.total_volume)
+ if(!reagents.total_volume && !noclear) //scooped up all of it
+ qdel(src)
+ return
+ if(is_hot(W)) //todo: make heating a reagent holder proc
+ if(istype(W, /obj/item/clothing/mask/cigarette)) return
+ else
+ src.reagents.chem_temp += 15
+ src.reagents.handle_reactions()
+ user << "You heat [src] with [W]!"
+
+/obj/effect/decal/cleanable/ex_act()
+ if(reagents)
+ for(var/datum/reagent/R in reagents.reagent_list)
+ R.on_ex_act()
+ ..()
+
+/obj/effect/decal/cleanable/fire_act()
+ reagents.chem_temp += 30
+ reagents.handle_reactions()
..()
\ No newline at end of file
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 62a9bb7a57b..ad68762c631 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -22,9 +22,9 @@
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user, params)
if(W.attack_verb.len)
- visible_message("\red \The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
+ visible_message("[user] has [pick(W.attack_verb)] \the [src] with \the [W]!")
else
- visible_message("\red \The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]")
+ visible_message("[user] has attacked \the [src] with \the [W]!")
var/damage = W.force / 4.0
@@ -45,7 +45,7 @@
/obj/effect/spider/proc/healthcheck()
if(health <= 0)
- del(src)
+ qdel(src)
/obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
@@ -54,17 +54,18 @@
/obj/effect/spider/stickyweb
icon_state = "stickyweb1"
- New()
- if(prob(50))
- icon_state = "stickyweb2"
+
+/obj/effect/spider/stickyweb/New()
+ if(prob(50))
+ icon_state = "stickyweb2"
/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
- if(istype(mover, /mob/living/simple_animal/hostile/giant_spider))
+ if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
return 1
else if(istype(mover, /mob/living))
if(prob(50))
- mover << "\red You get stuck in \the [src] for a moment."
+ mover << "You get stuck in \the [src] for a moment."
return 0
else if(istype(mover, /obj/item/projectile))
return prob(30)
@@ -75,37 +76,40 @@
desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs"
var/amount_grown = 0
- New()
- pixel_x = rand(3,-3)
- pixel_y = rand(3,-3)
- processing_objects.Add(src)
+ var/player_spiders = 0
+
+/obj/effect/spider/eggcluster/New()
+ pixel_x = rand(3,-3)
+ pixel_y = rand(3,-3)
+ processing_objects.Add(src)
/obj/effect/spider/eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
- var/num = rand(2,6)
+ var/num = rand(3,12)
for(var/i=0, i[src] dies!")
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
- del(src)
+ qdel(src)
/obj/effect/spider/spiderling/healthcheck()
if(health <= 0)
@@ -137,8 +141,9 @@
entry_vent = null
return
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents)
- /*if(prob(50))
- src.visible_message("[src] scrambles into the ventillation ducts!")*/
+ if(prob(50))
+ visible_message("[src] scrambles into the ventillation ducts!", \
+ "You hear something squeezing through the ventilation ducts.")
spawn(rand(20,60))
loc = exit_vent
@@ -151,7 +156,7 @@
return
if(prob(50))
- src.visible_message("\blue You hear something squeezing through the ventilation ducts.",2)
+ audible_message("You hear something squeezing through the ventilation ducts.")
sleep(travel_time)
if(!exit_vent || exit_vent.welded)
@@ -167,30 +172,34 @@
entry_vent = null
//=================
- else if(prob(25))
- var/list/nearby = oview(5, src)
+ else if(prob(33))
+ var/list/nearby = oview(10, src)
if(nearby.len)
var/target_atom = pick(nearby)
- walk_to(src, target_atom, 5)
- if(prob(25))
- src.visible_message("\blue \the [src] skitters[pick(" away"," around","")].")
- else if(prob(5))
+ walk_to(src, target_atom)
+ if(prob(40))
+ src.visible_message("\The [src] skitters[pick(" away"," around","")].")
+ else if(prob(10))
//ventcrawl!
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
- walk_to(src, entry_vent, 5)
+ walk_to(src, entry_vent, 1)
break
-
- if(prob(1))
- src.visible_message("\blue \the [src] chitters.")
- if(isturf(loc) && amount_grown > 0)
+ if(isturf(loc))
amount_grown += rand(0,2)
if(amount_grown >= 100)
if(!grow_as)
- grow_as = pick(typesof(/mob/living/simple_animal/hostile/giant_spider))
- new grow_as(src.loc)
- del(src)
+ grow_as = pick(typesof(/mob/living/simple_animal/hostile/poison/giant_spider))
+ var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(src.loc)
+ if(player_spiders)
+ var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET)
+ var/client/C = null
+
+ if(candidates.len)
+ C = pick(candidates)
+ S.key = C.key
+ qdel(src)
/obj/effect/decal/cleanable/spiderling_remains
name = "spiderling remains"
@@ -204,11 +213,11 @@
icon_state = "cocoon1"
health = 60
- New()
+/obj/effect/spider/cocoon/New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
/obj/effect/spider/cocoon/Destroy()
- src.visible_message("\red \the [src] splits open.")
+ src.visible_message("\The [src] splits open.")
for(var/atom/movable/A in contents)
A.loc = src.loc
..()
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 7afbe5cd866..f7c42003809 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -605,7 +605,7 @@
user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
if(M.ckey)
- msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG
if(!iscarbon(user))
M.LAssailant = null
diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm
deleted file mode 100644
index 764be72b131..00000000000
--- a/code/game/objects/items/apc_frame.dm
+++ /dev/null
@@ -1,43 +0,0 @@
-// APC HULL
-
-/obj/item/apc_frame
- name = "APC frame"
- desc = "Used for repairing or building APCs"
- icon = 'icons/obj/apc_repair.dmi'
- icon_state = "apc_frame"
- flags = CONDUCT
-
-/obj/item/apc_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- ..()
- if (istype(W, /obj/item/weapon/wrench))
- new /obj/item/stack/sheet/metal( get_turf(src.loc), 2 )
- del(src)
-
-/obj/item/apc_frame/proc/try_build(turf/on_wall)
- if (get_dist(on_wall,usr)>1)
- return
- var/ndir = get_dir(usr,on_wall)
- if (!(ndir in cardinal))
- return
- var/turf/loc = get_turf(usr)
- var/area/A = loc.loc
- if (!istype(loc, /turf/simulated/floor))
- usr << "\red APC cannot be placed on this spot."
- return
- if (A.requires_power == 0 || A.name == "Space")
- usr << "\red APC cannot be placed in this area."
- return
- if (A.get_apc())
- usr << "\red This area already has APC."
- return //only one APC per area
- for(var/obj/machinery/power/terminal/T in loc)
- if (T.master)
- usr << "\red There is another network terminal here."
- return
- else
- var/obj/item/stack/cable_coil/C = new /obj/item/stack/cable_coil(loc)
- C.amount = 10
- usr << "You cut the cables and disassemble the unused power terminal."
- del(T)
- new /obj/machinery/power/apc(loc, ndir, 1)
- del(src)
diff --git a/code/game/objects/items/contraband.dm b/code/game/objects/items/contraband.dm
index d2536da66ec..c82e63cebf2 100644
--- a/code/game/objects/items/contraband.dm
+++ b/code/game/objects/items/contraband.dm
@@ -40,9 +40,9 @@
name = pick("lunar","vorpal","hardcore","willow", "void","loopy","electro", "cyber","heavy", "ninja", "hydro", "blue", "red", "green", "purple", "strong", "divine","carp" ,"deadly","dead","vicious" ,"wild" ,"demon", "chill", "solid", "liquid", "crazy", "super", "hyper", "space", "wizard", "rainbow", "star", "turbo", "prism", "sticky") + " " + pick("jack","zero","null","beat","nip","bubbles" ,"ice","medicine","venom","shock","solar" ,"spice" ,"shredder", "heart" , "heat", "pill","hopper","scum","fruit", "bolt", "deck", "butter", "runoff", "grease", "flair", "sweat", "zone", "blast")
- reagents.add_reagent(pick("pancuronium","neurotoxin","frostoil", "toxin","morphine", "carpotoxin", "hippiesdelight","methamphetamine","haloperidol" ,"cryptobiolin", "hydrocodone", "psilocybin", "mindbreaker", "capsaicin", "space_drugs" , "epinephrine", "serotrotium"), pick(5,7,10,13,15))
- reagents.add_reagent(pick("pancuronium","neurotoxin","frostoil", "toxin","morphine", "carpotoxin", "hippiesdelight","methamphetamine","haloperidol" ,"cryptobiolin", "hydrocodone", "psilocybin", "mindbreaker", "capsaicin", "space_drugs" , "epinephrine", "serotrotium"), pick(5,7,10,13,15))
- reagents.add_reagent(pick("pancuronium","neurotoxin","frostoil", "toxin","morphine", "carpotoxin", "hippiesdelight","methamphetamine","haloperidol" ,"cryptobiolin", "hydrocodone", "psilocybin", "mindbreaker", "capsaicin", "space_drugs" , "epinephrine", "serotrotium"), pick(5,7,10,13,15))
+ reagents.add_reagent(pick("pancuronium","neurotoxin","frostoil", "toxin","morphine", "carpotoxin", "hippiesdelight","methamphetamine","haloperidol" , "hydrocodone", "psilocybin", "lsd", "capsaicin", "space_drugs" , "epinephrine", "serotrotium"), pick(5,7,10,13,15))
+ reagents.add_reagent(pick("pancuronium","neurotoxin","frostoil", "toxin","morphine", "carpotoxin", "hippiesdelight","methamphetamine","haloperidol" ,"hydrocodone", "psilocybin", "lsd", "capsaicin", "space_drugs" , "epinephrine", "serotrotium"), pick(5,7,10,13,15))
+ reagents.add_reagent(pick("pancuronium","neurotoxin","frostoil", "toxin","morphine", "carpotoxin", "hippiesdelight","methamphetamine","haloperidol" , "hydrocodone", "psilocybin", "lsd", "capsaicin", "space_drugs" , "epinephrine", "serotrotium"), pick(5,7,10,13,15))
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index fe8fe4138bd..43fbdea11a5 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -81,4 +81,62 @@
colour = temp
update_window(usr)
else
- ..()
\ No newline at end of file
+ ..()
+
+
+//Spraycan stuff
+
+/obj/item/toy/crayon/spraycan
+ icon_state = "spraycan_cap"
+ desc = "A metallic container containing tasty paint."
+ var/capped = 1
+ instant = 1
+ validSurfaces = list(/turf/simulated/floor,/turf/simulated/wall)
+
+/obj/item/toy/crayon/spraycan/New()
+ ..()
+ name = "NanoTrasen-brand Rapid Paint Applicator"
+ update_icon()
+
+/obj/item/toy/crayon/spraycan/attack_self(mob/living/user as mob)
+ var/choice = input(user,"Spraycan options") in list("Toggle Cap","Change Drawing","Change Color")
+ switch(choice)
+ if("Toggle Cap")
+ user << "You [capped ? "Remove" : "Replace"] the cap of the [src]"
+ capped = capped ? 0 : 1
+ icon_state = "spraycan[capped ? "_cap" : ""]"
+ update_icon()
+ if("Change Drawing")
+ ..()
+ if("Change Color")
+ colour = input(user,"Choose Color") as color
+ update_icon()
+
+/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user as mob, proximity)
+ if(!proximity)
+ return
+ if(capped)
+ return
+ else
+ if(iscarbon(target))
+ if(uses-10 > 0)
+ uses = uses - 10
+ var/mob/living/carbon/human/C = target
+ user.visible_message(" [user] sprays [src] into the face of [target]!")
+ if(C.client)
+ C.eye_blurry = max(C.eye_blurry, 3)
+ C.eye_blind = max(C.eye_blind, 1)
+ if(C.eyecheck() <= 0) // no eye protection? ARGH IT BURNS.
+ C.confused = max(C.confused, 3)
+ C.Weaken(3)
+ C.lip_style = "spray_face"
+ C.lip_color = colour
+ C.update_body()
+ playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
+ ..()
+
+/obj/item/toy/crayon/spraycan/update_icon()
+ overlays.Cut()
+ var/image/I = image('icons/obj/crayons.dmi',icon_state = "[capped ? "spraycan_cap_colors" : "spraycan_colors"]")
+ I.color = colour
+ overlays += I
\ No newline at end of file
diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm
new file mode 100644
index 00000000000..f69e9025637
--- /dev/null
+++ b/code/game/objects/items/dehy_carp.dm
@@ -0,0 +1,43 @@
+/*
+ * Dehydrated Carp
+ * Instant carp, just add water
+ */
+
+// Child of carpplushie because this should do everything the toy does and more
+/obj/item/toy/carpplushie/dehy_carp
+ var/mob/owner = null // Carp doesn't attack owner, set when using in hand
+ var/owned = 1 // Boolean, no owner to begin with
+
+// Attack self
+/obj/item/toy/carpplushie/dehy_carp/attack_self(mob/user as mob)
+ src.add_fingerprint(user) // Anyone can add their fingerprints to it with this
+ if(owned)
+ user << "[src] stares up at you with friendly eyes."
+ owner = user
+ owned = 0
+ return ..()
+
+
+/obj/item/toy/carpplushie/dehy_carp/afterattack(obj/O, mob/user,proximity)
+ if(!proximity) return
+ if(istype(O,/obj/structure/sink))
+ user << "You place [src] under a stream of water..."
+ user.drop_item()
+ loc = get_turf(O)
+ return Swell()
+ ..()
+
+/obj/item/toy/carpplushie/dehy_carp/proc/Swell()
+ desc = "It's growing!"
+ visible_message("[src] swells up!")
+
+ // Animation
+ icon = 'icons/mob/animal.dmi'
+ flick("carp_swell", src)
+ // Wait for animation to end
+ sleep(6)
+ // Make space carp
+ var/mob/living/simple_animal/hostile/carp/C = new /mob/living/simple_animal/hostile/carp(get_turf(src))
+ // Make carp non-hostile to user, yes this means
+ C.faction |= "\ref[owner]"
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 144b920631c..70791bddab2 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -15,7 +15,7 @@
M.attack_log += text("\[[time_stamp()]\] Has been carded with [src.name] by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to card [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to card [M.name] ([M.ckey]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] to card [M.name] ([M.ckey]) (JMP)")
transfer_ai("AICORE", "AICARD", M, user)
return
diff --git a/code/game/objects/items/devices/guitar.dm b/code/game/objects/items/devices/guitar.dm
index c302536ac88..2de509fb8fb 100644
--- a/code/game/objects/items/devices/guitar.dm
+++ b/code/game/objects/items/devices/guitar.dm
@@ -9,6 +9,7 @@
icon_override = 'icons/mob/in-hand/tools.dmi'
force = 10
var/datum/song/handheld/song
+ hitsound = 'sound/effects/guitarsmash.ogg'
/obj/item/device/guitar/New()
song = new("guitar", src)
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index e882adfae23..ee4f96b9230 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -51,7 +51,7 @@
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
bombers += "[key_name(user)] attached a [item] to a transfer valve."
- msg_admin_attack("[key_name_admin(user)] attached [item] to a transfer valve.")
+ msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] attached [item] to a transfer valve.")
log_game("[key_name_admin(user)] attached [item] to a transfer valve.")
attacher = user
nanomanager.update_uis(src) // update all UIs attached to src
diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm
index 47acfb7c132..0efcf5e6f84 100644
--- a/code/game/objects/items/devices/violin.dm
+++ b/code/game/objects/items/devices/violin.dm
@@ -7,6 +7,7 @@
icon_state = "violin"
item_state = "violin"
force = 10
+ hitsound = 'sound/weapons/smash.ogg'
var/datum/song/handheld/song
/obj/item/device/violin/New()
diff --git a/code/game/objects/items/mountable_frames/air_alarm.dm b/code/game/objects/items/mountable_frames/air_alarm.dm
new file mode 100644
index 00000000000..28fe58e567e
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/air_alarm.dm
@@ -0,0 +1,16 @@
+/*
+AIR ALARM ITEM
+Handheld air alarm frame, for placing on walls
+Code shamelessly copied from apc_frame
+*/
+/obj/item/mounted/frame/alarm_frame
+ name = "air alarm frame"
+ desc = "Used for building Air Alarms"
+ icon = 'icons/obj/monitors.dmi'
+ icon_state = "alarm_bitem"
+ m_amt = 2000
+ mount_reqs = list("simfloor", "nospace")
+
+/obj/item/mounted/frame/alarm_frame/do_build(turf/on_wall, mob/user)
+ new /obj/machinery/alarm(get_turf(src), get_dir(on_wall, user), 1)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/items/mountable_frames/apc_frame.dm b/code/game/objects/items/mountable_frames/apc_frame.dm
new file mode 100644
index 00000000000..5e092638707
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/apc_frame.dm
@@ -0,0 +1,29 @@
+/obj/item/mounted/frame/apc_frame
+ name = "APC frame"
+ desc = "Used for repairing or building APCs"
+ icon = 'icons/obj/apc_repair.dmi'
+ icon_state = "apc_frame"
+ mount_reqs = list("simfloor", "nospace")
+
+/obj/item/mounted/frame/apc_frame/try_build(turf/on_wall, mob/user)
+ if(..())
+ var/turf/turf_loc = get_turf(user)
+ var/area/area_loc = turf_loc.loc
+ if (area_loc.get_apc())
+ user << "This area already has an APC."
+ return //only one APC per area
+ for(var/obj/machinery/power/terminal/T in turf_loc)
+ if (T.master)
+ user << "There is another network terminal here."
+ return
+ else
+ var/obj/item/stack/cable_coil/C = new /obj/item/stack/cable_coil(turf_loc)
+ C.amount = 10
+ user << "You cut the cables and disassemble the unused power terminal."
+ qdel(T)
+ return 1
+ return
+
+/obj/item/mounted/frame/apc_frame/do_build(turf/on_wall, mob/user)
+ new /obj/machinery/power/apc(get_turf(src), get_dir(user, on_wall), 1)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/items/mountable_frames/fire_alarm.dm b/code/game/objects/items/mountable_frames/fire_alarm.dm
new file mode 100644
index 00000000000..ceec9b7c716
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/fire_alarm.dm
@@ -0,0 +1,10 @@
+/obj/item/mounted/frame/firealarm
+ name = "fire alarm frame"
+ desc = "Used for building Fire Alarms"
+ icon = 'icons/obj/monitors.dmi'
+ icon_state = "fire_bitem"
+ mount_reqs = list("simfloor", "nospace")
+
+/obj/item/mounted/frame/firealarm/do_build(turf/on_wall, mob/user)
+ new /obj/machinery/firealarm(get_turf(src), get_dir(on_wall, user), 1)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/items/mountable_frames/frames.dm b/code/game/objects/items/mountable_frames/frames.dm
new file mode 100644
index 00000000000..f8d097be795
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/frames.dm
@@ -0,0 +1,25 @@
+/obj/item/mounted/frame
+ name = "mountable frame"
+ desc = "Place it on a wall."
+ var/sheets_refunded = 2
+ var/list/mount_reqs = list() //can contain simfloor, nospace. Used in try_build to see if conditions are needed, then met
+
+/obj/item/mounted/frame/attackby(obj/item/weapon/W, mob/user)
+ ..()
+ if (istype(W, /obj/item/weapon/wrench) && sheets_refunded)
+ //new /obj/item/stack/sheet/metal( get_turf(src.loc), sheets_refunded )
+ var/obj/item/stack/sheet/metal/M = getFromPool(/obj/item/stack/sheet/metal, get_turf(src))
+ M.amount = sheets_refunded
+ qdel(src)
+
+/obj/item/mounted/frame/try_build(turf/on_wall, mob/user)
+ if(..()) //if we pass the parent tests
+ var/turf/turf_loc = get_turf(user)
+
+ if (src.mount_reqs.Find("simfloor") && !istype(turf_loc, /turf/simulated/floor))
+ user << "[src] cannot be placed on this spot."
+ return
+ if (src.mount_reqs.Find("nospace") && (areaMaster.requires_power == 0 || areaMaster.name == "Space"))
+ user << "[src] cannot be placed in this area."
+ return
+ return 1
\ No newline at end of file
diff --git a/code/game/objects/items/mountable_frames/lights.dm b/code/game/objects/items/mountable_frames/lights.dm
new file mode 100644
index 00000000000..cb264794f6b
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/lights.dm
@@ -0,0 +1,39 @@
+/obj/item/mounted/frame/light_fixture
+ name = "light fixture frame"
+ desc = "Used for building lights."
+ icon = 'icons/obj/lighting.dmi'
+ icon_state = "tube-construct-item"
+ var/fixture_type = "tube"
+ mount_reqs = list("simfloor")
+
+/obj/item/mounted/frame/light_fixture/do_build(turf/on_wall, mob/user)
+ user << "You begin attaching [src] to \the [on_wall]."
+ playsound(get_turf(src), 'sound/machines/click.ogg', 75, 1)
+ var/constrdir = user.dir
+ var/constrloc = get_turf(user)
+ if (!do_after(user, 30))
+ return
+ var/obj/machinery/light_construct/newlight
+ switch(fixture_type)
+ if("bulb")
+ newlight = new /obj/machinery/light_construct/small(constrloc)
+ if("tube")
+ newlight = new /obj/machinery/light_construct(constrloc)
+ else
+ newlight = new /obj/machinery/light_construct/small(constrloc)
+ newlight.dir = constrdir
+ newlight.fingerprints = src.fingerprints
+ newlight.fingerprintshidden = src.fingerprintshidden
+ newlight.fingerprintslast = src.fingerprintslast
+
+ user.visible_message("[user] attaches \the [src] to \the [on_wall].", \
+ "You attach \the [src] to \the [on_wall].")
+ qdel(src)
+
+/obj/item/mounted/frame/light_fixture/small
+ name = "small light fixture frame"
+ desc = "Used for building small lights."
+ icon = 'icons/obj/lighting.dmi'
+ icon_state = "bulb-construct-item"
+ fixture_type = "bulb"
+ sheets_refunded = 1
\ No newline at end of file
diff --git a/code/game/objects/items/mountable_frames/mountables.dm b/code/game/objects/items/mountable_frames/mountables.dm
new file mode 100644
index 00000000000..e280b8e0cc3
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/mountables.dm
@@ -0,0 +1,34 @@
+/obj/item/mounted
+ var/list/buildon_types = list(/turf/simulated/wall)
+
+
+/obj/item/mounted/afterattack(var/atom/A, mob/user, proximity_flag)
+ var/found_type = 0
+ for(var/turf_type in src.buildon_types)
+ if(istype(A, turf_type))
+ found_type = 1
+ break
+
+ if(found_type)
+ if(try_build(A, user, proximity_flag))
+ return do_build(A, user)
+ else
+ ..()
+
+/obj/item/mounted/proc/try_build(turf/on_wall, mob/user, proximity_flag) //checks
+ if(!on_wall || !user)
+ return
+ if (proximity_flag != 1) //if we aren't next to the wall
+ return
+ if (!( get_dir(on_wall,user) in cardinal))
+ user << "You need to be standing next to a wall to place \the [src]."
+ return
+
+ if(gotwallitem(get_turf(user), get_dir(on_wall,user)))
+ user << "There's already an item on this wall!"
+ return
+
+ return 1
+
+/obj/item/mounted/proc/do_build(turf/on_wall, mob/user) //the buildy bit after we pass the checks
+ return
diff --git a/code/game/objects/items/mountable_frames/newscaster_frame.dm b/code/game/objects/items/mountable_frames/newscaster_frame.dm
new file mode 100644
index 00000000000..f853bbadf66
--- /dev/null
+++ b/code/game/objects/items/mountable_frames/newscaster_frame.dm
@@ -0,0 +1,32 @@
+/obj/item/mounted/frame/newscaster_frame
+ name = "newscaster frame"
+ desc = "Used to build newscasters, just secure to the wall."
+ icon_state = "newscaster"
+ item_state = "syringe_kit"
+ m_amt = 14000
+ g_amt = 8000
+ mount_reqs = list("simfloor", "nospace")
+
+/obj/item/mounted/frame/newscaster_frame/try_build(turf/on_wall, mob/user)
+ if(..())
+ var/turf/loc = get_turf(usr)
+ var/area/A = loc.loc
+ if (!istype(loc, /turf/simulated/floor))
+ usr << "Newscaster cannot be placed on this spot."
+ return
+ if (A.requires_power == 0 || A.name == "Space")
+ usr << "Newscaster cannot be placed in this area."
+ return
+
+ for(var/obj/machinery/newscaster/T in loc)
+ usr << "There is another newscaster here."
+ return
+
+ return 1
+ return
+
+/obj/item/mounted/frame/newscaster_frame/do_build(turf/on_wall, mob/user)
+ var/obj/machinery/newscaster/N = new /obj/machinery/newscaster(get_turf(src), get_dir(on_wall, user), 1)
+ N.pixel_y -= (loc.y - on_wall.y) * 32
+ N.pixel_x -= (loc.x - on_wall.x) * 32
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm
index c265dc20324..0bbd8ba35aa 100644
--- a/code/game/objects/items/random_items.dm
+++ b/code/game/objects/items/random_items.dm
@@ -61,7 +61,7 @@
// identify_probability = 0
New()
..()
- var/global/list/chems_only = list("slimejelly","blood","water","lube","charcoal","toxin","cyanide","morphine","epinephrine","space_drugs","serotrotium","oxygen","copper","nitrogen","hydrogen","potassium","mercury","sulfur","carbon","chlorine","fluorine","sodium","phosphorus","lithium","sugar","sacid","facid","glycerol","radium","mutadone","thermite","mutagen","virusfood","iron","gold","silver","uranium","aluminum","silicon","fuel","cleaner","atrazine","plasma","teporone","cryptobiolin","lexorin","silver_sulfadiazine","salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide","pen_acid","mannitol","oculine","styptic_powder","methamphetamine","cryoxadone","clonexadone","spaceacillin","carpotoxin","mindbreaker","fluorosurfactant","fluorosurfactant","ethanol","ammonia","diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin","enzyme","nothing","salglu_solution","antifreeze","neurotoxin")
+ var/global/list/chems_only = list("slimejelly","blood","water","lube","charcoal","toxin","cyanide","morphine","epinephrine","space_drugs","serotrotium","oxygen","copper","nitrogen","hydrogen","potassium","mercury","sulfur","carbon","chlorine","fluorine","sodium","phosphorus","lithium","sugar","sacid","facid","glycerol","radium","mutadone","thermite","mutagen","virusfood","iron","gold","silver","uranium","aluminum","silicon","fuel","cleaner","atrazine","plasma","teporone","lexorin","silver_sulfadiazine","salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide","pen_acid","mannitol","oculine","styptic_powder","methamphetamine","cryoxadone","clonexadone","spaceacillin","carpotoxin","mindbreaker","fluorosurfactant","fluorosurfactant","ethanol","ammonia","diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin","enzyme","nothing","salglu_solution","antifreeze","neurotoxin")
var/global/list/rare_chems = list("minttoxin","nanites","xenomicrobes","adminordrazine")
var/datum/reagent/R = pick(chems_only + rare_chems)
@@ -123,7 +123,7 @@
New()
..()
- var/global/list/meds_only = list("charcoal","toxin","cyanide","morphine","epinephrine","space_drugs","serotrotium","mutadone","mutagen","teporone","cryptobiolin","lexorin","silver_sulfadiazine","salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide","pen_acid","mannitol","oculine","styptic_powder","methamphetamine","spaceacillin","carpotoxin","mindbreaker","ethanol","ammonia","diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin","nothing","salglu_solution","neurotoxin")
+ var/global/list/meds_only = list("charcoal","toxin","cyanide","morphine","epinephrine","space_drugs","serotrotium","mutadone","mutagen","teporone","lexorin","silver_sulfadiazine","salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide","pen_acid","mannitol","oculine","styptic_powder","methamphetamine","spaceacillin","carpotoxin","mindbreaker","ethanol","ammonia","diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin","nothing","salglu_solution","neurotoxin")
var/global/list/rare_meds = list("nanites","xenomicrobes","minttoxin","adminordrazine","blood")
var/i = 1
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 8371dde6416..d8baba60d41 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -13,7 +13,7 @@
M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
if(M.ckey)
- msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] to attack [M.name] ([M.ckey]) (JMP)")
if(!iscarbon(user))
M.LAssailant = null
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 69ab0899003..66dd12bf0b9 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -28,6 +28,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
), 2), \
null, \
new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts, 2), \
+ new/datum/stack_recipe("glass table frame parts", /obj/item/weapon/table_parts/glass, 2), \
new/datum/stack_recipe("rack parts", /obj/item/weapon/rack_parts), \
new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1), \
null, \
@@ -63,12 +64,12 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
), 4), \
null, \
new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade), \
- new/datum/stack_recipe("light fixture frame", /obj/item/light_fixture_frame, 2), \
- new/datum/stack_recipe("small light fixture frame", /obj/item/light_fixture_frame/small, 1), \
+ new/datum/stack_recipe("light fixture frame", /obj/item/mounted/frame/light_fixture, 2), \
+ new/datum/stack_recipe("small light fixture frame", /obj/item/mounted/frame/light_fixture/small, 1), \
null, \
- new/datum/stack_recipe("apc frame", /obj/item/apc_frame, 2), \
- new/datum/stack_recipe("air alarm frame", /obj/item/alarm_frame, 2), \
- new/datum/stack_recipe("fire alarm frame", /obj/item/firealarm_frame, 2), \
+ new/datum/stack_recipe("apc frame", /obj/item/mounted/frame/apc_frame, 2), \
+ new/datum/stack_recipe("air alarm frame", /obj/item/mounted/frame/alarm_frame, 2), \
+ new/datum/stack_recipe("fire alarm frame", /obj/item/mounted/frame/firealarm, 2), \
null, \
)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 84538d70327..6386a2f1292 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -451,6 +451,7 @@
var/instant = 0
var/colourName = "red" //for updateIcon purposes
var/dat
+ var/list/validSurfaces = list(/turf/simulated/floor)
/obj/item/toy/crayon/suicide_act(mob/user)
user.visible_message("[user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide.")
@@ -497,7 +498,7 @@
if("random_letter")
temp = pick(letters)
if("letter")
- temp = input("Choose the letter.", "Crayon scribbles") in letters
+ temp = input("Choose the letter.", "Scribbles") in letters
if("random_rune")
temp = "rune[rand(1,6)]"
if("random_graffiti")
@@ -511,7 +512,7 @@
/obj/item/toy/crayon/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
- if(istype(target,/turf/simulated/floor))
+ if(is_type_in_list(target,validSurfaces))
var/temp = "rune"
if(letters.Find(drawtype))
temp = "letter"
@@ -524,18 +525,19 @@
if(uses)
uses--
if(!uses)
- user << "You used up your crayon!"
+ user << "You used up your [src.name]!"
qdel(src)
return
/obj/item/toy/crayon/attack(mob/M as mob, mob/user as mob)
+ var/huffable = istype(src,/obj/item/toy/crayon/spraycan)
if(M == user)
- user << "You take a bite of the crayon. Delicious!"
+ user << "You take a [huffable ? "huff" : "bite"] of the [src.name]. Delicious!"
user.nutrition += 5
if(uses)
uses -= 5
if(uses <= 0)
- user << "You ate your crayon!"
+ user << "There is no more of [src.name] left!"
qdel(src)
else
..()
@@ -1187,14 +1189,15 @@ obj/item/toy/cards/deck/syndicate/black
desc = "An adorable stuffed toy that resembles a space carp."
icon = 'icons/obj/toy.dmi'
icon_state = "carpplushie"
- attack_verb = list("bit", "ate", "fin slapped")
+ attack_verb = list("bitten", "eaten", "fin slapped")
var/bitesound = 'sound/weapons/bite.ogg'
- w_class = 2.0
-/obj/item/toy/carpplushie/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+// Attack mob
+/obj/item/toy/carpplushie/attack(mob/M as mob, mob/user as mob)
playsound(loc, bitesound, 20, 1) // Play bite sound in local area
return ..()
+// Attack self
/obj/item/toy/carpplushie/attack_self(mob/user as mob)
playsound(src.loc, bitesound, 20, 1)
return ..()
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index 5ebe282547f..d26e8c5a408 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -7,35 +7,38 @@
var/colour = "red"
var/open = 0
-
/obj/item/weapon/lipstick/purple
name = "purple lipstick"
colour = "purple"
/obj/item/weapon/lipstick/jade
+ //It's still called Jade, but theres no HTML color for jade, so we use lime.
name = "jade lipstick"
- colour = "jade"
+ colour = "lime"
/obj/item/weapon/lipstick/black
name = "black lipstick"
colour = "black"
-
/obj/item/weapon/lipstick/random
name = "lipstick"
/obj/item/weapon/lipstick/random/New()
- colour = pick("red","purple","jade","black")
+ colour = pick("red","purple","lime","black","green","blue","white")
name = "[colour] lipstick"
/obj/item/weapon/lipstick/attack_self(mob/user as mob)
+ overlays.Cut()
user << "You twist \the [src] [open ? "closed" : "open"]."
open = !open
if(open)
- icon_state = "[initial(icon_state)]_[colour]"
+ var/image/colored = image("icon"='icons/obj/items.dmi', "icon_state"="lipstick_uncap_color")
+ colored.color = colour
+ icon_state = "lipstick_uncap"
+ overlays += colored
else
- icon_state = initial(icon_state)
+ icon_state = "lipstick"
/obj/item/weapon/lipstick/attack(mob/M as mob, mob/user as mob)
if(!open) return
@@ -50,7 +53,8 @@
if(H == user)
user.visible_message("[user] does their lips with \the [src].", \
"You take a moment to apply \the [src]. Perfect!")
- H.lip_style = colour
+ H.lip_style = "lipstick"
+ H.lip_color = colour
H.update_body()
else
user.visible_message("[user] begins to do [H]'s lips with \the [src].", \
@@ -58,33 +62,12 @@
if(do_after(user, 20) && do_after(H, 20, 5, 0)) //user needs to keep their active hand, H does not.
user.visible_message("[user] does [H]'s lips with \the [src].", \
"You apply \the [src].")
- H.lip_style = colour
+ H.lip_style = "lipstick"
+ H.lip_color = colour
H.update_body()
else
user << "Where are the lips on that?"
-//you can wipe off lipstick with paper!
-/obj/item/weapon/paper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(user.zone_sel.selecting == "mouth")
- if(!istype(M, /mob)) return
-
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H == user)
- user << "You wipe off the lipstick with [src]."
- H.lip_style = null
- H.update_body()
- else
- user.visible_message("[user] begins to wipe [H]'s lipstick off with \the [src].", \
- "You begin to wipe off [H]'s lipstick.")
- if(do_after(user, 10) && do_after(H, 10, 5, 0)) //user needs to keep their active hand, H does not.
- user.visible_message("[user] wipes [H]'s lipstick off with \the [src].", \
- "You wipe off [H]'s lipstick.")
- H.lip_style = null
- H.update_body()
- else
- ..()
-
/obj/item/weapon/razor
name = "electric razor"
desc = "The latest and greatest power razor born from the science of shaving."
diff --git a/code/game/objects/items/weapons/grenades.dm b/code/game/objects/items/weapons/grenades.dm
index 8457afa0e36..74d2038edb7 100644
--- a/code/game/objects/items/weapons/grenades.dm
+++ b/code/game/objects/items/weapons/grenades.dm
@@ -59,7 +59,7 @@
var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)
B1.reagents.add_reagent("space_drugs", 25)
- B1.reagents.add_reagent("mindbreaker", 25)
+ B1.reagents.add_reagent("lsd", 25)
B1.reagents.add_reagent("potassium", 25)
B2.reagents.add_reagent("phosphorus", 25)
B2.reagents.add_reagent("sugar", 25)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index fc1177fca3b..9b5c0324e77 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -89,7 +89,7 @@
update_icon()
else if(clown_check(user))
// This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it.
- var/log_str = "[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP)."
+ var/log_str = "[key_name(usr)][isAntag(usr) ? "(ANTAG)" : ""]? has primed a [name] for detonation at [A.name] (JMP)."
msg_admin_attack(log_str)
log_game(log_str)
bombers += "[log_str]"
@@ -137,7 +137,7 @@
contained = "\[[contained]\]"
var/turf/bombturf = get_turf(loc)
var/area/A = bombturf.loc
- var/log_str = "[key_name(usr)]? has completed [name] at [A.name] (JMP) [contained]."
+ var/log_str = "[key_name(usr)][isAntag(usr) ? "(ANTAG)" : ""]? has completed [name] at [A.name] (JMP) [contained]."
msg_admin_attack(log_str)
log_game(log_str)
else
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 2e9c8dd64ed..fb9bc8d0ab6 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -62,7 +62,7 @@
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- var/log_str = "[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP)."
+ var/log_str = "[key_name(usr)][isAntag(usr) ? "(ANTAG)" : ""]? has primed a [name] for detonation at [A.name] (JMP)."
msg_admin_attack(log_str)
log_game(log_str)
bombers += "[log_str]"
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
index 0f7609ed24e..a32f7d6d152 100644
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ b/code/game/objects/items/weapons/hydroponics.dm
@@ -198,7 +198,7 @@
M.attack_log += text("\[[time_stamp()]\] Had the [src.name] used on them by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] on [M.name] ([M.ckey]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] on [M.name] ([M.ckey]) (JMP)")
if(!iscarbon(user))
M.LAssailant = null
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index 79942234741..7e9b207ea4b 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -34,7 +34,7 @@
M.attack_log += text("\[[time_stamp()]\] Implanted with [src.name] ([src.imp.name]) by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] ([src.imp.name]) to implant [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) implanted [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] implanted [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
user.show_message("\red You implanted the implant into [M].")
if(src.imp.implanted(M, user))
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index a898fa55066..aa35239fc9a 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -177,6 +177,15 @@
src.add_fingerprint(user)
return
+//Syndie variant of Secure Briefcase. Contains space cash, slightly more robust.
+/obj/item/weapon/storage/secure/briefcase/syndie
+ force = 15.0
+
+/obj/item/weapon/storage/secure/briefcase/syndie/New()
+ for(var/i = 0, i < storage_slots - 2, i++)
+ new /obj/item/weapon/spacecash/c1000(src)
+ return ..()
+
// -----------------------------
// Secure Safe
// -----------------------------
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 5999b5576e0..d46088a6647 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -138,6 +138,17 @@
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
return
+/obj/item/weapon/storage/box/syndie_kit/hardsuit
+ name = "Boxed Blood Red Suit and Helmet"
+ can_hold = list(/obj/item/clothing/suit/space/rig/syndi, /obj/item/clothing/head/helmet/space/rig/syndi)
+ max_w_class = 3
+
+/obj/item/weapon/storage/box/syndie_kit/hardsuit/New()
+ ..()
+ new /obj/item/clothing/suit/space/rig/syndi(src)
+ new /obj/item/clothing/head/helmet/space/rig/syndi(src)
+ return
+
/obj/item/weapon/storage/box/syndie_kit/conversion
name = "box (CK)"
diff --git a/code/game/objects/items/weapons/table_rack_parts.dm b/code/game/objects/items/weapons/table_rack_parts.dm
index 2c2b44ae387..03a07d4a2d1 100644
--- a/code/game/objects/items/weapons/table_rack_parts.dm
+++ b/code/game/objects/items/weapons/table_rack_parts.dm
@@ -62,6 +62,21 @@
del(src)
return
+/*
+ * Glass Table Parts
+ */
+/obj/item/weapon/table_parts/glass/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+ if (istype(W, /obj/item/weapon/wrench))
+ new /obj/item/stack/sheet/metal( user.loc )
+ new /obj/item/stack/sheet/metal( user.loc )
+ del(src)
+
+/obj/item/weapon/table_parts/glass/attack_self(mob/user as mob)
+ new /obj/structure/glasstable_frame( user.loc )
+ user.drop_item()
+ del(src)
+ return
+
/*
* Rack Parts
*/
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 5f82bd20aef..761b445d7ee 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -256,7 +256,7 @@
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
else if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1 && src.welding)
- msg_admin_attack("[key_name_admin(user)] triggered a fueltank explosion.")
+ msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] triggered a fueltank explosion.")
log_game("[key_name(user)] triggered a fueltank explosion.")
user << "\red That was stupid of you."
var/obj/structure/reagent_dispensers/fueltank/tank = O
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index 2b9424dd594..7909019481e 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -355,6 +355,59 @@ obj/item/weapon/twohanded/
desc = "A spear brought over from the Kidan homeworld."
+///CHAINSAW///
+
+/obj/item/weapon/twohanded/chainsaw
+ icon_override = 'icons/mob/in-hand/swords.dmi'
+ icon_state = "chainsaw0"
+ name = "Chainsaw"
+ desc = "Perfect for felling trees or fellow spaceman."
+ force = 15
+ throwforce = 15
+ throw_speed = 1
+ throw_range = 5
+ w_class = 4.0 // can't fit in backpacks
+ force_unwielded = 15 //still pretty robust
+ force_wielded = 50 //you'll gouge their eye out! Or a limb...maybe even their entire body!
+ wieldsound = 'sound/weapons/chainsawstart.ogg'
+ hitsound = null
+ flags = NOSHIELD
+ origin_tech = "materials=6;syndicate=4"
+ attack_verb = list("sawed", "cut", "hacked", "carved", "cleaved", "butchered", "felled", "timbered")
+ sharp = 1
+ edge = 1
+ no_embed = 1
+
+
+/obj/item/weapon/twohanded/chainsaw/update_icon()
+ if(wielded)
+ icon_state = "chainsaw[wielded]"
+ else
+ icon_state = "chainsaw0"
+
+
+/obj/item/weapon/twohanded/chainsaw/attack(mob/target as mob, mob/living/user as mob)
+ if(wielded)
+ playsound(loc, 'sound/weapons/chainsaw.ogg', 100, 1, -1) //incredibly loud; you ain't goin' for stealth with this thing. Credit to Lonemonk of Freesound for this sound.
+ if(isrobot(target))
+ ..()
+ return
+ if(!isliving(target))
+ return
+ else
+ target.Weaken(4)
+ ..()
+ return
+ else
+ playsound(loc, "swing_hit", 50, 1, -1)
+ return ..()
+
+/obj/item/weapon/twohanded/chainsaw/IsShield() //Disarming someone with a chainsaw should be difficult.
+ if(wielded)
+ return 1
+ else
+ return 0
+
// SINGULOHAMMER
/obj/item/weapon/twohanded/singularityhammer
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index d63f07d4e06..91e8d1259be 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -41,7 +41,7 @@
else
M.LAssailant = user
- msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!"
diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm
index f9e49fcc40b..fd0c12f00c0 100644
--- a/code/game/objects/structures/electricchair.dm
+++ b/code/game/objects/structures/electricchair.dm
@@ -1,15 +1,24 @@
-
/obj/structure/stool/bed/chair/e_chair
name = "electric chair"
desc = "Looks absolutely SHOCKING!"
icon_state = "echair0"
- var/on = 0
var/obj/item/assembly/shock_kit/part = null
var/last_time = 1.0
+ var/delay_time = 50
/obj/structure/stool/bed/chair/e_chair/New()
..()
overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir)
+ spawn(2)
+ if(isnull(part)) //This e-chair was not custom built
+ part = new(src)
+ var/obj/item/clothing/head/helmet/part1 = new(part)
+ var/obj/item/device/radio/electropack/part2 = new(part)
+ part2.frequency = 1445
+ part2.code = 6
+ part2.master = part
+ part.part1 = part1
+ part.part2 = part2
return
/obj/structure/stool/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
@@ -24,20 +33,17 @@
return
return
-/obj/structure/stool/bed/chair/e_chair/verb/toggle()
- set name = "Toggle Electric Chair"
+/obj/structure/stool/bed/chair/e_chair/verb/activate_e_chair()
+ set name = "Activate Electric Chair"
set category = "Object"
set src in oview(1)
if(usr.stat || !usr.canmove || usr.restrained())
return
- if(on)
- on = 0
- icon_state = "echair0"
- else
- on = 1
- icon_state = "echair1"
- shock()
- usr << "You switch [on ? "on" : "off"] [src]."
+ if(last_time + delay_time > world.time)
+ usr << "\The [src] is not ready yet!"
+ return
+ usr << "You activate \the [src]."
+ shock()
return
/obj/structure/stool/bed/chair/e_chair/rotate()
@@ -47,34 +53,36 @@
return
/obj/structure/stool/bed/chair/e_chair/proc/shock()
- if(!on)
- return
- if(last_time + 50 > world.time)
+ if(last_time + delay_time > world.time)
return
last_time = world.time
+ icon_state = "echair1"
+ spawn(delay_time)
+ icon_state = "echair0"
+
// special power handling
var/area/A = get_area(src)
if(!isarea(A))
return
if(!A.powered(EQUIP))
return
- A.use_power(EQUIP, 5000)
+ A.use_power(5000, EQUIP)
var/light = A.power_light
A.updateicon()
- flick("echair1", src)
+ flick("echair_shock", src)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(12, 1, src)
s.start()
+ visible_message("The electric chair went off!", "You hear a deep sharp shock!")
if(buckled_mob)
- buckled_mob.burn_skin(85)
+ buckled_mob.burn_skin(90)
buckled_mob << "You feel a deep shock course through your body!"
sleep(1)
- buckled_mob.burn_skin(85)
- buckled_mob.Stun(600)
- on = 0
- visible_message("The electric chair went off!", "You hear a deep sharp shock!")
+ buckled_mob.burn_skin(90)
+ sleep(5)
+ buckled_mob.burn_skin(max(rand(5,20),rand(5,20),rand(5,20)))
A.power_light = light
A.updateicon()
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 118016cceeb..334086d5f36 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -136,12 +136,12 @@
if(propelled || (pulling && (pulling.a_intent == "harm")))
var/mob/living/occupant = buckled_mob
unbuckle()
-
+
if (pulling && (pulling.a_intent == "hurt"))
occupant.throw_at(A, 3, 3, pulling)
else if (propelled)
occupant.throw_at(A, 3, propelled)
-
+
occupant.apply_effect(6, STUN, 0)
occupant.apply_effect(6, WEAKEN, 0)
occupant.apply_effect(6, STUTTER, 0)
@@ -157,7 +157,7 @@
pulling.attack_log += "\[[time_stamp()]\] Crashed [occupant.name]'s ([occupant.ckey]) [name] into \a [A]"
occupant.attack_log += "\[[time_stamp()]\] Thrusted into \a [A] by [pulling.name] ([pulling.ckey]) with \the [name]"
- msg_admin_attack("[pulling.name] ([pulling.ckey]) has thrusted [occupant.name]'s ([occupant.ckey]) [name] into \a [A] (JMP)")
+ msg_admin_attack("[pulling.name] ([pulling.ckey])[isAntag(pulling) ? "(ANTAG)" : ""] has thrusted [occupant.name]'s ([occupant.ckey]) [name] into \a [A] (JMP)")
else
occupant.visible_message("[occupant] crashed into \the [A]!")
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 46558088bc8..814fe2fc07e 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -237,6 +237,22 @@
icon_state = "wood_tabledir2"
if(6)
icon_state = "wood_tabledir3"
+ else if(istype(src,/obj/structure/table/glass))
+ switch(table_type)
+ if(0)
+ icon_state = "glass_table"
+ if(1)
+ icon_state = "glass_table_1tileendtable"
+ if(2)
+ icon_state = "glass_table_1tilethick"
+ if(3)
+ icon_state = "glass_table_dir"
+ if(4)
+ icon_state = "glass_table_middle"
+ if(5)
+ icon_state = "glass_tabledir2"
+ if(6)
+ icon_state = "glass_tabledir3"
else
switch(table_type)
if(0)
@@ -668,6 +684,113 @@
return 1
+/obj/structure/glasstable_frame
+ name = "glass table frame"
+ desc = "A metal frame for a glass table."
+ icon = 'icons/obj/structures.dmi'
+ icon_state = "glass_table_frame"
+ density = 1
+
+/obj/structure/glasstable_frame/attackby(obj/item/I as obj, mob/user as mob, params)
+ if(istype(I, /obj/item/stack/sheet/glass))
+ var/obj/item/stack/sheet/glass/G = I
+ if(G.amount >= 2)
+ user << "You start to add the glass to \the [src]."
+ if(do_after(user, 10))
+ G.use(2)
+ user << "You add the glass to \the [src]."
+ playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ new /obj/structure/table/glass(loc)
+ del(src)
+ else
+ user << "You don't have enough glass! You need at least 2 sheets."
+ return
+
+ if(iswrench(I))
+ user << "You start to deconstruct \the [src]."
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
+ if(do_after(user, 10))
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1)
+ user << "You dismantle \the [src]."
+ new /obj/item/stack/sheet/metal(loc)
+ new /obj/item/stack/sheet/metal(loc)
+ del(src)
+
+/obj/structure/table/glass
+ name = "glass table"
+ desc = "Looks fragile. You should totally flip it. It is begging for it."
+ icon_state = "glass_table"
+ parts = /obj/item/weapon/table_parts/glass
+ health = 10
+
+/obj/structure/table/glass/flip(var/direction)
+ src.collapse()
+
+/obj/structure/table/glass/proc/collapse() //glass table collapse is called twice in this code, more efficent to just have a proc
+ src.visible_message("\The [src] shatters, and the frame collapses!", "You hear metal collapsing and glass shattering.")
+ new /obj/item/weapon/table_parts/glass(loc)
+ getFromPool(/obj/item/weapon/shard, loc)
+ if(prob(50)) //50% chance to spawn two shards
+ getFromPool(/obj/item/weapon/shard, loc)
+ qdel(src)
+
+/obj/structure/table/glass/attackby(obj/item/I as obj, mob/user as mob, params)
+
+ if (istype(I, /obj/item/weapon/grab))
+ var/obj/item/weapon/grab/G = I
+ if(G.affecting.buckled)
+ user << "[G.affecting] is buckled to [G.affecting.buckled]!"
+ return
+ if(G.state < GRAB_AGGRESSIVE)
+ user << "You need a better grip to do that!"
+ return
+ if(!G.confirm())
+ return
+ G.affecting.loc = src.loc
+ G.affecting.Weaken(7)
+ visible_message("[G.assailant] smashes [G.affecting] onto \the [src]!")
+ del(I)
+ src.collapse()
+ return
+
+ if (istype(I, /obj/item/weapon/wrench))
+ user << "\blue Now disassembling the glass table"
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ sleep(50)
+ new /obj/item/weapon/table_parts/glass( src.loc )
+ new /obj/item/stack/sheet/glass( src.loc )
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ del(src)
+ return
+
+ if(isrobot(user))
+ return
+ if(istype(I, /obj/item/weapon/melee/energy/blade))
+ var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, src.loc)
+ spark_system.start()
+ playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(src.loc, "sparks", 50, 1)
+ for(var/mob/O in viewers(user, 4))
+ O.show_message("\The [src] was sliced apart by [user]!", 1, "You hear glass being sliced apart.", 2)
+ new /obj/item/weapon/table_parts/glass( src.loc )
+ new /obj/item/stack/sheet/glass( src.loc )
+ del(src)
+ return
+
+ if(!(I.flags & ABSTRACT))
+ if(user.drop_item())
+ I.Move(loc)
+ var/list/click_params = params2list(params)
+ //Center the icon where the user clicked.
+ if(!click_params || !click_params["icon-x"] || !click_params["icon-y"])
+ return
+ //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
+ I.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
+ I.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
+
+ return 1
+
/*
* Reinforced tables
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 244be08e426..568f4d45e9a 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -135,7 +135,7 @@ var/global/wcColored
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
if(M)
- msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [M.real_name] ([formatPlayerPanel(M,M.ckey)])!")
+ msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [M.real_name][isAntag(M) ? "(ANTAG)" : ""] ([formatPlayerPanel(M,M.ckey)])!")
log_admin("Window with pdiff [pdiff] at [loc] deanchored by [M.real_name] ([M.ckey])!")
else
msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [AM]!")
@@ -144,7 +144,7 @@ var/global/wcColored
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
if(M)
- msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [M.real_name] ([formatPlayerPanel(M,M.ckey)])!")
+ msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [M.real_name][isAntag(M) ? "(ANTAG)" : ""] ([formatPlayerPanel(M,M.ckey)])!")
log_admin("Window with pdiff [pdiff] at [loc] destroyed by [M.real_name] ([M.ckey])!")
else
msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [AM]!")
@@ -158,7 +158,7 @@ var/global/wcColored
user.visible_message("[user] smashes through [src]!")
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
- msg_admin_attack("Window destroyed by hulk [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!")
+ msg_admin_attack("Window destroyed by hulk [user.real_name][isAntag(user) ? "(ANTAG)" : ""] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!")
log_admin("Window destroyed by hulk [user.real_name] ([user.ckey]) with pdiff [pdiff] at [loc]!")
destroy()
else if (usr.a_intent == "harm")
@@ -187,7 +187,7 @@ var/global/wcColored
user.visible_message("[user] smashes through [src]!")
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
- msg_admin_attack("Window destroyed by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!")
+ msg_admin_attack("Window destroyed by [user.real_name][isAntag(user) ? "(ANTAG)" : ""] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!")
destroy()
else //for nicer text~
user.visible_message("[user] smashes into [src]!")
@@ -258,7 +258,7 @@ var/global/wcColored
if(!anchored)
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
- msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!")
+ msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name][isAntag(user) ? "(ANTAG)" : ""] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!")
log_admin("Window with pdiff [pdiff] deanchored by [user.real_name] ([user.ckey]) at [loc]!")
else if(!reinf)
anchored = !anchored
@@ -268,7 +268,7 @@ var/global/wcColored
if(!anchored)
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
- msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!")
+ msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name][isAntag(user) ? "(ANTAG)" : ""] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!")
log_admin("Window with pdiff [pdiff] deanchored by [user.real_name] ([user.ckey]) at [loc]!")
else if(istype(W, /obj/item/weapon/crowbar) && reinf && state <= 1)
state = 1 - state
@@ -310,7 +310,7 @@ var/global/wcColored
step(src, get_dir(user, src))
var/pdiff=performWallPressureCheck(src.loc)
if(pdiff>0)
- msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!")
+ msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name][isAntag(user) ? "(ANTAG)" : ""] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!")
log_admin("Window with pdiff [pdiff] deanchored by [user.real_name] ([user.ckey]) at [loc]!")
else
playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 8c5b9018c30..6a763055b3b 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -451,46 +451,9 @@
O.show_message("The wall was sliced apart by [user]!", 1, "You hear metal being sliced apart and sparks flying.", 2)
return
- else if(istype(W,/obj/item/apc_frame))
- var/obj/item/apc_frame/AH = W
- AH.try_build(src)
+ else if(istype(W,/obj/item/mounted)) //if we place it, we don't want to have a silly message
return
- else if(istype(W,/obj/item/newscaster_frame))
- var/obj/item/newscaster_frame/AH = W
- AH.try_build(src)
- return 1
-
- else if(istype(W,/obj/item/alarm_frame))
- var/obj/item/alarm_frame/AH = W
- AH.try_build(src)
- return
-
- else if(istype(W,/obj/item/firealarm_frame))
- var/obj/item/firealarm_frame/AH = W
- AH.try_build(src)
- return
-
- else if(istype(W,/obj/item/light_fixture_frame))
- var/obj/item/light_fixture_frame/AH = W
- AH.try_build(src)
- return
-
- else if(istype(W,/obj/item/light_fixture_frame/small))
- var/obj/item/light_fixture_frame/small/AH = W
- AH.try_build(src)
- return
-/*
- else if(istype(W,/obj/item/rust_fuel_compressor_frame))
- var/obj/item/rust_fuel_compressor_frame/AH = W
- AH.try_build(src)
- return
-
- else if(istype(W,/obj/item/rust_fuel_assembly_port_frame))
- var/obj/item/rust_fuel_assembly_port_frame/AH = W
- AH.try_build(src)
- return
-*/
//Poster stuff
else if(istype(W,/obj/item/weapon/contraband/poster))
place_poster(W,user)
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index 1ff89a02a3f..2ef06abefae 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -284,32 +284,7 @@
del(MS)
//APC
- else if( istype(W,/obj/item/apc_frame) )
- var/obj/item/apc_frame/AH = W
- AH.try_build(src)
-
- else if(istype(W,/obj/item/newscaster_frame))
- var/obj/item/newscaster_frame/AH = W
- AH.try_build(src)
- return 1
-
- else if( istype(W,/obj/item/alarm_frame) )
- var/obj/item/alarm_frame/AH = W
- AH.try_build(src)
-
- else if(istype(W,/obj/item/firealarm_frame))
- var/obj/item/firealarm_frame/AH = W
- AH.try_build(src)
- return
-
- else if(istype(W,/obj/item/light_fixture_frame))
- var/obj/item/light_fixture_frame/AH = W
- AH.try_build(src)
- return
-
- else if(istype(W,/obj/item/light_fixture_frame/small))
- var/obj/item/light_fixture_frame/small/AH = W
- AH.try_build(src)
+ else if(istype(W,/obj/item/mounted))
return
//Poster stuff
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index dee6c2afaaf..a108dd54287 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -987,3 +987,41 @@ proc/formatLocation(var/location)
proc/formatPlayerPanel(var/mob/U,var/text="PP")
return "[text]"
+
+//returns 1 to let the dragdrop code know we are trapping this event
+//returns 0 if we don't plan to trap the event
+/datum/admins/proc/cmd_ghost_drag(var/mob/dead/observer/frommob, var/mob/living/tomob)
+ if(!istype(frommob))
+ return //extra sanity check to make sure only observers are shoved into things
+
+ //same as assume-direct-control perm requirements.
+ if (!check_rights(R_VAREDIT,0) || !check_rights(R_ADMIN|R_DEBUG,0))
+ return 0
+
+ if (!frommob.ckey)
+ return 0
+
+
+ var/question = ""
+ if (tomob.ckey)
+ question = "This mob already has a user ([tomob.key]) in control of it! "
+ question += "Are you sure you want to place [frommob.name]([frommob.key]) in control of [tomob.name]?"
+
+ var/ask = alert(question, "Place ghost in control of mob?", "Yes", "No")
+ if (ask != "Yes")
+ return 1
+
+ if(!frommob || !tomob) //make sure the mobs don't go away while we waited for a response
+ return 1
+
+ if(tomob.client) //no need to ghostize if there is no client
+ tomob.ghostize(0)
+
+ message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of [tomob.name].")
+ log_admin("[key_name(usr)] stuffed [frommob.ckey] into [tomob.name].")
+ feedback_add_details("admin_verb","CGD")
+
+ tomob.ckey = frommob.ckey
+ qdel(frommob)
+
+ return 1
\ No newline at end of file
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index 49ded54e4c5..c7d5853ae31 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -268,7 +268,7 @@ var/list/forbidden_varedit_object_types = list(
/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
if(!check_rights(R_VAREDIT)) return
- var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state", "mutantrace")
+ var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state")
for(var/p in forbidden_varedit_object_types)
if( istype(O,p) )
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index f45154aaf52..1cfd5174c17 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -516,7 +516,6 @@ client/proc/one_click_antag()
new_vox.real_name = capitalize(newname)
new_vox.name = new_vox.real_name
new_vox.age = rand(12,20)
- new_vox.dna.mutantrace = "vox"
new_vox.set_species("Vox")
new_vox.languages = list() // Removing language from chargen.
new_vox.flavor_text = ""
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 9d028acf4a2..be39f1be89a 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -45,7 +45,7 @@
if(!status)
status = 1
bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
- msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
+ msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
user << "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited."
else
status = 0
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 0ede8d0ba98..f472b070830 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -23,7 +23,6 @@
var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
var/corpseidicon = null //For setting it to be a gold, silver, centcomm etc ID
- var/mutantrace = "human"
var/timeofdeath = null
var/coffin = 0
diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm
index 180fbf7a331..2f1edeacaa5 100644
--- a/code/modules/awaymissions/mission_code/wildwest.dm
+++ b/code/modules/awaymissions/mission_code/wildwest.dm
@@ -80,19 +80,40 @@
user.mutations.Add(LASER)
user.mutations.Add(RESIST_COLD)
user.mutations.Add(XRAY)
- user.dna.mutantrace = "shadow"
+ if(ishuman(user))
+ var/mob/living/carbon/human/human = user
+ if(human.species.name != "Shadow")
+ user << "\red Your flesh rapidly mutates!"
+ user << "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids."
+ user << "\red Your body reacts violently to light. \green However, it naturally heals in darkness."
+ user << "Aside from your new traits, you are mentally unchanged and retain your prior obligations."
+ human.set_species("Shadow")
user.regenerate_icons()
if("Wealth")
user << "Your wish is granted, but at a terrible cost..."
user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart."
new /obj/structure/closet/syndicate/resources/everything(loc)
- user.dna.mutantrace = "shadow"
+ if(ishuman(user))
+ var/mob/living/carbon/human/human = user
+ if(human.species.name != "Shadow")
+ user << "\red Your flesh rapidly mutates!"
+ user << "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids."
+ user << "\red Your body reacts violently to light. \green However, it naturally heals in darkness."
+ user << "Aside from your new traits, you are mentally unchanged and retain your prior obligations."
+ human.set_species("Shadow")
user.regenerate_icons()
if("Immortality")
user << "Your wish is granted, but at a terrible cost..."
user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart."
user.verbs += /mob/living/carbon/proc/immortality
- user.dna.mutantrace = "shadow"
+ if(ishuman(user))
+ var/mob/living/carbon/human/human = user
+ if(human.species.name != "Shadow")
+ user << "\red Your flesh rapidly mutates!"
+ user << "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids."
+ user << "\red Your body reacts violently to light. \green However, it naturally heals in darkness."
+ user << "Aside from your new traits, you are mentally unchanged and retain your prior obligations."
+ human.set_species("Shadow")
user.regenerate_icons()
if("To Kill")
user << "Your wish is granted, but at a terrible cost..."
@@ -107,7 +128,14 @@
for(var/datum/objective/OBJ in user.mind.objectives)
user << "Objective #[obj_count]: [OBJ.explanation_text]"
obj_count++
- user.dna.mutantrace = "shadow"
+ if(ishuman(user))
+ var/mob/living/carbon/human/human = user
+ if(human.species.name != "Shadow")
+ user << "\red Your flesh rapidly mutates!"
+ user << "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids."
+ user << "\red Your body reacts violently to light. \green However, it naturally heals in darkness."
+ user << "Aside from your new traits, you are mentally unchanged and retain your prior obligations."
+ human.set_species("Shadow")
user.regenerate_icons()
if("Peace")
user << "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence."
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index cb59d0f3282..29b3ccc999e 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -123,8 +123,6 @@ datum/preferences
var/species = "Human"
var/language = "None" //Secondary language
- var/slime_color = "blue" //need this for assigning to chars
- var/HRslime_color = ""
var/speciesprefs = 0//I hate having to do this, I really do (Using this for oldvox code, making names universal I guess
@@ -354,15 +352,10 @@ datum/preferences
dat += " Eyes "
dat += "Change Color
__
"
- if(species == "Unathi" || species == "Tajaran" || species == "Skrell")
+ if(species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Slime People")
dat += " Body Color "
dat += "Change Color
__
"
- if(species == "Slime People")
- HRslime_color = capitalize(slime_color)
- dat += " Slime Color "
- dat += "Change Slime Color[HRslime_color]"
-
dat += "
"
if (1) // General Preferences
@@ -1216,15 +1209,6 @@ datum/preferences
g_skin = hex2num(copytext(new_skin, 4, 6))
b_skin = hex2num(copytext(new_skin, 6, 8))
- if("slime_color")
- var/list/slime_colors
- slime_colors = slime_colorh
- if(species == "Slime People")
- var/new_slime = input(user, "Choose your slime color: ", "Character Preference") as null|anything in slime_colors
- if(new_slime)
- slime_color = slime_colors[slime_colors.Find(new_slime)]
- ShowChoices(user)
-
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
@@ -1482,8 +1466,6 @@ datum/preferences
character.h_style = h_style
character.f_style = f_style
- character.slime_color = slime_color
-
// Destroy/cyborgize organs
diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preferences_mysql.dm
index 61b88ed7be2..f098ff77989 100644
--- a/code/modules/client/preferences_mysql.dm
+++ b/code/modules/client/preferences_mysql.dm
@@ -120,7 +120,6 @@
rlimb_data = params2list(query.item[51])
nanotrasen_relation = query.item[52]
speciesprefs = text2num(query.item[53])
- slime_color = query.item[54]
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
@@ -129,7 +128,6 @@
if(isnull(language)) language = "None"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(isnull(speciesprefs)) speciesprefs = initial(speciesprefs)
- if(isnull(slime_color)) slime_color = initial(slime_color)
if(!real_name) real_name = random_name(gender,species)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
@@ -192,14 +190,14 @@
firstquery.Execute()
while(firstquery.NextRow())
if(text2num(firstquery.item[1]) == default_slot)
- var/DBQuery/query = dbcon.NewQuery("UPDATE characters SET OOC_Notes='[sql_sanitize_text(metadata)]',real_name='[sql_sanitize_text(real_name)]',name_is_always_random='[be_random_name]',gender='[gender]',age='[age]',species='[sql_sanitize_text(species)]',language='[sql_sanitize_text(language)]',hair_red='[r_hair]',hair_green='[g_hair]',hair_blue='[b_hair]',facial_red='[r_facial]',facial_green='[g_facial]',facial_blue='[b_facial]',skin_tone='[s_tone]',skin_red='[r_skin]',skin_green='[g_skin]',skin_blue='[b_skin]',hair_style_name='[sql_sanitize_text(h_style)]',facial_style_name='[sql_sanitize_text(f_style)]',eyes_red='[r_eyes]',eyes_green='[g_eyes]',eyes_blue='[b_eyes]',underwear='[underwear]',undershirt='[undershirt]',backbag='[backbag]',b_type='[b_type]',alternate_option='[alternate_option]',job_support_high='[job_support_high]',job_support_med='[job_support_med]',job_support_low='[job_support_low]',job_medsci_high='[job_medsci_high]',job_medsci_med='[job_medsci_med]',job_medsci_low='[job_medsci_low]',job_engsec_high='[job_engsec_high]',job_engsec_med='[job_engsec_med]',job_engsec_low='[job_engsec_low]',job_karma_high='[job_karma_high]',job_karma_med='[job_karma_med]',job_karma_low='[job_karma_low]',flavor_text='[sql_sanitize_text(flavor_text)]',med_record='[sql_sanitize_text(med_record)]',sec_record='[sql_sanitize_text(sec_record)]',gen_record='[sql_sanitize_text(gen_record)]',player_alt_titles='[playertitlelist]',be_special='[be_special]',disabilities='[disabilities]',organ_data='[organlist]',rlimb_data='[rlimblist]',nanotrasen_relation='[nanotrasen_relation]', speciesprefs='[speciesprefs]', slime_color='[slime_color]' WHERE ckey='[C.ckey]' AND slot='[default_slot]'")
+ var/DBQuery/query = dbcon.NewQuery("UPDATE characters SET OOC_Notes='[sql_sanitize_text(metadata)]',real_name='[sql_sanitize_text(real_name)]',name_is_always_random='[be_random_name]',gender='[gender]',age='[age]',species='[sql_sanitize_text(species)]',language='[sql_sanitize_text(language)]',hair_red='[r_hair]',hair_green='[g_hair]',hair_blue='[b_hair]',facial_red='[r_facial]',facial_green='[g_facial]',facial_blue='[b_facial]',skin_tone='[s_tone]',skin_red='[r_skin]',skin_green='[g_skin]',skin_blue='[b_skin]',hair_style_name='[sql_sanitize_text(h_style)]',facial_style_name='[sql_sanitize_text(f_style)]',eyes_red='[r_eyes]',eyes_green='[g_eyes]',eyes_blue='[b_eyes]',underwear='[underwear]',undershirt='[undershirt]',backbag='[backbag]',b_type='[b_type]',alternate_option='[alternate_option]',job_support_high='[job_support_high]',job_support_med='[job_support_med]',job_support_low='[job_support_low]',job_medsci_high='[job_medsci_high]',job_medsci_med='[job_medsci_med]',job_medsci_low='[job_medsci_low]',job_engsec_high='[job_engsec_high]',job_engsec_med='[job_engsec_med]',job_engsec_low='[job_engsec_low]',job_karma_high='[job_karma_high]',job_karma_med='[job_karma_med]',job_karma_low='[job_karma_low]',flavor_text='[sql_sanitize_text(flavor_text)]',med_record='[sql_sanitize_text(med_record)]',sec_record='[sql_sanitize_text(sec_record)]',gen_record='[sql_sanitize_text(gen_record)]',player_alt_titles='[playertitlelist]',be_special='[be_special]',disabilities='[disabilities]',organ_data='[organlist]',rlimb_data='[rlimblist]',nanotrasen_relation='[nanotrasen_relation]', speciesprefs='[speciesprefs]' WHERE ckey='[C.ckey]' AND slot='[default_slot]'")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during character slot saving. Error : \[[err]\]\n")
message_admins("SQL ERROR during character slot saving. Error : \[[err]\]\n")
return
return 1
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO characters (ckey,slot,OOC_Notes,real_name,name_is_always_random,gender,age,species,language,hair_red,hair_green,hair_blue,facial_red,facial_green,facial_blue,skin_tone,skin_red,skin_green,skin_blue,hair_style_name,facial_style_name,eyes_red,eyes_green,eyes_blue,underwear,undershirt,backbag,b_type,alternate_option,job_support_high,job_support_med,job_support_low,job_medsci_high,job_medsci_med,job_medsci_low,job_engsec_high,job_engsec_med,job_engsec_low,job_karma_high,job_karma_med,job_karma_low,flavor_text,med_record,sec_record,gen_record,player_alt_titles,be_special,disabilities,organ_data,rlimb_data,nanotrasen_relation, speciesprefs, slime_color) VALUES ('[C.ckey]','[default_slot]','[sql_sanitize_text(metadata)]','[sql_sanitize_text(real_name)]','[be_random_name]','[gender]','[age]','[sql_sanitize_text(species)]','[sql_sanitize_text(language)]','[r_hair]','[g_hair]','[b_hair]','[r_facial]','[g_facial]','[b_facial]','[s_tone]','[r_skin]','[g_skin]','[b_skin]','[sql_sanitize_text(h_style)]','[sql_sanitize_text(f_style)]','[r_eyes]','[g_eyes]','[b_eyes]','[underwear]','[undershirt]','[backbag]','[b_type]','[alternate_option]','[job_support_high]','[job_support_med]','[job_support_low]','[job_medsci_high]','[job_medsci_med]','[job_medsci_low]','[job_engsec_high]','[job_engsec_med]','[job_engsec_low]','[job_karma_high]','[job_karma_med]','[job_karma_low]','[sql_sanitize_text(flavor_text)]','[sql_sanitize_text(med_record)]','[sql_sanitize_text(sec_record)]','[sql_sanitize_text(gen_record)]','[playertitlelist]','[be_special]','[disabilities]','[organlist]','[rlimblist]','[nanotrasen_relation]', '[speciesprefs]', '[slime_color]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO characters (ckey,slot,OOC_Notes,real_name,name_is_always_random,gender,age,species,language,hair_red,hair_green,hair_blue,facial_red,facial_green,facial_blue,skin_tone,skin_red,skin_green,skin_blue,hair_style_name,facial_style_name,eyes_red,eyes_green,eyes_blue,underwear,undershirt,backbag,b_type,alternate_option,job_support_high,job_support_med,job_support_low,job_medsci_high,job_medsci_med,job_medsci_low,job_engsec_high,job_engsec_med,job_engsec_low,job_karma_high,job_karma_med,job_karma_low,flavor_text,med_record,sec_record,gen_record,player_alt_titles,be_special,disabilities,organ_data,rlimb_data,nanotrasen_relation, speciesprefs) VALUES ('[C.ckey]','[default_slot]','[sql_sanitize_text(metadata)]','[sql_sanitize_text(real_name)]','[be_random_name]','[gender]','[age]','[sql_sanitize_text(species)]','[sql_sanitize_text(language)]','[r_hair]','[g_hair]','[b_hair]','[r_facial]','[g_facial]','[b_facial]','[s_tone]','[r_skin]','[g_skin]','[b_skin]','[sql_sanitize_text(h_style)]','[sql_sanitize_text(f_style)]','[r_eyes]','[g_eyes]','[b_eyes]','[underwear]','[undershirt]','[backbag]','[b_type]','[alternate_option]','[job_support_high]','[job_support_med]','[job_support_low]','[job_medsci_high]','[job_medsci_med]','[job_medsci_low]','[job_engsec_high]','[job_engsec_med]','[job_engsec_low]','[job_karma_high]','[job_karma_med]','[job_karma_low]','[sql_sanitize_text(flavor_text)]','[sql_sanitize_text(med_record)]','[sql_sanitize_text(sec_record)]','[sql_sanitize_text(gen_record)]','[playertitlelist]','[be_special]','[disabilities]','[organlist]','[rlimblist]','[nanotrasen_relation]', '[speciesprefs]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during character slot saving. Error : \[[err]\]\n")
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index a0cdd527b30..2831d63a652 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -131,9 +131,22 @@
else
src << "You will no longer hear ambient sounds."
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
- src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/verb/Toggle_Buzz() //No more headaches because headphones bump up shipambience.ogg to insanity levels.
+ set name = "Hear/Silence White Noise"
+ set category = "Preferences"
+ set desc = "Toggles hearing ambient white noise"
+ prefs.sound ^= SOUND_BUZZ
+ prefs.save_preferences(src)
+ if(prefs.sound & SOUND_BUZZ)
+ src << "You will now hear ambient white noise."
+ else
+ src << "You will no longer hear ambient white noise."
+ src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
+ feedback_add_details("admin_verb","TBuzz") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
/client/verb/Toggle_Heartbeat() //to toggle off heartbeat sounds, in case they get too annoying
set name = "Hear/Silence Heartbeat"
set category = "Preferences"
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 011c1f27f0a..05519f99a7e 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -133,6 +133,9 @@
var/vision_flags = 0
var/darkness_view = 0//Base human is 2
var/invisa_view = 0
+ var/flash_protect = 0 //Mal: What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS
+ var/tint = 0 //Mal: Sets the item's level of visual impairment tint, normally set to the same as flash_protect
+ // but seperated to allow items to protect but not impair vision, like space helmets
species_restricted = list("exclude","Kidan")
/*
SEE_SELF // can see self, no matter what
@@ -236,7 +239,8 @@ BLIND // can't see anything
slot_flags = SLOT_HEAD
var/loose = 10 // probability (0..100) of coming off your head when you fall over or lay down
var/blockTracking // Do we block AI tracking?
-
+ var/flash_protect = 0
+ var/tint = 0
//Mask
/obj/item/clothing/mask
@@ -247,6 +251,8 @@ BLIND // can't see anything
var/mask_adjusted = 0
var/ignore_maskadjust = 1
var/adjusted_flags = null
+ var/flash_protect = 0
+ var/tint = 0
//Proc that moves gas/breath masks out of the way
/obj/item/clothing/mask/proc/adjustmask(var/mob/user)
@@ -324,6 +330,7 @@ BLIND // can't see anything
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona","Vox")
loose = 0 // What kind of idiot designs a pressurized suit where the helmet can fall off?
+ flash_protect = 2
/obj/item/clothing/suit/space
name = "Space suit"
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 77e31587c41..74e19d7b1d7 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -137,6 +137,8 @@
icon_state = "sun"
item_state = "sunglasses"
darkness_view = 1
+ flash_protect = 1
+ tint = 1
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
@@ -148,6 +150,8 @@
icon_state = "sun"
item_state = "sunglasses"
darkness_view = 1
+ flash_protect = 1
+ tint = 1
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
@@ -160,6 +164,8 @@
item_state = "welding-g"
icon_action_button = "action_welding_g"
var/up = 0
+ flash_protect = 2
+ tint = 2
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
@@ -184,12 +190,16 @@
flags_inv |= HIDEEYES
icon_state = initial(icon_state)
usr << "You flip the [src] down to protect your eyes."
+ flash_protect = 2
+ tint = initial(tint) //better than istype
else
src.up = !src.up
src.flags &= ~HEADCOVERSEYES
flags_inv &= ~HIDEEYES
icon_state = "[initial(icon_state)]up"
usr << "You push the [src] up out of your face."
+ flash_protect = 0
+ tint = 0
usr.update_inv_glasses()
@@ -198,6 +208,8 @@
desc = "Welding goggles made from more expensive materials, strangely smells like potatoes."
icon_state = "rwelding-g"
item_state = "rwelding-g"
+ flash_protect = 2
+ tint = 0
icon_action_button = "action_welding_g"
species_fit = list("Vox")
sprite_sheets = list(
@@ -213,6 +225,8 @@
icon_state = "blindfold"
item_state = "blindfold"
//vision_flags = BLIND
+ flash_protect = 2
+ tint = 3 //to make them blind
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
@@ -230,6 +244,8 @@
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks many flashes."
icon_state = "bigsunglasses"
item_state = "bigsunglasses"
+ flash_protect = 1
+ tint = 1
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
@@ -240,6 +256,8 @@
desc = "Sunglasses with a HUD."
icon_state = "sunhud"
darkness_view = 1
+ flash_protect = 1
+ tint = 1
var/obj/item/clothing/glasses/hud/security/hud = null
species_fit = list("Vox")
sprite_sheets = list(
@@ -259,6 +277,7 @@
origin_tech = "magnets=3"
vision_flags = SEE_MOBS
invisa_view = 2
+ flash_protect = -1
emp_act(severity)
if(istype(src.loc, /mob/living/carbon/human))
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 9a52deadebc..3942b732624 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -19,6 +19,7 @@
name = "Advanced Health Scanner HUD"
desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. Includes anti-flash filter."
icon_state = "advmedhud"
+ flash_protect = 1
/obj/item/clothing/glasses/hud/health/night
name = "Night Vision Health Scanner HUD"
@@ -40,6 +41,7 @@
desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records."
icon_state = "securityhud"
var/global/list/jobs[0]
+ flash_protect = 1
/obj/item/clothing/glasses/hud/security/jensenshades
name = "Augmented shades"
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 92d71afc888..d5420a8bd4d 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -20,6 +20,8 @@
m_amt = 1750
g_amt = 400
var/up = 0
+ flash_protect = 2
+ tint = 2
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
icon_action_button = "action_welding"
@@ -44,12 +46,16 @@
flags_inv |= (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
icon_state = initial(icon_state)
usr << "You flip the [src] down to protect your eyes."
+ flash_protect = 2
+ tint = 2
else
src.up = !src.up
src.flags &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH)
flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
icon_state = "[initial(icon_state)]up"
usr << "You push the [src] up out of your face."
+ flash_protect = 0
+ tint = 0
usr.update_inv_head() //so our mob-overlays update
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index 5379e5e77ca..bce0a0212d2 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -126,6 +126,7 @@
desc = "A lightweight space helmet with the basic ability to protect the wearer from the vacuum of space during emergencies."
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20)
+ flash_protect = 0
//Mime's Hardsuit
/obj/item/clothing/head/helmet/space/eva/mime
diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm
index d1fa45e2018..e54b737584f 100644
--- a/code/modules/clothing/spacesuits/rig.dm
+++ b/code/modules/clothing/spacesuits/rig.dm
@@ -490,6 +490,7 @@
_color = "medical"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES
armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50)
+ flash_protect = 0
/obj/item/clothing/suit/space/rig/medical
icon_state = "rig-medical"
diff --git a/code/modules/computer3/file.dm b/code/modules/computer3/file.dm
index 849312ec50e..1cbb363894a 100644
--- a/code/modules/computer3/file.dm
+++ b/code/modules/computer3/file.dm
@@ -140,7 +140,6 @@
/datum/file/data/genome/SE
name = "Structural Enzymes"
- var/mutantrace = null
/datum/file/data/genome/UE
name = "Unique Enzymes"
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index 227737ba99c..ce128607439 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -26,6 +26,6 @@
var/obj/vent = pick(vents)
var/obj/effect/spider/spiderling/S = new(vent.loc)
if(prob(66))
- S.grow_as = /mob/living/simple_animal/hostile/giant_spider/nurse
+ S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/nurse
vents -= vent
spawncount--
\ No newline at end of file
diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm
index 412f34de47d..4efd8e87582 100644
--- a/code/modules/events/tear.dm
+++ b/code/modules/events/tear.dm
@@ -44,25 +44,8 @@
spawn(rand(30,120))
- var/blocked = list(/mob/living/simple_animal/hostile,
- /mob/living/simple_animal/hostile/pirate,
- /mob/living/simple_animal/hostile/pirate/ranged,
- /mob/living/simple_animal/hostile/russian,
- /mob/living/simple_animal/hostile/russian/ranged,
- /mob/living/simple_animal/hostile/syndicate,
- /mob/living/simple_animal/hostile/syndicate/melee,
- /mob/living/simple_animal/hostile/syndicate/melee/space,
- /mob/living/simple_animal/hostile/syndicate/ranged,
- /mob/living/simple_animal/hostile/syndicate/ranged/space,
- /mob/living/simple_animal/hostile/alien/queen/large,
- /mob/living/simple_animal/hostile/faithless,
- /mob/living/simple_animal/hostile/panther,
- /mob/living/simple_animal/hostile/snake,
- /mob/living/simple_animal/hostile/retaliate,
- /mob/living/simple_animal/hostile/retaliate/clown,
- /mob/living/simple_animal/hostile/spaceWorm/,
- /mob/living/simple_animal/hostile/spaceWorm/wormHead/
- )//exclusion list for things you don't want the reaction to create.
+ var/blocked = blocked_mobs //global variable for blocked mobs
+
var/list/critters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs
for(var/i = 1, i <= 5, i++)
diff --git a/code/modules/events/tgevents/vent_clog.dm b/code/modules/events/tgevents/vent_clog.dm
index 1e31e08485d..808e4a7e052 100755
--- a/code/modules/events/tgevents/vent_clog.dm
+++ b/code/modules/events/tgevents/vent_clog.dm
@@ -22,8 +22,8 @@
var/list/gunk = list("water","carbon","flour","radium","toxin","cleaner","nutriment","condensedcapsaicin","psilocybin","lube",
"atrazine","banana","charcoal","space_drugs","methamphetamine","holywater","ethanol","hot_coco","facid",
- "blood","morphine","fluorine","mutadone","mutagen","hydrocodone","fuel","cryptobiolin",
- "haloperidol","mindbreaker","nanites","lipolicide","frostoil","salglu_solution","beepskysmash",
+ "blood","morphine","fluorine","mutadone","mutagen","hydrocodone","fuel",
+ "haloperidol","lsd","nanites","lipolicide","frostoil","salglu_solution","beepskysmash",
"omnizine", "amanitin", "adminordrazine", "neurotoxin", "synaptizine")
var/datum/reagents/R = new/datum/reagents(50)
R.my_atom = vent
diff --git a/code/modules/food/candy_maker.dm b/code/modules/food/candy_maker.dm
index c6fe36f48b1..cfe59a95209 100644
--- a/code/modules/food/candy_maker.dm
+++ b/code/modules/food/candy_maker.dm
@@ -323,8 +323,7 @@
for(var/i=1,iHad the [src.name] used on them by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] on [M.name] ([M.ckey]) (JMP)")
+ msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] on [M.name] ([M.ckey]) (JMP)")
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index a63f834fe7c..b2100a1240f 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -762,7 +762,7 @@ proc/populate_seed_list()
mutants = list("reishi","amanita","plumphelmet")
packet_icon = "mycelium-chanter"
plant_icon = "chanter"
- chems = list("nutriment" = list(1,25))
+ chems = list("nutriment" = list(1,25), "fungus" = list(1,10))
lifespan = 35
maturation = 7
@@ -1255,7 +1255,7 @@ proc/populate_seed_list()
packet_icon = "seed-corn"
products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/corn)
plant_icon = "corn"
- chems = list("nutriment" = list(1,10))
+ chems = list("nutriment" = list(1,10), "corn_starch" = list(3,5))
lifespan = 25
maturation = 8
@@ -1287,7 +1287,7 @@ proc/populate_seed_list()
packet_icon = "seed-wheat"
products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/wheat)
plant_icon = "wheat"
- chems = list("nutriment" = list(1,25), "corn_starch" = list(3,5))
+ chems = list("nutriment" = list(1,25))
lifespan = 25
maturation = 6
diff --git a/code/modules/jungle/jungle_plants.dm b/code/modules/jungle/jungle_plants.dm
index 2a48dcf4f9b..bf7d11529bf 100644
--- a/code/modules/jungle/jungle_plants.dm
+++ b/code/modules/jungle/jungle_plants.dm
@@ -58,7 +58,7 @@
//*******************************//
var/list/fruit_icon_states = list("badrecipe","kudzupod","reishi","lime","grapes","boiledrorocore","chocolateegg")
-var/list/reagent_effects = list("toxin","charcoal","morphine","space_drugs","mindbreaker","haloperidol")
+var/list/reagent_effects = list("toxin","charcoal","morphine","space_drugs","lsd","haloperidol")
var/jungle_plants_init = 0
/proc/init_jungle_plants()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 7ae495373e3..22af8b0bedc 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -487,6 +487,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << browse(dat, "window=manifest;size=370x420;can_close=1")
+//this is called when a ghost is drag clicked to something.
+/mob/dead/observer/MouseDrop(atom/over)
+ if(!usr || !over) return
+ if (isobserver(usr) && usr.client && usr.client.holder && isliving(over))
+ if (usr.client.holder.cmd_ghost_drag(src,over))
+ return
+
+ return ..()
+
//BEGIN TELEPORT HREF CODE
/mob/dead/observer/Topic(href, href_list)
if(usr != src)
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 177d189cb2c..fa5725faf19 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -260,7 +260,7 @@
desc = "The common galactic tongue."
speech_verb = "says"
whisper_verb = "whispers"
- key = "0"
+ key = "9"
flags = RESTRICTED
syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah")
@@ -468,6 +468,12 @@
. = (L in languages)
languages.Remove(L)
+/mob/living/remove_language(rem_language)
+ var/datum/language/L = all_languages[rem_language]
+ if(default_language == L)
+ default_language = null
+ return ..()
+
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak(datum/language/speaking)
@@ -488,4 +494,32 @@
src << browse(dat, "window=checklanguage")
return
+/mob/living/check_languages()
+ var/dat = "Known Languages