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 = {" + + + + "} + 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 += "" + for(name in heads) + dat += "" + even = !even + if(sec.len > 0) + dat += "" + for(name in sec) + dat += "" + even = !even + if(eng.len > 0) + dat += "" + for(name in eng) + dat += "" + even = !even + if(med.len > 0) + dat += "" + for(name in med) + dat += "" + even = !even + if(sci.len > 0) + dat += "" + for(name in sci) + dat += "" + even = !even + if(civ.len > 0) + dat += "" + for(name in civ) + dat += "" + even = !even + // in case somebody is insane and added them to the manifest, why not + if(bot.len > 0) + dat += "" + for(name in bot) + dat += "" + even = !even + // misc guys + if(misc.len > 0) + dat += "" + for(name in misc) + dat += "" + even = !even + + dat += "
NameRank
Heads
[name][heads[name]]
Security
[name][sec[name]]
Engineering
[name][eng[name]]
Medical
[name][med[name]]
Science
[name][sci[name]]
Civilian
[name][civ[name]]
Silicon
[name][bot[name]]
Miscellaneous
[name][misc[name]]
" + 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