diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index 03fd38532c..630433c973 100644 --- a/code/datums/autolathe/arms.dm +++ b/code/datums/autolathe/arms.dm @@ -298,6 +298,15 @@ name = "speedloader (.38 rubber)" path =/obj/item/ammo_magazine/s38/rubber +/datum/category_item/autolathe/arms/speedloader_45 + name = "speedloader (.45)" + path = /obj/item/ammo_magazine/s45 + hidden = 1 + +/datum/category_item/autolathe/arms/speedloader_45r + name = "speedloader (.45 rubber)" + path = /obj/item/ammo_magazine/s45/rubber + // Commented out until metal exploits with autolathe is fixed. /*/datum/category_item/autolathe/arms/pistol_clip_45 name = "ammo clip (.45)" diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm index d644a9eaa8..c0b7600aad 100644 --- a/code/datums/uplink/ammunition.dm +++ b/code/datums/uplink/ammunition.dm @@ -22,6 +22,14 @@ name = "Pistol Magazine (.45 AP)" path = /obj/item/ammo_magazine/m45/ap +/datum/uplink_item/item/ammo/s45m + name = "Speedloader (.45)" + path = /obj/item/ammo_magazine/s45 + +/datum/uplink_item/item/ammo/s45map + name = "Speedloader (.45 AP)" + path = /obj/item/ammo_magazine/s45/ap + /datum/uplink_item/item/ammo/tommymag name = "Tommygun Magazine (.45)" path = /obj/item/ammo_magazine/m45tommy diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index f46f03d90f..7a9926c102 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -640,7 +640,7 @@ name = "Nonstandard suit cycler" model_text = "Nonstandard" req_access = list(access_syndicate) - departments = list("Mercenary") + departments = list("Mercenary", "Charring") can_repair = 1 /obj/machinery/suit_cycler/attack_ai(mob/user as mob) @@ -752,7 +752,7 @@ //Clear the access reqs, disable the safeties, and open up all paintjobs. user << "You run the sequencer across the interface, corrupting the operating protocols." - departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Crowd Control","Emergency Medical Response","^%###^%$") + departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Crowd Control","Emergency Medical Response","^%###^%$", "Charring") species = list("Human","Skrell","Unathi","Tajara", "Teshari", "Nevrean", "Akula", "Sergal", "Flatland Zorren", "Highlander Zorren", "Vulpkanin", "Promethean", "Xenomorph Hybrid", "Vasilissan", "Rapala") //VORESTATION EDIT emagged = 1 @@ -1073,6 +1073,15 @@ suit.name = "blood-red voidsuit" suit.item_state = "syndie_voidsuit" suit.icon_state = "rig-syndie" + if("Charring") + if(helmet) + helmet.name = "soot-covered voidsuit helmet" + helmet.icon_state = "rig0-firebug" + helmet.item_state = "rig0-firebug" + if(suit) + suit.name = "soot-covered voidsuit" + suit.item_state = "rig-firebug" + suit.icon_state = "rig-firebug" if(helmet) helmet.name = "refitted [helmet.name]" if(suit) suit.name = "refitted [suit.name]" diff --git a/code/game/objects/items/gunbox.dm b/code/game/objects/items/gunbox.dm new file mode 100644 index 0000000000..add1530ca4 --- /dev/null +++ b/code/game/objects/items/gunbox.dm @@ -0,0 +1,19 @@ +/obj/item/gunbox + name = "detective's gun box" + desc = "A secure box containing a Detective's sidearm." + icon = 'icons/obj/storage.dmi' + icon_state = "gunbox" + w_class = ITEMSIZE_HUGE + +/obj/item/gunbox/attack_self(mob/living/user) + var/list/options = list() + options[".45 Pistol"] = list(/obj/item/weapon/gun/projectile/colt/detective, /obj/item/ammo_magazine/m45/rubber, /obj/item/ammo_magazine/m45/rubber) + options[".45 Revolver"] = list(/obj/item/weapon/gun/projectile/revolver/detective45, /obj/item/ammo_magazine/s45/rubber, /obj/item/ammo_magazine/s45/rubber) + var/choice = input(user,"Would you prefer a pistol or a revolver?") as null|anything in options + if(src && choice) + var/list/things_to_spawn = options[choice] + for(var/new_type in things_to_spawn) // Spawn all the things, the gun and the ammo. + var/atom/movable/AM = new new_type(get_turf(src)) + if(istype(AM, /obj/item/weapon/gun)) + to_chat(user, "You have chosen \the [AM]. Say hello to your new friend.") + qdel(src) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 98ecb2bec7..c2b6e4653a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -260,6 +260,17 @@ new /obj/item/device/camera(src) new /obj/item/weapon/storage/fancy/vials(src) //VOREStation Edit - adding vials for new hypo new /obj/item/toy/plushie/therapy/blue(src) + new /obj/item/weapon/storage/box/pillbottles(src) + new /obj/item/weapon/storage/box/pillbottles(src) + new /obj/item/weapon/storage/box/beakers(src) + new /obj/item/weapon/storage/box/autoinjectors(src) + new /obj/item/weapon/storage/box/syringes(src) + new /obj/item/weapon/reagent_containers/dropper(src) + new /obj/item/weapon/reagent_containers/dropper(src) + new /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline(src) + new /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline(src) + new /obj/item/weapon/reagent_containers/glass/bottle/antitoxin(src) + new /obj/item/weapon/reagent_containers/glass/bottle/antitoxin(src) return /obj/structure/closet/secure_closet/psych @@ -276,8 +287,21 @@ New() ..() - new /obj/item/weapon/storage/box/pillbottles(src) - new /obj/item/weapon/storage/box/pillbottles(src) + new /obj/item/clothing/under/rank/psych(src) + new /obj/item/clothing/under/rank/psych/turtleneck(src) + new /obj/item/clothing/suit/straight_jacket(src) + new /obj/item/weapon/reagent_containers/glass/bottle/stoxin(src) + new /obj/item/weapon/reagent_containers/syringe(src) + new /obj/item/weapon/storage/pill_bottle/citalopram(src) + new /obj/item/weapon/reagent_containers/pill/methylphenidate(src) + new /obj/item/weapon/clipboard(src) + new /obj/item/weapon/folder/white(src) + new /obj/item/device/taperecorder(src) + new /obj/item/device/tape/random(src) + new /obj/item/device/tape/random(src) + new /obj/item/device/tape/random(src) + new /obj/item/device/camera(src) + new /obj/item/toy/plushie/therapy/blue(src) return /obj/structure/closet/secure_closet/medical_wall diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index f4af008dd4..fe09268ecd 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -296,6 +296,7 @@ ..() new /obj/item/clothing/accessory/badge/holo/detective(src) new /obj/item/clothing/gloves/black(src) + new /obj/item/gunbox(src) new /obj/item/weapon/storage/belt/detective(src) new /obj/item/weapon/storage/box/evidence(src) new /obj/item/device/radio/headset/headset_sec(src) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index c5ebcf7587..7f6c093384 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1226,21 +1226,6 @@ var/datum/announcement/minor/admin_min_announcer = new if(istype(H)) H.regenerate_icons() - -/* - helper proc to test if someone is an event manager or not. Got tired of writing this same check all over the place. -*/ -/proc/is_eventM(client/C) - - if(!istype(C)) - return 0 - if(!C.holder) - return 0 - - if(C.holder.rights == R_EVENT) - return 1 - return 0 - /proc/get_options_bar(whom, detail = 2, name = 0, link = 1, highlight_special = 1) if(!whom) return "(*null*)" diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm index b6d0abbe1c..473770ac2b 100644 --- a/code/modules/admin/admin_secrets.dm +++ b/code/modules/admin/admin_secrets.dm @@ -100,18 +100,18 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_item/admin_secret category = /datum/admin_secret_category/admin_secrets log = 0 - permissions = R_ADMIN + permissions = R_ADMIN|R_EVENT /datum/admin_secret_item/random_event category = /datum/admin_secret_category/random_events - permissions = R_FUN + permissions = R_FUN|R_EVENT warn_before_use = 1 /datum/admin_secret_item/fun_secret category = /datum/admin_secret_category/fun_secrets - permissions = R_FUN + permissions = R_FUN|R_EVENT warn_before_use = 1 /datum/admin_secret_item/final_solution category = /datum/admin_secret_category/final_solutions - permissions = R_FUN|R_SERVER|R_ADMIN + permissions = R_FUN|R_SERVER|R_ADMIN|R_EVENT diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 2151bc1ab0..9d3e492698 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -8,7 +8,6 @@ var/list/admin_verbs_default = list( /client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, // /client/proc/check_antagonists, //shows all antags, // /client/proc/cmd_mod_say, - /client/proc/cmd_eventM_check_new_players, // /client/proc/deadchat //toggles deadchat on/off, // /client/proc/toggle_ahelp_sound, ) @@ -336,11 +335,11 @@ var/list/admin_verbs_mod = list( ) var/list/admin_verbs_event_manager = list( + /client/proc/cmd_event_say, /client/proc/cmd_admin_pm_context, /client/proc/cmd_admin_pm_panel, /datum/admins/proc/PlayerNotes, /client/proc/admin_ghost, - /client/proc/cmd_mod_say, /datum/admins/proc/show_player_info, /client/proc/dsay, /client/proc/cmd_admin_subtle_message, @@ -454,9 +453,6 @@ var/list/admin_verbs_event_manager = list( feedback_add_details("admin_verb","TAVVS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - - /client/proc/admin_ghost() set category = "Admin" set name = "Aghost" @@ -467,7 +463,7 @@ var/list/admin_verbs_event_manager = list( if(ghost.can_reenter_corpse) ghost.reenter_corpse() else - ghost << "Error: Aghost: Can't reenter corpse, event managers that use adminHUD while aghosting are not permitted to enter their corpse again" + to_chat(ghost, "Error: Aghost: Can't reenter corpse.") return feedback_add_details("admin_verb","P") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 1531790268..92536a6e05 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -363,20 +363,14 @@ PM "} - - if(usr.client) - var/client/C = usr.client - if(is_eventM(C)) - dat += {" N/A "} - else - switch(is_special_character(M)) - if(0) - dat += {"Traitor?"} - if(1) - dat += {"Traitor?"} - if(2) - dat += {"Traitor?"} + switch(is_special_character(M)) + if(0) + dat += {"Traitor?"} + if(1) + dat += {"Traitor?"} + if(2) + dat += {"Traitor?"} else dat += {" N/A "} diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index 63209f84b4..264e5ad64e 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -36,7 +36,8 @@ if(check_rights(R_ADMIN, 0)) sender_name = "[sender_name]" for(var/client/C in admins) - C << "" + create_text_tag("mod", "MOD:", C) + " [sender_name]([admin_jump_link(mob, C.holder)]): [msg]" + if(check_rights(R_ADMIN|R_MOD|R_SERVER)) + C << "" + create_text_tag("mod", "MOD:", C) + " [sender_name]([admin_jump_link(mob, C.holder)]): [msg]" feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -45,7 +46,7 @@ set name = "Esay" set hidden = 1 - if(!check_rights(R_ADMIN|R_MOD|R_EVENT|R_SERVER)) + if(!check_rights(R_ADMIN|R_MOD|R_EVENT|R_SERVER|R_EVENT)) return msg = sanitize(msg) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index c14c74edd1..b80d95e3c1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -65,42 +65,6 @@ message_admins("SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1) feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_eventM_check_new_players() //Allows event managers / admins to determine who the newer players are. - set category = "Admin" - set name = "Check new Players" - if(!holder) - src << "Only staff members may use this command." - - var/age = alert(src, "Age check", "Show accounts yonger then _____ days","7", "30" , "All") - - if(age == "All") - age = 9999999 - else - age = text2num(age) - - var/missing_ages = 0 - var/msg = "" - - var/highlight_special_characters = 1 - if(is_eventM(usr.client)) - highlight_special_characters = 0 - - for(var/client/C in clients) - if(C.player_age == "Requires database") - missing_ages = 1 - continue - if(C.player_age < age) - msg += "[key_name(C, 1, 1, highlight_special_characters)]: account is [C.player_age] days old
" - - if(missing_ages) - src << "Some accounts did not have proper ages set in their clients. This function requires database to be present" - - if(msg != "") - src << browse(msg, "window=Player_age_check") - else - src << "No matches for that age range found." - - /client/proc/cmd_admin_world_narrate() // Allows administrators to fluff events a little easier -- TLE set category = "Special Verbs" set name = "Global Narrate" diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index a2cc9aafb9..84a187ef91 100644 --- a/code/modules/economy/economy_misc.dm +++ b/code/modules/economy/economy_misc.dm @@ -49,6 +49,7 @@ /var/list/economic_species_modifier = list( /datum/species/human = 10, + /datum/species/human/vatgrown = 10, /datum/species/skrell = 12, /datum/species/unathi = 7, /datum/species/tajaran = 7, diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm index edfa6b1a86..e31b26fbb1 100644 --- a/code/modules/integrated_electronics/core/helpers.dm +++ b/code/modules/integrated_electronics/core/helpers.dm @@ -18,7 +18,9 @@ else io_list.Add(new io_type(src, io_entry, default_data)) -/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, var/new_data) +/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, datum/new_data) + if (istype(new_data) && !isweakref(new_data)) + new_data = weakref(new_data) var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) return pin.write_data_to_pin(new_data) diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index c417c3e4fd..0a516e360a 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -29,6 +29,28 @@ if(assembly) assembly.give_power(adjusted_power) +/obj/item/integrated_circuit/passive/power/starter + name = "starter" + desc = "This tiny circuit will send a pulse right after device is turned on, or when power is restored." + icon_state = "led" + complexity = 1 + activators = list("pulse out" = IC_PINTYPE_PULSE_OUT) + origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/is_charge=0 + +/obj/item/integrated_circuit/passive/power/starter/make_energy() + if(assembly.battery) + if(assembly.battery.charge) + if(!is_charge) + activate_pin(1) + is_charge=1 + else + is_charge=0 + else + is_charge=0 + return FALSE + // For implants. /obj/item/integrated_circuit/passive/power/metabolic_siphon name = "metabolic siphon" @@ -82,6 +104,44 @@ origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_RESEARCH var/power_amount = 250 +//fuel cell + +/obj/item/integrated_circuit/passive/power/chemical_cell + name = "fuel cell" + desc = "Produces electricity from chemicals." + icon_state = "chemical_cell" + extended_desc = "This is effectively an internal beaker. It will consume and produce power from phoron, slime jelly, welding fuel, carbon,\ + ethanol, nutriments and blood, in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." + flags = OPENCONTAINER + complexity = 4 + inputs = list() + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) + activators = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + var/volume = 60 + var/list/fuel = list("phoron" = 50000, "slimejelly" = 25000, "fuel" = 15000, "carbon" = 10000, "ethanol"= 10000, "nutriment" =8000, "blood" = 5000) + +/obj/item/integrated_circuit/passive/power/chemical_cell/New() + ..() + create_reagents(volume) + +/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user) + set_pin_data(IC_OUTPUT, 2, weakref(src)) + push_data() + ..() + +/obj/item/integrated_circuit/passive/power/chemical_cell/on_reagent_change() + set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + push_data() + +/obj/item/integrated_circuit/passive/power/chemical_cell/make_energy() + if(assembly) + for(var/I in fuel) + if((assembly.battery.maxcharge-assembly.battery.charge) / CELLRATE > fuel[I]) + if(reagents.remove_reagent(I, 1)) + assembly.give_power(fuel[I]) + // For really fat machines. /obj/item/integrated_circuit/passive/power/relay/large diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index 7b5846eb8d..e490ccd27a 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -27,13 +27,10 @@ /obj/item/integrated_circuit/transfer/multiplexer/do_work() var/input_index = get_pin_data(IC_INPUT, 1) - var/output = null if(!isnull(input_index) && (input_index >= 1 && input_index < inputs.len)) - output = get_pin_data(IC_INPUT, input_index + 1) - - set_pin_data(IC_OUTPUT, 1, output) - push_data() + set_pin_data(IC_OUTPUT, 1,get_pin_data(IC_INPUT, input_index + 1)) + push_data() activate_pin(2) /obj/item/integrated_circuit/transfer/multiplexer/medium @@ -79,10 +76,8 @@ /obj/item/integrated_circuit/transfer/demultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - var/output = get_pin_data(IC_INPUT, 2) - for(var/i = 1 to outputs.len) - set_pin_data(IC_OUTPUT, i, i == output_index ? output : null) + set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null) activate_pin(2) @@ -101,4 +96,51 @@ name = "sixteen demultiplexer" icon_state = "dmux16" w_class = ITEMSIZE_SMALL + number_of_outputs = 16 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer + name = "two pulse demultiplexer" + desc = "Selector switch to choose the pin to be activated by number." + extended_desc = "The first input pin is used to select which of the pulse out pins will be activated after activation of the circuit. \ + If the output selection is outside the valid range then no output is given." + complexity = 2 + icon_state = "dmux2" + inputs = list("output selection" = IC_PINTYPE_NUMBER) + outputs = list() + activators = list("select" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 4 + var/number_of_outputs = 2 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/New() + for(var/i = 1 to number_of_outputs) + // outputs += "output [i]" + activators["output [i]"] = IC_PINTYPE_PULSE_OUT + complexity = number_of_outputs + + ..() + desc += " It has [number_of_outputs] output pins." + extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]." + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() + var/output_index = get_pin_data(IC_INPUT, 1) + + if(output_index == Clamp(output_index, 1, number_of_outputs)) + activate_pin(round(output_index + 1 ,1)) + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium + name = "four pulse demultiplexer" + icon_state = "dmux4" + number_of_outputs = 4 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/large + name = "eight pulse demultiplexer" + icon_state = "dmux8" + w_class = ITEMSIZE_SMALL + number_of_outputs = 8 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge + name = "sixteen pulse demultiplexer" + icon_state = "dmux16" + w_class = ITEMSIZE_SMALL number_of_outputs = 16 \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 00e5bf2ea4..8da4fad6d8 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -110,8 +110,10 @@ /obj/item/integrated_circuit/input/adv_med_scanner - name = "integrated advanced medical analyser" - desc = "A very small version of the medbot's medical analyser. This allows the machine to know how healthy someone is. \ + + name = "integrated advanced medical analyzer" + desc = "A very small version of the medibot's medical analyzer. This allows the machine to know how healthy someone is. \ + This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." icon_state = "medscan_adv" complexity = 12 @@ -134,7 +136,9 @@ var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human) if(!istype(H)) //Invalid input return + if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range.. + var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100 var/missing_health = H.getMaxHealth() - H.health @@ -336,6 +340,7 @@ // Set the pins so when someone sees them, they won't show as null set_pin_data(IC_INPUT, 1, frequency) set_pin_data(IC_INPUT, 2, code) + push_data() /obj/item/integrated_circuit/input/signaler/Destroy() if(radio_controller) @@ -464,6 +469,7 @@ set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 2, null) if(!T) + push_data() return set_pin_data(IC_OUTPUT, 1, T.x) @@ -486,7 +492,7 @@ "speaker" = IC_PINTYPE_STRING, "message" = IC_PINTYPE_STRING ) - activators = list("on message received" = IC_PINTYPE_PULSE_IN, "on translation" = IC_PINTYPE_PULSE_OUT) + activators = list("on message received" = IC_PINTYPE_PULSE_OUT, "on translation" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 15 @@ -618,7 +624,6 @@ push_data() activate_pin(2) - /obj/item/integrated_circuit/input/atmo_scanner name = "integrated atmospheric analyser" desc = "The same atmospheric analysis module that is integrated into every PDA. \ @@ -850,4 +855,4 @@ else set_pin_data(IC_OUTPUT, 1, 0) push_data() - activate_pin(2) \ No newline at end of file + activate_pin(2) diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/code/modules/integrated_electronics/subtypes/lists.dm index 84e0724bb9..943141b071 100644 --- a/code/modules/integrated_electronics/subtypes/lists.dm +++ b/code/modules/integrated_electronics/subtypes/lists.dm @@ -52,12 +52,123 @@ push_data() activate_pin(2) +/obj/item/integrated_circuit/list/search + name = "search circuit" + desc = "This circuit will give index of desired element in the list." + extended_desc = "Search will start at 1 position and will return first matching position." + inputs = list( + "list" = IC_PINTYPE_LIST, + "item" = IC_PINTYPE_ANY + ) + outputs = list( + "index" = IC_PINTYPE_NUMBER + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/search/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/item = get_pin_data(IC_INPUT, 2) + set_pin_data(IC_OUTPUT, 1, input_list.Find(item)) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/at + name = "at circuit" + desc = "This circuit will pick an element from a list by index." + extended_desc = "If there is no element with such index, result will be null." + inputs = list( + "list" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_NUMBER + ) + outputs = list("item" = IC_PINTYPE_ANY) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/at/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/index = get_pin_data(IC_INPUT, 2) + var/item = input_list[index] + set_pin_data(IC_OUTPUT, 1, item) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/delete + name = "delete circuit" + desc = "This circuit will delete the element from a list by index." + extended_desc = "If there is no element with such index, result list will be unchanged." + inputs = list( + "list" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_NUMBER + ) + outputs = list( + "item" = IC_PINTYPE_LIST + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/delete/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/list/red_list = list() + var/index = get_pin_data(IC_INPUT, 2) + var/j = 0 + for(var/I in input_list) + j = j + 1 + if(j != index) + red_list.Add(I) + set_pin_data(IC_OUTPUT, 1, red_list) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/write + name = "write circuit" + desc = "This circuit will write element in list with given index." + extended_desc = "If there is no element with such index, it will give the same list, as before." + inputs = list( + "list" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_NUMBER, + "item" = IC_PINTYPE_ANY + ) + outputs = list( + "redacted list" = IC_PINTYPE_LIST + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/write/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/index = get_pin_data(IC_INPUT, 2) + var/item = get_pin_data(IC_INPUT, 3) + input_list[index] = item + set_pin_data(IC_OUTPUT, 1, input_list) + push_data() + activate_pin(2) + +obj/item/integrated_circuit/list/len + name = "len circuit" + desc = "This circuit will give length of the list." + inputs = list( + "list" = IC_PINTYPE_LIST, + ) + outputs = list( + "item" = IC_PINTYPE_NUMBER + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/len/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + set_pin_data(IC_OUTPUT, 1, input_list.len) + push_data() + activate_pin(2) + + /obj/item/integrated_circuit/list/jointext name = "join text circuit" desc = "This circuit will add all elements of a list into one string, seperated by a character." extended_desc = "Default settings will encode the entire list into a string." inputs = list( - "list to join" = IC_PINTYPE_LIST, + "list to join" = IC_PINTYPE_LIST,// "delimiter" = IC_PINTYPE_CHAR, "start" = IC_PINTYPE_NUMBER, "end" = IC_PINTYPE_NUMBER diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index fa4fd9ded6..40f617e62e 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -40,8 +40,15 @@ O.push_data() activate_pin(2) +/obj/item/integrated_circuit/memory/tiny + name = "small memory circuit" + desc = "This circuit can store two pieces of data." + icon_state = "memory2" + power_draw_per_use = 2 + number_of_pins = 2 + /obj/item/integrated_circuit/memory/medium - name = "memory circuit" + name = "medium memory circuit" desc = "This circuit can store four pieces of data." icon_state = "memory4" power_draw_per_use = 2 diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index f528434129..e1e3f56c89 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -37,9 +37,7 @@ amount_to_move = 20000 /obj/item/integrated_circuit/power/transmitter/do_work() - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) + var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) if(AM) if(!assembly) @@ -72,7 +70,15 @@ set_pin_data(IC_OUTPUT, 2, cell.maxcharge) set_pin_data(IC_OUTPUT, 3, cell.percent()) activate_pin(2) + push_data() return TRUE + else + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) + set_pin_data(IC_OUTPUT, 3, null) + activate_pin(2) + push_data() + return FALSE return FALSE /obj/item/integrated_circuit/power/transmitter/large/do_work() diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 25a80c2a28..e6d65bd07a 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -1,6 +1,8 @@ /obj/item/integrated_circuit/reagent category_text = "Reagent" var/volume = 0 + unacidable = 1 + phoronproof = 1 origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/New() @@ -18,13 +20,23 @@ complexity = 20 cooldown_per_use = 30 SECONDS inputs = list() - outputs = list() - activators = list("create smoke" = IC_PINTYPE_PULSE_IN) + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) + activators = list("create smoke" = IC_PINTYPE_PULSE_IN,"on smoked" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) volume = 100 power_draw_per_use = 20 +/obj/item/integrated_circuit/reagent/smoke/on_reagent_change() + set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + push_data() + + +/obj/item/integrated_circuit/reagent/smoke/interact(mob/user) + set_pin_data(IC_OUTPUT, 2, weakref(src)) + push_data() + ..() + /obj/item/integrated_circuit/reagent/smoke/do_work() playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() @@ -33,52 +45,141 @@ for(var/i = 1 to 8) smoke_system.start() reagents.clear_reagents() + activate_pin(2) /obj/item/integrated_circuit/reagent/injector name = "integrated hypo-injector" desc = "This scary looking thing is able to pump liquids into whatever it's pointed at." icon_state = "injector" extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \ - must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing." + must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. A negative amount makes the injector draw out reagents." flags = OPENCONTAINER complexity = 20 cooldown_per_use = 6 SECONDS inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) inputs_default = list("2" = 5) - outputs = list() - activators = list("inject" = IC_PINTYPE_PULSE_IN) + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) + activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH volume = 30 power_draw_per_use = 15 + var/direc = 1 + var/transfer_amount = 10 + +/obj/item/integrated_circuit/reagent/injector/interact(mob/user) + set_pin_data(IC_OUTPUT, 2, weakref(src)) + push_data() + ..() + + +/obj/item/integrated_circuit/reagent/injector/on_reagent_change() + set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + push_data() + +/obj/item/integrated_circuit/reagent/injector/on_data_written() + var/new_amount = get_pin_data(IC_INPUT, 2) + if(new_amount < 0) + new_amount = -new_amount + direc = 0 + else + direc = 1 + if(isnum(new_amount)) + new_amount = Clamp(new_amount, 0, volume) + transfer_amount = new_amount -/obj/item/integrated_circuit/reagent/injector/proc/inject_amount() - var/amount = get_pin_data(IC_INPUT, 2) - if(isnum(amount)) - return Clamp(amount, 0, 30) /obj/item/integrated_circuit/reagent/injector/do_work() set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing - var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) if(!istype(AM)) //Invalid input + activate_pin(3) return - if(!reagents.total_volume) // Empty - return - if(AM.can_be_injected_by(src)) - if(isliving(AM)) - var/mob/living/L = AM - var/turf/T = get_turf(AM) - T.visible_message("[src] is trying to inject [L]!") - sleep(3 SECONDS) - if(!L.can_be_injected_by(src)) + + if(direc == 1) + + if(!istype(AM)) //Invalid input + activate_pin(3) + return + if(!reagents.total_volume) // Empty + activate_pin(3) + return + if(AM.can_be_injected_by(src)) + if(isliving(AM)) + var/mob/living/L = AM + var/turf/T = get_turf(AM) + T.visible_message("[src] is trying to inject [L]!") + sleep(3 SECONDS) + if(!L.can_be_injected_by(src)) + activate_pin(3) + return + var/contained = reagents.get_reagents() + var/trans = reagents.trans_to_mob(L, transfer_amount, CHEM_BLOOD) + message_admins("[src] injected \the [L] with [trans]u of [contained].") + to_chat(AM, "You feel a tiny prick!") + visible_message("[src] injects [L]!") + else + reagents.trans_to(AM, transfer_amount) + else + + if(reagents.total_volume >= volume) // Full + activate_pin(3) + return + var/obj/target = AM + if(!target.reagents) + activate_pin(3) + return + var/turf/TS = get_turf(src) + var/turf/TT = get_turf(AM) + if(!TS.Adjacent(TT)) + activate_pin(3) + return + var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume) + if(ismob(target))//Blood! + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/T = target + if(!T.dna) + if(T.reagents.trans_to_obj(src, tramount)) + activate_pin(2) + else + activate_pin(3) + return + if(NOCLONE in T.mutations) //target done been et, no more blood in him + if(T.reagents.trans_to_obj(src, tramount)) + activate_pin(2) + else + activate_pin(3) + return + return + var/datum/reagent/B + if(istype(T, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = T + if(H.species && !H.should_have_organ(O_HEART)) + H.reagents.trans_to_obj(src, tramount) + else + B = T.take_blood(src, tramount) + else + B = T.take_blood(src,tramount) + if (B) + reagents.reagent_list |= B + reagents.update_total() + on_reagent_change() + reagents.handle_reactions() + B = null + visible_message( "Machine takes a blood sample from [target].") + else + activate_pin(3) return - var/contained = reagents.get_reagents() - var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD) - message_admins("[src] injected \the [L] with [trans]u of [contained].") - to_chat(AM, "You feel a tiny prick!") - visible_message("[src] injects [L]!") - else - reagents.trans_to(AM, inject_amount()) + + else //if not mob + if(!target.reagents.total_volume) + visible_message( "[target] is empty.") + activate_pin(3) + return + target.reagents.trans_to_obj(src, tramount) + activate_pin(2) + + + /obj/item/integrated_circuit/reagent/pump name = "reagent pump" @@ -96,11 +197,17 @@ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 + var/direc = 1 power_draw_per_use = 10 /obj/item/integrated_circuit/reagent/pump/on_data_written() var/new_amount = get_pin_data(IC_INPUT, 3) - if(!isnull(new_amount)) + if(new_amount < 0) + new_amount = -new_amount + direc = 0 + else + direc = 1 + if(isnum(new_amount)) new_amount = Clamp(new_amount, 0, 50) transfer_amount = new_amount @@ -111,17 +218,23 @@ if(!istype(source) || !istype(target)) //Invalid input return var/turf/T = get_turf(src) - if(source.Adjacent(T) && target.Adjacent(T)) + var/turf/TS = get_turf(source) + var/turf/TT = get_turf(target) + if(TS.Adjacent(T) && TT.Adjacent(T)) if(!source.reagents || !target.reagents) return if(ismob(source) || ismob(target)) return if(!source.is_open_container() || !target.is_open_container()) return - if(!target.reagents.get_free_space()) - return - - source.reagents.trans_to(target, transfer_amount) + if(direc) + if(!target.reagents.get_free_space()) + return + source.reagents.trans_to(target, transfer_amount) + else + if(!source.reagents.get_free_space()) + return + target.reagents.trans_to(source, transfer_amount) activate_pin(2) /obj/item/integrated_circuit/reagent/storage @@ -132,12 +245,18 @@ flags = OPENCONTAINER complexity = 4 inputs = list() - outputs = list("volume used" = IC_PINTYPE_NUMBER) + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) volume = 60 + +/obj/item/integrated_circuit/reagent/storage/interact(mob/user) + set_pin_data(IC_OUTPUT, 2, weakref(src)) + push_data() + ..() + /obj/item/integrated_circuit/reagent/storage/on_reagent_change() set_pin_data(IC_OUTPUT, 1, reagents.total_volume) push_data() @@ -150,4 +269,95 @@ flags = OPENCONTAINER | NOREACT complexity = 8 spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) \ No newline at end of file + origin_tech = list(TECH_MATERIALS = 4, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/obj/item/integrated_circuit/reagent/storage/big + name = "big reagent storage" + desc = "Stores liquid inside, and away from electrical components. Can store up to 180u." + icon_state = "reagent_storage_big" + extended_desc = "This is effectively an internal beaker." + flags = OPENCONTAINER + complexity = 16 + volume = 180 + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/obj/item/integrated_circuit/reagent/storage/scan + name = "reagent scanner" + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents." + icon_state = "reagent_scan" + extended_desc = "Mostly useful for reagent filter." + flags = OPENCONTAINER + complexity = 8 + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"list of reagents" = IC_PINTYPE_LIST) + activators = list("scan" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/obj/item/integrated_circuit/reagent/storage/scan/do_work() + var/cont[0] + for(var/datum/reagent/RE in reagents.reagent_list) + cont += RE.id + set_pin_data(IC_OUTPUT, 3, cont) + push_data() + + +/obj/item/integrated_circuit/reagent/filter + name = "reagent filter" + desc = "Filtering liquids by list of desired or unwanted reagents." + icon_state = "reagent_filter" + extended_desc = "This is a filter which will move liquids from the source ref to the target ref. \ + It will move all reagents, except list, given in fourth pin if amount value is positive.\ + Or it will move only desired reagents if amount is negative, The third pin determines \ + how much reagent is moved per pulse, between 0 and 50. Amount is given for each separate reagent." + flags = OPENCONTAINER + complexity = 8 + inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER, "list of reagents" = IC_PINTYPE_LIST) + inputs_default = list("3" = 5) + outputs = list() + activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + var/transfer_amount = 10 + var/direc = 1 + power_draw_per_use = 10 + +/obj/item/integrated_circuit/reagent/filter/on_data_written() + var/new_amount = get_pin_data(IC_INPUT, 3) + if(new_amount < 0) + new_amount = -new_amount + direc = 0 + else + direc = 1 + if(isnum(new_amount)) + new_amount = Clamp(new_amount, 0, 50) + transfer_amount = new_amount + +/obj/item/integrated_circuit/reagent/filter/do_work() + var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) + var/list/demand = get_pin_data(IC_INPUT, 4) + if(!istype(source) || !istype(target)) //Invalid input + return + var/turf/T = get_turf(src) + if(source.Adjacent(T) && target.Adjacent(T)) + if(!source.reagents || !target.reagents) + return + if(ismob(source) || ismob(target)) + return + if(!source.is_open_container() || !target.is_open_container()) + return + if(!target.reagents.get_free_space()) + return + for(var/datum/reagent/G in source.reagents.reagent_list) + if (!direc) + if(G.id in demand) + source.reagents.trans_id_to(target, G.id, transfer_amount) + else + if(!(G.id in demand)) + source.reagents.trans_id_to(target, G.id, transfer_amount) + activate_pin(2) + push_data() + + + diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7ca7f74737..a84eae381b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -321,19 +321,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!client) return - var/mentor = is_eventM(usr.client) - if(!config.antag_hud_allowed && (!client.holder || mentor)) + if(!config.antag_hud_allowed && !client.holder) src << "Admins have disabled this for this round." return var/mob/observer/dead/M = src if(jobban_isbanned(M, "AntagHUD")) src << "You have been banned from using this feature" return - if(config.antag_hud_restricted && !M.has_enabled_antagHUD && (!client.holder || mentor)) + if(config.antag_hud_restricted && !M.has_enabled_antagHUD && !client.holder) var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No") if(response == "No") return M.can_reenter_corpse = 0 - if(!M.has_enabled_antagHUD && (!client.holder || mentor)) + if(!M.has_enabled_antagHUD && !client.holder) M.has_enabled_antagHUD = 1 if(M.antagHUD) M.antagHUD = 0 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index cb4aa33ab3..524cc7d4b6 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -294,6 +294,8 @@ var/global/list/damage_icon_parts = list() base_icon = chest.get_icon() for(var/obj/item/organ/external/part in organs) + if(isnull(part) || part.is_stump()) + continue var/icon/temp = part.get_icon(skeleton) //That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST //And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index cbcdc069aa..4e7fa35f32 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -160,6 +160,7 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c add_language(LANGUAGE_EAL, 1) add_language(LANGUAGE_SCHECHI, 1) add_language(LANGUAGE_SIGN, 1) + add_language(LANGUAGE_ROOTLOCAL, 1) if(!safety)//Only used by AIize() to successfully spawn an AI. if (!B)//If there is no player/brain inside. diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 2ccbc8cea7..176b2184d8 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -400,7 +400,7 @@ proc/is_blind(A) return // Can't talk in deadchat if you can't see it. for(var/mob/M in player_list) - if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && !is_eventM(M.client))) && M.is_preference_enabled(/datum/client_preference/show_dsay)) + if(M.client && (!istype(M, /mob/new_player) && M.stat == DEAD) && M.is_preference_enabled(/datum/client_preference/show_dsay)) var/follow var/lname if(M.forbid_seeing_deadchat && !M.client.holder) diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 0b91e3e39b..ad642f3215 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -324,7 +324,7 @@ name = "Overeye Long" icon_state = "hair_longovereye" - fag + flowhair name = "Flow Hair" icon_state = "hair_f" diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 342e10db84..10a4b5ead9 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -159,6 +159,34 @@ name = "ammo clip (.45 flash)" ammo_type = /obj/item/ammo_casing/a45f +/obj/item/ammo_magazine/s45 + name = "speedloader (.45)" + icon_state = "45s" + ammo_type = /obj/item/ammo_casing/a45 + matter = list(DEFAULT_WALL_MATERIAL = 525) //metal costs are very roughly based around 1 .45 casing = 75 metal + caliber = ".45" + max_ammo = 7 + multiple_sprites = 1 + +/obj/item/ammo_magazine/s45/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/s45/rubber + name = "speedloader (.45 rubber)" + ammo_type = /obj/item/ammo_casing/a45r + +/obj/item/ammo_magazine/s45/practice + name = "speedloader (.45 practice)" + ammo_type = /obj/item/ammo_casing/a45p + +/obj/item/ammo_magazine/s45/flash + name = "speedloader (.45 flash)" + ammo_type = /obj/item/ammo_casing/a45f + +/obj/item/ammo_magazine/s45/ap + name = "speedloader (.45 AP)" + ammo_type = /obj/item/ammo_casing/a45ap + ///////// 9mm ///////// /obj/item/ammo_magazine/m9mm diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index e545ebb848..9a9f0b4bd6 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -23,7 +23,7 @@ icon_state = "[initial(icon_state)]-e" /obj/item/weapon/gun/projectile/colt/detective - desc = "A Martian recreation of an old Terran pistol. Uses .45 rounds." + desc = "A Martian recreation of an old pistol. Uses .45 rounds." magazine_type = /obj/item/ammo_magazine/m45/rubber /obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun() @@ -60,7 +60,8 @@ options["H&K VP"] = "VP78" options["P08 Luger"] = "p08" options["P08 Luger, Brown"] = "p08b" - var/choice = input(M,"What do you want the gun's sprite to be?","Resprite Gun") in options + options["Glock 37"] = "enforcer_black" + var/choice = input(M,"Choose your sprite!","Resprite Gun") in options if(src && choice && !M.stat && in_range(M,src)) icon_state = options[choice] unique_reskin = options[choice] diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 81355d1031..20671d6fd5 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -66,6 +66,58 @@ M << "You name the gun [input]. Say hello to your new friend." return 1 +/obj/item/weapon/gun/projectile/revolver/detective45 + name = ".45 revolver" + desc = "A fancy replica of an old revolver, modified for .45 rounds and a seven-shot cylinder." + icon_state = "detective" + caliber = ".45" + origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) + fire_sound = 'sound/weapons/gunshot_heavy.ogg' + ammo_type = /obj/item/ammo_casing/a45r + max_shells = 7 + + +obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() + set name = "Name Gun" + set category = "Object" + set desc = "Rename your gun. If you're the Detective." + + var/mob/M = usr + if(!M.mind) return 0 + var/job = M.mind.assigned_role + if(job != "Detective") + M << "You don't feel cool enough to name this gun, chump." + return 0 + + var/input = sanitizeSafe(input("What do you want to name the gun?", ,""), MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src)) + name = input + M << "You name the gun [input]. Say hello to your new friend." + return 1 + +/obj/item/weapon/gun/projectile/revolver/detective45/verb/reskin_gun() + set name = "Resprite gun" + set category = "Object" + set desc = "Click to choose a sprite for your gun." + + var/mob/M = usr + var/list/options = list() + options["Colt Detective Special"] = "detective" + options["Ruger GP100"] = "GP100" + options["Colt Single Action Army"] = "detective_peacemaker" + options["Colt Single Action Army, Dark"] = "detective_peacemaker_dark" + options["H&K PT"] = "detective_panther" + options["Vintage LeMat"] = "lemat_old" + options["Webley MKVI "] = "webley" + var/choice = input(M,"Choose your sprite!","Resprite Gun") in options + if(src && choice && !M.stat && in_range(M,src)) + icon_state = options[choice] + M << "Your gun is now sprited as [choice]. Say hello to your new friend." + return 1 + + + // Blade Runner pistol. /obj/item/weapon/gun/projectile/revolver/deckard name = "\improper Deckard .38" diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 393ee201a8..aefbebe1f6 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -210,6 +210,7 @@ icon_state = "vial" matter = list("glass" = 250) volume = 30 + w_class = ITEMSIZE_TINY amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25) flags = OPENCONTAINER diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 6312d08d84..88b6d9d064 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -76,6 +76,13 @@ ..() reagents.add_reagent("water",1000) +/obj/structure/reagent_dispensers/watertank/high/New() + name = "high-capacity water tank" + desc = "A highly-pressurized water tank made to hold vast amounts of water.." + icon_state = "watertank_high" + ..() + reagents.add_reagent("water",4000) + /obj/structure/reagent_dispensers/fueltank name = "fueltank" desc = "A fueltank." diff --git a/html/changelog.html b/html/changelog.html index cb2923c0f1..610d80aa38 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,20 @@ -->
+

06 November 2017

+

Atermonera updated:

+ +

Woodrat updated:

+ +

24 September 2017

Belsima updated: