diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 114f9b7c11f..2e14fb96eb6 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -57,3 +57,4 @@ #define INFECTION_LEVEL_ONE 100 #define INFECTION_LEVEL_TWO 500 #define INFECTION_LEVEL_THREE 1000 +#define INFECTION_LEVEL_MAX 1500 \ No newline at end of file diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index a79bf09d951..a33adbae29a 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/supplypacks/contraband.dm b/code/datums/supplypacks/contraband.dm index cbe52301dff..d600c2969ce 100644 --- a/code/datums/supplypacks/contraband.dm +++ b/code/datums/supplypacks/contraband.dm @@ -63,11 +63,13 @@ /obj/item/clothing/suit/storage/vest/heavy/merc, /obj/item/clothing/glasses/night, /obj/item/weapon/storage/box/anti_photons, - /obj/item/ammo_magazine/clip/c12g/pellet, /obj/item/ammo_magazine/clip/c12g + /obj/item/ammo_magazine/clip/c12g/pellet, + /obj/item/ammo_magazine/clip/c12g ), list( //the doc, /obj/item/weapon/storage/firstaid/combat, - /obj/item/weapon/gun/projectile/dartgun, /obj/item/weapon/reagent_containers/hypospray, + /obj/item/weapon/gun/projectile/dartgun, + /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate, /obj/item/weapon/reagent_containers/glass/bottle/cyanide, /obj/item/ammo_magazine/chemdart diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm index b4d51ed1b53..fef3f3e350c 100644 --- a/code/datums/supplypacks/medical.dm +++ b/code/datums/supplypacks/medical.dm @@ -119,7 +119,7 @@ /obj/item/weapon/storage/belt/medical, /obj/item/device/radio/headset/heads/cmo, /obj/item/clothing/under/rank/chief_medical_officer, - /obj/item/weapon/reagent_containers/hypospray, + /obj/item/weapon/reagent_containers/hypospray/vial, /obj/item/clothing/accessory/stethoscope, /obj/item/clothing/glasses/hud/health, /obj/item/clothing/suit/storage/toggle/labcoat/cmo, diff --git a/code/datums/supplypacks/voidsuits.dm b/code/datums/supplypacks/voidsuits.dm index 658ed5562f4..dda9aa4ed4b 100644 --- a/code/datums/supplypacks/voidsuits.dm +++ b/code/datums/supplypacks/voidsuits.dm @@ -142,7 +142,7 @@ /obj/item/clothing/shoes/magboots = 2, /obj/item/weapon/tank/oxygen = 2 ) - cost = 50 + cost = 60 containertype = "/obj/structure/closet/crate/secure" containername = "Vey-Med Medical voidsuit crate" access = access_medical_equip diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm index d644a9eaa8c..c0b7600aad7 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/atoms_movable.dm b/code/game/atoms_movable.dm index b7210f22a30..e4bd3b85ead 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,6 +1,6 @@ /atom/movable layer = 3 - appearance_flags = TILE_BOUND + appearance_flags = TILE_BOUND|PIXEL_SCALE var/last_move = null var/anchored = 0 // var/elevation = 2 - not used anywhere @@ -15,7 +15,7 @@ var/moved_recently = 0 var/mob/pulledby = null var/item_state = null // Used to specify the item state for the on-mob overlays. - + var/icon_scale = 1 // Used to scale icons up or down in update_transform(). var/auto_init = 1 /atom/movable/New() @@ -296,3 +296,12 @@ return null return text2num(pickweight(candidates)) +/atom/movable/proc/update_transform() + var/matrix/M = matrix() + M.Scale(icon_scale) + src.transform = M + +// Use this to set the object's scale. +/atom/movable/proc/adjust_scale(new_scale) + icon_scale = new_scale + update_transform() diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 82976e075fc..b0f19c3ba3a 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -4,6 +4,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E var/list/datum/absorbed_dna/absorbed_dna = list() var/list/absorbed_languages = list() // Necessary because of set_species stuff var/absorbedcount = 0 + var/lingabsorbedcount = 1 //Starts at one, because that's us var/chem_charges = 20 var/chem_recharge_rate = 0.5 var/chem_storage = 50 @@ -11,8 +12,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E var/changelingID = "Changeling" var/geneticdamage = 0 var/isabsorbing = 0 - var/geneticpoints = 5 - var/max_geneticpoints = 5 + var/geneticpoints = 7 + var/max_geneticpoints = 7 var/readapts = 1 var/max_readapts = 2 var/list/purchased_powers = list() diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 396e6faf347..0af67b22ed6 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -90,16 +90,23 @@ continue absorbDNA(dna_data) changeling.absorbedcount++ + T.mind.changeling.absorbed_dna.len = 1 - changeling.geneticpoints += 5 - changeling.max_geneticpoints += 5 + // This is where lings get boosts from eating eachother + if(T.mind.changeling.lingabsorbedcount) + for(var/a = 1 to T.mind.changeling.lingabsorbedcount) + changeling.lingabsorbedcount++ + changeling.geneticpoints += 4 + changeling.max_geneticpoints += 4 + src << "We absorbed another changeling, and we grow stronger. Our genomes increase." T.mind.changeling.chem_charges = 0 T.mind.changeling.geneticpoints = -1 T.mind.changeling.max_geneticpoints = -1 //To prevent revival. T.mind.changeling.absorbedcount = 0 + T.mind.changeling.lingabsorbedcount = 0 changeling.absorbedcount++ changeling.isabsorbing = 0 diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 48f0f02bfca..65ad3d7f01f 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -7,8 +7,8 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' /datum/game_mode/heist name = "Heist" config_tag = "heist" - required_players = 9 - required_players_secret = 9 + required_players = 12 + required_players_secret = 12 required_enemies = 3 round_description = "An unidentified bluespace signature is approaching the station!" extended_round_description = "The Company's majority control of phoron in the system has marked the \ diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index e85af7e82b6..f7233c1266a 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -12,8 +12,8 @@ var/list/nuke_disks = list() colony of sizable population and considerable wealth causes it to often be the target of various \ attempts of robbery, fraud and other malicious actions." config_tag = "mercenary" - required_players = 9 - required_players_secret = 9 + required_players = 12 + required_players_secret = 12 required_enemies = 3 end_on_antag_death = 0 var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 39d3f739d72..850f061250d 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -440,7 +440,7 @@ datum/objective/steal "a chief medical officer's jumpsuit" = /obj/item/clothing/under/rank/chief_medical_officer, "a head of security's jumpsuit" = /obj/item/clothing/under/rank/head_of_security, "a head of personnel's jumpsuit" = /obj/item/clothing/under/rank/head_of_personnel, - "the hypospray" = /obj/item/weapon/reagent_containers/hypospray, + "the hypospray" = /obj/item/weapon/reagent_containers/hypospray/vial, "the colony director's pinpointer" = /obj/item/weapon/pinpointer, "an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof, ) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index f74b1d6185f..a0ac2f646cb 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -74,7 +74,7 @@ var/global/datum/controller/occupations/job_master proc/FreeRole(var/rank) //making additional slot on the fly var/datum/job/job = GetJob(rank) - if(job && job.current_positions >= job.total_positions && job.total_positions != -1) + if(job && job.total_positions != -1) job.total_positions++ return 1 return 0 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index acd7a446c19..9b01f7b6bd7 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -127,6 +127,36 @@ icon = 'icons/obj/doors/Doormaint.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_mai +/obj/machinery/door/airlock/maintenance/cargo + icon = 'icons/obj/doors/Doormaint_cargo.dmi' + req_one_access = list(access_cargo) + +/obj/machinery/door/airlock/maintenance/command + icon = 'icons/obj/doors/Doormaint_command.dmi' + req_one_access = list(access_heads) + +/obj/machinery/door/airlock/maintenance/common + icon = 'icons/obj/doors/Doormaint_common.dmi' + +/obj/machinery/door/airlock/maintenance/engi + icon = 'icons/obj/doors/Doormaint_engi.dmi' + req_one_access = list(access_engine) + +/obj/machinery/door/airlock/maintenance/int + icon = 'icons/obj/doors/Doormaint_int.dmi' + +/obj/machinery/door/airlock/maintenance/medical + icon = 'icons/obj/doors/Doormaint_med.dmi' + req_one_access = list(access_medical) + +/obj/machinery/door/airlock/maintenance/rnd + icon = 'icons/obj/doors/Doormaint_rnd.dmi' + req_one_access = list(access_research) + +/obj/machinery/door/airlock/maintenance/sec + icon = 'icons/obj/doors/Doormaint_sec.dmi' + req_one_access = list(access_security) + /obj/machinery/door/airlock/external name = "External Airlock" icon = 'icons/obj/doors/Doorext.dmi' diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm index 45501a3de76..434f7e64cb5 100644 --- a/code/game/machinery/doors/multi_tile.dm +++ b/code/game/machinery/doors/multi_tile.dm @@ -2,15 +2,44 @@ /obj/machinery/door/airlock/multi_tile width = 2 appearance_flags = 0 + var/obj/machinery/filler_object/filler1 + var/obj/machinery/filler_object/filler2 /obj/machinery/door/airlock/multi_tile/New() ..() SetBounds() + if(opacity) + create_fillers() + +/obj/machinery/door/airlock/multi_tile/Destroy() + qdel_null(filler1) + qdel_null(filler2) + return ..() /obj/machinery/door/airlock/multi_tile/Move() . = ..() SetBounds() +/obj/machinery/door/airlock/multi_tile/open() + . = ..() + + if(filler1) + filler1.set_opacity(opacity) + if(filler2) + filler2.set_opacity(opacity) + + return . + +/obj/machinery/door/airlock/multi_tile/close() + . = ..() + + if(filler1) + filler1.set_opacity(opacity) + if(filler2) + filler2.set_opacity(opacity) + + return . + /obj/machinery/door/airlock/multi_tile/proc/SetBounds() if(dir in list(EAST, WEST)) bound_width = width * world.icon_size @@ -19,9 +48,35 @@ bound_width = world.icon_size bound_height = width * world.icon_size +/obj/machinery/door/airlock/multi_tile/proc/create_fillers() + if(src.dir > 3) + filler1 = new/obj/machinery/filler_object (src.loc) + filler2 = new/obj/machinery/filler_object (get_step(src,EAST)) + else + filler1 = new/obj/machinery/filler_object (src.loc) + filler2 = new/obj/machinery/filler_object (get_step(src,NORTH)) + filler1.density = 0 + filler2.density = 0 + filler1.set_opacity(opacity) + filler2.set_opacity(opacity) + /obj/machinery/door/airlock/multi_tile/glass name = "Glass Airlock" icon = 'icons/obj/doors/Door2x1glass.dmi' opacity = 0 glass = 1 assembly_type = /obj/structure/door_assembly/multi_tile + +/obj/machinery/door/airlock/multi_tile/metal + name = "Airlock" + icon = 'icons/obj/doors/Door2x1metal.dmi' + assembly_type = /obj/structure/door_assembly/multi_tile + +/obj/machinery/filler_object + name = "" + icon = 'icons/obj/doors/rapid_pdoor.dmi' + icon_state = "" + density = 0 + +/obj/machinery/door/airlock/multi_tile/metal/mait + icon = 'icons/obj/doors/Door2x1_Maint.dmi' diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 30a0743e097..7f76bc978c4 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","Tajara","Skrell","Unathi", "Teshari") 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/bodybag.dm b/code/game/objects/items/bodybag.dm index 16e27006b49..a23abb5b066 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -59,7 +59,7 @@ //..() //Doesn't need to run the parent. Since when can fucking bodybags be welded shut? -Agouri return else if(istype(W, /obj/item/weapon/wirecutters)) - user << "You cut the tag off the bodybag" + to_chat(user, "You cut the tag off the bodybag") src.name = "body bag" src.overlays.Cut() return @@ -160,7 +160,7 @@ O.name = "used stasis bag" O.icon = src.icon O.icon_state = "bodybag_used" - O.desc = "Pretty useless now.." + O.desc = "Pretty useless now..." qdel(src) /obj/structure/closet/body_bag/cryobag/MouseDrop(over_object, src_location, over_location) @@ -211,9 +211,9 @@ /obj/structure/closet/body_bag/cryobag/examine(mob/user) ..() if(Adjacent(user)) //The bag's rather thick and opaque from a distance. - user << "You peer into \the [src]." + to_chat(user, "You peer into \the [src].") if(syringe) - user << "It has a syringe added to it." + to_chat(user, "It has a syringe added to it.") for(var/mob/living/L in contents) L.examine(user) diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index decb40d8079..3f1c67aafb9 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -374,7 +374,10 @@ // This proc is used so that we can return out of the revive process while ensuring that busy and update_icon() are handled /obj/item/weapon/shockpaddles/proc/do_revive(mob/living/carbon/human/H, mob/user) if(!H.client && !H.teleop) - to_chat(find_dead_player(H.ckey, 1), "Someone is attempting to resuscitate you. Re-enter your body if you want to be revived!") + for(var/mob/observer/dead/ghost in player_list) + if(ghost.mind == H.mind) + to_chat(ghost, "Someone is attempting to resuscitate you. Re-enter your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") + break //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process user.visible_message("\The [user] begins to place [src] on [H]'s chest.", "You begin to place [src] on [H]'s chest...") diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm index 62cb9d9862c..dbac918609c 100644 --- a/code/game/objects/items/devices/geiger.dm +++ b/code/game/objects/items/devices/geiger.dm @@ -1,7 +1,7 @@ -#define RAD_LEVEL_LOW 5 //10 // Around the level at which radiation starts to become harmful -#define RAD_LEVEL_MODERATE 15 //15 -#define RAD_LEVEL_HIGH 50 //50 -#define RAD_LEVEL_VERY_HIGH 100 //100 +#define RAD_LEVEL_LOW 0.01 // Around the level at which radiation starts to become harmful +#define RAD_LEVEL_MODERATE 10 +#define RAD_LEVEL_HIGH 25 +#define RAD_LEVEL_VERY_HIGH 50 //Geiger counter //Rewritten version of TG's geiger counter @@ -19,7 +19,14 @@ /obj/item/device/geiger/New() processing_objects |= src +/obj/item/device/geiger/Destroy() + processing_objects -= src + return ..() + /obj/item/device/geiger/process() + get_radiation() + +/obj/item/device/geiger/proc/get_radiation() if(!scanning) return radiation_count = radiation_repository.get_rads_at_turf(get_turf(src)) @@ -27,12 +34,29 @@ /obj/item/device/geiger/examine(mob/user) ..(user) - to_chat(user, "[scanning ? "ambient" : "stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq.") + get_radiation() + to_chat(user, "[scanning ? "Ambient" : "Stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq.") + +/obj/item/device/geiger/rad_act(amount) + if(!amount || !scanning) + return FALSE + + if(amount > radiation_count) + radiation_count = amount + + var/sound = "geiger" + if(amount < 5) + sound = "geiger_weak" + playsound(src, sound, between(10, 10 + (radiation_count * 4), 100), 0) + if(sound == "geiger_weak") // A weak geiger sound every two seconds sounds too infrequent. + spawn(1 SECOND) + playsound(src, sound, between(10, 10 + (radiation_count * 4), 100), 0) + update_icon() /obj/item/device/geiger/attack_self(var/mob/user) scanning = !scanning update_icon() - to_chat(user, "\icon[src] You switch [scanning ? "on" : "off"] [src].") + to_chat(user, "\icon[src] You switch [scanning ? "on" : "off"] \the [src].") /obj/item/device/geiger/update_icon() if(!scanning) @@ -40,12 +64,18 @@ return 1 switch(radiation_count) - if(null) icon_state = "geiger_on_1" - if(-INFINITY to RAD_LEVEL_LOW) icon_state = "geiger_on_1" - if(RAD_LEVEL_LOW + 1 to RAD_LEVEL_MODERATE) icon_state = "geiger_on_2" - if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) icon_state = "geiger_on_3" - if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) icon_state = "geiger_on_4" - if(RAD_LEVEL_VERY_HIGH + 1 to INFINITY) icon_state = "geiger_on_5" + if(null) + icon_state = "geiger_on_1" + if(-INFINITY to RAD_LEVEL_LOW) + icon_state = "geiger_on_1" + if(RAD_LEVEL_LOW to RAD_LEVEL_MODERATE) + icon_state = "geiger_on_2" + if(RAD_LEVEL_MODERATE to RAD_LEVEL_HIGH) + icon_state = "geiger_on_3" + if(RAD_LEVEL_HIGH to RAD_LEVEL_VERY_HIGH) + icon_state = "geiger_on_4" + if(RAD_LEVEL_VERY_HIGH to INFINITY) + icon_state = "geiger_on_5" #undef RAD_LEVEL_LOW #undef RAD_LEVEL_MODERATE diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 53d647a4f0b..ca4b8d8066e 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -8,7 +8,7 @@ var/spamcheck = 0 var/emagged = 0 var/insults = 0 - var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TATER!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!") + var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TERRORIST!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "GLORY TO ALMACH!") /obj/item/device/megaphone/attack_self(mob/living/user as mob) if (user.client) diff --git a/code/game/objects/items/gunbox.dm b/code/game/objects/items/gunbox.dm new file mode 100644 index 00000000000..add1530ca48 --- /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/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index dde2f168b0e..d878dd74fec 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -75,11 +75,11 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open) - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + to_chat(user, "The [affecting.name] is cut open, you'll need more than a bandage!") return if(affecting.is_bandaged()) - user << "The wounds on [M]'s [affecting.name] have already been bandaged." + to_chat(user, "The wounds on [M]'s [affecting.name] have already been bandaged.") return 1 else user.visible_message("\The [user] starts treating [M]'s [affecting.name].", \ @@ -93,9 +93,13 @@ if(used == amount) break if(!do_mob(user, M, W.damage/5)) - user << "You must stand still to bandage wounds." + to_chat(user, "You must stand still to bandage wounds.") break + if(affecting.is_bandaged()) // We do a second check after the delay, in case it was bandaged after the first check. + to_chat(user, "The wounds on [M]'s [affecting.name] have already been bandaged.") + return 1 + if (W.current_stage <= W.max_bleeding_stage) user.visible_message("\The [user] bandages \a [W.desc] on [M]'s [affecting.name].", \ "You bandage \a [W.desc] on [M]'s [affecting.name]." ) @@ -111,9 +115,9 @@ affecting.update_damages() if(used == amount) if(affecting.is_bandaged()) - user << "\The [src] is used up." + to_chat(user, "\The [src] is used up.") else - user << "\The [src] is used up, but there are more wounds to treat on \the [affecting.name]." + to_chat(user, "\The [src] is used up, but there are more wounds to treat on \the [affecting.name].") use(used) /obj/item/stack/medical/ointment @@ -135,17 +139,20 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open) - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + to_chat(user, "The [affecting.name] is cut open, you'll need more than a bandage!") return if(affecting.is_salved()) - user << "The wounds on [M]'s [affecting.name] have already been salved." + to_chat(user, "The wounds on [M]'s [affecting.name] have already been salved.") return 1 else user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \ "You start salving the wounds on [M]'s [affecting.name]." ) if(!do_mob(user, M, 10)) - user << "You must stand still to salve wounds." + to_chat(user, "You must stand still to salve wounds.") + return 1 + if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check. + to_chat(user, "The wounds on [M]'s [affecting.name] have already been salved.") return 1 user.visible_message("[user] salved wounds on [M]'s [affecting.name].", \ "You salved wounds on [M]'s [affecting.name]." ) @@ -169,11 +176,11 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open) - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + to_chat(user, "The [affecting.name] is cut open, you'll need more than a bandage!") return if(affecting.is_bandaged() && affecting.is_disinfected()) - user << "The wounds on [M]'s [affecting.name] have already been treated." + to_chat(user, "The wounds on [M]'s [affecting.name] have already been treated.") return 1 else user.visible_message("\The [user] starts treating [M]'s [affecting.name].", \ @@ -187,8 +194,11 @@ if(used == amount) break if(!do_mob(user, M, W.damage/5)) - user << "You must stand still to bandage wounds." + to_chat(user, "You must stand still to bandage wounds.") break + if(affecting.is_bandaged() && affecting.is_disinfected()) // We do a second check after the delay, in case it was bandaged after the first check. + to_chat(user, "The wounds on [M]'s [affecting.name] have already been bandaged.") + return 1 if (W.current_stage <= W.max_bleeding_stage) user.visible_message("\The [user] cleans \a [W.desc] on [M]'s [affecting.name] and seals the edges with bioglue.", \ "You clean and seal \a [W.desc] on [M]'s [affecting.name]." ) @@ -205,9 +215,9 @@ affecting.update_damages() if(used == amount) if(affecting.is_bandaged()) - user << "\The [src] is used up." + to_chat(user, "\The [src] is used up.") else - user << "\The [src] is used up, but there are more wounds to treat on \the [affecting.name]." + to_chat(user, "\The [src] is used up, but there are more wounds to treat on \the [affecting.name].") use(used) /obj/item/stack/medical/advanced/ointment @@ -228,16 +238,19 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open) - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + to_chat(user, "The [affecting.name] is cut open, you'll need more than a bandage!") if(affecting.is_salved()) - user << "The wounds on [M]'s [affecting.name] have already been salved." + to_chat(user, "The wounds on [M]'s [affecting.name] have already been salved.") return 1 else user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \ "You start salving the wounds on [M]'s [affecting.name]." ) if(!do_mob(user, M, 10)) - user << "You must stand still to salve wounds." + to_chat(user, "You must stand still to salve wounds.") + return 1 + if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check. + to_chat(user, "The wounds on [M]'s [affecting.name] have already been salved.") return 1 user.visible_message( "[user] covers wounds on [M]'s [affecting.name] with regenerative membrane.", \ "You cover wounds on [M]'s [affecting.name] with regenerative membrane." ) @@ -264,20 +277,23 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) var/limb = affecting.name if(!(affecting.organ_tag in splintable_organs)) - user << "You can't use \the [src] to apply a splint there!" + to_chat(user, "You can't use \the [src] to apply a splint there!") return if(affecting.splinted) - user << "[M]'s [limb] is already splinted!" + to_chat(user, "[M]'s [limb] is already splinted!") return if (M != user) user.visible_message("[user] starts to apply \the [src] to [M]'s [limb].", "You start to apply \the [src] to [M]'s [limb].", "You hear something being wrapped.") else if(( !user.hand && (affecting.organ_tag in list(BP_R_ARM, BP_R_HAND)) || \ user.hand && (affecting.organ_tag in list(BP_L_ARM, BP_L_HAND)) )) - user << "You can't apply a splint to the arm you're using!" + to_chat(user, "You can't apply a splint to the arm you're using!") return user.visible_message("[user] starts to apply \the [src] to their [limb].", "You start to apply \the [src] to your [limb].", "You hear something being wrapped.") if(do_after(user, 50, M)) + if(affecting.splinted) + to_chat(user, "[M]'s [limb] is already splinted!") + return if(M == user && prob(75)) user.visible_message("\The [user] fumbles [src].", "You fumble [src].", "You hear something being wrapped.") return diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index 95803696d49..63a0df6d326 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -6,6 +6,7 @@ icon_state = "nanopaste" origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) amount = 10 + toolspeed = 0.75 //Used in surgery, shouldn't be the same speed as a normal screwdriver on mechanical organ repair. w_class = ITEMSIZE_SMALL no_variants = FALSE @@ -14,12 +15,13 @@ return 0 if (istype(M,/mob/living/silicon/robot)) //Repairing cyborgs var/mob/living/silicon/robot/R = M - if (R.getBruteLoss() || R.getFireLoss() ) - R.adjustBruteLoss(-15) - R.adjustFireLoss(-15) - R.updatehealth() - use(1) - user.visible_message("\The [user] applied some [src] on [R]'s damaged areas.",\ + if (R.getBruteLoss() || R.getFireLoss()) + if(do_after(user,7 * toolspeed)) + R.adjustBruteLoss(-15) + R.adjustFireLoss(-15) + R.updatehealth() + use(1) + user.visible_message("\The [user] applied some [src] on [R]'s damaged areas.",\ "You apply some [src] at [R]'s damaged areas.") else user << "All [R]'s systems are nominal." @@ -28,14 +30,17 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) - if(S.open >= 2) - if (S && (S.robotic >= ORGAN_ROBOT)) - if(!S.get_damage()) - user << "Nothing to fix here." - else if(can_use(1)) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - S.heal_damage(15, 15, robo_repair = 1) - H.updatehealth() - use(1) - user.visible_message("\The [user] applies some nanite paste on [user != M ? "[M]'s [S.name]" : "[S]"] with [src].",\ - "You apply some nanite paste on [user == M ? "your" : "[M]'s"] [S.name].") + if (S && (S.robotic >= ORGAN_ROBOT)) + if(!S.get_damage()) + user << "Nothing to fix here." + else if(can_use(1)) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(S.open >= 2) + if(do_after(user,5 * toolspeed)) + S.heal_damage(20, 20, robo_repair = 1) + else if(do_after(user,5 * toolspeed)) + S.heal_damage(10,10, robo_repair =1) + H.updatehealth() + use(1) + user.visible_message("\The [user] applies some nanite paste on [user != M ? "[M]'s [S.name]" : "[S]"] with [src].",\ + "You apply some nanite paste on [user == M ? "your" : "[M]'s"] [S.name].") diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 59b064572d3..11d13abe776 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -1060,4 +1060,22 @@ var/list/multi_point_spawns /obj/item/clothing/suit/space/void/security/riot, /obj/item/clothing/head/helmet/space/void/security/riot ) + ) + +/obj/random/multiple/voidsuit/mining + name = "Random Mining Voidsuit" + desc = "This is a random mining voidsuit." + icon = 'icons/obj/clothing/suits.dmi' + icon_state = "rig-mining" + +/obj/random/multiple/voidsuit/mining/item_to_spawn() + return pick( + prob(5);list( + /obj/item/clothing/suit/space/void/mining, + /obj/item/clothing/head/helmet/space/void/mining + ), + prob(1);list( + /obj/item/clothing/suit/space/void/mining/alt, + /obj/item/clothing/head/helmet/space/void/mining/alt + ) ) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index fe838a5291f..0af7913df8f 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -36,7 +36,7 @@ playsound(user, 'sound/machines/lockreset.ogg', 50, 1) if(do_after(user, 20 * O.toolspeed)) src.locked = 0 - user << " You disable the locking modules." + to_chat(user, " You disable the locking modules.") update_icon() return else if(istype(O, /obj/item/weapon)) @@ -50,7 +50,7 @@ else playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time if(W.force < 15) - user << "The cabinet's protective glass glances off the hit." + to_chat(user, "The cabinet's protective glass glances off the hit.") else src.hitstaken++ if(src.hitstaken == 4) @@ -63,12 +63,14 @@ if (istype(O, /obj/item/weapon/material/twohanded/fireaxe) && src.localopened) if(!fireaxe) if(O:wielded) - user << "Unwield the axe first." - return + O:wielded = 0 + O.update_icon() + //to_chat(user, "Unwield the axe first.") + //return fireaxe = O user.remove_from_mob(O) src.contents += O - user << "You place the fire axe back in the [src.name]." + to_chat(user, "You place the fire axe back in the [src.name].") update_icon() else if(src.smashed) @@ -91,11 +93,11 @@ spawn(10) update_icon() return else - user << "Resetting circuitry..." + to_chat(user, "Resetting circuitry...") playsound(user, 'sound/machines/lockenable.ogg', 50, 1) if(do_after(user,20 * O.toolspeed)) src.locked = 1 - user << " You re-enable the locking modules." + to_chat(user, " You re-enable the locking modules.") return else localopened = !localopened @@ -116,13 +118,13 @@ hasaxe = 1 if(src.locked) - user <<"The cabinet won't budge!" + to_chat(user, "The cabinet won't budge!") return if(localopened) if(fireaxe) user.put_in_hands(fireaxe) fireaxe = null - user << "You take the fire axe from the [name]." + to_chat (user, "You take the fire axe from the [name].") src.add_fingerprint(user) update_icon() else @@ -149,7 +151,7 @@ attack_tk(mob/user as mob) if(localopened && fireaxe) fireaxe.forceMove(loc) - user << "You telekinetically remove the fire axe." + to_chat(user, "You telekinetically remove the fire axe.") fireaxe = null update_icon() return @@ -161,9 +163,9 @@ if (isrobot(usr) || src.locked || src.smashed) if(src.locked) - usr << "The cabinet won't budge!" + to_chat(usr, "The cabinet won't budge!") else if(src.smashed) - usr << "The protective glass is broken!" + to_chat(usr, "The protective glass is broken!") return localopened = !localopened @@ -180,23 +182,23 @@ if(fireaxe) usr.put_in_hands(fireaxe) fireaxe = null - usr << "You take the Fire axe from the [name]." + to_chat(usr, "You take the Fire axe from the [name].") else - usr << "The [src.name] is empty." + to_chat(usr, "The [src.name] is empty.") else - usr << "The [src.name] is closed." + to_chat(usr, "The [src.name] is closed.") update_icon() attack_ai(mob/user as mob) if(src.smashed) - user << "The security of the cabinet is compromised." + to_chat(user, "The security of the cabinet is compromised.") return else locked = !locked if(locked) - user << "Cabinet locked." + to_chat(user, "Cabinet locked.") else - user << "Cabinet unlocked." + to_chat(user, "Cabinet unlocked.") return update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers 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 dbbdee3711b..9e5f0b7815c 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -204,7 +204,7 @@ new /obj/item/device/radio/headset/heads/cmo(src) new /obj/item/device/radio/headset/heads/cmo/alt(src) new /obj/item/device/flash(src) - new /obj/item/weapon/reagent_containers/hypospray(src) + new /obj/item/weapon/reagent_containers/hypospray/vial(src) new /obj/item/clothing/suit/storage/hooded/wintercoat/medical(src) new /obj/item/clothing/shoes/boots/winter/medical(src) new /obj/item/weapon/storage/box/freezer(src) @@ -243,21 +243,17 @@ New() ..() - 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) + 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 @@ -274,8 +270,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 d863aecd24b..83aa687957a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -276,15 +276,13 @@ ..() 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) new /obj/item/device/radio/headset/headset_sec/alt(src) new /obj/item/clothing/suit/storage/vest/detective(src) - new /obj/item/ammo_magazine/m45/rubber(src) - new /obj/item/ammo_magazine/m45/rubber(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/projectile/colt/detective(src) new /obj/item/clothing/accessory/holster/armpit(src) new /obj/item/device/flashlight/maglight(src) new /obj/item/weapon/reagent_containers/food/drinks/flask/detflask(src) diff --git a/code/game/objects/structures/fitness.dm b/code/game/objects/structures/fitness.dm new file mode 100644 index 00000000000..3bb158a576b --- /dev/null +++ b/code/game/objects/structures/fitness.dm @@ -0,0 +1,65 @@ +/obj/structure/fitness + icon = 'icons/obj/stationobjs.dmi' + anchored = 1 + var/being_used = 0 + +/obj/structure/fitness/punchingbag + name = "punching bag" + desc = "A punching bag." + icon_state = "punchingbag" + density = 1 + var/list/hit_message = list("hit", "punch", "kick", "robust") + +/obj/structure/fitness/punchingbag/attack_hand(var/mob/living/carbon/human/user) + if(!istype(user)) + ..() + return + if(user.nutrition < 20) + to_chat(user, "You need more energy to use the punching bag. Go eat something.") + else + if(user.a_intent == I_HURT) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + flick("[icon_state]_hit", src) + playsound(src.loc, 'sound/effects/woodhit.ogg', 25, 1, -1) + user.do_attack_animation(src) + user.nutrition = user.nutrition - 5 + to_chat(user, "You [pick(hit_message)] \the [src].") + +/obj/structure/fitness/weightlifter + name = "weightlifting machine" + desc = "A machine used to lift weights." + icon_state = "weightlifter" + var/weight = 1 + var/list/qualifiers = list("with ease", "without any trouble", "with great effort") + +/obj/structure/fitness/weightlifter/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1) + weight = ((weight) % qualifiers.len) + 1 + to_chat(user, "You set the machine's weight level to [weight].") + +/obj/structure/fitness/weightlifter/attack_hand(var/mob/living/carbon/human/user) + if(!istype(user)) + return + if(user.loc != src.loc) + to_chat(user, "You must be on the weight machine to use it.") + return + if(user.nutrition < 50) + to_chat(user, "You need more energy to lift weights. Go eat something.") + return + if(being_used) + to_chat(user, "The weight machine is already in use by somebody else.") + return + else + being_used = 1 + playsound(src.loc, 'sound/effects/weightlifter.ogg', 50, 1) + user.set_dir(SOUTH) + flick("[icon_state]_[weight]", src) + if(do_after(user, 20 + (weight * 10))) + playsound(src.loc, 'sound/effects/weightdrop.ogg', 25, 1) + user.nutrition -= weight * 10 + to_chat(user, "You lift the weights [qualifiers[weight]].") + being_used = 0 + else + to_chat(user, "Against your previous judgement, perhaps working out is not for you.") + being_used = 0 diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 42ee6af2e3e..c457e3ae2cc 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -77,6 +77,9 @@ return return +/obj/structure/morgue/attack_robot(mob/user) + if(Adjacent(user)) + attack_hand(user) /obj/structure/morgue/attack_hand(mob/user as mob) if (src.connected) @@ -156,6 +159,10 @@ connected = null return ..() +/obj/structure/m_tray/attack_robot(mob/user) + if(Adjacent(user)) + attack_hand(user) + /obj/structure/m_tray/attack_hand(mob/user as mob) if (src.connected) for(var/atom/movable/A as mob|obj in src.loc) @@ -181,7 +188,7 @@ if (user != O) for(var/mob/B in viewers(user, 3)) if ((B.client && !( B.blinded ))) - B << "\The [user] stuffs [O] into [src]!" + to_chat(B, "\The [user] stuffs [O] into [src]!") return @@ -189,25 +196,16 @@ * Crematorium */ -/obj/structure/crematorium +/obj/structure/morgue/crematorium name = "crematorium" desc = "A human incinerator. Works well on barbeque nights." icon = 'icons/obj/stationobjs.dmi' icon_state = "crema1" - density = 1 - var/obj/structure/c_tray/connected = null - anchored = 1.0 var/cremating = 0 var/id = 1 var/locked = 0 -/obj/structure/crematorium/Destroy() - if(connected) - qdel(connected) - connected = null - return ..() - -/obj/structure/crematorium/proc/update() +/obj/structure/morgue/crematorium/update() if (src.connected) src.icon_state = "crema0" else @@ -217,37 +215,7 @@ src.icon_state = "crema1" return -/obj/structure/crematorium/ex_act(severity) - switch(severity) - if(1.0) - for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) - ex_act(severity) - qdel(src) - return - if(2.0) - if (prob(50)) - for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) - ex_act(severity) - qdel(src) - return - if(3.0) - if (prob(5)) - for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) - ex_act(severity) - qdel(src) - return - return - -/obj/structure/crematorium/attack_hand(mob/user as mob) -// if (cremating) AWW MAN! THIS WOULD BE SO MUCH MORE FUN ... TO WATCH -// user.show_message("Uh-oh, that was a bad idea.", 1) -// //usr << "Uh-oh, that was a bad idea." -// src:loc:poison += 20000000 -// src:loc:firelevel = src:loc:poison -// return +/obj/structure/morgue/crematorium/attack_hand(mob/user as mob) if (cremating) usr << "It's locked." return @@ -260,10 +228,10 @@ qdel(src.connected) else if (src.locked == 0) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - src.connected = new /obj/structure/c_tray( src.loc ) - step(src.connected, SOUTH) + src.connected = new /obj/structure/m_tray/c_tray( src.loc ) + step(src.connected, EAST) src.connected.layer = OBJ_LAYER - var/turf/T = get_step(src, SOUTH) + var/turf/T = get_step(src, EAST) if (T.contents.Find(src.connected)) src.connected.connected = src src.icon_state = "crema0" @@ -276,7 +244,7 @@ src.add_fingerprint(user) update() -/obj/structure/crematorium/attackby(P as obj, mob/user as mob) +/obj/structure/morgue/crematorium/attackby(P as obj, mob/user as mob) if (istype(P, /obj/item/weapon/pen)) var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text if (user.get_active_hand() != P) @@ -291,13 +259,13 @@ src.add_fingerprint(user) return -/obj/structure/crematorium/relaymove(mob/user as mob) +/obj/structure/morgue/crematorium/relaymove(mob/user as mob) if (user.stat || locked) return - src.connected = new /obj/structure/c_tray( src.loc ) - step(src.connected, SOUTH) + src.connected = new /obj/structure/m_tray/c_tray( src.loc ) + step(src.connected, EAST) src.connected.layer = OBJ_LAYER - var/turf/T = get_step(src, SOUTH) + var/turf/T = get_step(src, EAST) if (T.contents.Find(src.connected)) src.connected.connected = src src.icon_state = "crema0" @@ -309,25 +277,22 @@ src.connected = null return -/obj/structure/crematorium/proc/cremate(atom/A, mob/user as mob) -// for(var/obj/machinery/crema_switch/O in src) //trying to figure a way to call the switch, too drunk to sort it out atm -// if(var/on == 1) -// return +/obj/structure/morgue/crematorium/proc/cremate(atom/A, mob/user as mob) if(cremating) return //don't let you cremate something twice or w/e if(contents.len <= 0) for (var/mob/M in viewers(src)) - M.show_message("You hear a hollow crackle.", 1) + to_chat(M,"You hear a hollow crackle.") return else if(!isemptylist(src.search_contents_for(/obj/item/weapon/disk/nuclear))) - usr << "You get the feeling that you shouldn't cremate one of the items in the cremator." + to_chat(user,"You get the feeling that you shouldn't cremate one of the items in the cremator.") return for (var/mob/M in viewers(src)) - M.show_message("You hear a roar as the crematorium activates.", 1) + to_chat(M,"You hear a roar as the crematorium activates.") cremating = 1 locked = 1 @@ -363,51 +328,11 @@ /* * Crematorium tray */ -/obj/structure/c_tray +/obj/structure/m_tray/c_tray name = "crematorium tray" desc = "Apply body before burning." icon = 'icons/obj/stationobjs.dmi' icon_state = "cremat" - density = 1 - layer = 2.0 - var/obj/structure/crematorium/connected = null - anchored = 1 - throwpass = 1 - -/obj/structure/c_tray/Destroy() - if(connected && connected.connected == src) - connected.connected = null - connected = null - return ..() - -/obj/structure/c_tray/attack_hand(mob/user as mob) - if (src.connected) - for(var/atom/movable/A as mob|obj in src.loc) - if (!( A.anchored )) - A.forceMove(src.connected) - //Foreach goto(26) - src.connected.connected = null - src.connected.update() - add_fingerprint(user) - //SN src = null - qdel(src) - return - return - -/obj/structure/c_tray/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) - if ((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src) || user.contents.Find(O))) - return - if (!ismob(O) && !istype(O, /obj/structure/closet/body_bag)) - return - if (!ismob(user) || user.stat || user.lying || user.stunned) - return - O.forceMove(src.loc) - if (user != O) - for(var/mob/B in viewers(user, 3)) - if ((B.client && !( B.blinded ))) - B << text("[] stuffs [] into []!", user, O, src) - //Foreach goto(99) - return /obj/machinery/button/crematorium name = "crematorium igniter" @@ -421,9 +346,9 @@ if(..()) return if(src.allowed(user)) - for (var/obj/structure/crematorium/C in world) + for (var/obj/structure/morgue/crematorium/C in world) if (C.id == id) if (!C.cremating) C.cremate(user) else - usr << "Access denied." + to_chat(user,"Access denied.") diff --git a/code/game/sound.dm b/code/game/sound.dm index c23614942bc..afeeaafcaef 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -51,6 +51,8 @@ var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/ef var/list/mechstep_sound = list('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg') var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg') var/list/can_sound = list('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg') +var/list/geiger_sound = list('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg') +var/list/geiger_weak_sound = list('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg') //var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') @@ -186,4 +188,6 @@ var/const/FALLOFF_SOUNDS = 0.5 if ("canopen") soundin = pick(can_sound) if ("mechstep") soundin = pick(mechstep_sound) //if ("gunshot") soundin = pick(gun_sound) + if("geiger") soundin = pick(geiger_sound) + if("geiger_weak") soundin = pick(geiger_weak_sound) return soundin diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index fa6dec5715b..8fafb555a33 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -43,6 +43,8 @@ var/ooc_style = "everyone" if(holder && !holder.fakekey) ooc_style = "elevated" + if(holder.rights & R_EVENT) + ooc_style = "event_manager" if(holder.rights & R_MOD) ooc_style = "moderator" if(holder.rights & R_DEBUG) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 121e355d22e..c7d0bb262b5 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1223,21 +1223,6 @@ proc/admin_notice(var/message, var/rights) 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 b6d0abbe1c3..473770ac2b5 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 2503c73abba..0b02b98ef32 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, ) @@ -330,11 +329,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, @@ -448,9 +447,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" @@ -461,7 +457,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! @@ -777,7 +773,7 @@ var/list/admin_verbs_event_manager = list( set category = "Admin" if(holder) - if(alert("Confirm self-deadmin for the round? You can't re-admin yourself without someont promoting you.",,"Yes","No") == "Yes") + if(alert("Confirm self-deadmin for the round? You can't re-admin yourself without someone promoting you.",,"Yes","No") == "Yes") log_admin("[src] deadmined themself.") message_admins("[src] deadmined themself.", 1) deadmin() diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 15317902684..92536a6e053 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 63209f84b4e..264e5ad64eb 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 c14c74edd12..b80d95e3c18 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/client/preference_setup/traits/trait_defines.dm b/code/modules/client/preference_setup/traits/trait_defines.dm index 0431ac611b9..86b8ede6f70 100644 --- a/code/modules/client/preference_setup/traits/trait_defines.dm +++ b/code/modules/client/preference_setup/traits/trait_defines.dm @@ -72,6 +72,25 @@ Regardless, you find it quite difficult to land shots where you wanted them to go." modifier_type = /datum/modifier/trait/inaccurate +/datum/trait/modifier/physical/smaller + name = "Smaller" + modifier_type = /datum/modifier/trait/smaller + mutually_exclusive = list(/datum/trait/modifier/physical/small, /datum/trait/modifier/physical/large, /datum/trait/modifier/physical/larger) + +/datum/trait/modifier/physical/small + name = "Small" + modifier_type = /datum/modifier/trait/small + mutually_exclusive = list(/datum/trait/modifier/physical/smaller, /datum/trait/modifier/physical/large, /datum/trait/modifier/physical/larger) + +/datum/trait/modifier/physical/large + name = "Large" + modifier_type = /datum/modifier/trait/large + mutually_exclusive = list(/datum/trait/modifier/physical/smaller, /datum/trait/modifier/physical/small, /datum/trait/modifier/physical/larger) + +/datum/trait/modifier/physical/larger + name = "Larger" + modifier_type = /datum/modifier/trait/larger + mutually_exclusive = list(/datum/trait/modifier/physical/smaller, /datum/trait/modifier/physical/small, /datum/trait/modifier/physical/large) // These two traits might be borderline, feel free to remove if they get abused. /datum/trait/modifier/physical/high_metabolism diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index 31830fb275c..3c5dc32e687 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -150,20 +150,20 @@ item_state_slots = list(slot_r_hand_str = "medical_voidsuit_bio", slot_l_hand_str = "medical_voidsuit_bio") armor = list(melee = 45, bullet = 5, laser = 20, energy = 5, bomb = 15, bio = 100, rad = 75) -//Medical Surplus Voidsuit +//Medical Streamlined Voidsuit /obj/item/clothing/head/helmet/space/void/medical/alt name = "streamlined medical voidsuit helmet" desc = "A trendy, lightly radiation-shielded voidsuit helmet trimmed in a fetching green." icon_state = "rig0-medicalalt" - armor = list(melee = 30, bullet = 5, laser = 10,energy = 5, bomb = 5, bio = 100, rad = 60) + armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 80) light_overlay = "helmet_light_dual_green" /obj/item/clothing/suit/space/void/medical/alt icon_state = "rig-medicalalt" name = "streamlined medical voidsuit" desc = "A more recent model of Vey-Med voidsuit, featuring the latest in radiation shielding technology, without sacrificing comfort or style." - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) - armor = list(melee = 30, bullet = 5, laser = 10,energy = 5, bomb = 5, bio = 100, rad = 60) + slowdown = 0 + armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 80) //Security /obj/item/clothing/head/helmet/space/void/security diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index a2cc9aafb9e..84a187ef91d 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 edfa6b1a86c..e31b26fbb1a 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/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm index c22d65e4214..8621e2b7ed1 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/code/modules/integrated_electronics/core/pins.dm @@ -112,6 +112,8 @@ list[]( /datum/integrated_io/proc/write_data_to_pin(var/new_data) if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) // Anything else is a type we don't want. + if(istext(new_data)) + new_data = sanitizeSafe(new_data, MAX_MESSAGE_LEN, 0, 0) data = new_data holder.on_data_written() diff --git a/code/modules/integrated_electronics/core/special_pins/string_pin.dm b/code/modules/integrated_electronics/core/special_pins/string_pin.dm index 6128418c1f3..595a2053187 100644 --- a/code/modules/integrated_electronics/core/special_pins/string_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/string_pin.dm @@ -4,11 +4,14 @@ /datum/integrated_io/string/ask_for_pin_data(mob/user) var/new_data = input("Please type in a string.","[src] string writing") as null|text - if(holder.check_interactivity(user) ) + new_data = sanitizeSafe(new_data, MAX_MESSAGE_LEN, 0, 0) + + if(new_data && holder.check_interactivity(user) ) to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") write_data_to_pin(new_data) /datum/integrated_io/string/write_data_to_pin(var/new_data) + new_data = sanitizeSafe(new_data, MAX_MESSAGE_LEN, 0, 0) if(isnull(new_data) || istext(new_data)) data = new_data holder.on_data_written() diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm index 08765b94e51..0f702be3de0 100644 --- a/code/modules/integrated_electronics/core/tools.dm +++ b/code/modules/integrated_electronics/core/tools.dm @@ -125,6 +125,7 @@ if("string") accepting_refs = 0 new_data = input("Now type in a string.","[src] string writing") as null|text + new_data = sanitizeSafe(new_data, MAX_MESSAGE_LEN, 0, 0) if(istext(new_data) && CanInteract(user, physical_state)) data_to_write = new_data to_chat(user, "You set \the [src]'s memory to \"[new_data]\".") diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index c417c3e4fd0..0a516e360a7 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 7b5846eb8d0..e490ccd27a9 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 00e5bf2ea41..8da4fad6d8e 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 84e0724bb93..943141b071a 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 fa4fd9ded63..40f617e62e7 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 f5284341294..e1e3f56c892 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 25a80c2a28d..e6d65bd07a3 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/_modifiers/modifiers.dm b/code/modules/mob/_modifiers/modifiers.dm index ee6d914fa69..3facabe6f97 100644 --- a/code/modules/mob/_modifiers/modifiers.dm +++ b/code/modules/mob/_modifiers/modifiers.dm @@ -41,6 +41,7 @@ var/accuracy // Positive numbers makes hitting things with guns easier, negatives make it harder. Each point makes it 15% easier or harder, just like evasion. var/accuracy_dispersion // Positive numbers make gun firing cover a wider tile range, and therefore more inaccurate. Negatives help negate dispersion penalties. var/metabolism_percent // Adjusts the mob's metabolic rate, which affects reagent processing. Won't affect mobs without reagent processing. + var/icon_scale_percent // Makes the holder's icon get scaled up or down. /datum/modifier/New(var/new_holder, var/new_origin) holder = new_holder @@ -62,6 +63,8 @@ holder.modifiers.Remove(src) if(mob_overlay_state) // We do this after removing ourselves from the list so that the overlay won't remain. holder.update_modifier_visuals() + if(icon_scale_percent) // Correct the scaling. + holder.update_transform() qdel(src) // Override this for special effects when it gets removed. @@ -117,6 +120,8 @@ modifiers.Add(mod) if(mod.mob_overlay_state) update_modifier_visuals() + if(mod.icon_scale_percent) + update_transform() return mod @@ -198,6 +203,8 @@ effects += "Your metabolism is [metabolism_percent > 1.0 ? "faster" : "slower"], \ causing reagents in your body to process, and hunger to occur [multipler_to_percentage(metabolism_percent, TRUE)] [metabolism_percent > 1.0 ? "faster" : "slower"]." + if(!isnull(icon_scale_percent)) + effects += "Your appearance is [multipler_to_percentage(icon_scale_percent, TRUE)] [icon_scale_percent > 1 ? "larger" : "smaller"]." return jointext(effects, "
") diff --git a/code/modules/mob/_modifiers/traits.dm b/code/modules/mob/_modifiers/traits.dm index 824343c41c4..3e9e8278e42 100644 --- a/code/modules/mob/_modifiers/traits.dm +++ b/code/modules/mob/_modifiers/traits.dm @@ -58,4 +58,28 @@ desc = "Your body's metabolism is slower than average." metabolism_percent = 0.5 - incoming_healing_percent = 0.6 \ No newline at end of file + incoming_healing_percent = 0.6 + +/datum/modifier/trait/larger + name = "Larger" + desc = "Your body is larger than average." + + icon_scale_percent = 1.2 + +/datum/modifier/trait/large + name = "Large" + desc = "Your body is a bit larger than average." + + icon_scale_percent = 1.1 + +/datum/modifier/trait/small + name = "Small" + desc = "Your body is a bit smaller than average." + + icon_scale_percent = 0.95 + +/datum/modifier/trait/smaller + name = "Smaller" + desc = "Your body is smaller than average." + + icon_scale_percent = 0.9 \ No newline at end of file diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 5f208dd8d7c..52426454e22 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -316,19 +316,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/alien/alien_attacks.dm b/code/modules/mob/living/carbon/alien/alien_attacks.dm index e201e851167..c120b9deefa 100644 --- a/code/modules/mob/living/carbon/alien/alien_attacks.dm +++ b/code/modules/mob/living/carbon/alien/alien_attacks.dm @@ -15,7 +15,7 @@ if (I_GRAB) if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, src ) M.put_in_active_hand(G) @@ -56,4 +56,4 @@ for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) O.show_message(text("[] has attempted to punch []!", M, src), 1) - return \ No newline at end of file + return diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 615a3ecf533..81ea775ab9a 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -18,17 +18,9 @@ var/skiparms = 0 var/skipfeet = 0 - - var/cloaked = 0 // 0 for normal, 1 for cloaked close - - if(mind && mind.changeling && mind.changeling.cloaked && !istype(user, /mob/observer)) - var/distance = get_dist(user, src) - if(distance > 2) - src.loc.examine(user) - return - else - cloaked = 1 - + if(alpha <= 50) + src.loc.examine(user) + return var/looks_synth = looksSynthetic() @@ -97,8 +89,6 @@ if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender T = gender_datums[PLURAL] - if(cloaked) - T = gender_datums[NEUTER] else if(species && species.ambiguous_genders) var/can_detect_gender = FALSE @@ -458,25 +448,18 @@ msg += "Medical records: \[View\] \[Add comment\]\n" - if(print_flavor_text() && !cloaked) + if(print_flavor_text()) msg += "[print_flavor_text()]\n" msg += "*---------*
" msg += applying_pressure - if (pose && !cloaked) + if (pose) if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "[T.He] [pose]" user << jointext(msg, null) - -/mob/living/carbon/human/get_description_fluff() - if(mind && mind.changeling && mind.changeling.cloaked) - return "" - else - return ..() - //Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records. /proc/hasHUD(mob/M as mob, hudtype) if(istype(M, /mob/living/carbon/human)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 52c81df2ab7..92ea71f8293 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -318,8 +318,6 @@ //repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere /mob/living/carbon/human/proc/get_visible_name() - if( mind && mind.changeling && mind.changeling.cloaked) - return "Unknown" if( wear_mask && (wear_mask.flags_inv&HIDEFACE) ) //Wearing a mask which hides our face, use id-name if possible return get_id_name("Unknown") if( head && (head.flags_inv&HIDEFACE) ) @@ -1136,6 +1134,9 @@ if(species.default_language) add_language(species.default_language) + if(species.icon_scale != 1) + update_transform() + if(species.base_color && default_colour) //Apply colour. r_skin = hex2num(copytext(species.base_color,2,4)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index beb91704293..fbb98c3f984 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -29,7 +29,6 @@ var/g_synth //Same as above var/b_synth //Same as above - var/size_multiplier = 1 //multiplier for the mob's icon size var/damage_multiplier = 1 //multiplies melee combat damage var/icon_update = 1 //whether icon updating shall take place diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 40d9d7402ee..61bded2e159 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -11,7 +11,6 @@ // Icon/appearance vars. var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. - var/icobase_add // Icon set for highlight blends when applicable. var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. var/speech_bubble_appearance = "normal" // Part of icon_state to use for speech bubbles when talking. See talk.dmi for available icons. @@ -29,9 +28,10 @@ var/tail // Name of tail state in species effects icon file. var/tail_animation // If set, the icon to obtain tail animation states from. - var/tail_animation_add // Highlight overlay for tail. var/tail_hair + var/icon_scale = 1 // Makes the icon larger/smaller. + var/race_key = 0 // Used for mob icon cache string. var/icon/icon_template // Used for mob icon generation for non-32x32 species. var/mob_size = MOB_MEDIUM diff --git a/code/modules/mob/living/carbon/human/species/species_getters.dm b/code/modules/mob/living/carbon/human/species/species_getters.dm index e0be03af1dd..efb053eddfe 100644 --- a/code/modules/mob/living/carbon/human/species/species_getters.dm +++ b/code/modules/mob/living/carbon/human/species/species_getters.dm @@ -10,9 +10,6 @@ /datum/species/proc/get_tail_animation(var/mob/living/carbon/human/H) return tail_animation -/datum/species/proc/get_tail_animation_a(var/mob/living/carbon/human/H) - return tail_animation_add - /datum/species/proc/get_tail_hair(var/mob/living/carbon/human/H) return tail_hair @@ -31,9 +28,6 @@ /datum/species/proc/get_icobase(var/mob/living/carbon/human/H, var/get_deform) return (get_deform ? deform : icobase) -/datum/species/proc/get_icobase_a(var/mob/living/carbon/human/H) - return icobase_add - /datum/species/proc/get_station_variant() return name diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index 5ab786f8f6f..a894ce52ee2 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -85,7 +85,7 @@ var/datum/species/shapeshifter/promethean/prometheans /mob/living/carbon/human/proc/regenerate ) - valid_transform_species = list("Human", "Unathi", "Tajara", "Skrell", "Diona", "Teshari", "Monkey") + valid_transform_species = list("Human", "Vatborn", "Unathi", "Tajara", "Skrell", "Diona", "Teshari", "Monkey") monochromatic = 1 var/heal_rate = 0.5 // Temp. Regen per tick. diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index 308c62c4bda..0a6e1df9a48 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -26,9 +26,8 @@ tail_hair = "feathers" reagent_tag = IS_TESHARI - icobase = 'icons/mob/human_races/r_seromi_m.dmi' - icobase_add = 'icons/mob/human_races/r_seromi_a.dmi' - deform = 'icons/mob/human_races/r_seromi_m.dmi' + icobase = 'icons/mob/human_races/r_seromi.dmi' + deform = 'icons/mob/human_races/r_seromi.dmi' damage_overlays = 'icons/mob/human_races/masks/dam_seromi.dmi' damage_mask = 'icons/mob/human_races/masks/dam_mask_seromi.dmi' blood_mask = 'icons/mob/human_races/masks/blood_seromi.dmi' diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index 686519394fd..372451808e2 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -25,12 +25,10 @@ /datum/species/unathi name = "Unathi" name_plural = "Unathi" - icobase = 'icons/mob/human_races/r_lizard_m.dmi' - icobase_add = 'icons/mob/human_races/r_lizard_a.dmi' + icobase = 'icons/mob/human_races/r_lizard.dmi' deform = 'icons/mob/human_races/r_def_lizard.dmi' tail = "sogtail" - tail_animation = 'icons/mob/species/unathi/tail_m.dmi' - tail_animation_add = 'icons/mob/species/unathi/tail_a.dmi' + tail_animation = 'icons/mob/species/unathi/tail.dmi' unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) primitive_form = "Stok" darksight = 3 @@ -41,6 +39,8 @@ burn_mod = 0.85 metabolic_rate = 0.85 item_slowdown_mod = 0.5 + mob_size = MOB_LARGE + blood_volume = 840 num_alternate_languages = 3 secondary_langs = list(LANGUAGE_UNATHI) name_language = LANGUAGE_UNATHI @@ -130,12 +130,10 @@ /datum/species/tajaran name = "Tajara" name_plural = "Tajaran" - icobase = 'icons/mob/human_races/r_tajaran_m.dmi' - icobase_add = 'icons/mob/human_races/r_tajaran_a.dmi' + icobase = 'icons/mob/human_races/r_tajaran.dmi' deform = 'icons/mob/human_races/r_def_tajaran.dmi' tail = "tajtail" - tail_animation = 'icons/mob/species/tajaran/tail_m.dmi' - tail_animation_add = 'icons/mob/species/tajaran/tail_a.dmi' + tail_animation = 'icons/mob/species/tajaran/tail.dmi' unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) darksight = 8 slowdown = -0.5 @@ -213,8 +211,7 @@ /datum/species/skrell name = "Skrell" name_plural = "Skrell" - icobase = 'icons/mob/human_races/r_skrell_m.dmi' - icobase_add = 'icons/mob/human_races/r_skrell_a.dmi' + icobase = 'icons/mob/human_races/r_skrell.dmi' deform = 'icons/mob/human_races/r_def_skrell.dmi' primitive_form = "Neaera" unarmed_types = list(/datum/unarmed_attack/punch) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index a436fad6825..ebaa6866e01 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -159,16 +159,29 @@ Please contact me on #coderbus IRC. ~Carn x for(var/inner_entry in entry) overlays += inner_entry + update_transform() + +/mob/living/carbon/human/update_transform() + // First, get the correct size. + var/desired_scale = icon_scale + + desired_scale *= species.icon_scale + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.icon_scale_percent)) + desired_scale *= M.icon_scale_percent + + // Regular stuff again. if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone. var/matrix/M = matrix() M.Turn(90) - M.Scale(size_multiplier) + M.Scale(desired_scale) M.Translate(1,-6) src.transform = M else var/matrix/M = matrix() - M.Scale(size_multiplier) - M.Translate(0, 16*(size_multiplier-1)) + M.Scale(desired_scale) + M.Translate(0, 16*(desired_scale-1)) src.transform = M var/global/list/damage_icon_parts = list() @@ -293,6 +306,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) @@ -1133,22 +1148,14 @@ var/global/list/damage_icon_parts = list() if(!tail_icon) //generate a new one var/species_tail_anim = species.get_tail_animation(src) - var/species_tail_anim_a = species.get_tail_animation_a(src) - if(!species_tail_anim) - species_tail_anim = 'icons/effects/species.dmi' - if(!species_tail_anim_a) - species_tail_anim_a = 'icons/effects/species_a.dmi' + if(!species_tail_anim) species_tail_anim = 'icons/effects/species.dmi' tail_icon = new/icon(species_tail_anim) - var/tail_icon_a = new/icon(species_tail_anim_a) - tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_MULTIPLY) - tail_icon.Blend(tail_icon_a, ICON_ADD) + tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) // The following will not work with animated tails. var/use_species_tail = species.get_tail_hair(src) if(use_species_tail) var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.get_tail(src)]_[use_species_tail]") - var/icon/hair_icon_a = icon('icons/effects/species_a.dmi', "[species.get_tail(src)]_[use_species_tail]") - hair_icon.Blend(rgb(r_hair, g_hair, b_hair), ICON_MULTIPLY) - hair_icon.Blend(hair_icon_a, ICON_ADD) + hair_icon.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) tail_icon.Blend(hair_icon, ICON_OVERLAY) tail_icon_cache[icon_key] = tail_icon diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b87eac5a1df..c6fd9b20e96 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1004,3 +1004,17 @@ default behaviour is: // Called by job_controller. /mob/living/proc/equip_post_job() return + + +/mob/living/update_transform() + // First, get the correct size. + var/desired_scale = icon_scale + for(var/datum/modifier/M in modifiers) + if(!isnull(M.icon_scale_percent)) + desired_scale *= M.icon_scale_percent + + // Now for the regular stuff. + var/matrix/M = matrix() + M.Scale(desired_scale) + M.Translate(0, 16*(desired_scale-1)) + src.transform = M \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index ad3a41fbc86..b48a1609d9e 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -17,10 +17,6 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/proc/show_laws_verb, /mob/living/silicon/ai/proc/toggle_acceleration, /mob/living/silicon/ai/proc/toggle_hologram_movement, - /mob/living/silicon/ai/proc/toggle_hidden_verbs, -) - -var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.com/1172/, /mob/living/silicon/ai/proc/ai_announcement, /mob/living/silicon/ai/proc/ai_call_shuttle, /mob/living/silicon/ai/proc/ai_camera_track, @@ -160,6 +156,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. @@ -794,16 +791,5 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c if(rig) rig.force_rest(src) -/mob/living/silicon/ai/proc/toggle_hidden_verbs() - set name = "Toggle Hidden Verbs" - set category = "AI Settings" - - if(/mob/living/silicon/ai/proc/ai_announcement in verbs) - src << "Extra verbs toggled off." - verbs -= ai_verbs_hidden - else - src << "Extra verbs toggled on." - verbs |= ai_verbs_hidden - #undef AI_CHECK_WIRELESS #undef AI_CHECK_RADIO diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2deb4bc0b22..6c3cd7f1dbd 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -394,6 +394,11 @@ C.toggled = 1 src << "You enable [C.name]." +/mob/living/silicon/robot/verb/spark_plug() //So you can still sparkle on demand without violence. + set category = "Robot Commands" + set name = "Emit Sparks" + spark_system.start() + // this function displays jetpack pressure in the stat panel /mob/living/silicon/robot/proc/show_jetpack_pressure() // if you have a jetpack, show the internal tank pressure @@ -637,7 +642,8 @@ else if( !(istype(W, /obj/item/device/robotanalyzer) || istype(W, /obj/item/device/healthanalyzer)) ) - spark_system.start() + if(W.force > 0) + spark_system.start() return ..() /mob/living/silicon/robot/attack_hand(mob/user) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index f229d537a8b..c21ab59deff 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -90,6 +90,7 @@ var/assist_distance = 25 // Radius in which I'll ask my comrades for help. var/supernatural = 0 // If the mob is supernatural (used in null-rod stuff for banishing?) var/grab_resist = 75 // Chance of me resisting a grab attempt. + var/taser_kill = 1 // Is the mob weak to tasers //Attack ranged settings var/ranged = 0 // Do I attack at range? @@ -1439,16 +1440,17 @@ //Shot with taser/stunvolver /mob/living/simple_animal/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) - var/stunDam = 0 - var/agonyDam = 0 + if(taser_kill) + var/stunDam = 0 + var/agonyDam = 0 - if(stun_amount) - stunDam += stun_amount * 0.5 - adjustFireLoss(stunDam) + if(stun_amount) + stunDam += stun_amount * 0.5 + adjustFireLoss(stunDam) - if(agony_amount) - agonyDam += agony_amount * 0.5 - adjustFireLoss(agonyDam) + if(agony_amount) + agonyDam += agony_amount * 0.5 + adjustFireLoss(agonyDam) /mob/living/simple_animal/emp_act(severity) if(!isSynthetic()) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 92a8b3bdebc..6063526c897 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -534,6 +534,7 @@ if(M != usr) return if(usr == src) return if(!Adjacent(usr)) return + if(usr.incapacitated(INCAPACITATION_STUNNED | INCAPACITATION_FORCELYING | INCAPACITATION_KNOCKOUT | INCAPACITATION_RESTRAINED)) return //Incapacitated. if(istype(M,/mob/living/silicon/ai)) return show_inv(usr) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 56104d34f44..b7fdd7714de 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 752a2b53029..4b729f0a706 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/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm index f756b71efa4..01d7008a096 100644 --- a/code/modules/organs/internal/appendix.dm +++ b/code/modules/organs/internal/appendix.dm @@ -18,6 +18,8 @@ return 0 /obj/item/organ/internal/appendix/process() + ..() + if(!inflamed || !owner) return diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 28fbf62f1ea..7dd2bd948ef 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -44,21 +44,6 @@ tmp_owner.internal_organs_by_name[organ_tag] = new replace_path(tmp_owner, 1) tmp_owner = null -/obj/item/organ/internal/pariah_brain - name = "brain remnants" - desc = "Did someone tread on this? It looks useless for cloning or cyborgification." - organ_tag = "brain" - parent_organ = BP_HEAD - icon = 'icons/mob/alien.dmi' - icon_state = "chitin" - vital = 1 - -/obj/item/organ/internal/brain/xeno - name = "thinkpan" - desc = "It looks kind of like an enormous wad of purple bubblegum." - icon = 'icons/mob/alien.dmi' - icon_state = "chitin" - /obj/item/organ/internal/brain/New() ..() health = config.default_brain_health @@ -127,6 +112,21 @@ target.key = brainmob.key ..() +/obj/item/organ/internal/pariah_brain + name = "brain remnants" + desc = "Did someone tread on this? It looks useless for cloning or cyborgification." + organ_tag = "brain" + parent_organ = BP_HEAD + icon = 'icons/mob/alien.dmi' + icon_state = "chitin" + vital = 1 + +/obj/item/organ/internal/brain/xeno + name = "thinkpan" + desc = "It looks kind of like an enormous wad of purple bubblegum." + icon = 'icons/mob/alien.dmi' + icon_state = "chitin" + /obj/item/organ/internal/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." diff --git a/code/modules/organs/internal/kidneys.dm b/code/modules/organs/internal/kidneys.dm index a547a2539fe..19652a6376d 100644 --- a/code/modules/organs/internal/kidneys.dm +++ b/code/modules/organs/internal/kidneys.dm @@ -9,6 +9,7 @@ /obj/item/organ/internal/kidneys/process() ..() + if(!owner) return // Coffee is really bad for you with busted kidneys. diff --git a/code/modules/organs/internal/organ_internal.dm b/code/modules/organs/internal/organ_internal.dm index a3fdc511fc4..43b3a4c4d7f 100644 --- a/code/modules/organs/internal/organ_internal.dm +++ b/code/modules/organs/internal/organ_internal.dm @@ -58,5 +58,7 @@ if (prob(3)) take_damage(1,silent=prob(30)) - //if(. >= 3 && antibiotics < 30) //INFECTION_LEVEL_THREE, others are handled on each specific organ - //Nothing that generic internal organs do for this + if(. >= 3 && antibiotics < 30) //INFECTION_LEVEL_THREE + if (prob(50)) + take_damage(1,silent=prob(15)) + diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 915258e1125..77706b95176 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -91,6 +91,9 @@ var/list/organ_cache = list() if(owner && vital) owner.death() +/obj/item/organ/proc/adjust_germ_level(var/amount) // Unless you're setting germ level directly to 0, use this proc instead + germ_level = Clamp(germ_level + amount, 0, INFECTION_LEVEL_MAX) + /obj/item/organ/process() if(loc != owner) @@ -117,9 +120,9 @@ var/list/organ_cache = list() if(config.organs_decay) damage += rand(1,3) if(damage >= max_damage) damage = max_damage - germ_level += rand(2,6) + adjust_germ_level(rand(2,6)) if(germ_level >= INFECTION_LEVEL_TWO) - germ_level += rand(2,6) + adjust_germ_level(rand(2,6)) if(germ_level >= INFECTION_LEVEL_THREE) die() @@ -158,12 +161,12 @@ var/list/organ_cache = list() owner.adjustToxLoss(infection_damage) if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) - germ_level-- + adjust_germ_level(-1) if (germ_level >= INFECTION_LEVEL_ONE/2) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes if(antibiotics < 5 && prob(round(germ_level/6))) - germ_level++ + adjust_germ_level(1) if(germ_level >= INFECTION_LEVEL_ONE) . = 1 //Organ qualifies for effect-specific processing @@ -179,7 +182,7 @@ var/list/organ_cache = list() if (germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) . = 3 //Organ qualifies for effect-specific processing - germ_level++ //Germ_level increases without overdose of antibiotics + adjust_germ_level(rand(5,10)) //Germ_level increases without overdose of antibiotics /obj/item/organ/proc/handle_rejection() // Process unsuitable transplants. TODO: consider some kind of @@ -193,13 +196,13 @@ var/list/organ_cache = list() if(rejecting % 10 == 0) //Only fire every ten rejection ticks. switch(rejecting) if(1 to 50) - germ_level++ + adjust_germ_level(1) if(51 to 200) - germ_level += rand(1,2) + adjust_germ_level(rand(1,2)) if(201 to 500) - germ_level += rand(2,3) + adjust_germ_level(rand(2,3)) if(501 to INFINITY) - germ_level += rand(3,5) + adjust_germ_level(rand(3,5)) owner.reagents.add_reagent("toxin", rand(1,2)) /obj/item/organ/proc/receive_chem(chemical as obj) @@ -238,9 +241,11 @@ var/list/organ_cache = list() if (germ_level < INFECTION_LEVEL_ONE) germ_level = 0 //cure instantly else if (germ_level < INFECTION_LEVEL_TWO) - germ_level -= 6 //at germ_level == 500, this should cure the infection in a minute + adjust_germ_level(-6) //at germ_level < 500, this should cure the infection in a minute + else if (germ_level < INFECTION_LEVEL_THREE) + adjust_germ_level(-2) //at germ_level < 1000, this will cure the infection in 5 minutes else - germ_level -= 2 //at germ_level == 1000, this will cure the infection in 5 minutes + adjust_germ_level(-1) // You waited this long to get treated, you don't really deserve this organ //Adds autopsy data for used_weapon. /obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 40ab0ab500e..3c986b16fd8 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -71,7 +71,7 @@ var/global/list/limb_icon_cache = list() overlays |= lip_icon mob_icon.Blend(lip_icon, ICON_OVERLAY) - //Head markings, duplicated (sadly) below. + //Head markings. for(var/M in markings) var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") @@ -132,22 +132,21 @@ var/global/list/limb_icon_cache = list() mob_icon = new /icon(species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]") apply_colouration(mob_icon) - //Body markings, does not include head, duplicated (sadly) above. - for(var/M in markings) - var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") - mark_s.Blend(markings[M]["color"], ICON_ADD) - overlays |= mark_s //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons - icon_cache_key += "[M][markings[M]["color"]]" + //Body markings, actually does not include head this time. Done separately above. + if(!istype(src,/obj/item/organ/external/head)) + for(var/M in markings) + var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] + var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") + mark_s.Blend(markings[M]["color"], ICON_ADD) + overlays |= mark_s //So when it's not on your body, it has icons + mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons + icon_cache_key += "[M][markings[M]["color"]]" if(body_hair && islist(h_col) && h_col.len >= 3) var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" if(!limb_icon_cache[cache_key]) var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]") - var/icon/IA = icon(species.get_icobase_a(owner), "[icon_name]_[body_hair]") - I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) - I.Blend(IA, ICON_ADD) + I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_ADD) limb_icon_cache[cache_key] = I mob_icon.Blend(limb_icon_cache[cache_key], ICON_OVERLAY) @@ -163,7 +162,10 @@ var/global/list/limb_icon_cache = list() if(nonsolid) applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000") - applying.SetIntensity(0.7) + if(species && species.get_bodytype(owner) != "Human") + applying.SetIntensity(1.5) // Unathi, Taj and Skrell have -very- dark base icons. + else + applying.SetIntensity(0.7) else if(status & ORGAN_DEAD) icon_cache_key += "_dead" @@ -177,12 +179,7 @@ var/global/list/limb_icon_cache = list() applying.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) icon_cache_key += "_tone_[s_tone]" else if(s_col && s_col.len >= 3) - applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_MULTIPLY) - var/gender = "f" - if(owner && owner.gender == MALE) - gender = "m" - var/icon_a = new /icon(species.get_icobase_a(owner), "[icon_name][gendered_icon ? "_[gender]" : ""]") - applying.Blend(icon_a, ICON_ADD) + applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD) icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]" // Translucency. diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 990c97b1c2b..1de92fe7430 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -119,8 +119,8 @@ /obj/item/weapon/pen/reagent/paralysis/New() ..() - reagents.add_reagent("zombiepowder", 10) - reagents.add_reagent("cryptobiolin", 15) + reagents.add_reagent("zombiepowder", 5) + reagents.add_reagent("cryptobiolin", 10) /* * Chameleon pen diff --git a/code/modules/power/grid_checker.dm b/code/modules/power/grid_checker.dm index b8a123e02fa..8127383651c 100644 --- a/code/modules/power/grid_checker.dm +++ b/code/modules/power/grid_checker.dm @@ -4,6 +4,8 @@ than the alternative." icon_state = "gridchecker_on" circuit = /obj/item/weapon/circuitboard/grid_checker + density = 1 + anchored = 1 var/power_failing = FALSE // Turns to TRUE when the grid check event is fired by the Game Master, or perhaps a cheeky antag. // Wire stuff below. var/datum/wires/grid_checker/wires diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 342e10db840..10a4b5ead94 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 e545ebb8485..9a9f0b4bd69 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 81355d10314..20671d6fd58 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 44dce0a7ad2..1961b1feb3b 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 6312d08d84d..88b6d9d0640 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/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index fd8e3bf0cac..6100dda029e 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -5,7 +5,7 @@ icon_state = "generator0" var/active = 0 var/field_radius = 3 - var/max_field_radius = 100 + var/max_field_radius = 150 var/list/field = list() density = 1 var/locked = 0 @@ -323,4 +323,4 @@ T = locate(gen_turf.x + field_radius, gen_turf.y + y_offset, gen_turf.z) if (T) out += T - return out \ No newline at end of file + return out diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 5b3cb80b151..f42f2dcf051 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -24,6 +24,7 @@ em {font-style: normal;font-weight: bold;} .ooc .moderator {color: #184880;} .ooc .developer {color: #1b521f;} .ooc .admin {color: #b82e00;} +.ooc .event_manager {color: #660033;} .ooc .aooc {color: #960018;} /* Admin: Private Messages */ @@ -36,7 +37,7 @@ em {font-style: normal;font-weight: bold;} .mod_channel {color: #735638; font-weight: bold;} .mod_channel .admin {color: #b82e00; font-weight: bold;} .admin_channel {color: #9611D4; font-weight: bold;} -.event_channel {color: #009933; font-weight: bold;} +.event_channel {color: #cc3399; font-weight: bold;} /* Radio: Misc */ .deadsay {color: #530FAD;} diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index f8f735f8676..eb0e41e117c 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -12,7 +12,8 @@ /area/holodeck, /area/supply/station, /area/mine, - /area/vacant/vacant_shop + /area/vacant/vacant_shop, + /area/turbolift ) var/list/exempt_from_atmos = typesof(/area/maintenance, @@ -33,6 +34,11 @@ /area/vacant/vacant_shop ) + // Some maps have areas specific to the map, so include those. + exempt_areas += using_map.unit_test_exempt_areas + exempt_from_atmos += using_map.unit_test_exempt_from_atmos + exempt_from_apc += using_map.unit_test_exempt_from_apc + for(var/area/A in world) if(A.z == 1 && !(A.type in exempt_areas)) area_test_count++ diff --git a/html/changelog.html b/html/changelog.html index cb2923c0f14..610d80aa387 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:

diff --git a/polaris.dme b/polaris.dme index a9c79da700c..0c4ebdf186b 100644 --- a/polaris.dme +++ b/polaris.dme @@ -806,6 +806,7 @@ #include "code\game\objects\items\contraband.dm" #include "code\game\objects\items\crayons.dm" #include "code\game\objects\items\glassjar.dm" +#include "code\game\objects\items\gunbox.dm" #include "code\game\objects\items\latexballoon.dm" #include "code\game\objects\items\paintkit.dm" #include "code\game\objects\items\shooting_range.dm" @@ -995,6 +996,7 @@ #include "code\game\objects\structures\door_assembly.dm" #include "code\game\objects\structures\electricchair.dm" #include "code\game\objects\structures\extinguisher.dm" +#include "code\game\objects\structures\fitness.dm" #include "code\game\objects\structures\flora.dm" #include "code\game\objects\structures\girders.dm" #include "code\game\objects\structures\gravemarker.dm" diff --git a/sound/effects/weightdrop.ogg b/sound/effects/weightdrop.ogg new file mode 100644 index 00000000000..07945daaf86 Binary files /dev/null and b/sound/effects/weightdrop.ogg differ diff --git a/sound/effects/weightlifter.ogg b/sound/effects/weightlifter.ogg new file mode 100644 index 00000000000..51a0d497854 Binary files /dev/null and b/sound/effects/weightlifter.ogg differ diff --git a/sound/items/geiger1.ogg b/sound/items/geiger1.ogg new file mode 100644 index 00000000000..b8220856594 Binary files /dev/null and b/sound/items/geiger1.ogg differ diff --git a/sound/items/geiger2.ogg b/sound/items/geiger2.ogg new file mode 100644 index 00000000000..4c0d734463c Binary files /dev/null and b/sound/items/geiger2.ogg differ diff --git a/sound/items/geiger3.ogg b/sound/items/geiger3.ogg new file mode 100644 index 00000000000..a9a5924d80c Binary files /dev/null and b/sound/items/geiger3.ogg differ diff --git a/sound/items/geiger4.ogg b/sound/items/geiger4.ogg new file mode 100644 index 00000000000..dfad69866cc Binary files /dev/null and b/sound/items/geiger4.ogg differ diff --git a/sound/items/geiger5.ogg b/sound/items/geiger5.ogg new file mode 100644 index 00000000000..1e5f20913cb Binary files /dev/null and b/sound/items/geiger5.ogg differ diff --git a/sound/items/geiger_weak1.ogg b/sound/items/geiger_weak1.ogg new file mode 100644 index 00000000000..cadfcde746c Binary files /dev/null and b/sound/items/geiger_weak1.ogg differ diff --git a/sound/items/geiger_weak2.ogg b/sound/items/geiger_weak2.ogg new file mode 100644 index 00000000000..12f54ae6698 Binary files /dev/null and b/sound/items/geiger_weak2.ogg differ diff --git a/sound/items/geiger_weak3.ogg b/sound/items/geiger_weak3.ogg new file mode 100644 index 00000000000..c935711aacf Binary files /dev/null and b/sound/items/geiger_weak3.ogg differ diff --git a/sound/items/geiger_weak4.ogg b/sound/items/geiger_weak4.ogg new file mode 100644 index 00000000000..2b17311a825 Binary files /dev/null and b/sound/items/geiger_weak4.ogg differ