diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index f7098594a93..a379c5706f9 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -93,14 +93,15 @@ 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) + 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) qdel(src) /obj/machinery/atmospherics/proc/nullifyPipenet(datum/pipeline/P) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index a6ecae8b300..928561abe94 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1260,6 +1260,18 @@ var/global/list/common_tools = list( return 1000 else return 0 + if(istype(W, /obj/item/candle)) + var/obj/item/candle/O = W + if(O.lit) + return 1000 + else + return 0 + if(istype(W, /obj/item/device/flashlight/flare)) + var/obj/item/device/flashlight/flare/O = W + if(O.on) + return 1000 + else + return 0 if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) return 3800 if(istype(W, /obj/item/weapon/melee/energy)) @@ -1302,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) @@ -1393,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/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/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/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index dbb47efeab8..8cd861754a4 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -211,207 +211,104 @@ That prevents a few funky behaviors. */ //What operation to perform based on target, what ineraction to perform based on object used, target itself, user. The object used is src and calls this proc. /obj/item/proc/transfer_ai(var/choice as text, var/interaction as text, var/target, var/mob/U as mob) - if(!src:flush) - switch(choice) - if("AICORE")//AI mob. - var/mob/living/silicon/ai/T = target - if(!T.mind) - U << "No intelligence patterns detected." //No more magical carding of empty cores, AI RETURN TO BODY!!!11 - return - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - if(C.contents.len)//If there is an AI on card. - U << "Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one." + if(istype(src, /obj/item/device/aicard)) + var/obj/item/device/aicard/icard = src + if(icard.flush) + U << "ERROR: AI flush is in progress, cannot execute transfer protocol." + return + + switch(choice) + if("AICORE")//AI mob. + var/mob/living/silicon/ai/T = target + if(!T.mind) + U << "No intelligence patterns detected." //No more magical carding of empty cores, AI RETURN TO BODY!!!11 + return + switch(interaction) + if("AICARD") + var/obj/item/device/aicard/C = src + if(C.contents.len)//If there is an AI on card. + U << "Transfer failed: Existing AI found on this terminal. Remove existing AI to install a new one." + else + if (ticker.mode.name == "AI malfunction") + var/datum/game_mode/malfunction/malf = ticker.mode + for (var/datum/mind/malfai in malf.malf_ai) + if (T.mind == malfai) + U << "ERROR: Remote transfer interface disabled."//Do ho ho ho~ + return + new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location. + T.aiRestorePowerRoutine = 0//So the AI initially has power. + T.control_disabled = 1//Can't control things remotely if you're stuck in a card! + T.radio_enabled = 0 //No talking on the built-in radio for you either! + T.loc = C//Throw AI into the card. + C.name = "intelliCard - [T.name]" + if (T.stat == 2) + C.icon_state = "aicard-404" else - if (ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if (T.mind == malfai) - U << "ERROR: \black Remote transfer interface disabled."//Do ho ho ho~ - return - new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location. - T.aiRestorePowerRoutine = 0//So the AI initially has power. - T.control_disabled = 1//Can't control things remotely if you're stuck in a card! - T.radio_enabled = 0 //No talking on the built-in radio for you either! - T.loc = C//Throw AI into the card. - C.name = "inteliCard - [T.name]" - if (T.stat == 2) + C.icon_state = "aicard-full" + T.cancel_camera() + T << "You have been downloaded to a mobile storage device. Remote device connection severed." + U << "Transfer successful: [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." + + if("INACTIVE")//Inactive AI object. + var/obj/structure/AIcore/deactivated/T = target + switch(interaction) + if("AICARD") + var/obj/item/device/aicard/C = src + var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever. + if(A)//If AI exists on the card. Else nothing since both are empty. + A.control_disabled = 0 + A.radio_enabled = 1 + A.loc = T.loc//To replace the terminal. + C.icon_state = "aicard" + C.name = "intelliCard" + C.overlays.Cut() + A.cancel_camera() + A << "You have been uploaded to a stationary terminal. Remote device connection restored." + U << "Transfer successful: [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." + qdel(T) + + if("AIFIXER")//AI Fixer terminal. + var/obj/machinery/computer/aifixer/T = target + switch(interaction) + if("AICARD") + var/obj/item/device/aicard/C = src + if(!T.contents.len) + if (!C.contents.len) + U << "No AI to copy over!"//Well duh + else for(var/mob/living/silicon/ai/A in C) + C.icon_state = "aicard" + C.name = "intelliCard" + C.overlays.Cut() + A.loc = T + T.occupier = A + A.control_disabled = 1 + A.radio_enabled = 0 + if (A.stat == 2) + T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404") + else + T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") + T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty") + A.cancel_camera() + A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here." + U << "Transfer successful: [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." + else + if(!C.contents.len && T.occupier && !T.active) + C.name = "intelliCard - [T.occupier.name]" + T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") + if (T.occupier.stat == 2) C.icon_state = "aicard-404" + T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404") else C.icon_state = "aicard-full" - T.cancel_camera() - T << "You have been downloaded to a mobile storage device. Remote device connection severed." - U << "Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - if("NINJASUIT") - var/obj/item/clothing/suit/space/space_ninja/C = src - if(C.AI)//If there is an AI on card. - U << "Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one." - else - if (ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if (T.mind == malfai) - U << "ERROR: \black Remote transfer interface disabled." - return - if(T.stat)//If the ai is dead/dying. - U << "ERROR: \black [T.name] data core is corrupted. Unable to install." - else - new /obj/structure/AIcore/deactivated(T.loc) - T.aiRestorePowerRoutine = 0 - T.control_disabled = 1 - T.radio_enabled = 0 - T.loc = C - C.AI = T - T.cancel_camera() - T << "You have been downloaded to a mobile storage device. Remote device connection severed." - U << "Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - - if("INACTIVE")//Inactive AI object. - var/obj/structure/AIcore/deactivated/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever. - if(A)//If AI exists on the card. Else nothing since both are empty. - A.control_disabled = 0 - A.radio_enabled = 1 - A.loc = T.loc//To replace the terminal. - C.icon_state = "aicard" - C.name = "inteliCard" - C.overlays.Cut() - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Remote device connection restored." - U << "Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." - qdel(T) - if("NINJASUIT") - var/obj/item/clothing/suit/space/space_ninja/C = src - var/mob/living/silicon/ai/A = C.AI - if(A) - A.control_disabled = 0 - A.radio_enabled = 1 - C.AI = null - A.loc = T.loc - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Remote device connection restored." - U << "Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." - qdel(T) - if("AIFIXER")//AI Fixer terminal. - var/obj/machinery/computer/aifixer/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - if(!T.contents.len) - if (!C.contents.len) - U << "No AI to copy over!"//Well duh - else for(var/mob/living/silicon/ai/A in C) - C.icon_state = "aicard" - C.name = "inteliCard" - C.overlays.Cut() - A.loc = T - T.occupier = A - A.control_disabled = 1 - A.radio_enabled = 0 - if (A.stat == 2) - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404") - else - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty") - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here." - U << "Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." - else - if(!C.contents.len && T.occupier && !T.active) - C.name = "inteliCard - [T.occupier.name]" - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") - if (T.occupier.stat == 2) - C.icon_state = "aicard-404" - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404") - else - C.icon_state = "aicard-full" - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full") - T.occupier << "You have been downloaded to a mobile storage device. Still no remote access." - U << "Transfer successful: \black [T.occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - T.occupier.loc = C - T.occupier.cancel_camera() - T.occupier = null - else if (C.contents.len) - U << "ERROR: \black Artificial intelligence detected on terminal." - else if (T.active) - U << "ERROR: \black Reconstruction in progress." - else if (!T.occupier) - U << "ERROR: \black Unable to locate artificial intelligence." - if("NINJASUIT") - var/obj/item/clothing/suit/space/space_ninja/C = src - if(!T.contents.len) - if (!C.AI) - U << "No AI to copy over!" - else - var/mob/living/silicon/ai/A = C.AI - A.loc = T - T.occupier = A - C.AI = null - A.control_disabled = 1 - A.radio_enabled = 0 - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty") - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here." - U << "Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." - else - if(!C.AI && T.occupier && !T.active) - if (T.occupier.stat) - U << "ERROR: \black [T.occupier.name] data core is corrupted. Unable to install." - else - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full") - T.occupier << "You have been downloaded to a mobile storage device. Still no remote access." - U << "Transfer successful: \black [T.occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - T.occupier.loc = C - T.occupier.cancel_camera() - T.occupier = null - else if (C.AI) - U << "ERROR: \black Artificial intelligence detected on terminal." - else if (T.active) - U << "ERROR: \black Reconstruction in progress." - else if (!T.occupier) - U << "ERROR: \black Unable to locate artificial intelligence." - if("NINJASUIT")//Ninjasuit - var/obj/item/clothing/suit/space/space_ninja/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - if(T.s_initialized&&U==T.affecting)//If the suit is initialized and the actor is the user. - - var/mob/living/silicon/ai/A_T = locate() in C//Determine if there is an AI on target card. Saves time when checking later. - var/mob/living/silicon/ai/A = T.AI//Deterine if there is an AI in suit. - - if(A)//If the host AI card is not empty. - if(A_T)//If there is an AI on the target card. - U << "ERROR: \black [A_T.name] already installed. Remove [A_T.name] to install a new one." - else - A.loc = C//Throw them into the target card. Since they are already on a card, transfer is easy. - C.name = "inteliCard - [A.name]" - C.icon_state = "aicard-full" - T.AI = null - A.cancel_camera() - A << "You have been uploaded to a mobile storage device." - U << "SUCCESS: \black [A.name] ([rand(1000,9999)].exe) removed from host and stored within local memory." - else//If host AI is empty. - if(C.flush)//If the other card is flushing. - U << "ERROR: \black AI flush is in progress, cannot execute transfer protocol." - else - if(A_T&&!A_T.stat)//If there is an AI on the target card and it's not inactive. - A_T.loc = T//Throw them into suit. - C.icon_state = "aicard" - C.name = "inteliCard" - C.overlays.Cut() - T.AI = A_T - A_T.cancel_camera() - A_T << "You have been uploaded to a mobile storage device." - U << "SUCCESS: \black [A_T.name] ([rand(1000,9999)].exe) removed from local memory and installed to host." - else if(A_T)//If the target AI is dead. Else just go to return since nothing would happen if both are empty. - U << "ERROR: \black [A_T.name] data core is corrupted. Unable to install." - else - U << "ERROR: \black AI flush is in progress, cannot execute transfer protocol." - return \ No newline at end of file + T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full") + T.occupier << "You have been downloaded to a mobile storage device. Still no remote access." + U << "Transfer successful: [T.occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." + T.occupier.loc = C + T.occupier.cancel_camera() + T.occupier = null + else if (C.contents.len) + U << "ERROR: Artificial intelligence detected on terminal." + else if (T.active) + U << "ERROR: Reconstruction in progress." + else if (!T.occupier) + U << "ERROR: Unable to locate artificial intelligence." \ No newline at end of file diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 2b3f208b9fe..44943554a88 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,6 +1,6 @@ /obj/machinery/computer/aifixer name = "\improper AI system integrity restorer" - desc = "Used with inteliCards containing nonfunctioning AIs to restore them to working order." + desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order." icon = 'icons/obj/computer.dmi' icon_state = "ai-fixer" req_access = list(access_captain, access_robotics, access_heads) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 617b2e43719..9d47eff072f 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 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/objects/items.dm b/code/game/objects/items.dm index 12bb5ad2f9e..029341e0188 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/aicard.dm b/code/game/objects/items/devices/aicard.dm index 94c273e62e3..40a78956230 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -1,5 +1,5 @@ /obj/item/device/aicard - name = "inteliCard" + name = "intelliCard" desc = "A storage device for AIs. Patent pending." icon = 'icons/obj/aicards.dmi' icon_state = "aicard" // aicard-full @@ -23,7 +23,7 @@ if (!in_range(src, user)) return user.set_machine(src) - var/dat = "Intelicard
" + var/dat = "Intellicard
" var/laws for(var/mob/living/silicon/ai/A in src) dat += "Stored AI: [A.name]
System integrity: [(A.health+100)/2]%
" @@ -107,7 +107,7 @@ if ("Wireless") for(var/mob/living/silicon/ai/A in src) A.control_disabled = !A.control_disabled - A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!" + A << "The intellicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!" if (A.control_disabled) overlays -= image('icons/obj/aicards.dmi', "aicard-on") else diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 14cadcc0a74..14d5d18ed58 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/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 4c41d33541d..4ff44ecbb84 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -22,6 +22,8 @@ syndie = 1//Signifies that it de-crypts Syndicate transmissions /obj/item/device/encryptionkey/binary + name = "binary translator key" + desc = "An encryption key for a radio headset. To access the binary channel, use :b." icon_state = "cypherkey" translate_binary = 1 origin_tech = "syndicate=3" diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 432e6f4bc3d..6cf2b1b36ac 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -14,7 +14,6 @@ /obj/item/device/radio/headset/New() ..() - keyslot = new /obj/item/device/encryptionkey/ recalculateChannels() /obj/item/device/radio/headset/Destroy() @@ -66,7 +65,7 @@ desc = "This is used by your elite security force. \nTo access the security channel, use :s." icon_state = "sec_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_sec + keyslot = new /obj/item/device/encryptionkey/headset_sec /obj/item/device/radio/headset/headset_sec/alt name = "security bowman headset" @@ -80,49 +79,49 @@ desc = "When the engineers wish to chat like girls. \nTo access the engineering channel, use :e. " icon_state = "eng_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_eng + keyslot = new /obj/item/device/encryptionkey/headset_eng /obj/item/device/radio/headset/headset_rob name = "robotics radio headset" desc = "Made specifically for the roboticists, who cannot decide between departments. \nTo access the engineering channel, use :e. For research, use :n." icon_state = "rob_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_rob + keyslot = new /obj/item/device/encryptionkey/headset_rob /obj/item/device/radio/headset/headset_med name = "medical radio headset" desc = "A headset for the trained staff of the medbay. \nTo access the medical channel, use :m." icon_state = "med_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_med + keyslot = new /obj/item/device/encryptionkey/headset_med /obj/item/device/radio/headset/headset_sci name = "science radio headset" desc = "A sciency headset. Like usual. \nTo access the science channel, use :n." icon_state = "sci_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_sci + keyslot = new /obj/item/device/encryptionkey/headset_sci /obj/item/device/radio/headset/headset_medsci name = "medical research radio headset" desc = "A headset that is a result of the mating between medical and science. \nTo access the medical channel, use :m. For science, use :n." icon_state = "medsci_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_medsci + keyslot = new /obj/item/device/encryptionkey/headset_medsci /obj/item/device/radio/headset/headset_com name = "command radio headset" desc = "A headset with a commanding channel. \nTo access the command channel, use :c." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_com + keyslot = new /obj/item/device/encryptionkey/headset_com /obj/item/device/radio/headset/heads/captain name = "\proper the captain's headset" desc = "The headset of the king. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/captain + keyslot = new /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/heads/captain/alt name = "\proper the captain's bowman headset" @@ -136,14 +135,14 @@ desc = "Headset of the fellow who keeps society marching towards technological singularity. \nTo access the science channel, use :n. For command, use :c." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/rd + keyslot = new /obj/item/device/encryptionkey/heads/rd /obj/item/device/radio/headset/heads/hos name = "\proper the head of security's headset" desc = "The headset of the man in charge of keeping order and protecting the station. \nTo access the security channel, use :s. For command, use :c." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/hos + keyslot = new /obj/item/device/encryptionkey/heads/hos /obj/item/device/radio/headset/heads/hos/alt name = "\proper the head of security's bowman headset" @@ -157,46 +156,46 @@ desc = "The headset of the guy in charge of keeping the station powered and undamaged. \nTo access the engineering channel, use :e. For command, use :c." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/ce + keyslot = new /obj/item/device/encryptionkey/heads/ce /obj/item/device/radio/headset/heads/cmo name = "\proper the chief medical officer's headset" desc = "The headset of the highly trained medical chief. \nTo access the medical channel, use :m. For command, use :c." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/cmo + keyslot = new /obj/item/device/encryptionkey/heads/cmo /obj/item/device/radio/headset/heads/hop name = "\proper the head of personnel's headset" desc = "The headset of the guy who will one day be captain. \nChannels are as follows: :u - supply, :v - service, :c - command." icon_state = "com_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/hop + keyslot = new /obj/item/device/encryptionkey/heads/hop /obj/item/device/radio/headset/headset_cargo name = "supply radio headset" desc = "A headset used by the QM and his slaves. \nTo access the supply channel, use :u." icon_state = "cargo_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_cargo + keyslot = new /obj/item/device/encryptionkey/headset_cargo /obj/item/device/radio/headset/headset_srv name = "service radio headset" desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean. \nTo access the service channel, use :v." icon_state = "srv_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_service + keyslot = new /obj/item/device/encryptionkey/headset_service /obj/item/device/radio/headset/headset_cent name = "\improper Centcom headset" desc = "A headset used by the upper echelons of Nanotrasen. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." icon_state = "cent_headset" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/captain + keyslot = new /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/ai name = "\proper Integrated Subspace Transceiver " - keyslot2 = new /obj/item/device/encryptionkey/ai + keyslot = new /obj/item/device/encryptionkey/ai /obj/item/device/radio/headset/ai/receive_range(freq, level) return ..(freq, level, 1) @@ -234,7 +233,7 @@ user << "You pop out the encryption keys in the headset!" else - user << "This headset doesn't have any encryption keys! How useless..." + user << "This headset doesn't have any unique encryption keys! How useless..." if(istype(W, /obj/item/device/encryptionkey/)) if(keyslot && keyslot2) @@ -277,15 +276,6 @@ for(var/ch_name in channels) - //this is the most hilarious piece of code i have seen this week, so im not going to remove it - /* - if(!radio_controller) - sleep(30) // Waiting for the radio_controller to be created. - if(!radio_controller) - src.name = "broken radio headset" - return - */ - secure_radio_connections[ch_name] = add_radio(src, radiochannels[ch_name]) return diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 966256487df..b58c54799bb 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -74,10 +74,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(!isliving(M)) return M.IgniteMob() - if(!istype(M,/mob/living/carbon)) - return - if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth" && lit) - var/obj/item/clothing/mask/cigarette/cig = M.wear_mask + var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M,user) + if(lit && cig) if(M == user) cig.attackby(src, user) else @@ -85,6 +83,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM else ..() +/obj/item/proc/help_light_cig(mob/living/carbon/M as mob, mob/living/carbon/user as mob) + if(!iscarbon(M)) + return + if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth") + var/obj/item/clothing/mask/cigarette/cig = M.wear_mask + return cig ////////////////// //FINE SMOKABLES// @@ -113,46 +117,21 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() + var/lighting_text = "[user] lights their [name] with [W]." if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.isOn())//Badasses dont get blinded while lighting their cig with a welding tool - light("[user] casually lights the [name] with [W], what a badass.") - + lighting_text = "[user] casually lights the [name] with [W], what a badass." else if(istype(W, /obj/item/weapon/lighter/zippo)) - var/obj/item/weapon/lighter/zippo/Z = W - if(Z.lit) - light("With a single flick of their wrist, [user] smoothly lights their [name] with [W]. Damn they're cool.") - + lighting_text = "With a single flick of their wrist, [user] smoothly lights their [name] with [W]. Damn they're cool." else if(istype(W, /obj/item/weapon/lighter)) - var/obj/item/weapon/lighter/L = W - if(L.lit) - light("After some fiddling, [user] manages to light their [name] with [W].") - - else if(istype(W, /obj/item/weapon/match)) - var/obj/item/weapon/match/M = W - if(M.lit == 1) //checking for lit = 1 instead of just lit prevents cigarettes being lit by used matches - light("[user] lights their [name] with [W].") - - else if(istype(W, /obj/item/weapon/melee/energy/sword)) - var/obj/item/weapon/melee/energy/sword/S = W - if(S.active) - light("[user] swings their [W], barely missing their nose. They light their [name] in the process.") - + lighting_text = "After some fiddling, [user] manages to light their [name] with [W]." + else if(istype(W, /obj/item/weapon/melee/energy)) + lighting_text = "[user] swings their [W], barely missing their nose. They light their [name] in the process." else if(istype(W, /obj/item/device/assembly/igniter)) - light("[user] fiddles with [W], and manages to light their [name].") - - else if(istype(W, /obj/item/clothing/mask/cigarette)) - var/obj/item/clothing/mask/cigarette/M = W - if(M.lit) - light("[user] lights their [name] with [W].") - else if(istype(W, /obj/item/candle)) - var/obj/item/candle/C = W - if(C.lit) - light("[user] lights their [name] with [W].") + lighting_text = "[user] fiddles with [W], and manages to light their [name]." else if(istype(W, /obj/item/device/flashlight/flare)) - var/obj/item/device/flashlight/flare/F = W - if(F.on) - light("[user] lights their [name] with [W] like a real badass.") + lighting_text = "[user] lights their [name] with [W] like a real badass." + if(is_hot(W)) + light(lighting_text) return /obj/item/clothing/mask/cigarette/afterattack(obj/item/weapon/reagent_containers/glass/glass, mob/user as mob, proximity) @@ -256,8 +235,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/cigarette/attack(mob/living/carbon/M, mob/living/carbon/user) if(!istype(M)) return ..() - if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_sel && user.zone_sel.selecting == "mouth" && lit) - var/obj/item/clothing/mask/cigarette/cig = M.wear_mask + var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M,user) + if(lit && cig) if(M == user) cig.attackby(src, user) else @@ -514,10 +493,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(!isliving(M)) return M.IgniteMob() - if(!istype(M,/mob/living/carbon)) - return - if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth" && lit) - var/obj/item/clothing/mask/cigarette/cig = M.wear_mask + var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M,user) + if(lit && cig) if(M == user) cig.attackby(src, user) else @@ -534,7 +511,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM location.hotspot_expose(700, 5) return - /obj/item/weapon/lighter/pickup(mob/user) if(lit) SetLuminosity(0) diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 498c4b334f9..12df49b5a23 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -1,5 +1,11 @@ /obj/item/weapon/melee/energy var/active = 0 + var/force_on = 30 //force when active + var/throwforce_on = 20 + var/icon_state_on = "axe1" + var/attack_verb_on = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + w_class = 2 + var/w_class_on = 4 /obj/item/weapon/melee/energy/suicide_act(mob/user) user.visible_message(pick("[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.", \ @@ -14,34 +20,22 @@ desc = "An energised battle axe." icon_state = "axe0" force = 40.0 - throwforce = 25.0 + force_on = 150 + throwforce = 25 + throwforce_on = 30 hitsound = 'sound/weapons/bladeslice.ogg' throw_speed = 3 throw_range = 5 - w_class = 3.0 + w_class = 3 + w_class_on = 5 flags = CONDUCT | NOSHIELD origin_tech = "combat=3" attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") + attack_verb_on = null /obj/item/weapon/melee/energy/axe/suicide_act(mob/user) - user.visible_message("[user] swings the [src.name] towards /his head! It looks like \he's trying to commit suicide.") - return (BRUTELOSS|FIRELOSS) - -/obj/item/weapon/melee/energy/axe/attack_self(mob/user) - active = !active - if(active) - user << "[src] is now energised." - force = 150 //these are the drugs, friend - hitsound = 'sound/weapons/blade1.ogg' - icon_state = "axe1" - w_class = 5 - else - user << "[src] can now be concealed." - force = 40 - hitsound = 'sound/weapons/bladeslice.ogg' - icon_state = "axe0" - w_class = 3 //it goes back to three you goose - add_fingerprint(user) + user.visible_message("[user] swings the [src.name] towards /his head! It looks like \he's trying to commit suicide.") + return (BRUTELOSS|FIRELOSS) /obj/item/weapon/melee/energy/sword name = "energy sword" @@ -52,11 +46,10 @@ hitsound = "swing_hit" //it starts deactivated throw_speed = 3 throw_range = 5 - w_class = 2.0 flags = NOSHIELD + attack_verb = null origin_tech = "magnets=3;syndicate=4" var/hacked = 0 - item_color = null /obj/item/weapon/melee/energy/sword/New() if(item_color == null) @@ -67,33 +60,31 @@ return 1 return 0 -/obj/item/weapon/melee/energy/sword/attack_self(mob/living/carbon/human/user) - if (user.disabilities & CLUMSY && prob(50)) +/obj/item/weapon/melee/energy/attack_self(mob/living/carbon/user) + if(user.disabilities & CLUMSY && prob(50)) user << "You accidentally cut yourself with [src], like a doofus!" user.take_organ_damage(5,5) active = !active if (active) - force = 30 - throwforce = 20 + force = force_on + throwforce = throwforce_on hitsound = 'sound/weapons/blade1.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - if(istype(src,/obj/item/weapon/melee/energy/sword/pirate)) - icon_state = "cutlass1" + if(attack_verb_on) + attack_verb = attack_verb_on + if(!item_color) + icon_state = icon_state_on else icon_state = "sword[item_color]" - w_class = 4 + w_class = w_class_on playsound(user, 'sound/weapons/saberon.ogg', 35, 1) //changed it from 50% volume to 35% because deafness user << "[src] is now active." else - force = 3 - throwforce = 5.0 - hitsound = "swing_hit" - attack_verb = null - if(istype(src,/obj/item/weapon/melee/energy/sword/pirate)) - icon_state = "cutlass0" - else - icon_state = "sword0" - w_class = 2 + force = initial(force) + throwforce = initial(throwforce) + hitsound = initial(hitsound) + attack_verb = initial(attack_verb) + icon_state = initial(icon_state) + w_class = initial(w_class) playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) //changed it from 50% volume to 35% because deafness user << "[src] can now be concealed." add_fingerprint(user) @@ -166,6 +157,10 @@ name = "energy cutlass" desc = "Arrrr matey." icon_state = "cutlass0" + icon_state_on = "cutlass1" + +/obj/item/weapon/melee/energy/sword/pirate/New() + return /obj/item/weapon/melee/energy/blade name = "energy blade" @@ -173,12 +168,12 @@ icon_state = "blade" force = 30 //Normal attacks deal esword damage hitsound = 'sound/weapons/blade1.ogg' + active = 1 throwforce = 1//Throwing or dropping the item deletes it. throw_speed = 3 throw_range = 1 w_class = 4.0//So you can't hide it in your pocket or some such. flags = NOSHIELD - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/datum/effect/effect/system/spark_spread/spark_system //Most of the other special functions are handled in their own files. aka special snowflake code so kewl @@ -192,3 +187,6 @@ /obj/item/weapon/melee/energy/blade/proc/throw() qdel(src) + +/obj/item/weapon/melee/energy/blade/attack_self(mob/user) + return 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/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/gloves/ninja.dm b/code/modules/clothing/gloves/ninja.dm index 3ec928c9e29..0b05f32fb8d 100644 --- a/code/modules/clothing/gloves/ninja.dm +++ b/code/modules/clothing/gloves/ninja.dm @@ -46,65 +46,39 @@ if(!proximity) // todo: you could add ninja stars or computer hacking here return 0 - // Move an AI into and out of things - if(istype(A,/mob/living/silicon/ai)) - if(suit.s_control) - A.add_fingerprint(H) - suit.transfer_ai("AICORE", "NINJASUIT", A, H) - return 1 - else - H << "ERROR: \black Remote access channel disabled." - return 0 - - if(istype(A,/obj/structure/AIcore/deactivated)) - if(suit.s_control) - A.add_fingerprint(H) - suit.transfer_ai("INACTIVE","NINJASUIT",A, H) - return 1 - else - H << "ERROR: \black Remote access channel disabled." - return 0 - if(istype(A,/obj/machinery/computer/aifixer)) - if(suit.s_control) - A.add_fingerprint(H) - suit.transfer_ai("AIFIXER","NINJASUIT",A, H) - return 1 - else - H << "ERROR: \black Remote access channel disabled." - return 0 + A.add_fingerprint(H) // steal energy from powered things if(istype(A,/mob/living/silicon/robot)) - A.add_fingerprint(H) drain("CYBORG",A,suit) return 1 + if(istype(A,/obj/machinery/power/apc)) - A.add_fingerprint(H) drain("APC",A,suit) return 1 + if(istype(A,/obj/structure/cable)) - A.add_fingerprint(H) drain("WIRE",A,suit) return 1 + if(istype(A,/obj/structure/grille)) var/obj/structure/cable/C = locate() in A.loc if(C) drain("WIRE",C,suit) return 1 + if(istype(A,/obj/machinery/power/smes)) - A.add_fingerprint(H) drain("SMES",A,suit) return 1 + if(istype(A,/obj/mecha)) - A.add_fingerprint(H) drain("MECHA",A,suit) return 1 - // download research - if(istype(A,/obj/machinery/computer/rdconsole)) - A.add_fingerprint(H) + if(istype(A,/obj/machinery/computer/rdconsole)) // download research drain("RESEARCH",A,suit) return 1 + if(istype(A,/obj/machinery/r_n_d/server)) A.add_fingerprint(H) var/obj/machinery/r_n_d/server/S = A @@ -116,3 +90,15 @@ drain("RESEARCH",A,suit) return 1 + //do AI transfers + if(istype(A,/mob/living/silicon/ai)) + suit.NAI.transfer_ai("AICORE", "AICARD", A, H) + return 1 + + if(istype(A,/obj/structure/AIcore/deactivated)) + suit.NAI.transfer_ai("INACTIVE","AICARD",A, H) + return 1 + + if(istype(A,/obj/machinery/computer/aifixer)) + suit.NAI.transfer_ai("AIFIXER","AICARD",A, H) + return 1 diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 28d8d3ff50c..256138f8beb 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -44,7 +44,6 @@ name = "detective's fedora" desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat." icon_state = "detective" - allowed = list(/obj/item/weapon/reagent_containers/food/snacks/candy_corn, /obj/item/weapon/pen) armor = list(melee = 50, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) //Mime diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm index 5aa48fa2b6f..47d2d3aede6 100644 --- a/code/modules/clothing/spacesuits/ninja.dm +++ b/code/modules/clothing/spacesuits/ninja.dm @@ -3,7 +3,6 @@ name = "ninja hood" icon_state = "s-ninja" item_state = "s-ninja_mask" - allowed = list(/obj/item/weapon/stock_parts/cell) armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25) strip_delay = 12 unacidable = 1 @@ -56,8 +55,11 @@ var/a_boost = 3.0//Number of adrenaline boosters. //Onboard AI related variables. - var/mob/living/silicon/ai/AI//If there is an AI inside the suit. + + var/obj/item/device/aicard/NAI //Integrated intellicard. + var/obj/item/device/paicard/pai//A slot for a pAI device + var/obj/effect/overlay/hologram//Is the AI hologram on or off? Visible only to the wearer of the suit. This works by attaching an image to a blank overlay. - var/flush = 0//If an AI purge is in progress. + var/s_control = 1//If user in control of the suit. diff --git a/code/modules/events/ninja.dm b/code/modules/events/ninja.dm index 0b24c0b8a55..29c7f0e613b 100644 --- a/code/modules/events/ninja.dm +++ b/code/modules/events/ninja.dm @@ -172,7 +172,7 @@ Ninja.internals.icon_state = "internal1" if(Ninja.mind != Mind) //something has gone wrong! - ERROR("The ninja wasn't assigned the right mind. ;ç;") + ERROR("The ninja wasn't assigned the right mind. ;ç;") Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one @@ -404,17 +404,17 @@ ________________________________________________________________________________ U:gloves.item_state = "s-ninjan" else if(U.mind.special_role!="Space Ninja") - U << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..." + U << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..." U.gib() return 0 if(!istype(U:head, /obj/item/clothing/head/helmet/space/space_ninja)) - U << "ERROR: 100113 \black UNABLE TO LOCATE HEAD GEAR\nABORTING..." + U << "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING..." return 0 if(!istype(U:shoes, /obj/item/clothing/shoes/space_ninja)) - U << "ERROR: 122011 \black UNABLE TO LOCATE FOOT GEAR\nABORTING..." + U << "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING..." return 0 if(!istype(U:gloves, /obj/item/clothing/gloves/space_ninja)) - U << "ERROR: 110223 \black UNABLE TO LOCATE HAND GEAR\nABORTING..." + U << "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING..." return 0 affecting = U @@ -570,7 +570,7 @@ ________________________________________________________________________________ U.incorporeal_move = 0 kamikaze = 0 k_unlock = 0 - U << "Disengaging mode...\n\blackCODE NAME: KAMIKAZE" + U << "Disengaging mode...\nCODE NAME: KAMIKAZE" //=======//AI VERBS//=======// @@ -1088,12 +1088,13 @@ ________________________________________________________________________________ reagent_id == "radium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account radium used for adrenaline boosting. cell = new/obj/item/weapon/stock_parts/cell/high//The suit should *always* have a battery because so many things rely on it. cell.charge = 9000//Starting charge should not be higher than maximum charge. It leads to problems with recharging. + NAI = new(src) //ninja intellicard /obj/item/clothing/suit/space/space_ninja/Destroy() if(affecting)//To make sure the window is closed. affecting << browse(null, "window=hack spideros") if(AI)//If there are AIs present when the ninja kicks the bucket. - killai() + killai(NAI) if(hologram)//If there is a hologram qdel(hologram.i_attached)//Delete it and the attached image. qdel(hologram) @@ -1106,15 +1107,18 @@ ________________________________________________________________________________ qdel(n_shoes) qdel(src) -/obj/item/clothing/suit/space/space_ninja/proc/killai(mob/living/silicon/ai/A = AI) - if(A.client) - A << "Self-erase protocol dete-- *bzzzzz*" - A << browse(null, "window=hack spideros") - AI = null - A.death(1)//Kill, deleting mob. - qdel(A) + + +/obj/item/clothing/suit/space/space_ninja/proc/killai(var/obj/item/device/aicard/NAI) + for(var/mob/living/silicon/ai/A in src) + if(A.client) + A << "Self-erase protocol dete-- *bzzzzz*" + A << browse(null, "window=hack spideros") + NAI.flush = 1 return + + //=======//SUIT VERBS//=======// //Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. @@ -1170,10 +1174,10 @@ ________________________________________________________________________________ //Let's check for some safeties. if(s_initialized&&!affecting) terminate()//Kills the suit and attached objects. if(!s_initialized) return//When turned off the proc stops. - if(AI&&AI.stat==2)//If there is an AI and it's ded. Shouldn't happen without purging, could happen. - if(!s_control) - ai_return_control()//Return control to ninja if the AI was previously in control. - killai()//Delete AI. + for(var/mob/living/silicon/ai/A in NAI) + if(A&&A.stat==2)//If there is an AI and it's ded. Shouldn't happen without purging, could happen. + if(!s_control) + ai_return_control()//Return control to ninja if the AI was previously in control. //Now let's do the normal processing. if(s_coold) s_coold--//Checks for ability s_cooldown first. @@ -1215,7 +1219,7 @@ ________________________________________________________________________________ U << "Extending neural-net interface...\nNow monitoring brain wave pattern..." if(3) if(U.stat==2||U.health<=0) - U << "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG..." + U << "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG..." unlock_suit() break lock_suit(U,1)//Check for icons. @@ -1236,9 +1240,9 @@ ________________________________________________________________________________ if(!U.mind||U.mind.assigned_role!="MODE")//Your run of the mill persons shouldn't know what it is. Or how to turn it on. U << "You do not understand how this suit functions. Where the heck did it even come from?" else if(s_initialized) - U << "The suit is already functioning. \black Please report this bug." + U << "The suit is already functioning. Please report this bug." else - U << "ERROR: \black You cannot use this function at this time." + U << "ERROR: You cannot use this function at this time." return //=======//DEINITIALIZE//=======// @@ -1247,12 +1251,12 @@ ________________________________________________________________________________ if(affecting==loc&&!s_busy) var/mob/living/carbon/human/U = affecting if(!s_initialized) - U << "The suit is not initialized. \black Please report this bug." + U << "The suit is not initialized. Please report this bug." return if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") return - if(s_busy||flush) - U << "ERROR: \black You cannot use this function at this time." + if(s_busy || NAI.flush) + U << "ERROR: You cannot use this function at this time." return s_busy = 1 for(var/i = 0,i<7,i++) @@ -1432,7 +1436,7 @@ ________________________________________________________________________________
  • Voice masking generates a random name the ninja can use over the radio and in-person. Although, the former use is recommended.
  • Toggling vision cycles to one of the following: thermal, meson, or darkness vision. The starting mode allows one to scout the identity of those in view, revealing their role. Traitors, revolutionaries, wizards, and other such people will be made known to you.
  • Stealth, when activated, drains more battery charge and works similarly to a syndicate cloak. The cloak will deactivate when most Abilities are utilized.
  • -
  • On-board AI: The suit is able to download an AI much like an intelicard. Check with SpiderOS for details once downloaded.
  • +
  • On-board AI: The suit is able to download an AI much like an intellicard. Check with SpiderOS for details once downloaded.
  • SpiderOS is a specialized, PDA-like screen that allows for a small variety of functions, such as injecting healing chemicals directly from the suit. You are using it now, if that was not already obvious. You may also download AI modules directly to the OS.
  • Abilities: @@ -1453,45 +1457,12 @@ ________________________________________________________________________________ That is all you will need to know. The rest will come with practice and talent. Good luck!

    Master /N

    - "}//This has always bothered me but not anymore! + "} if(5) - var/laws dat += "

    AI Control:

    " - //var/mob/living/silicon/ai/A = AI - if(AI)//If an AI exists. - dat += "Stored AI: [A.name]
    " - dat += "System integrity: [(A.health+100)/2]%
    " + if(NAI) + NAI.attack_self(display_to) //Just accesses the integrated Intellicard. If an AI is in control of the suit then I guess it can interact with its own card. How meta. - //I personally think this makes things a little more fun. Ninjas can override all but law 0. - //if (A.laws.zeroth) - // laws += "
  • 0: [A.laws.zeroth]
  • " - - for (var/index = 1, index <= A.laws.ion.len, index++) - var/law = A.laws.ion[index] - if (length(law) > 0) - var/num = ionnum() - laws += "
  • [num]. [law]
  • " - - var/number = 1 - for (var/index = 1, index <= A.laws.inherent.len, index++) - var/law = A.laws.inherent[index] - if (length(law) > 0) - laws += "
  • [number]: [law]
  • " - number++ - - for (var/index = 1, index <= A.laws.supplied.len, index++) - var/law = A.laws.supplied[index] - if (length(law) > 0) - laws += "
  • [number]: [law]
  • " - number++ - - dat += "

    Laws:

    " - - if (!flush) - dat += "Purge AI
    " - else - dat += "Purge in progress...
    " - dat += " [A.control_disabled ? "Enable" : "Disable"] Wireless Activity" if(6) dat += {"

    Activate Abilities:

    @@ -1568,7 +1539,7 @@ ________________________________________________________________________________ U.electrocute_act(damage, src,0.1,1)//The last argument is a safety for the human proc that checks for gloves. cell.charge -= damage else - A << "ERROR: \black Not enough energy remaining." + A << "ERROR: Not enough energy remaining." if("Message") var/obj/item/device/pda/P = locate(href_list["target"]) @@ -1629,7 +1600,7 @@ ________________________________________________________________________________ for(var/i, i<4, i++) switch(i) if(0) - U << "Engaging mode...\n\blackCODE NAME: KAMIKAZE" + U << "Engaging mode...\nCODE NAME: KAMIKAZE" if(1) U << "Re-routing power nodes... \nUnlocking limiter..." if(2) @@ -1643,7 +1614,7 @@ ________________________________________________________________________________ return sleep(s_delay) else - U << "ERROR: \black Unable to initiate mode." + U << "ERROR: Unable to initiate mode." else U << browse(null, "window=spideros") s_busy = 0 @@ -1665,7 +1636,7 @@ ________________________________________________________________________________ t_disk.loc = T t_disk = null else - U << "ERROR: \black Could not eject disk." + U << "ERROR: Could not eject disk." if("Copy to Disk") var/datum/tech/current_data = locate(href_list["target"]) @@ -1686,7 +1657,7 @@ ________________________________________________________________________________ pai.loc = T pai = null else - U << "ERROR: \black Could not eject pAI card." + U << "ERROR: Could not eject pAI card." if("Override AI Laws") var/law_zero = A.laws.zeroth//Remembers law zero, if there is one. @@ -1707,25 +1678,25 @@ ________________________________________________________________________________ if(AI==A) switch(i) if(0) - A << "WARNING: \black purge procedure detected. \nNow hacking host..." - U << "WARNING: HACKING AT��TEMP� IN PR0GRESs!" + A << "WARNING: purge procedure detected. \nNow hacking host..." + U << "WARNING: HACKING AT��TEMP� IN PR0GRESs!" spideros = 0 k_unlock = 0 U << browse(null, "window=spideros") if(1) A << "Disconnecting neural interface..." - U << "WAR�NING: �R�O0�Gr�--S 2&3%" + U << "WAR�NING: �R�O0�Gr�--S 2&3%" if(2) A << "Shutting down external protocol..." - U << "WARNING: P����RֆGr�5S 677^%" + U << "WARNING: P����RֆGr�5S 677^%" cancel_stealth() if(3) A << "Connecting to kernel..." - U << "WARNING: �R�r�R_404" + U << "WARNING: �R�r�R_404" A.control_disabled = 0 if(4) A << "Connection established and secured. Menu updated." - U << "W�r#nING: #%@!!WȆ|_4�54@ \nUn�B88l3 T� L�-�o-L�CaT2 ##$!�RN�0..%.." + U << "W�r#nING: #%@!!WȆ|_4�54@ \nUn�B88l3 T� L�-�o-L�CaT2 ##$!�RN�0..%.." grant_AI_verbs() return sleep(s_delay) @@ -1733,7 +1704,7 @@ ________________________________________________________________________________ s_busy = 0 U << "Hacking attempt disconnected. Resuming normal operation." else - flush = 1 + NAI.flush = 1 A.suiciding = 1 A << "Your core files are being purged! This is the end..." spawn(0) @@ -1742,9 +1713,9 @@ ________________________________________________________________________________ A.adjustOxyLoss(2) A.updatehealth() sleep(10) - killai() + killai(NAI) U << "Artificial Intelligence was terminated. Rebooting..." - flush = 0 + NAI.flush = 0 if("Wireless AI") A.control_disabled = !A.control_disabled @@ -1769,19 +1740,21 @@ ________________________________________________________________________________ hologram.invisibility = 101//So that it doesn't show up, ever. This also means one could attach a number of images to a single obj and display them differently to differnet people. hologram.anchored = 1//So it cannot be dragged by space wind and the like. hologram.dir = get_dir(T,affecting.loc) - var/image/I = image(AI.holo_icon,hologram)//Attach an image to object. - hologram.i_attached = I//To attach the image in order to later reference. - AI << I - affecting << I - affecting << "An image flicks to life nearby. It appears visible to you only." - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear + for(var/mob/living/silicon/ai/A in NAI) + var/image/I = image(A.holo_icon,hologram)//Attach an image to object. + hologram.i_attached = I//To attach the image in order to later reference. + A << I + affecting << I + affecting << "An image flicks to life nearby. It appears visible to you only." - ai_holo_process()//Move to initialize + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear + + ai_holo_process()//Move to initialize else - AI << "ERROR: \black Image feed in progress." + AI << "ERROR: Image feed in progress." else - AI << "ERROR: \black Unable to project image." + AI << "ERROR: Unable to project image." return /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_process() @@ -1831,11 +1804,13 @@ ________________________________________________________________________________ set category = "AI Ninja Equip" set src = usr.loc - AI << browse(null, "window=spideros")//Close window - AI << "You have seized your hacking attempt. [affecting.real_name] has regained control." - affecting << "UPDATE: [AI.real_name] has ceased hacking attempt. All systems clear." - remove_AI_verbs() + for(var/mob/living/silicon/ai/A in NAI) + AI << browse(null, "window=spideros")//Close window + AI << "You have seized your hacking attempt. [affecting.real_name] has regained control." + affecting << "UPDATE: [A.real_name] has ceased hacking attempt. All systems clear." + + remove_AI_verbs() return //=======//GENERAL SUIT PROCS//=======// @@ -1846,7 +1821,7 @@ ________________________________________________________________________________ if(s_control) I:transfer_ai("NINJASUIT","AICARD",src,U) else - U << "ERROR: \black Remote access channel disabled." + U << "ERROR: Remote access channel disabled." return//Return individually so that ..() can run properly at the end of the proc. else if(istype(I, /obj/item/device/paicard) && !pai)//If it's a pai card. U:drop_item() @@ -1901,7 +1876,7 @@ ________________________________________________________________________________ TD.stored = null U << "Data analyzed and updated. Disk erased." else - U << "ERROR: \black Procedure interrupted. Process terminated." + U << "ERROR: Procedure interrupted. Process terminated." else I.loc = src t_disk = I @@ -1967,7 +1942,7 @@ ________________________________________________________________________________ user << "There are [s_bombs] smoke bomb\s remaining." user << "There are [a_boost] adrenaline booster\s remaining." else - user << "�rr�R �a��a�� No-�-� f��N� 3RR�r" + user << "�rr�R �a��a�� No-�-� f��N� 3RR�r" /* =================================================================================== @@ -2116,7 +2091,7 @@ ________________________________________________________________________________ for(var/datum/tech/analyzing_data in A:files.known_tech) if(current_data.id==analyzing_data.id) if(analyzing_data.level>current_data.level) - U << "Database: \black UPDATED." + U << "Database: UPDATED." current_data.level = analyzing_data.level break//Move on to next. else break//Otherwise, quit processing. @@ -2328,7 +2303,7 @@ It is possible to destroy the net by the occupant or someone else. for(var/mob/O in viewers(src, 3)) O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2) if(!isnull(master))//As long as they still exist. - master << "ERROR: \black unable to initiate transport protocol. Procedure terminated." + master << "ERROR: unable to initiate transport protocol. Procedure terminated." qdel(src) return @@ -2342,7 +2317,7 @@ It is possible to destroy the net by the occupant or someone else. if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. if(!isnull(master))//As long as they still exist. - master << "ERROR: \black unable to locate \the [mob_name]. Procedure terminated." + master << "ERROR: unable to locate \the [mob_name]. Procedure terminated." qdel(src)//Get rid of the net. return @@ -2378,7 +2353,7 @@ It is possible to destroy the net by the occupant or someone else. O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2) if(!isnull(master))//As long as they still exist. - master << "SUCCESS: \black transport procedure of \the [affecting] complete." + master << "SUCCESS: transport procedure of \the [affecting] complete." M.anchored = 0//Important. 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/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/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 4d7ffb41382..6bb20acc14f 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -33,7 +33,7 @@ return !config.silent_ai /mob/living/silicon/ai/radio(message, message_mode) - if(!radio_enabled || aiRestorePowerRoutine || stat) //AI cannot speak if radio is disabled (via intelicard) or depowered. + if(!radio_enabled || aiRestorePowerRoutine || stat) //AI cannot speak if radio is disabled (via intellicard) or depowered. src << "Your radio transmitter is offline!" return 0 ..(message,message_mode) 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/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 905768d542e..b4ed4629bc3 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,12 +74,14 @@ return //Exclude lasertag guns from the CLUMSY check. - if(clumsy_check) - if(user.disabilities & CLUMSY && prob(40)) - user << "You shoot yourself in the foot with \the [src]!" - afterattack(user, user) - user.drop_item() - return + if(clumsy_check && can_shoot()) + if(istype(user, /mob/living)) + var/mob/living/M = user + if (M.disabilities & CLUMSY && prob(40)) + user << "You shoot yourself in the foot with \the [src]!" + process_fire(user,user,0,params) + M.drop_item() + return if (!user.IsAdvancedToolUser()) user << "You don't have the dexterity to do this!" @@ -82,18 +96,23 @@ user << "Your fingers don't fit in the trigger guard!" return + process_fire(target,user,flag,params) + +/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..49727229591 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) 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..9cf93d215e0 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -71,3 +71,4 @@ xxnoob = Game Master tkdrg = Game Master Cuboos = Game Master thunder12345 = Game Master +wjohnston = 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 57009026e86..012f9616097 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 33af023bd79..a0985007ed0 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/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