diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index f7098594a93..abf71c4ea0d 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -93,14 +93,11 @@ Pipelines + Other Objects -> Pipe network
return ..()
/obj/machinery/atmospherics/Deconstruct()
- var/turf/T = loc
- stored.loc = T
- transfer_fingerprints_to(stored)
- if(istype(src, /obj/machinery/atmospherics/pipe))
- for(var/obj/machinery/meter/meter in T)
- if(meter.target == src)
- new /obj/item/pipe_meter(T)
- qdel(meter)
+ if(can_unwrench)
+ var/turf/T = loc
+ stored.loc = T
+ transfer_fingerprints_to(stored)
+
qdel(src)
/obj/machinery/atmospherics/proc/nullifyPipenet(datum/pipeline/P)
@@ -127,7 +124,7 @@ Pipelines + Other Objects -> Pipe network
return img
-/obj/machinery/atmospherics/proc/construction(D, P)
+/obj/machinery/atmospherics/construction(D, P)
dir = D
initialize_directions = P
var/turf/T = loc
diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm
index 7884a5ad12c..a3bb5355947 100644
--- a/code/ATMOSPHERICS/pipes.dm
+++ b/code/ATMOSPHERICS/pipes.dm
@@ -40,4 +40,13 @@
return ..()
/obj/machinery/atmospherics/pipe/setPipenet(datum/pipeline/P)
- parent = P
\ No newline at end of file
+ parent = P
+
+/obj/machinery/atmospherics/pipe/Destroy()
+ var/turf/T = loc
+ for(var/obj/machinery/meter/meter in T)
+ if(meter.target == src)
+ var/obj/item/pipe_meter/PM = new (T)
+ meter.transfer_fingerprints_to(PM)
+ qdel(meter)
+ ..()
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm
index 29f16311b63..434a4b3c9e7 100644
--- a/code/ATMOSPHERICS/pipes/manifold.dm
+++ b/code/ATMOSPHERICS/pipes/manifold.dm
@@ -25,6 +25,8 @@
/obj/machinery/atmospherics/pipe/manifold/New()
color = pipe_color
+ ..()
+
switch(dir)
if(NORTH)
initialize_directions = EAST|SOUTH|WEST
@@ -34,7 +36,6 @@
initialize_directions = SOUTH|WEST|NORTH
if(WEST)
initialize_directions = NORTH|EAST|SOUTH
- ..()
/obj/machinery/atmospherics/pipe/manifold/initialize()
for(var/D in cardinal)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index a85c69e7b81..928561abe94 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1314,44 +1314,32 @@ var/global/list/common_tools = list(
Checks if that loc and dir has a item on the wall
*/
var/list/WALLITEMS = list(
- "/obj/machinery/power/apc", "/obj/machinery/alarm", "/obj/item/device/radio/intercom",
- "/obj/structure/extinguisher_cabinet", "/obj/structure/reagent_dispensers/peppertank",
- "/obj/machinery/status_display", "/obj/machinery/requests_console", "/obj/machinery/light_switch", "/obj/effect/sign",
- "/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/machinery/power/apc, /obj/machinery/alarm, /obj/item/device/radio/intercom,
+ /obj/structure/extinguisher_cabinet, /obj/structure/reagent_dispensers/peppertank,
+ /obj/machinery/status_display, /obj/machinery/requests_console, /obj/machinery/light_switch, /obj/structure/sign,
+ /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
)
/proc/gotwallitem(loc, dir)
+ var/locdir = get_step(loc, dir)
for(var/obj/O in loc)
- for(var/item in WALLITEMS)
- if(istype(O, text2path(item)))
- //Direction works sometimes
- if(O.dir == dir)
- return 1
-
- //Some stuff doesn't use dir properly, so we need to check pixel instead
- switch(dir)
- if(SOUTH)
- if(O.pixel_y > 10)
- return 1
- if(NORTH)
- if(O.pixel_y < -10)
- return 1
- if(WEST)
- if(O.pixel_x > 10)
- return 1
- if(EAST)
- if(O.pixel_x < -10)
- return 1
+ if(is_type_in_list(O, WALLITEMS))
+ //Direction works sometimes
+ if(O.dir == dir)
+ return 1
+ //Some stuff doesn't use dir properly, so we need to check pixel instead
+ //That's exactly what get_wall_mounted_turf() does
+ if(get_wall_mounted_turf(O) == locdir)
+ return 1
//Some stuff is placed directly on the wallturf (signs)
- 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)
- return 1
+ for(var/obj/O in locdir)
+ if(is_type_in_list(O, WALLITEMS))
+ if(O.pixel_x == 0 && O.pixel_y == 0)
+ return 1
return 0
/proc/format_text(text)
@@ -1405,3 +1393,21 @@ var/list/WALLITEMS = list(
step(AM, pick(alldirs))
chance = max(chance - (initial_chance / steps), 0)
steps--
+
+/proc/get_wall_mounted_turf(atom/A)
+ /* This proc uses the pixel_x/y vars to guess the fake turf of a wall mounted atom.
+ Needless to say, this is an error prone method and possibly open to exploits.
+ It is however faster than using icon procs to get a more accurate reading.
+ I've only tested this proc on APCs. Use it with care.*/
+ if(is_type_in_list(A, WALLITEMS))
+ var/stepdir = 0
+
+ if(A.pixel_x > 10) stepdir |= EAST
+ if(A.pixel_x < -10) stepdir |= WEST
+ if(A.pixel_y > 10) stepdir |= NORTH
+ if(A.pixel_y < -10) stepdir |= SOUTH
+
+ if(stepdir)
+ return get_step(A, stepdir)
+ return get_turf(A)
+
diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm
index 1af635b5d18..c9754a87c48 100644
--- a/code/controllers/voting.dm
+++ b/code/controllers/voting.dm
@@ -176,7 +176,7 @@ var/datum/controller/vote/vote = new()
if(mode == "custom")
text += "\n[question]"
log_vote(text)
- world << "\n[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote."
+ world << "\n[text]\nType vote or click here to place your votes.\nYou have [config.vote_period/10] seconds to vote."
time_remaining = round(config.vote_period/10)
return 1
return 0
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index e98fec043ed..368a3e69c93 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -79,6 +79,105 @@
if(foundrecord)
foundrecord.fields["rank"] = assignment
+/obj/effect/datacore/proc/get_manifest(monochrome, OOC)
+ var/list/heads = list()
+ var/list/sec = list()
+ var/list/eng = list()
+ var/list/med = list()
+ var/list/sci = list()
+ var/list/civ = list()
+ var/list/bot = list()
+ var/list/misc = list()
+ var/dat = {"
+
+
+ | Name | Rank |
+ "}
+ var/even = 0
+ // sort mobs
+ for(var/datum/data/record/t in data_core.general)
+ var/name = t.fields["name"]
+ var/rank = t.fields["rank"]
+ var/department = 0
+ if(rank in command_positions)
+ heads[name] = rank
+ department = 1
+ if(rank in security_positions)
+ sec[name] = rank
+ department = 1
+ if(rank in engineering_positions)
+ eng[name] = rank
+ department = 1
+ if(rank in medical_positions)
+ med[name] = rank
+ department = 1
+ if(rank in science_positions)
+ sci[name] = rank
+ department = 1
+ if(rank in civilian_positions)
+ civ[name] = rank
+ department = 1
+ if(rank in nonhuman_positions)
+ bot[name] = rank
+ department = 1
+ if(!department && !(name in heads))
+ misc[name] = rank
+ if(heads.len > 0)
+ dat += "| Heads |
"
+ for(name in heads)
+ dat += "| [name] | [heads[name]] |
"
+ even = !even
+ if(sec.len > 0)
+ dat += "| Security |
"
+ for(name in sec)
+ dat += "| [name] | [sec[name]] |
"
+ even = !even
+ if(eng.len > 0)
+ dat += "| Engineering |
"
+ for(name in eng)
+ dat += "| [name] | [eng[name]] |
"
+ even = !even
+ if(med.len > 0)
+ dat += "| Medical |
"
+ for(name in med)
+ dat += "| [name] | [med[name]] |
"
+ even = !even
+ if(sci.len > 0)
+ dat += "| Science |
"
+ for(name in sci)
+ dat += "| [name] | [sci[name]] |
"
+ even = !even
+ if(civ.len > 0)
+ dat += "| Civilian |
"
+ for(name in civ)
+ dat += "| [name] | [civ[name]] |
"
+ even = !even
+ // in case somebody is insane and added them to the manifest, why not
+ if(bot.len > 0)
+ dat += "| Silicon |
"
+ for(name in bot)
+ dat += "| [name] | [bot[name]] |
"
+ even = !even
+ // misc guys
+ if(misc.len > 0)
+ dat += "| Miscellaneous |
"
+ for(name in misc)
+ dat += "| [name] | [misc[name]] |
"
+ even = !even
+
+ dat += "
"
+ dat = replacetext(dat, "\n", "")
+ dat = replacetext(dat, "\t", "")
+ return dat
+
+
var/record_id_num = 1001
/obj/effect/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
if(H.mind && (H.mind.assigned_role != "MODE"))
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 16d32663163..84f5828ea77 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -23,7 +23,11 @@
icon_state = "pinoff"
usr << "You deactivate the pinpointer."
-/obj/item/weapon/pinpointer/proc/point_at(atom/target)
+/obj/item/weapon/pinpointer/proc/scandisk()
+ if(!the_disk)
+ the_disk = locate()
+
+/obj/item/weapon/pinpointer/proc/point_at(atom/target, spawnself = 1)
if(!active)
return
if(!target)
@@ -46,13 +50,15 @@
icon_state = "pinonmedium"
if(16 to INFINITY)
icon_state = "pinonfar"
- spawn(5)
- .()
+ if(spawnself)
+ spawn(5)
+ .()
/obj/item/weapon/pinpointer/proc/workdisk()
- if(!the_disk)
- the_disk = locate()
- point_at(the_disk)
+ scandisk()
+ point_at(the_disk, 0)
+ spawn(5)
+ .()
/obj/item/weapon/pinpointer/examine(mob/user)
..()
@@ -183,14 +189,10 @@
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep
visible_message("Shuttle Locator active.") //Lets the mob holding it know that the mode has changed
return //Get outta here
+ scandisk()
if(!the_disk)
- the_disk = locate()
- if(!the_disk)
- icon_state = "pinonnull"
- return
-// if(loc.z != the_disk.z) //If you are on a different z-level from the disk
-// icon_state = "pinonnull"
-// else
+ icon_state = "pinonnull"
+ return
dir = get_dir(src, the_disk)
switch(get_dist(src, the_disk))
if(0)
diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm
index f8974fd36c8..78a56a386f0 100644
--- a/code/game/machinery/Freezer.dm
+++ b/code/game/machinery/Freezer.dm
@@ -21,6 +21,9 @@
component_parts += new /obj/item/stack/cable_coil(null, 1)
RefreshParts()
+/obj/machinery/atmospherics/unary/cold_sink/freezer/construction()
+ ..(dir,dir)
+
/obj/machinery/atmospherics/unary/cold_sink/freezer/RefreshParts()
var/H
var/T
@@ -141,6 +144,9 @@
component_parts += new /obj/item/stack/cable_coil(null, 1)
RefreshParts()
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/construction()
+ ..(dir,dir)
+
/obj/machinery/atmospherics/unary/heat_reservoir/heater/RefreshParts()
var/H
var/T
@@ -204,7 +210,7 @@
//user << browse(dat, "window=freezer;size=400x500")
//onclose(user, "freezer")
- var/datum/browser/popup = new(user, "freezer", "Cryo Gas Cooling System", 400, 240) // Set up the popup browser window
+ var/datum/browser/popup = new(user, "freezer", "Cryo Gas Heating System", 400, 240) // Set up the popup browser window
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.set_content(dat)
popup.open()
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 22d472812f9..ca16ad5dbc3 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -269,7 +269,7 @@
/obj/machinery/camera/proc/cancelCameraAlarm()
alarm_on = 0
for(var/mob/living/silicon/S in mob_list)
- S.cancelAlarm("Camera", get_area(src), list(src), src)
+ S.cancelAlarm("Camera", get_area(src), src)
/obj/machinery/camera/proc/can_use()
if(!status)
diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm
index e80f0799943..4454d5a89cb 100644
--- a/code/game/machinery/camera/motion.dm
+++ b/code/game/machinery/camera/motion.dm
@@ -42,7 +42,8 @@
/obj/machinery/camera/proc/cancelAlarm()
if (detectTime == -1)
for (var/mob/living/silicon/aiPlayer in player_list)
- if (status) aiPlayer.cancelAlarm("Motion", src.loc.loc)
+ if (status)
+ aiPlayer.cancelAlarm("Motion", get_area(src), src)
detectTime = 0
return 1
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index d7bde33688d..8441647f791 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -130,6 +130,7 @@
if(component_check)
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/machinery/new_machine = new src.circuit.build_path(src.loc)
+ new_machine.construction()
for(var/obj/O in new_machine.component_parts)
qdel(O)
new_machine.component_parts = list()
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index eb5faffcafd..24312770103 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -18,7 +18,6 @@
/obj/machinery/atmospherics/unary/cryo_cell/New()
..()
initialize_directions = dir
- initialize()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/cryo_tube(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
@@ -29,6 +28,9 @@
component_parts += new /obj/item/stack/cable_coil(null, 1)
RefreshParts()
+/obj/machinery/atmospherics/unary/cryo_cell/construction()
+ ..(dir,dir)
+
/obj/machinery/atmospherics/unary/cryo_cell/RefreshParts()
var/C
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 857008e4edf..3f799cc41a8 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -242,7 +242,8 @@ Class Procs:
return
//stop AIs from leaving windows open and using then after they lose vision
//apc_override is needed here because AIs use their own APC when powerless
- if(cameranet && !cameranet.checkTurfVis(get_turf(M)) && !apc_override)
+ //the snowflake get_wall_mounted_turf() is because APCs in maint aren't actually in view of the inner camera
+ if(cameranet && !cameranet.checkTurfVis(get_wall_mounted_turf(M)) && !apc_override)
return
return 1
@@ -334,8 +335,8 @@ Class Procs:
/obj/machinery/proc/default_change_direction_wrench(var/mob/user, var/obj/item/weapon/wrench/W)
if(panel_open && istype(W))
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- dir = pick(WEST,EAST,SOUTH,NORTH)
- user << "You clumsily rotate [src]."
+ dir = turn(dir,-90)
+ user << "You rotate [src]."
return 1
return 0
@@ -381,3 +382,7 @@ Class Procs:
W.play_rped_sound()
return 1
return 0
+
+//called on machinery construction (i.e from frame to machinery) but not on initialization
+/obj/machinery/proc/construction()
+ return
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index f63ea425196..85fc2a42869 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -517,6 +517,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
return
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
+ scan_user(usr)
if(href_list["set_channel_name"])
src.channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "", MAX_NAME_LEN)
while (findtext(src.channel_name," ") == 1)
@@ -547,6 +548,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else
var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
if(choice=="Confirm")
+ scan_user(usr)
news_network.CreateFeedChannel(src.channel_name, src.scanned_user, c_locked)
feedback_inc("newscaster_channels",1)
src.screen=5
@@ -632,6 +634,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else
var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
if(choice=="Confirm")
+ scan_user(usr)
if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
var/datum/feed_message/WANTED = new /datum/feed_message
WANTED.author = src.channel_name
@@ -752,6 +755,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
var/datum/feed_message/FM = locate(href_list["new_comment"])
var/cominput = copytext(stripped_input(usr, "Write your message:", "New comment", null),1,141)
if(cominput)
+ scan_user(usr)
var/datum/feed_comment/FC = new/datum/feed_comment
FC.author = scanned_user
FC.body = cominput
@@ -1054,9 +1058,11 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
src.scanned_user ="Unknown"
else
src.scanned_user ="Unknown"
- else
+ else if(istype(user,/mob/living/silicon))
var/mob/living/silicon/ai_user = user
src.scanned_user = "[ai_user.name] ([ai_user.job])"
+ else
+ ERROR("Newscaster used by non-human/silicon mob: [user.type]")
/obj/machinery/newscaster/proc/print_paper()
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index eee59dd82b2..30e11d25386 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -354,12 +354,16 @@
var/atom/cur_target = null
var/scan_range = 9 //You will never see them coming
var/health = 200 //Because it lacks a cover, and is mostly to keep people from touching the syndie shuttle.
+ var/base_icon_state = "syndieturret"
+ var/projectile_type = /obj/item/projectile/bullet
+ var/fire_sound = 'sound/weapons/Gunshot.ogg'
icon = 'icons/obj/turrets.dmi'
icon_state = "syndieturret0"
/obj/machinery/gun_turret/New()
..()
take_damage(0) //check your health
+ icon_state = "[base_icon_state]" + "0"
/obj/machinery/gun_turret/ex_act(severity, target)
switch(severity)
@@ -377,7 +381,7 @@
/obj/machinery/gun_turret/update_icon()
if(state > 2 || state < 0) //someone fucked up the vars so fix them
take_damage(0)
- icon_state = "syndieturret" + "[state]"
+ icon_state = "[base_icon_state]" + "[state]"
return
@@ -479,8 +483,8 @@
return
if (targloc == curloc)
return
- playsound(src, 'sound/weapons/Gunshot.ogg', 50, 1)
- var/obj/item/projectile/A = new /obj/item/projectile/bullet(curloc)
+ playsound(src, fire_sound, 50, 1)
+ var/obj/item/projectile/A = new projectile_type(curloc)
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index bdb48027570..e1b0d3ef1e4 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -975,7 +975,7 @@
/obj/item/clothing/tie/scarf/lightblue=1,/obj/item/clothing/tie/scarf/white=1,/obj/item/clothing/tie/scarf/black=1,
/obj/item/clothing/tie/scarf/zebra=1,/obj/item/clothing/tie/scarf/christmas=1,/obj/item/clothing/tie/stripedredscarf=1,
/obj/item/clothing/tie/stripedbluescarf=1,/obj/item/clothing/tie/stripedgreenscarf=1,/obj/item/clothing/tie/waistcoat=1,
- /obj/item/clothing/under/sundress=2,/obj/item/clothing/under/blacktango=1,/obj/item/clothing/suit/jacket=3,
+ /obj/item/clothing/under/sundress=2,/obj/item/clothing/under/stripeddress = 1, /obj/item/clothing/under/sailordress = 1, /obj/item/clothing/under/redeveninggown = 1, /obj/item/clothing/under/blacktango=1,/obj/item/clothing/suit/jacket=3,
/obj/item/clothing/glasses/regular=2,/obj/item/clothing/head/sombrero=1,/obj/item/clothing/suit/poncho=1,
/obj/item/clothing/suit/ianshirt=1,/obj/item/clothing/shoes/laceup=2,/obj/item/clothing/shoes/sneakers/black=4,
/obj/item/clothing/shoes/sandal=1)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index df3c30675bd..82cf59a988e 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -119,7 +119,7 @@
if (istype(src.loc, /obj/item/weapon/storage))
//If the item is in a storage item, take it out
var/obj/item/weapon/storage/S = src.loc
- S.remove_from_storage(src)
+ S.remove_from_storage(src, user.loc)
src.throwing = 0
if (loc == user)
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 5735a6af412..71959e986ae 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -2,7 +2,7 @@
name = "flash"
desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production."
icon_state = "flash"
- item_state = "flashbang" //looks exactly like a flash (and nothing like a flashbang)
+ item_state = "flashtool"
throwforce = 0
w_class = 1
throw_speed = 3
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 8ef7199f100..f7cd722f7d4 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -304,16 +304,10 @@
if(M.client)
M.client.screen -= W
- if(new_location)
- if(ismob(loc))
- W.dropped(usr)
- if(ismob(new_location))
- W.layer = 20
- else
- W.layer = initial(W.layer)
- W.loc = new_location
- else
- W.loc = get_turf(src)
+ if(ismob(loc))
+ W.dropped(usr)
+ W.layer = initial(W.layer)
+ W.loc = new_location
if(usr)
orient2hud(usr)
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 3b7ab8924b7..7111ef392aa 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -184,12 +184,11 @@
..()
if(severity == 3)
if(prob(25))
- density = 0
+ table_destroy(1)
/obj/structure/table/blob_act()
if(prob(75))
table_destroy(1)
- qdel(src)
return
/obj/structure/table/attack_alien(mob/living/user)
@@ -231,8 +230,11 @@
else
return 0
-
-/obj/structure/table/MouseDrop_T(obj/O, mob/user)
+/obj/structure/table/MouseDrop_T(atom/movable/O, mob/user)
+ if(ismob(O) && user == O && ishuman(user))
+ if(user.canmove)
+ climb_table(user)
+ return
if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O))
return
if(isrobot(user))
@@ -358,10 +360,6 @@
* TABLE CLIMBING
*/
-/obj/structure/table/MouseDrop_T(mob/target, mob/living/carbon/human/user)
- if(istype(target) && user == target && istype(user))
- if(user.canmove)
- climb_table(user)
/obj/structure/table/proc/climb_table(mob/user)
src.add_fingerprint(user)
@@ -494,21 +492,20 @@
if(1.0)
qdel(src)
if(2.0)
- qdel(src)
if(prob(50))
- new /obj/item/weapon/rack_parts(src.loc)
+ rack_destroy()
+ else
+ qdel(src)
if(3.0)
if(prob(25))
- qdel(src)
- new /obj/item/weapon/rack_parts(src.loc)
+ rack_destroy()
/obj/structure/rack/blob_act()
if(prob(75))
qdel(src)
return
else if(prob(50))
- new /obj/item/weapon/rack_parts(src.loc)
- qdel(src)
+ rack_destroy()
return
/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0)
@@ -534,9 +531,8 @@
/obj/structure/rack/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/wrench))
- new /obj/item/weapon/rack_parts( src.loc )
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- qdel(src)
+ rack_destroy()
return
if(isrobot(user))
@@ -559,38 +555,42 @@
"You kick [src].")
if(HULK in user.mutations)
- health -= 5
+ rack_destroy()
else
health -= rand(1,2)
- healthcheck()
+ healthcheck()
/obj/structure/rack/attack_alien(mob/living/user)
user.do_attack_animation(src)
visible_message("[user] slices [src] apart!")
- new /obj/item/weapon/rack_parts(loc)
- density = 0
- qdel(src)
+ rack_destroy()
/obj/structure/rack/attack_animal(mob/living/simple_animal/user)
if(user.environment_smash)
user.do_attack_animation(src)
visible_message("[user] smashes [src] apart!")
- new /obj/item/weapon/rack_parts(loc)
- density = 0
- qdel(src)
+ rack_destroy()
/obj/structure/rack/attack_tk() // no telehulk sorry
return
/obj/structure/rack/proc/healthcheck()
if(health <= 0)
- density = 0
- var/obj/item/weapon/rack_parts/newparts = new(loc)
- transfer_fingerprints_to(newparts)
- qdel(src)
+ rack_destroy()
return
+/*
+ * Rack destruction
+ */
+
+/obj/structure/rack/proc/rack_destroy()
+ density = 0
+ var/obj/item/weapon/rack_parts/newparts = new(loc)
+ transfer_fingerprints_to(newparts)
+ qdel(src)
+
+
/*
* Rack Parts
*/
diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm
index f1033633551..51f52b5de4c 100644
--- a/code/game/turfs/simulated/floor/light_floor.dm
+++ b/code/game/turfs/simulated/floor/light_floor.dm
@@ -8,7 +8,7 @@
luminosity = 5
icon_state = "light_on"
floor_tile = /obj/item/stack/tile/light
- broken_states = list("light-broken")
+ broken_states = list("light_broken")
var/on = 1
var/state //0 = fine, 1 = flickering, 2 = breaking, 3 = broken
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 5c90623466a..254b1c3ad20 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -374,4 +374,31 @@
item_state = "wcoat"
item_color = "black_tango"
fitted = 0
+ can_adjust = 0
+
+/obj/item/clothing/under/stripeddress
+ name = "striped dress"
+ desc = "Fashion in space."
+ icon_state = "striped_dress"
+ item_state = "stripeddress"
+ item_color = "striped_dress"
+ fitted = 0
+ can_adjust = 0
+
+/obj/item/clothing/under/sailordress
+ name = "sailor dress"
+ desc = "Formal wear for a leading lady."
+ icon_state = "sailor_dress"
+ item_state = "sailordress"
+ item_color = "sailor_dress"
+ fitted = 0
+ can_adjust = 0
+
+/obj/item/clothing/under/redeveninggown
+ name = "red evening gown"
+ desc = "Fancy dress for space bar singers."
+ icon_state = "red_evening_gown"
+ item_state = "redeveninggown"
+ item_color = "red_evening_gown"
+ fitted = 0
can_adjust = 0
\ No newline at end of file
diff --git a/code/modules/food&drinks/food/snacks_pastry.dm b/code/modules/food&drinks/food/snacks_pastry.dm
index 319b1db0562..af97eab4323 100644
--- a/code/modules/food&drinks/food/snacks_pastry.dm
+++ b/code/modules/food&drinks/food/snacks_pastry.dm
@@ -211,21 +211,10 @@
name = "\improper Donk-pocket"
desc = "The food of choice for the seasoned traitor."
icon_state = "donkpocket"
- var/warm = 0
/obj/item/weapon/reagent_containers/food/snacks/donkpocket/New()
..()
reagents.add_reagent("nutriment", 4)
- reagents.add_reagent("sugar", 5)
-
-/obj/item/weapon/reagent_containers/food/snacks/donkpocket/proc/cooltime() //Not working, derp?
- if(warm)
- spawn(4200) //ew
- warm = 0
- reagents.del_reagent("tricordrazine")
- reagents.add_reagent("sugar", 5)
- name = initial(name)
- return
/obj/item/weapon/reagent_containers/food/snacks/fortunecookie
name = "fortune cookie"
diff --git a/code/modules/food&drinks/recipes/microwave/recipes_pastry.dm b/code/modules/food&drinks/recipes/microwave/recipes_pastry.dm
index 8320a99f771..b7621899467 100644
--- a/code/modules/food&drinks/recipes/microwave/recipes_pastry.dm
+++ b/code/modules/food&drinks/recipes/microwave/recipes_pastry.dm
@@ -71,34 +71,10 @@
/datum/recipe/donkpocket
reagents = list("flour" = 5)
items = list(
- /obj/item/weapon/reagent_containers/food/snacks/faggot,
+ /obj/item/weapon/reagent_containers/food/snacks/faggot
)
- result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket //SPECIAL
+ result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket
-/datum/recipe/donkpocket/proc/warm_up(var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked)
- being_cooked.warm = 1
- being_cooked.reagents.add_reagent("tricordrazine", 5)
- being_cooked.reagents.del_reagent("sugar")
- being_cooked.bitesize = 6
- being_cooked.name = "Warm " + being_cooked.name
- being_cooked.cooltime()
-
-/datum/recipe/donkpocket/make_food(var/obj/container as obj)
- var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = ..(container)
- warm_up(being_cooked)
- return being_cooked
-
-/datum/recipe/donkpocket/warm
- reagents = list() //This is necessary since this is a child object of the above recipe and we don't want donk pockets to need flour
- items = list(
- /obj/item/weapon/reagent_containers/food/snacks/donkpocket
- )
- result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket //SPECIAL
- make_food(var/obj/container as obj)
- var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = locate() in container
- if(being_cooked && !being_cooked.warm)
- warm_up(being_cooked)
- return being_cooked
////////////////////////////////////////////////MUFFINS////////////////////////////////////////////////
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index f7da665c052..703d4b577e0 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -301,3 +301,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return 0
usr.visible_message("[src] points to [A]")
return 1
+
+/mob/dead/observer/verb/view_manfiest()
+ set name = "View Crew Manifest"
+ set category = "Ghost"
+
+ var/dat
+ dat += "Crew Manifest
"
+ dat += data_core.get_manifest()
+
+ src << browse(dat, "window=manifest;size=370x420;can_close=1")
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 30c30cc6e0d..4b12eb1cf13 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -548,7 +548,7 @@ var/list/ai_list = list()
cleared = 1
L -= I
if (cleared)
- queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
+ queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
if (viewalerts) ai_alerts()
return !cleared
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 7a7b4ddc838..b3707f263cb 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -385,7 +385,7 @@
cleared = 1
L -= I
if (cleared)
- queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0)
+ queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
// if (viewalerts) robot_alerts()
return !cleared
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index fd087516a33..72c56c7f554 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -25,10 +25,13 @@
var/output = "Setup Character
"
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
- if(!ready) output += "Declare Ready
"
- else output += "You are ready Cancel
"
+ if(ready)
+ output += "\[ Ready | Not Ready \]
"
+ else
+ output += "\[ Ready | Not Ready \]
"
else
+ output += "View the Crew Manifest
"
output += "Join Game!
"
output += "Observe
"
@@ -98,7 +101,10 @@
return 1
if(href_list["ready"])
- ready = text2num(href_list["ready"])
+ if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
+ ready = !ready
+ else
+ ready = 0
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
@@ -136,6 +142,9 @@
return
LateChoices()
+ if(href_list["manifest"])
+ ViewManifest()
+
if(href_list["SelectedJob"])
if(!enter_allowed)
@@ -364,6 +373,12 @@
return new_character
+/mob/new_player/proc/ViewManifest()
+ var/dat = ""
+ dat += "Crew Manifest
"
+ dat += data_core.get_manifest(OOC = 1)
+
+ src << browse(dat, "window=manifest;size=370x420;can_close=1")
/mob/new_player/Move()
return 0
diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm
index 801d9b6e2e8..0f85597e0ec 100644
--- a/code/modules/projectiles/ammunition.dm
+++ b/code/modules/projectiles/ammunition.dm
@@ -73,21 +73,34 @@
stored_ammo.Insert(1,b)
return b
-/obj/item/ammo_box/proc/give_round(var/obj/item/ammo_casing/r)
- var/obj/item/ammo_casing/rb = r
- if (rb)
- if (stored_ammo.len < max_ammo && rb.caliber == caliber)
- stored_ammo += rb
- rb.loc = src
- return 1
+/obj/item/ammo_box/proc/give_round(var/obj/item/ammo_casing/R, var/replace_spent = 0)
+ if(!R || (R.caliber != caliber))
+ return 0
+
+ if (stored_ammo.len < max_ammo)
+ stored_ammo += R
+ R.loc = src
+ return 1
+
+ //for accessibles magazines (e.g internal ones) when full, start replacing spent ammo
+ else if(replace_spent)
+ for(var/obj/item/ammo_casing/AC in stored_ammo)
+ if(!AC.BB)//found a spent ammo
+ stored_ammo -= AC
+ AC.loc = get_turf(src.loc)
+
+ stored_ammo += R
+ R.loc = src
+ return 1
+
return 0
-/obj/item/ammo_box/attackby(var/obj/item/A as obj, mob/user as mob, var/silent = 0)
+/obj/item/ammo_box/attackby(var/obj/item/A as obj, mob/user as mob, var/silent = 0, var/replace_spent = 0)
var/num_loaded = 0
if(istype(A, /obj/item/ammo_box))
var/obj/item/ammo_box/AM = A
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
- var/did_load = give_round(AC)
+ var/did_load = give_round(AC, replace_spent)
if(did_load)
AM.stored_ammo -= AC
num_loaded++
@@ -95,17 +108,18 @@
break
if(istype(A, /obj/item/ammo_casing))
var/obj/item/ammo_casing/AC = A
- if(give_round(AC))
+ if(give_round(AC, replace_spent))
user.drop_item()
AC.loc = src
num_loaded++
+
if(num_loaded)
if(!silent)
user << "You load [num_loaded] shell\s into \the [src]!"
A.update_icon()
update_icon()
- return num_loaded
- return 0
+
+ return num_loaded
/obj/item/ammo_box/attack_self(mob/user as mob)
var/obj/item/ammo_casing/A = get_round()
diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm
index d901f87c4a9..f9d3c7410a0 100644
--- a/code/modules/projectiles/ammunition/magazines.dm
+++ b/code/modules/projectiles/ammunition/magazines.dm
@@ -1,4 +1,9 @@
////////////////INTERNAL MAGAZINES//////////////////////
+
+//internals magazines are accessible, so replace spent ammo if full when trying to put a live one in
+/obj/item/ammo_box/magazine/internal/give_round(var/obj/item/ammo_casing/R)
+ return ..(R,1)
+
/obj/item/ammo_box/magazine/internal/cylinder
name = "revolver cylinder"
desc = "Oh god, this shouldn't be here"
diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm
index 8abcea10af0..c5f2b3a0e7d 100644
--- a/code/modules/projectiles/firing.dm
+++ b/code/modules/projectiles/firing.dm
@@ -34,7 +34,7 @@
return 0
if(targloc == curloc) //Fire the projectile
user.bullet_act(BB)
- qdel(BB)
+ del(BB)
return 1
BB.loc = get_turf(user)
BB.starting = get_turf(user)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 97e0779a17f..240b2378209 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -1,3 +1,7 @@
+ #define SAWN_INTACT 0
+ #define SAWN_OFF 1
+ #define SAWN_SAWING -1
+
/obj/item/weapon/gun
name = "gun"
desc = "It's a gun. It's pretty terrible, though."
@@ -23,6 +27,7 @@
var/obj/item/ammo_casing/chambered = null
var/trigger_guard = 1
var/sawn_desc = null
+ var/sawn_state = SAWN_INTACT
/obj/item/weapon/gun/proc/process_chamber()
return 0
@@ -30,12 +35,17 @@
/obj/item/weapon/gun/proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver.
return 1
+//check if there's enough ammo/energy/whatever to shoot one time
+//i.e if clicking would make it shoot
+/obj/item/weapon/gun/proc/can_shoot()
+ return 1
+
/obj/item/weapon/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
user << "*click*"
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
-/obj/item/weapon/gun/proc/shoot_live_shot(mob/living/user as mob|obj, var/pointblank = 0, var/mob/pbtarget = null)
+/obj/item/weapon/gun/proc/shoot_live_shot(mob/living/user as mob|obj, var/pointblank = 0, var/mob/pbtarget = null, var/message = 1)
if(recoil)
spawn()
shake_camera(user, recoil + 1, recoil)
@@ -44,6 +54,8 @@
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 50, 1)
+ if(!message)
+ return
if(pointblank)
user.visible_message("[user] fires [src] point blank at [pbtarget]!", "You fire [src] point blank at [pbtarget]!", "You hear a [istype(src, /obj/item/weapon/gun/energy) ? "laser blast" : "gunshot"]!")
else
@@ -62,43 +74,53 @@
return
//Exclude lasertag guns from the CLUMSY check.
- if(clumsy_check)
+ if(clumsy_check && can_shoot())
if(istype(user, /mob/living))
var/mob/living/M = user
if ((CLUMSY in M.mutations) && prob(40))
- M << "You shoot yourself in the foot with \the [src]!"
- afterattack(user, user)
+ user << "You shoot yourself in the foot with \the [src]!"
+ process_fire(user,user,0,params)
M.drop_item()
return
+ if(isliving(user))
+ var/mob/living/L = user
+ if(!can_trigger_gun(L))
+ return
+
+ process_fire(target,user,flag,params)
+
+/obj/item/weapon/gun/proc/can_trigger_gun(mob/living/user)
if (!user.IsAdvancedToolUser())
user << "You don't have the dexterity to do this!"
- return
+ return 0
if(trigger_guard)
- if(istype(user, /mob/living))
- var/mob/living/M = user
- if (HULK in M.mutations)
- M << "Your meaty finger is much too large for the trigger guard!"
- return
+ if (HULK in user.mutations)
+ user << "Your meaty finger is much too large for the trigger guard!"
+ return 0
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna && NOGUNS in H.dna.species.specflags)
user << "Your fingers don't fit in the trigger guard!"
- return
+ return 0
+ return 1
+
+/obj/item/weapon/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, var/message = 1, params)
add_fingerprint(user)
+ if(!special_check(user))
+ return
+
if(chambered)
if(!chambered.fire(target, user, params, , suppressed))
shoot_with_empty_chamber(user)
else
- if(!special_check(user))
- return
if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
- shoot_live_shot(user, 1, target)
+ shoot_live_shot(user, 1, target,message)
else
- shoot_live_shot(user)
+ shoot_live_shot(user,message)
else
shoot_with_empty_chamber(user)
process_chamber()
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 08351551243..4c407cd5a20 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -35,7 +35,9 @@
/obj/item/weapon/gun/energy/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params)
newshot() //prepare a new shot
..()
-
+/obj/item/weapon/gun/energy/can_shoot()
+ var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ return power_supply.charge >= shot.e_cost
/obj/item/weapon/gun/energy/proc/newshot()
if (!ammo_type || !power_supply)
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index ebace57085b..75d5a076186 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -125,9 +125,11 @@ obj/item/weapon/gun/energy/laser/retro
/obj/item/weapon/gun/energy/laser/bluetag/process()
charge_tick++
- if(charge_tick < 4) return 0
+ if(charge_tick < 4)
+ return 0
charge_tick = 0
- if(!power_supply) return 0
+ if(!power_supply)
+ return 0
power_supply.give(100)
update_icon()
return 1
@@ -162,9 +164,11 @@ obj/item/weapon/gun/energy/laser/retro
/obj/item/weapon/gun/energy/laser/redtag/process()
charge_tick++
- if(charge_tick < 4) return 0
+ if(charge_tick < 4)
+ return 0
charge_tick = 0
- if(!power_supply) return 0
+ if(!power_supply)
+ return 0
power_supply.give(100)
update_icon()
return 1
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index f9a0be82b99..c575632c498 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -29,6 +29,9 @@
no_den_usage = 0
..()
+/obj/item/weapon/gun/magic/can_shoot()
+ return charges
+
/obj/item/weapon/gun/magic/proc/newshot()
if (charges && chambered)
chambered.newshot()
diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm
index d2c6a9a29ba..b1540df35b9 100644
--- a/code/modules/projectiles/guns/projectile.dm
+++ b/code/modules/projectiles/guns/projectile.dm
@@ -40,6 +40,11 @@
chambered.loc = src
return
+/obj/item/weapon/gun/projectile/can_shoot()
+ if(!magazine || !magazine.ammo_count(0))
+ return 0
+ return 1
+
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
..()
if (istype(A, /obj/item/ammo_box/magazine))
diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm
index 6cfa117be6a..10763b224d3 100644
--- a/code/modules/projectiles/guns/projectile/automatic.dm
+++ b/code/modules/projectiles/guns/projectile/automatic.dm
@@ -17,6 +17,9 @@
if(..() && chambered)
alarmed = 0
+/obj/item/weapon/gun/projectile/automatic/can_shoot()
+ return get_ammo()
+
/obj/item/weapon/gun/projectile/automatic/proc/empty_alarm()
if(!chambered && !get_ammo() && !alarmed)
playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 7188ce64cbc..c829cff0c4a 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -5,7 +5,7 @@
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
/obj/item/weapon/gun/projectile/revolver/chamber_round()
- if (chambered || !magazine)
+ if ((chambered && chambered.BB)|| !magazine) //if there's a live ammo in the chamber or no magazine
return
else if (magazine.ammo_count())
chambered = magazine.get_round(1)
@@ -37,6 +37,9 @@
else
user << "[src] is empty."
+/obj/item/weapon/gun/projectile/revolver/can_shoot()
+ return get_ammo(0,0)
+
/obj/item/weapon/gun/projectile/revolver/get_ammo(var/countchambered = 0, var/countempties = 1)
var/boolets = 0 //mature var names for mature people
if (chambered && countchambered)
@@ -172,7 +175,7 @@
return
/obj/item/weapon/gun/projectile/revolver/russian/attack_self(mob/user as mob)
- if(!spun && get_ammo(0,0))
+ if(!spun && can_shoot())
user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.")
Spin()
else
@@ -190,34 +193,35 @@
user << "[src] is empty."
/obj/item/weapon/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params)
- if(!spun && get_ammo(0,0))
- user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.")
- Spin()
- ..()
- spun = 0
-
-/obj/item/weapon/gun/projectile/revolver/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj)
- if(!spun && get_ammo(0,0))
- user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.")
- Spin()
+ if(user.a_intent == "harm") // Flogging action
+ return
+ if(isliving(user))
+ if(!can_trigger_gun(user))
+ return
+ if(target != user)
+ user << "A mechanism prevents you from shooting anyone but yourself."
return
-
- if(target == user)
- if(!chambered)
- user.visible_message("*click*", "*click*")
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(!spun)
+ user << "You need to spin the revolver's chamber first."
return
- if(isliving(target) && isliving(user))
- var/obj/item/organ/limb/affecting = user.zone_sel.selecting
- if(affecting == "head")
- var/obj/item/ammo_casing/AC = chambered
- if(AC.fire(user, user))
+ spun = 0
+
+ if(chambered)
+ var/obj/item/ammo_casing/AC = chambered
+ if(AC.fire(user, user))
+ playsound(user, fire_sound, 50, 1)
+ var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting))
+ var/limb_name = affecting.getDisplayName()
+ if(affecting == "head" || affecting == "eyes" || affecting == "mouth")
user.apply_damage(300, BRUTE, affecting)
- playsound(user, fire_sound, 50, 1)
- user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a [istype(AC.BB, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
- return
+ user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a gunshot!")
else
- user.visible_message("*click*", "*click*")
- return
- ..()
+ user.visible_message("[user.name] cowardly fires [src] at \his [limb_name]!", "You cowardly fire [src] at your [limb_name]!", "You hear a gunshot!")
+ return
+
+ user.visible_message("*click*")
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index 1858059454a..9683e458354 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -25,6 +25,11 @@
/obj/item/weapon/gun/projectile/shotgun/chamber_round()
return
+/obj/item/weapon/gun/projectile/shotgun/can_shoot()
+ if(!chambered)
+ return 0
+ return (chambered.BB ? 1 : 0)
+
/obj/item/weapon/gun/projectile/shotgun/attack_self(mob/living/user)
if(recentpump) return
pump(user)
@@ -69,8 +74,12 @@
/obj/item/weapon/gun/projectile/shotgun/riot/attackby(var/obj/item/A as obj, mob/user as mob)
..()
- if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
+ if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
sawoff(user)
+ if(istype(A, /obj/item/weapon/melee/energy))
+ var/obj/item/weapon/melee/energy/W = A
+ if(W.active)
+ sawoff(user)
/obj/item/weapon/gun/projectile/revolver/doublebarrel
name = "double-barreled shotgun"
@@ -89,27 +98,13 @@
..()
if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing))
chamber_round()
- if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
+ if(istype(A, /obj/item/weapon/melee/energy))
+ var/obj/item/weapon/melee/energy/W = A
+ if(W.active)
+ sawoff(user)
+ if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
sawoff(user)
-/obj/item/weapon/gun/projectile/proc/sawoff(mob/user as mob)
- user << "You begin to shorten \the [src]."
- if(get_ammo())
- afterattack(user, user)
- user.visible_message("The [src] goes off!", "The [src] goes off in your face!")
- return
- if(do_after(user, 30))
- name = "sawn-off [src.name]"
- desc = sawn_desc
- icon_state = initial(icon_state) + "-sawn"
- w_class = 3.0
- item_state = "gun"
- slot_flags &= ~SLOT_BACK //you can't sling it on your back
- slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
- user << "You shorten \the [src]!"
- update_icon()
- return
-
/obj/item/weapon/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user as mob)
var/num_unloaded = 0
while (get_ammo() > 0)
@@ -140,7 +135,7 @@
/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(var/obj/item/A as obj, mob/user as mob)
..()
- if(istype(A, /obj/item/stack/cable_coil))
+ if(istype(A, /obj/item/stack/cable_coil) && !sawn_state)
var/obj/item/stack/cable_coil/C = A
if(C.use(10))
flags = CONDUCT
@@ -150,4 +145,55 @@
update_icon()
else
user << "You need at least ten lengths of cable if you want to make a sling."
- return
\ No newline at end of file
+ return
+
+//Sawing guns related procs
+/obj/item/weapon/gun/projectile/proc/blow_up(mob/user as mob)
+ . = 0
+ for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
+ if(AC.BB)
+ process_fire(user, user)
+ . = 1
+
+/obj/item/weapon/gun/projectile/shotgun/blow_up(mob/user as mob)
+ . = 0
+ if(chambered && chambered.BB)
+ process_fire(user, user,0)
+ . = 1
+ for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
+ if(AC.BB)
+ chambered = AC
+ process_fire(user, user,0)
+ . = 1
+
+/obj/item/weapon/gun/projectile/proc/sawoff(mob/user as mob)
+ if(sawn_state == SAWN_OFF)
+ user << "\The [src] is already shorten."
+ return
+
+ if(sawn_state == SAWN_SAWING)
+ return
+
+ user.visible_message("[user] begin to shorten \the [src].", "You begin to shorten \the [src].")
+
+ //if there's any live ammo inside the gun, makes it go off
+ if(blow_up(user))
+ user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!")
+ return
+
+ sawn_state = SAWN_SAWING
+
+ if(do_after(user, 30))
+ name = "sawn-off [src.name]"
+ desc = sawn_desc
+ icon_state = initial(icon_state) + "-sawn"
+ w_class = 3.0
+ item_state = "gun"
+ slot_flags &= ~SLOT_BACK //you can't sling it on your back
+ slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
+ sawn_state = SAWN_OFF
+ user.visible_message("[user] shorten \the [src]!", "You shorten \the [src]!")
+ update_icon()
+ return
+ else
+ sawn_state = SAWN_INTACT
\ No newline at end of file
diff --git a/config/admins.txt b/config/admins.txt
index c56f60cb022..cec937826ec 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -71,3 +71,5 @@ xxnoob = Game Master
tkdrg = Game Master
Cuboos = Game Master
thunder12345 = Game Master
+wjohnston = Game Master
+mandurrh = Game Master
diff --git a/icons/mob/ears.dmi b/icons/mob/ears.dmi
index 8ff02f67652..fe9e2b691e7 100644
Binary files a/icons/mob/ears.dmi and b/icons/mob/ears.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 63275683038..045ac438a26 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index cee8a1f8dfe..00c696ff1f1 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index a7899f1235e..899ea046085 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 2e3699a733d..fbfafed94df 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi
index 00b0ba43ba1..bab5533b140 100644
Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index 11f6989810f..3513601fede 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 37c6e4af66d..d258dd1d68c 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index de4a3f70959..81a2fb808b8 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index 994cee57532..efe92414824 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ