diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 9692409d45..c87b9942df 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -8,6 +8,7 @@ #define HALLOSS "halloss" #define ELECTROCUTE "electrocute" #define BIOACID "bioacid" +#define SEARING "searing" #define CUT "cut" #define BRUISE "bruise" diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 2dc4afe70a..7f7e9e705e 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -175,6 +175,7 @@ #define MAT_LEAD "lead" #define MAT_SUPERMATTER "supermatter" #define MAT_METALHYDROGEN "mhydrogen" +#define MAT_OSMIUM "osmium" #define SHARD_SHARD "shard" #define SHARD_SHRAPNEL "shrapnel" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 8426edcfcf..efb94d4963 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -210,13 +210,17 @@ #define O_GBLADDER "gas bladder" #define O_POLYP "polyp segment" #define O_ANCHOR "anchoring ligament" +#define O_REGBRUTE "pneumoregenitor" +#define O_REGBURN "thermoregenitor" +#define O_REGOXY "respiroregenitor" +#define O_REGTOX "toxoregenitor" #define O_ACID "acid gland" #define O_EGG "egg sac" #define O_RESIN "resin spinner" #define O_AREJECT "immune hub" #define O_VENTC "morphoplastic node" #define O_VRLINK "virtual node" -#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK) +#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_REGBRUTE, O_REGBURN, O_REGOXY, O_REGTOX, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK) // External organs, aka limbs #define BP_L_FOOT "l_foot" diff --git a/code/__defines/xenoarcheaology.dm b/code/__defines/xenoarcheaology.dm index 45e40cfbde..8a4988b78c 100644 --- a/code/__defines/xenoarcheaology.dm +++ b/code/__defines/xenoarcheaology.dm @@ -36,7 +36,8 @@ #define ARCHAEO_ALIEN_ITEM 36 #define ARCHAEO_ALIEN_BOAT 37 #define ARCHAEO_IMPERION_CIRCUIT 38 -#define MAX_ARCHAEO 38 +#define ARCHAEO_TELECUBE 39 +#define MAX_ARCHAEO 39 #define DIGSITE_GARDEN 1 #define DIGSITE_ANIMAL 2 diff --git a/code/_helpers/icons_vr.dm b/code/_helpers/icons_vr.dm index be5de68e82..60765578e7 100644 --- a/code/_helpers/icons_vr.dm +++ b/code/_helpers/icons_vr.dm @@ -42,4 +42,18 @@ for(var/x_pixel = 1 to I.Width()) if (I.GetPixel(x_pixel, y_pixel)) return y_pixel - 1 - return null \ No newline at end of file + return null + +//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below. +/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready) + /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work. + e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/ + + if(istype(main) && istype(mask)) + if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made mask. + mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. + mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. + mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white background pixels. + + main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent). + return main diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 643ab6d790..6cde264566 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -114,6 +114,19 @@ trigger_aiming(TARGET_CAN_CLICK) return 1 + // VOREStation Addition Start: inbelly item interaction + if(isbelly(loc) && (loc == A.loc)) + if(W) + var/resolved = W.resolve_attackby(A,src) + if(!resolved && A && W) + W.afterattack(A, src, 1, params) // 1: clicking something Adjacent + else + if(ismob(A)) // No instant mob attacking + setClickCooldown(get_attack_speed()) + UnarmedAttack(A, 1) + return + // VOREStation Addition End + if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that return diff --git a/code/datums/outfits/military/fleet.dm b/code/datums/outfits/military/fleet.dm index cf5028978d..915917918c 100644 --- a/code/datums/outfits/military/fleet.dm +++ b/code/datums/outfits/military/fleet.dm @@ -1,21 +1,21 @@ /decl/hierarchy/outfit/military/fleet/pt name = OUTFIT_MILITARY("Fleet PT") - uniform = /obj/item/clothing/under/pt/fleet + uniform = /obj/item/clothing/under/solgov/pt/fleet shoes = /obj/item/clothing/shoes/black /decl/hierarchy/outfit/military/fleet/utility name = OUTFIT_MILITARY("Fleet Utility") - uniform = /obj/item/clothing/under/utility/fleet - shoes = /obj/item/clothing/shoes/boots/jackboots + uniform = /obj/item/clothing/under/solgov/utility/fleet + shoes = /obj/item/clothing/shoes/boots/duty /decl/hierarchy/outfit/military/fleet/service name = OUTFIT_MILITARY("Fleet Service") - uniform = /obj/item/clothing/under/service/fleet + uniform = /obj/item/clothing/under/solgov/service/fleet shoes = /obj/item/clothing/shoes/dress/white /decl/hierarchy/outfit/military/fleet/dress name = OUTFIT_MILITARY("Fleet Dress") - uniform = /obj/item/clothing/under/service/fleet + uniform = /obj/item/clothing/under/solgov/service/fleet shoes = /obj/item/clothing/shoes/dress/white suit = /obj/item/clothing/suit/storage/toggle/dress/fleet gloves = /obj/item/clothing/gloves/white diff --git a/code/datums/outfits/military/marines.dm b/code/datums/outfits/military/marines.dm index d818dabcaa..719b36c690 100644 --- a/code/datums/outfits/military/marines.dm +++ b/code/datums/outfits/military/marines.dm @@ -1,22 +1,22 @@ /decl/hierarchy/outfit/military/marine/pt name = OUTFIT_MILITARY("Marine PT") - uniform = /obj/item/clothing/under/pt/marine + uniform = /obj/item/clothing/under/solgov/pt/marine shoes = /obj/item/clothing/shoes/black /decl/hierarchy/outfit/military/marine/utility name = OUTFIT_MILITARY("Marine Utility") - uniform = /obj/item/clothing/under/utility/marine + uniform = /obj/item/clothing/under/solgov/utility/marine shoes = /obj/item/clothing/shoes/boots/jungle /decl/hierarchy/outfit/military/marine/service name = OUTFIT_MILITARY("Marine Service") - uniform = /obj/item/clothing/under/service/marine + uniform = /obj/item/clothing/under/solgov/service/marine shoes = /obj/item/clothing/shoes/dress suit = /obj/item/clothing/suit/storage/service/marine /decl/hierarchy/outfit/military/marine/dress name = OUTFIT_MILITARY("Marine Dress") - uniform = /obj/item/clothing/under/mildress/marine + uniform = /obj/item/clothing/under/solgov/mildress/marine shoes = /obj/item/clothing/shoes/dress/white suit = /obj/item/clothing/suit/dress/marine gloves = /obj/item/clothing/gloves/white diff --git a/code/datums/outfits/military/sifguard.dm b/code/datums/outfits/military/sifguard.dm index e1280f0cfe..9348224a9e 100644 --- a/code/datums/outfits/military/sifguard.dm +++ b/code/datums/outfits/military/sifguard.dm @@ -1,22 +1,22 @@ /decl/hierarchy/outfit/military/sifguard/pt name = OUTFIT_MILITARY("SifGuard PT") - uniform = /obj/item/clothing/under/pt/sifguard + uniform = /obj/item/clothing/under/solgov/pt/sifguard shoes = /obj/item/clothing/shoes/black /decl/hierarchy/outfit/military/sifguard/utility name = OUTFIT_MILITARY("SifGuard Utility") - uniform = /obj/item/clothing/under/utility/sifguard - shoes = /obj/item/clothing/shoes/boots/jackboots + uniform = /obj/item/clothing/under/solgov/utility/sifguard + shoes = /obj/item/clothing/shoes/boots/tactical /decl/hierarchy/outfit/military/sifguard/service name = OUTFIT_MILITARY("SifGuard Service") - uniform = /obj/item/clothing/under/utility/sifguard - shoes = /obj/item/clothing/shoes/boots/jackboots + uniform = /obj/item/clothing/under/solgov/utility/sifguard + shoes = /obj/item/clothing/shoes/boots/tactical suit = /obj/item/clothing/suit/storage/service/sifguard /decl/hierarchy/outfit/military/sifguard/dress name = OUTFIT_MILITARY("SifGuard Dress") - uniform = /obj/item/clothing/under/mildress/sifguard + uniform = /obj/item/clothing/under/solgov/mildress/sifguard shoes = /obj/item/clothing/shoes/dress suit = /obj/item/clothing/suit/dress/expedition gloves = /obj/item/clothing/gloves/white diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm index 5596d95f03..e345b18505 100644 --- a/code/datums/supplypacks/medical.dm +++ b/code/datums/supplypacks/medical.dm @@ -334,4 +334,18 @@ contains = list(/obj/item/device/defib_kit = 2) cost = 30 containertype = /obj/structure/closet/crate/medical - containername = "Defibrillator crate" \ No newline at end of file + containername = "Defibrillator crate" + +/datum/supply_pack/med/distillery + name = "Chemical distiller crate" + contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1) + cost = 175 + containertype = /obj/structure/largecrate + containername = "Chemical distiller crate" + +/datum/supply_pack/med/advdistillery + name = "Industrial Chemical distiller crate" + contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1) + cost = 250 + containertype = /obj/structure/largecrate + containername = "Industrial Chemical distiller crate" diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm index 344e2bbdbd..0538f83867 100644 --- a/code/datums/supplypacks/medical_vr.dm +++ b/code/datums/supplypacks/medical_vr.dm @@ -1,38 +1,50 @@ -/datum/supply_pack/med/medicalbiosuits - contains = list( - /obj/item/clothing/head/bio_hood/scientist = 3, - /obj/item/clothing/suit/bio_suit/scientist = 3, - /obj/item/clothing/suit/bio_suit/virology = 3, - /obj/item/clothing/head/bio_hood/virology = 3, - /obj/item/clothing/suit/bio_suit/cmo, - /obj/item/clothing/head/bio_hood/cmo, - /obj/item/clothing/shoes/white = 7, - /obj/item/clothing/mask/gas = 7, - /obj/item/weapon/tank/oxygen = 7, - /obj/item/weapon/storage/box/masks, - /obj/item/weapon/storage/box/gloves - ) - cost = 40 - -/datum/supply_pack/med/virologybiosuits - name = "Virology biohazard gear" - contains = list( - /obj/item/clothing/suit/bio_suit/virology = 3, - /obj/item/clothing/head/bio_hood/virology = 3, - /obj/item/clothing/mask/gas = 3, - /obj/item/weapon/tank/oxygen = 3, - /obj/item/weapon/storage/box/masks, - /obj/item/weapon/storage/box/gloves - ) - cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "Virology biohazard equipment" - access = access_medical_equip - -/datum/supply_pack/med/virus - name = "Virus sample crate" - contains = list(/obj/item/weapon/virusdish/random = 4) - cost = 25 - containertype = /obj/structure/closet/crate/secure - containername = "Virus sample crate" - access = access_medical_equip \ No newline at end of file +/datum/supply_pack/med/medicalbiosuits + contains = list( + /obj/item/clothing/head/bio_hood/scientist = 3, + /obj/item/clothing/suit/bio_suit/scientist = 3, + /obj/item/clothing/suit/bio_suit/virology = 3, + /obj/item/clothing/head/bio_hood/virology = 3, + /obj/item/clothing/suit/bio_suit/cmo, + /obj/item/clothing/head/bio_hood/cmo, + /obj/item/clothing/shoes/white = 7, + /obj/item/clothing/mask/gas = 7, + /obj/item/weapon/tank/oxygen = 7, + /obj/item/weapon/storage/box/masks, + /obj/item/weapon/storage/box/gloves + ) + cost = 40 + +/datum/supply_pack/med/virologybiosuits + name = "Virology biohazard gear" + contains = list( + /obj/item/clothing/suit/bio_suit/virology = 3, + /obj/item/clothing/head/bio_hood/virology = 3, + /obj/item/clothing/mask/gas = 3, + /obj/item/weapon/tank/oxygen = 3, + /obj/item/weapon/storage/box/masks, + /obj/item/weapon/storage/box/gloves + ) + cost = 40 + containertype = /obj/structure/closet/crate/secure + containername = "Virology biohazard equipment" + access = access_medical_equip + +/datum/supply_pack/med/virus + name = "Virus sample crate" + contains = list(/obj/item/weapon/virusdish/random = 4) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "Virus sample crate" + access = access_medical_equip + + +/datum/supply_pack/med/bloodpack + containertype = /obj/structure/closet/crate/medical/blood + +/datum/supply_pack/med/compactdefib + name = "Compact Defibrillator crate" + contains = list(/obj/item/device/defib_kit/compact = 1) + cost = 90 + containertype = /obj/structure/closet/crate/secure + containername = "Compact Defibrillator crate" + access = access_medical_equip diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 69733a60d8..eb2a88b497 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -284,7 +284,7 @@ var/global/datum/controller/gameticker/ticker var/mob/living/carbon/human/new_char = player.create_character() if(new_char) qdel(player) - if(istype(new_char)) + if(istype(new_char) && !(new_char.mind.assigned_role=="Cyborg")) data_core.manifest_inject(new_char) //VOREStation Edit End diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 8778b4e5f3..085c070f7d 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -149,6 +149,8 @@ var/power_losses var/last_power_draw = 0 var/obj/item/weapon/cell/cell + var/use_cell = TRUE + var/removeable_cell = TRUE /obj/machinery/portable_atmospherics/powered/powered() if(use_power) //using area power @@ -158,7 +160,7 @@ return 0 /obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/cell)) + if(use_cell && istype(I, /obj/item/weapon/cell)) if(cell) to_chat(user, "There is already a power cell installed.") return @@ -173,7 +175,7 @@ power_change() return - if(I.is_screwdriver()) + if(I.is_screwdriver() && removeable_cell) if(!cell) to_chat(user, "There is no power cell installed.") return diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index 88bf735f53..0baa68cf22 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -102,6 +102,12 @@ circuit = /obj/item/weapon/circuitboard/grinder frame_size = 3 +/datum/frame/frame_types/reagent_distillery + name = "Distillery" + frame_class = FRAME_CLASS_MACHINE + circuit = /obj/item/weapon/circuitboard/distiller + frame_size = 4 + /datum/frame/frame_types/display name = "Display" frame_class = FRAME_CLASS_DISPLAY diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index ab77220281..56fa5c75a0 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -74,6 +74,7 @@ var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg var/check_all = FALSE //If active, will fire on anything, including synthetics. var/ailock = FALSE // AI cannot use this + var/check_down = FALSE //If active, will shoot to kill when lethals are also on var/faction = null //if set, will not fire at people in the same faction for any reason. var/attacked = FALSE //if set to TRUE, the turret gets pissed off and shoots at people nearby (unless they have sec access!) @@ -103,6 +104,7 @@ check_weapons = TRUE check_anomalies = TRUE check_all = FALSE + check_down = TRUE /obj/machinery/porta_turret/can_catalogue(mob/user) // Dead turrets can't be scanned. if(stat & BROKEN) @@ -224,6 +226,7 @@ check_records = FALSE check_anomalies = FALSE check_all = FALSE + check_down = FALSE /obj/machinery/porta_turret/lasertag/red turret_type = "red" @@ -404,7 +407,7 @@ return 1 if(locked && !issilicon(user)) - to_chat(user, "Access denied.") + to_chat(user, "Controls locked.") return 1 return 0 @@ -438,6 +441,7 @@ settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all) + settings[++settings.len] = list("category" = "Neutralize Downed Entities", "setting" = "check_down", "value" = check_down) data["settings"] = settings ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) @@ -489,6 +493,8 @@ check_anomalies = value else if(href_list["command"] == "check_all") check_all = value + else if(href_list["command"] == "check_down") + check_down = value return 1 @@ -732,7 +738,7 @@ if(!emagged && issilicon(L) && check_all == FALSE) // Don't target silica, unless told to neutralize everything. return TURRET_NOT_TARGET - if(L.stat && !emagged) //if the perp is dead/dying, no need to bother really + if(L.stat == DEAD && !emagged) //if the perp is dead, no need to bother really return TURRET_NOT_TARGET //move onto next potential victim! if(get_dist(src, L) > 7) //if it's too far away, why bother? @@ -749,7 +755,7 @@ if(check_synth || check_all) //If it's set to attack all non-silicons or everything, target them! if(L.lying) - return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET + return check_down ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET return TURRET_PRIORITY_TARGET if(iscuffed(L)) // If the target is handcuffed, leave it alone @@ -766,7 +772,7 @@ return TURRET_NOT_TARGET //if threat level < 4, keep going if(L.lying) //if the perp is lying down, it's still a target but a less-important target - return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET + return check_down ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 0667860f95..74cdb2d368 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -628,6 +628,11 @@ /obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper + if(istype(Proj, /obj/item/projectile/test)) + var/obj/item/projectile/test/Test = Proj + Test.hit |= occupant // Register a hit on the occupant, for things like turrets, or in simple-mob cases stopping friendly fire in firing line mode. + return + src.log_message("Hit by projectile. Type: [Proj.name]([Proj.check_armour]).",1) call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment ..() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 591da02757..4e39439c12 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -716,7 +716,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. icon = 'icons/obj/device.dmi' //Worn icon generation for on-mob sprites -/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer) +/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument. //Get the required information about the base icon var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands) var/state2use = get_worn_icon_state(slot_name = slot_name) @@ -738,6 +738,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. if(!inhands) apply_custom(standing_icon) //Pre-image overridable proc to customize the thing apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders + if(istype(clip_mask)) //VOREStation Edit - For taur bodies/tails clipping off parts of uniforms and suits. + standing_icon = get_icon_difference(standing_icon, clip_mask, 1) var/image/standing = image(standing_icon) standing.alpha = alpha diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index e37587812a..a4859c08a5 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -116,7 +116,7 @@ data["flashlight"] = fon data["manifest"] = PDA_Manifest data["feeds"] = compile_news() - data["latest_news"] = get_recent_news() + //data["latest_news"] = get_recent_news() //VOREStation Edit, bandaid for catastrophic runtime lag in helper.dm if(cartridge) // If there's a cartridge, we need to grab the information from it data["cart_devices"] = cartridge.get_device_status() data["cart_templates"] = cartridge.ui_templates diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm index 63308e6caa..6b59d13ea5 100644 --- a/code/game/objects/items/weapons/circuitboards/frame.dm +++ b/code/game/objects/items/weapons/circuitboards/frame.dm @@ -170,6 +170,15 @@ /obj/item/weapon/stock_parts/gear = 1, /obj/item/weapon/reagent_containers/glass/beaker/large = 1) +/obj/item/weapon/circuitboard/distiller + build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery + board_type = new /datum/frame/frame_types/reagent_distillery + req_components = list( + /obj/item/weapon/stock_parts/capacitor = 1, + /obj/item/weapon/stock_parts/micro_laser = 1, + /obj/item/weapon/stock_parts/motor = 2, + /obj/item/weapon/stock_parts/gear = 1) + /obj/item/weapon/circuitboard/teleporter_hub name = T_BOARD("teleporter hub") build_path = /obj/machinery/teleport/hub diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 43e7e0f90c..d4a29d47f3 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -97,6 +97,23 @@ name = "seismic charge" desc = "Used to dig holes in specific areas without too much extra hole." - blast_heavy = 3 - blast_light = 5 - blast_flash = 8 + blast_heavy = 2 + blast_light = 4 + blast_flash = 7 + +/obj/item/weapon/plastique/seismic/attackby(var/obj/item/I, var/mob/user) + . = ..() + if(open_panel) + if(istype(I, /obj/item/weapon/stock_parts/micro_laser)) + var/obj/item/weapon/stock_parts/SP = I + var/new_blast_power = max(1, round(SP.rating / 2) + 1) + if(new_blast_power > blast_heavy) + to_chat(user, "You install \the [I] into \the [src].") + user.drop_from_inventory(I) + qdel(I) + blast_heavy = new_blast_power + blast_light = blast_heavy + round(new_blast_power * 0.5) + blast_flash = blast_light + round(new_blast_power * 0.75) + else + to_chat(user, "The [I] is not any better than the component already installed into this charge!") + return . \ No newline at end of file diff --git a/code/game/objects/items/weapons/explosives_vr.dm b/code/game/objects/items/weapons/explosives_vr.dm new file mode 100644 index 0000000000..a82ca02bbc --- /dev/null +++ b/code/game/objects/items/weapons/explosives_vr.dm @@ -0,0 +1,17 @@ +/obj/item/weapon/plastique/seismic/locked + desc = "Used to dig holes in specific areas without too much extra hole. Has extra mechanism that safely implodes the bomb if it is used in close proximity to the facility." + +/obj/item/weapon/plastique/seismic/locked/explode(var/location) + if(!target) + target = get_atom_on_turf(src) + if(!target) + target = src + + var/turf/T = get_turf(target) + if(T.z in using_map.map_levels) + target.visible_message("\The [src] lets out a loud beep as safeties trigger, before imploding and falling apart.") + target.overlays -= image_overlay + qdel(src) + return 0 + else + return ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm new file mode 100644 index 0000000000..56204be984 --- /dev/null +++ b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm @@ -0,0 +1,30 @@ +/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked + desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones. This one has a safety interlock that prevents release if used while in proximity to the facility." + req_access = list(access_armory) //for toggling safety + var/locked = 1 + +/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/detonate() + if(locked) + var/turf/T = get_turf(src) + if(T.z in using_map.map_levels) + icon_state = initial(icon_state) + active = 0 + return 0 + return ..() + +/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/attackby(obj/item/I, mob/user) + var/obj/item/weapon/card/id/id = I.GetID() + if(istype(id)) + if(check_access(id)) + locked = !locked + to_chat(user, "You [locked ? "enable" : "disable"] the safety lock on \the [src].") + else + to_chat(user, "Access denied.") + user.visible_message("[user] swipes \the [I] against \the [src].") + else + return ..() + +/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/emag_act(var/remaining_charges,var/mob/user) + ..() + locked = !locked + to_chat(user, "You [locked ? "enable" : "disable"] the safety lock on \the [src]!") \ No newline at end of file diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index 6aa1a5c540..6da8a1b933 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -31,6 +31,7 @@ var/dorm = 0 // determines if this ID has claimed a dorm already var/mining_points = 0 // For redeeming at mining equipment vendors + var/survey_points = 0 // For redeeming at explorer equipment vendors. /obj/item/weapon/card/id/examine(mob/user) set src in oview(1) diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index f825577d6f..d935d4eaa2 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -12,6 +12,12 @@ var/lpower = 2 var/lcolor = "#0099FF" + // If it uses energy. + var/use_cell = FALSE + var/hitcost = 120 + var/obj/item/weapon/cell/bcell = null + var/cell_type = /obj/item/weapon/cell/device + /obj/item/weapon/melee/energy/proc/activate(mob/living/user) if(active) return @@ -38,7 +44,31 @@ w_class = initial(w_class) set_light(0,0) +/obj/item/weapon/melee/energy/proc/use_charge(var/cost) + if(active) + if(bcell) + if(bcell.checked_use(cost)) + return 1 + else + return 0 + return null + +/obj/item/weapon/melee/energy/examine(mob/user) + if(!..(user, 1)) + return + + if(use_cell) + if(bcell) + to_chat(user, "The blade is [round(bcell.percent())]% charged.") + if(!bcell) + to_chat(user, "The blade does not have a power source installed.") + /obj/item/weapon/melee/energy/attack_self(mob/living/user as mob) + if(use_cell) + if((!bcell || bcell.charge < hitcost) && !active) + to_chat(user, "\The [src] does not seem to have power.") + return + var/datum/gender/TU = gender_datums[user.get_visible_gender()] if (active) if ((CLUMSY in user.mutations) && prob(50)) @@ -64,6 +94,37 @@ "\The [user] is falling on \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide.")) return (BRUTELOSS|FIRELOSS) +/obj/item/weapon/melee/energy/attack(mob/M, mob/user) + if(active && use_cell) + if(!use_charge(hitcost)) + deactivate(user) + visible_message("\The [src]'s blade flickers, before deactivating.") + return ..() + +/obj/item/weapon/melee/energy/attackby(obj/item/weapon/W, mob/user) + if(use_cell) + if(istype(W, cell_type)) + if(!bcell) + user.drop_item() + W.loc = src + bcell = W + to_chat(user, "You install a cell in [src].") + update_icon() + else + to_chat(user, "[src] already has a cell.") + else if(W.is_screwdriver() && bcell) + bcell.update_icon() + bcell.forceMove(get_turf(loc)) + bcell = null + to_chat(user, "You remove the cell from \the [src].") + deactivate() + update_icon() + return + return ..() + +/obj/item/weapon/melee/energy/get_cell() + return bcell + /* * Energy Axe */ @@ -90,11 +151,13 @@ /obj/item/weapon/melee/energy/axe/activate(mob/living/user) ..() + damtype = SEARING icon_state = "axe1" to_chat(user, "\The [src] is now energised.") /obj/item/weapon/melee/energy/axe/deactivate(mob/living/user) ..() + damtype = BRUTE icon_state = initial(icon_state) to_chat(user, "\The [src] is de-energised. It's just a regular axe now.") @@ -103,6 +166,20 @@ visible_message("\The [user] swings \the [src] towards [TU.his] head! It looks like [TU.he] [TU.is] trying to commit suicide.") return (BRUTELOSS|FIRELOSS) +/obj/item/weapon/melee/energy/axe/charge + name = "charge axe" + desc = "An energised axe." + active_force = 35 + active_throwforce = 20 + force = 15 + + use_cell = TRUE + hitcost = 120 + +/obj/item/weapon/melee/energy/axe/charge/loaded/New() + ..() + bcell = new/obj/item/weapon/cell/device/weapon(src) + /* * Energy Sword */ @@ -274,64 +351,7 @@ armor_penetration = 25 projectile_parry_chance = 40 - var/hitcost = 75 - var/obj/item/weapon/cell/bcell = null - var/cell_type = /obj/item/weapon/cell/device - -/obj/item/weapon/melee/energy/sword/charge/proc/use_charge(var/cost) - if(active) - if(bcell) - if(bcell.checked_use(cost)) - return 1 - else - return 0 - return null - -/obj/item/weapon/melee/energy/sword/charge/examine(mob/user) - if(!..(user, 1)) - return - - if(bcell) - to_chat(user, "The blade is [round(bcell.percent())]% charged.") - if(!bcell) - to_chat(user, "The blade does not have a power source installed.") - -/obj/item/weapon/melee/energy/sword/charge/attack_self(mob/user as mob) - if((!bcell || bcell.charge < hitcost) && !active) - to_chat(user, "\The [src] does not seem to have power.") - return - ..() - -/obj/item/weapon/melee/energy/sword/charge/attack(mob/M, mob/user) - if(active) - if(!use_charge(hitcost)) - deactivate(user) - visible_message("\The [src]'s blade flickers, before retracting.") - return ..() - -/obj/item/weapon/melee/energy/sword/charge/attackby(obj/item/weapon/W, mob/user) - if(istype(W, cell_type)) - if(!bcell) - user.drop_item() - W.loc = src - bcell = W - to_chat(user, "You install a cell in [src].") - update_icon() - else - to_chat(user, "[src] already has a cell.") - else if(W.is_screwdriver() && bcell) - bcell.update_icon() - bcell.forceMove(get_turf(loc)) - bcell = null - to_chat(user, "You remove the cell from \the [src].") - deactivate() - update_icon() - return - else - ..() - -/obj/item/weapon/melee/energy/sword/charge/get_cell() - return bcell + hitcost = 75 /obj/item/weapon/melee/energy/sword/charge/loaded/New() ..() diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index f478b2d11c..491d815776 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -504,6 +504,14 @@ mounted_pack.return_nozzle() to_chat(user, "\The [src] retracts to its fueltank.") +/obj/item/weapon/weldingtool/tubefed/survival + name = "tube-fed emergency welding tool" + desc = "A bulky, cooler-burning welding tool that draws from a worn welding tank." + icon_state = "tubewelder" + max_fuel = 5 + toolspeed = 1.75 + eye_safety_modifier = 2 + /* * Electric/Arc Welder */ diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index 27927b8180..1e63201f4e 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -11,6 +11,8 @@ origin_tech = list(TECH_MATERIAL = 1) matter = list(DEFAULT_WALL_MATERIAL = 18750) var/deployed = 0 + var/camo_net = FALSE + var/stun_length = 0.25 SECONDS /obj/item/weapon/beartrap/suicide_act(mob/user) var/datum/gender/T = gender_datums[user.get_visible_gender()] @@ -98,6 +100,7 @@ set_dir(L.dir) can_buckle = 1 buckle_mob(L) + L.Stun(stun_length) L << "The steel jaws of \the [src] bite into you, trapping you in place!" deployed = 0 can_buckle = initial(can_buckle) @@ -122,6 +125,21 @@ ..() if(!deployed) + if(camo_net) + alpha = 255 + icon_state = "beartrap0" else + if(camo_net) + alpha = 50 + icon_state = "beartrap1" + +/obj/item/weapon/beartrap/hunting + name = "hunting trap" + desc = "A mechanically activated leg trap. High-tech and reliable. Looks like it could really hurt if you set it off." + stun_length = 1 SECOND + camo_net = TRUE + color = "#C9DCE1" + + origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 1) diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm index 5df0c9dbe3..4225ed810a 100644 --- a/code/game/objects/items/weapons/weldbackpack.dm +++ b/code/game/objects/items/weapons/weldbackpack.dm @@ -7,6 +7,7 @@ w_class = ITEMSIZE_LARGE var/max_fuel = 350 var/obj/item/weapon/nozzle = null //Attached welder, or other spray device. + var/nozzle_type = /obj/item/weapon/weldingtool/tubefed var/nozzle_attached = 0 /obj/item/weapon/weldpack/Initialize() @@ -15,7 +16,7 @@ reagents = R R.my_atom = src R.add_reagent("fuel", max_fuel) - nozzle = new/obj/item/weapon/weldingtool/tubefed(src) + nozzle = new nozzle_type(src) nozzle_attached = 1 /obj/item/weapon/weldpack/Destroy() @@ -145,3 +146,14 @@ ..(user) user << text("\icon[] [] units of fuel left!", src, src.reagents.total_volume) return + +/obj/item/weapon/weldpack/survival + name = "emergency welding kit" + desc = "A heavy-duty, portable welding fluid carrier." + slot_flags = SLOT_BACK + icon = 'icons/obj/storage.dmi' + icon_state = "welderpack-e" + item_state = "welderpack" + w_class = ITEMSIZE_LARGE + max_fuel = 100 + nozzle_type = /obj/item/weapon/weldingtool/tubefed/survival diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm index eb5741c6a1..d39983af2f 100644 --- a/code/game/objects/random/mapping.dm +++ b/code/game/objects/random/mapping.dm @@ -65,6 +65,21 @@ prob(10);/obj/effect/mine/stun, prob(10);/obj/effect/mine/incendiary,) +/obj/random/humanoidremains + name = "Random Humanoid Remains" + desc = "This is a random pile of remains." + spawn_nothing_percentage = 15 + icon = 'icons/effects/blood.dmi' + icon_state = "remains" + +/obj/random/humanoidremains/item_to_spawn() + return pick(prob(30);/obj/effect/decal/remains/human, + prob(25);/obj/effect/decal/remains/ribcage, + prob(25);/obj/effect/decal/remains/tajaran, + prob(10);/obj/effect/decal/remains/unathi, + prob(10);/obj/effect/decal/remains/posi + ) + /obj/random_multi/single_item/captains_spare_id name = "Multi Point - Captain's Spare" id = "Captain's spare id" @@ -396,5 +411,54 @@ /obj/item/clothing/mask/luchador/rudos, /obj/item/clothing/mask/luchador/tecnicos, /obj/structure/closet/crate + ), + prob(1);list( + /obj/machinery/artifact, + /obj/structure/anomaly_container + ), + prob(1);list( + /obj/random/curseditem, + /obj/random/humanoidremains, + /obj/structure/closet/crate ) ) + +/* + * Turf swappers. + */ + +/obj/random/turf + name = "random Sif turf" + desc = "This is a random Sif turf." + + spawn_nothing_percentage = 20 + + var/override_outdoors = FALSE // Do we override our chosen turf's outdoors? + var/turf_outdoors = TRUE // Will our turf be outdoors? + +/obj/random/turf/spawn_item() + var/build_path = item_to_spawn() + + var/turf/T1 = get_turf(src) + T1.ChangeTurf(build_path, 1, 1, FALSE) + + if(override_outdoors) + T1.outdoors = turf_outdoors + +/obj/random/turf/item_to_spawn() + return pick(prob(25);/turf/simulated/floor/outdoors/grass/sif, + prob(25);/turf/simulated/floor/outdoors/dirt, + prob(25);/turf/simulated/floor/outdoors/grass/sif/forest, + prob(25);/turf/simulated/floor/outdoors/rocks) + +/obj/random/turf/lava + name = "random Lava spawn" + desc = "This is a random lava spawn." + + override_outdoors = TRUE + turf_outdoors = FALSE + +/obj/random/turf/lava/item_to_spawn() + return pick(prob(5);/turf/simulated/floor/lava, + prob(3);/turf/simulated/floor/outdoors/rocks/caves, + prob(1);/turf/simulated/mineral) diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm index 8f3a50bbed..790e5471d6 100644 --- a/code/game/objects/random/misc.dm +++ b/code/game/objects/random/misc.dm @@ -529,3 +529,14 @@ /obj/random/janusmodule/item_to_spawn() return pick(subtypesof(/obj/item/weapon/circuitboard/mecha/imperion)) + +/obj/random/curseditem + name = "random cursed item" + desc = "For use in dungeons." + icon = 'icons/obj/storage.dmi' + icon_state = "red" + +/obj/random/curseditem/item_to_spawn() + var/possible_object_paths = list(/obj/item/weapon/paper/carbon/cursedform) + possible_object_paths |= subtypesof(/obj/item/clothing/head/psy_crown) + return pick(possible_object_paths) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index e399c04d0b..aafa6f85f3 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -3,7 +3,7 @@ /obj/structure/closet/crate name = "crate" desc = "A rectangular steel crate." - icon = 'icons/obj/storage.dmi' + icon = 'icons/obj/storage_vr.dmi' //VOREStation edit icon_state = "crate" icon_opened = "crateopen" icon_closed = "crate" @@ -293,6 +293,9 @@ /obj/structure/closet/crate/solar name = "solar pack crate" + icon_state = "engi_crate" //VOREStation Edit + icon_opened = "engi_crateopen" //VOREStation Edit + icon_closed = "engi_crate" //VOREStation Edit starts_with = list( /obj/item/solar_assembly = 21, @@ -349,6 +352,7 @@ /obj/structure/closet/crate/bin name = "large bin" desc = "A large bin." + icon = 'icons/obj/storage.dmi' //VOREStation edit icon_state = "largebin" icon_opened = "largebinopen" icon_closed = "largebin" @@ -417,6 +421,7 @@ /obj/structure/closet/crate/secure/bin name = "secure bin" desc = "A secure bin." + icon = 'icons/obj/storage.dmi' //VOREStation edit icon_state = "largebins" icon_opened = "largebinsopen" icon_closed = "largebins" @@ -429,7 +434,7 @@ /obj/structure/closet/crate/large name = "large crate" desc = "A hefty metal crate." - icon = 'icons/obj/storage.dmi' + icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit icon_state = "largemetal" icon_opened = "largemetalopen" icon_closed = "largemetal" @@ -457,10 +462,10 @@ /obj/structure/closet/crate/secure/large name = "large crate" desc = "A hefty metal crate with an electronic locking system." - icon = 'icons/obj/storage.dmi' - icon_state = "largemetal" - icon_opened = "largemetalopen" - icon_closed = "largemetal" + icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit + icon_state = "largemetalsecure" //VOREStation Edit + icon_opened = "largemetalsecureopen" //VOREStation Edit + icon_closed = "largemetalsecure" //VOREStation Edit redlight = "largemetalr" greenlight = "largemetalg" diff --git a/code/game/objects/structures/crates_lockers/crates_vr.dm b/code/game/objects/structures/crates_lockers/crates_vr.dm index c2a5cee915..85eccb3d77 100644 --- a/code/game/objects/structures/crates_lockers/crates_vr.dm +++ b/code/game/objects/structures/crates_lockers/crates_vr.dm @@ -31,4 +31,9 @@ ..() - return \ No newline at end of file + return + +/obj/structure/closet/crate/medical/blood + icon_state = "blood" + icon_opened = "bloodopen" + icon_closed = "blood" \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index a7a4b77823..79bd5e2949 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -1,7 +1,7 @@ /obj/structure/largecrate name = "large crate" desc = "A hefty wooden crate." - icon = 'icons/obj/storage.dmi' + icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit icon_state = "densecrate" density = 1 var/list/starts_with @@ -82,10 +82,11 @@ starts_with = list(/obj/structure/vehiclecage/quadtrailer) /obj/structure/largecrate/animal - icon_state = "mulecrate" + icon_state = "lisacrate" //VOREStation Edit /obj/structure/largecrate/animal/mulebot name = "Mulebot crate" + icon_state = "mulecrate" //VOREStation Edit starts_with = list(/mob/living/bot/mulebot) /obj/structure/largecrate/animal/corgi diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 86a98e6a69..15bfe8ac89 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -1,14 +1,82 @@ +/obj/structure/flora + name = "flora" + desc = "A perfectly generic plant." + anchored = TRUE // Usually, plants don't move. Usually. + plane = DECAL_PLANE + layer = BELOW_MOB_LAYER + var/randomize_size = FALSE + var/max_x_scale = 1.25 + var/max_y_scale = 1.25 + var/min_x_scale = 0.9 + var/min_y_scale = 0.9 + var/harvest_tool = null // The type of item used to harvest the plant. + var/harvest_count = 0 + + var/randomize_harvest_count = TRUE + var/max_harvests = 0 + var/min_harvests = -1 + var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree. + +/obj/structure/flora/Initialize() + ..() + + if(randomize_size) + icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100 + icon_scale_y = rand(min_y_scale * 100, max_y_scale * 100) / 100 + + if(prob(50)) + icon_scale_x *= -1 + update_transform() + + if(randomize_harvest_count) + max_harvests = max(0, rand(min_harvests, max_harvests)) // Incase you want to weight it more toward 'not harvestable', set min_harvests to a negative value. + +/obj/structure/flora/examine(mob/user) + . = ..(user) + if(harvest_count < max_harvests) + to_chat(user, "\The [src] seems to have something hanging from it.") + +/obj/structure/flora/attackby(var/obj/item/weapon/W, var/mob/living/user) + if(can_harvest(W)) + var/harvest_spawn = pickweight(harvest_loot) + var/atom/movable/AM = spawn_harvest(harvest_spawn, user) + + if(!AM) + to_chat(user, "You fail to harvest anything from \the [src].") + + else + to_chat(user, "You harvest \the [AM] from \the [src].") + return + + ..(W, user) + +/obj/structure/flora/proc/can_harvest(var/obj/item/I) + . = FALSE + if(harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests) + . = TRUE + return . + +/obj/structure/flora/proc/spawn_harvest(var/path = null, var/mob/user = null) + if(!ispath(path)) + return 0 + var/turf/Target = get_turf(src) + if(user) + Target = get_turf(user) + + var/atom/movable/AM = new path(Target) + + harvest_count++ + return AM //bushes /obj/structure/flora/bush name = "bush" icon = 'icons/obj/flora/snowflora.dmi' icon_state = "snowbush1" - anchored = 1 /obj/structure/flora/bush/New() ..() @@ -20,6 +88,7 @@ icon = 'icons/obj/plants.dmi' icon_state = "plant-26" + anchored = FALSE //newbushes @@ -27,7 +96,6 @@ name = "bush" icon = 'icons/obj/flora/ausflora.dmi' icon_state = "firstbush_1" - anchored = 1 /obj/structure/flora/ausbushes/New() ..() @@ -144,6 +212,7 @@ icon_state = "hangskele" desc = "It's an anatomical model of a human skeletal system made of plaster." + plane = OBJ_PLANE //potted plants credit: Flashkirby /obj/structure/flora/pottedplant @@ -152,6 +221,8 @@ icon = 'icons/obj/plants.dmi' icon_state = "plant-01" + plane = OBJ_PLANE + /obj/structure/flora/pottedplant/large name = "large potted plant" desc = "This is a large plant. Three branches support pairs of waxy leaves." @@ -348,4 +419,22 @@ /obj/structure/flora/sif/eyes/Initialize() icon_state = "[initial(icon_state)][rand(1,3)]" - . = ..() \ No newline at end of file + . = ..() + +/datum/category_item/catalogue/flora/mosstendrils + name = "Sivian Flora - Moss Stalks" + desc = "A plant native to Sif. The plant is most closely related to the common, dense moss found covering Sif's terrain. \ + It has evolved a method of camouflage utilizing white hairs on its dorsal sides to make it appear as a small mound of snow from \ + above. It has no known use, though it is a common furnishing in contemporary homes." + value = CATALOGUER_REWARD_TRIVIAL + +/obj/structure/flora/sif/tendrils + name = "stocky tendrils" + desc = "A 'plant' made up of hardened moss. It has tiny hairs that bunch together to look like snow." + icon_state = "grass" + randomize_size = TRUE + catalogue_data = list(/datum/category_item/catalogue/flora/mosstendrils) + +/obj/structure/flora/sif/tendrils/Initialize() + icon_state = "[initial(icon_state)][rand(1,3)]" + . = ..() diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm index c02d813ffc..7cb1c3de3e 100644 --- a/code/game/objects/structures/flora/trees.dm +++ b/code/game/objects/structures/flora/trees.dm @@ -14,19 +14,10 @@ var/product_amount = 10 // How much of a stack you get, if the above is defined. var/is_stump = FALSE // If true, suspends damage tracking and most other effects. var/indestructable = FALSE // If true, the tree cannot die. - var/randomize_size = FALSE // If true, the tree will choose a random scale in the X and Y directions to stretch. /obj/structure/flora/tree/Initialize() icon_state = choose_icon_state() - if(randomize_size) - icon_scale_x = rand(90, 125) / 100 - icon_scale_y = rand(90, 125) / 100 - - if(prob(50)) - icon_scale_x *= -1 - update_transform() - return ..() /obj/structure/flora/tree/update_transform() @@ -39,7 +30,17 @@ /obj/structure/flora/tree/proc/choose_icon_state() return icon_state +/obj/structure/flora/tree/can_harvest(var/obj/item/I) + . = FALSE + if(!is_stump && harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests) + . = TRUE + return . + /obj/structure/flora/tree/attackby(var/obj/item/weapon/W, var/mob/living/user) + if(can_harvest(W)) + ..(W, user) + return + if(!istype(W)) return ..() @@ -302,6 +303,14 @@ product = /obj/item/stack/material/log/sif catalogue_data = list(/datum/category_item/catalogue/flora/sif_tree) randomize_size = TRUE + + harvest_tool = /obj/item/weapon/material/knife + max_harvests = 2 + min_harvests = -4 + harvest_loot = list( + /obj/item/weapon/reagent_containers/food/snacks/siffruit = 5 + ) + var/light_shift = 0 /obj/structure/flora/tree/sif/choose_icon_state() diff --git a/code/game/objects/structures/handrail_vr.dm b/code/game/objects/structures/handrail_vr.dm new file mode 100644 index 0000000000..340d8dedd3 --- /dev/null +++ b/code/game/objects/structures/handrail_vr.dm @@ -0,0 +1,8 @@ +/obj/structure/handrail + name = "handrail" + icon = 'icons/obj/handrail_vr.dmi' + icon_state = "handrail" + desc = "A safety railing with buckles to secure yourself to when floor isn't stable enough." + density = 0 + anchored = 1 + can_buckle = 1 diff --git a/code/game/objects/structures/props/blackbox.dm b/code/game/objects/structures/props/blackbox.dm index b6bae732f8..a28b82349f 100644 --- a/code/game/objects/structures/props/blackbox.dm +++ b/code/game/objects/structures/props/blackbox.dm @@ -105,4 +105,28 @@ **16/FEB/2562**
Something chitters.
End of transcript. - "} \ No newline at end of file + "} + +/obj/structure/prop/blackbox/xenofrigate + catalogue_data = list(/datum/category_item/catalogue/information/blackbox/xenofrigate) + +/datum/category_item/catalogue/information/blackbox/xenofrigate + name = "Black Box Data - MBT-540" + desc = {" +
+ Begin Log + @$&@$& Human ##:##:##: Attention unidentified vessel, state your designation and intent.
+ !#@$&&^ Human ##:##:##: Commander I don't think they're going to stop.
+ @$&@$& Human ##:##:##: Unidentified vessel, you have until the count of three before we engage weapon-
+ !#@$&&^ Human ##:##:##: Commander! Think about what you're-
+ A repeating clicking, before silence.
+ End of first log.
+ **
+ Begin Log
+ #!#^@$& Skrell ##:##:##: Director, I think you should see this.
+ ^@$& Skrell ##:##:##: Yes? What is it?
+ #!#^@$& Skrell ##:##:##: Another one of those ships has appeared near th-462$^ ---n colonies. I would strongly advise pursuing it.
+ ^@$& Skrell ##:##:##: A wise decision. If it is damaged like the last one, we may be able to finally see what is - What?
+ A repeating ping, before silence.
+ End of second log. + "} diff --git a/code/game/turfs/simulated/outdoors/grass.dm b/code/game/turfs/simulated/outdoors/grass.dm index 72b2ee7e57..e557fb16da 100644 --- a/code/game/turfs/simulated/outdoors/grass.dm +++ b/code/game/turfs/simulated/outdoors/grass.dm @@ -33,7 +33,8 @@ var/list/grass_types = list( var/tree_chance = 2 grass_types = list( - /obj/structure/flora/sif/eyes + /obj/structure/flora/sif/eyes = 1, + /obj/structure/flora/sif/tendrils = 10 ) catalogue_data = list(/datum/category_item/catalogue/flora/sif_grass) @@ -50,7 +51,7 @@ var/list/grass_types = list( //edge_blending_priority++ if(grass_chance && prob(grass_chance) && !check_density()) - var/grass_type = pick(grass_types) + var/grass_type = pickweight(grass_types) new grass_type(src) . = ..() diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm index 0f9be4ddbf..cccc028fa3 100644 --- a/code/game/turfs/simulated/outdoors/snow.dm +++ b/code/game/turfs/simulated/outdoors/snow.dm @@ -58,3 +58,10 @@ to_chat(M, "You slide across the ice!") M.SetStunned(1) step(M,M.dir) + +// Ice that is used for, say, areas floating on water or similar. +/turf/simulated/floor/outdoors/shelfice + name = "ice" + icon_state = "ice" + desc = "Looks slippery." + movement_cost = 4 diff --git a/code/modules/artifice/cursedform.dm b/code/modules/artifice/cursedform.dm new file mode 100644 index 0000000000..17f8fbf618 --- /dev/null +++ b/code/modules/artifice/cursedform.dm @@ -0,0 +1,40 @@ +/obj/item/weapon/paper/carbon/cursedform + name = "Form - Inventory Requisition r10.7.1E" + +/obj/item/weapon/paper/carbon/cursedform/Initialize() + ..() + info = {"

Form - Inventory Requisition r10.7.1E

General Request Form


General


Name:
Department:
Departmental Rank:
Organization(If not Nanotrasen):
Date:



Requested Item(s):
Quantity:
Reason for request:
Is this replacement equipment?:
If `Yes`; above, specify equiment and reason for replacement:


Authorization


Authorizing Department:
Authorizing Dept. Head:


Contact and Delivery


EPv2 Address of requesting party(Do not leave blank):
Delivery location or department:


Nanotrasen Employee Identification Number:
Signature of Requester and Date





Authorizor`s Nanotrasen Employee Identification Number:
Authorizing Signature and Date(Include authorizing department`s stamp below)




Shipping Department Only

(Do not write below this line)

Nanotrasen Purchasing Approval Code:
Nanotrasen Employee Identification Number:
Receiving Shipping Employee:
Signature and Date


"} + info_links = {"

Form - Inventory Requisition r10.7.1E

General Request Form


General


Name: write
Department: write
Departmental Rank: write
Organization(If not Nanotrasen): write
Date: write



Requested Item(s): write
Quantity: write
Reason for request: write
Is this replacement equipment?: write
If `Yes` above, specify equiment and reason for replacement: write


Authorization


Authorizing Department: write
Authorizing Dept. Head: write


Contact and Delivery


EPv2 Address of requesting party(Do not leave blank): write
Delivery location or department: write


Nanotrasen Employee Identification Number: write
Signature of Requester and Date

write



Authorizor`s Nanotrasen Employee Identification Number: write
Authorizing Signature and Date(Include authorizing department`s stamp below)

write


Shipping Department Only

(Do not write below this line)

Nanotrasen Purchasing Approval Code: write
Nanotrasen Employee Identification Number: write
Receiving Shipping Employee: write
Signature and Date

write
write"} + +/obj/item/weapon/paper/carbon/cursedform/AltClick() // No fun. + return + +/obj/item/weapon/paper/carbon/cursedform/burnpaper(obj/item/weapon/flame/P, mob/user) + var/class = "warning" + var/datum/gender/TU = gender_datums[user.get_visible_gender()] + + if(P.lit && !user.restrained()) + if(istype(P, /obj/item/weapon/flame/lighter/zippo)) + class = "rose" + + user.visible_message("[user] holds \the [P] up to \the [src], it looks like [TU.hes] trying to burn it!", \ + "You hold \the [P] up to \the [src], burning it slowly.") + + if(do_after(user, 2 SECONDS, src) && P.lit) + user.visible_message("[user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ + "You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") + + if(user.get_inactive_hand() == src) + user.drop_from_inventory(src) + + new /obj/effect/decal/cleanable/ash(src.loc) + qdel(src) + + else + to_chat(user,"You must hold \the [P] steady to burn \the [src].") + + if(isliving(user)) + var/mob/living/L = user + L.visible_message("[L] convulses, the very letters of \the [src] searing themselves into their eyes!", \ + "You convulse, the very letters of \the [src] searing themselves into your eyes!") + L.add_modifier(/datum/modifier/grievous_wounds, 10 MINUTES) diff --git a/code/modules/artifice/telecube.dm b/code/modules/artifice/telecube.dm new file mode 100644 index 0000000000..bb2af4b83d --- /dev/null +++ b/code/modules/artifice/telecube.dm @@ -0,0 +1,236 @@ +/* + * Home of the telecube. + */ + +/datum/category_item/catalogue/anomalous/precursor_a/telecube + name = "Quantomatically Entangled Digicube" + + desc = "An enigmatic cube that appears superficially similar to a Positronic Cube. \ + However, the similarities hopefully end there, as this device emits no sound during \ + operation or observation. Its alloy composition is unknown, though it is incredibly \ + dense, as it resists any and all forms of radiation.
\ + Upon physical contact, however, the device will translocate the offending entity to a \ + matching twin cube, generating no detectable radiation. This process occurs at speeds \ + unmatched even by modern predictions of Bluespace technology, and with no visible power \ + source." + + value = CATALOGUER_REWARD_HARD + +// Standard one needs to be smacked onto another one to link together. +/obj/item/weapon/telecube + name = "locus" + desc = "A strange metallic cube that pulses silently." + description_info = "Ctrl-Clicking on this object will attempt to activate its unique ability." + icon = 'icons/obj/props/telecube.dmi' + icon_state = "cube" + w_class = ITEMSIZE_SMALL + origin_tech = list(TECH_MATERIAL = 7, TECH_POWER = 6, TECH_BLUESPACE = 7, TECH_ANOMALY = 2, TECH_PRECURSOR = 2) + + catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/telecube) + + slowdown = 5 + + throw_range = 2 + + var/obj/item/weapon/telecube/mate = null + + var/start_paired = FALSE + var/mirror_colors = FALSE + + var/randomize_colors = FALSE + + var/glow_color = "#FFFFFF" + var/image/glow = null + var/image/charge = null + + var/shell_color = "#FFFFFF" + var/image/shell = null + + var/cooldown_time = 30 SECONDS + var/last_teleport = 0 + +// How far the cube will search for things to teleport. 0 = only contacting objects / mobs. + var/teleport_range = 0 // For all that is holy, do not change this unless you know what you're doing. + + var/omniteleport = FALSE // Will this teleport anchored things too? + +/obj/item/weapon/telecube/Initialize() + . = ..() + START_PROCESSING(SSobj, src) + last_teleport = world.time + + glow = image(icon = icon, icon_state = "[icon_state]-ready") + glow.plane = PLANE_LIGHTING_ABOVE + charge = image(icon = icon, icon_state = "[icon_state]-charging") + charge.plane = PLANE_LIGHTING_ABOVE + shell = image(icon = icon, icon_state = "[icon_state]") + + if(teleport_range) + description_info += "
" + description_info += "Alt-Clicking on this object will utilize its second unique ability." + + if(randomize_colors) + glow_color = rgb(rand(0, 255),rand(0, 255),rand(0, 255)) + shell_color = rgb(rand(0, 255),rand(0, 255),rand(0, 255)) + + if(start_paired) + mate = new(src.loc) + if(mirror_colors) + mate.glow_color = shell_color + mate.shell_color = glow_color + else + mate.glow_color = glow_color + mate.shell_color = shell_color + mate.pair_cube(src) + + glow.color = glow_color + charge.color = glow_color + shell.color = shell_color + + return + +/obj/item/weapon/telecube/process() + ..() + update_icon() + +/obj/item/weapon/telecube/update_icon() + . = ..() + glow.color = glow_color + charge.color = glow_color + shell.color = shell_color + + if(shell.color != initial(shell.color)) + cut_overlay(shell) + add_overlay(shell) + + if(world.time < (last_teleport + cooldown_time)) + cut_overlay(charge) + cut_overlay(glow) + add_overlay(charge) + else + cut_overlay(glow) + cut_overlay(charge) + add_overlay(glow) + +/obj/item/weapon/telecube/Destroy() + STOP_PROCESSING(SSobj, src) + if(mate) + var/turf/T = get_turf(mate) + mate.visible_message("\The [mate] collapses into itself!") + mate.mate = null + mate = null + explosion(T,1,3,7) + + ..() + +/obj/item/weapon/telecube/proc/pair_cube(var/obj/item/weapon/telecube/M) + if(mate) + return 0 + else + mate = M + update_icon() + return 1 + +/obj/item/weapon/telecube/proc/teleport_to_mate(var/atom/movable/A, var/areaporting = FALSE) + . = FALSE + + if(!A) + return . + + if(A == src || A == mate) + A.visible_message("\The [A] distorts and fades, before popping back into existence.") + return . + + var/mob/living/L = src.loc + + if(istype(L)) + L.drop_from_inventory(src) + forceMove(get_turf(src)) + + if(world.time < (last_teleport + cooldown_time)) + return . + + if((A.anchored && !omniteleport) || !mate) + A.visible_message("\The [A] distorts for a moment, before reforming in the same position.") + return . + + var/turf/TLocate = get_turf(mate) + + var/turf/T1 = get_turf(locate(TLocate.x + (A.x - x), TLocate.y + (A.y - y), TLocate.z)) + + if(T1) + A.visible_message("\The [A] fades out of existence.") + A.forceMove(T1) + . = TRUE + A.visible_message("\The [A] fades into existence.") + else + return . + + if(teleport_range && !areaporting) + for(var/atom/movable/M in orange(teleport_range, A)) + teleport_to_mate(M, TRUE) + +/obj/item/weapon/telecube/proc/swap_with_mate() + . = FALSE + + if(!mate || !teleport_range) + return . + + var/list/objects_near_me = range(teleport_range, get_turf(src)) + var/list/objects_near_mate = range(teleport_range, get_turf(mate)) + + for(var/atom/movable/M in objects_near_me) + teleport_to_mate(M, TRUE) + + for(var/atom/movable/M1 in objects_near_mate) + mate.teleport_to_mate(M1, TRUE) + + . = TRUE + return . + +/obj/item/weapon/telecube/CtrlClick(mob/user) + if(Adjacent(user)) + if(teleport_to_mate(user)) + last_teleport = world.time + return + +/obj/item/weapon/telecube/AltClick(mob/user) + if(Adjacent(user)) + if(swap_with_mate()) + last_teleport = world.time + mate.last_teleport = world.time + return + +/obj/item/weapon/telecube/Bump(atom/movable/AM) + if(teleport_to_mate(AM)) + last_teleport = world.time + . = ..() + +/obj/item/weapon/telecube/Bumped(atom/movable/M as mob|obj) + if(teleport_to_mate(M)) + last_teleport = world.time + . = ..() + +// Subtypes + +/obj/item/weapon/telecube/mated + start_paired = TRUE + +/obj/item/weapon/telecube/randomized + randomize_colors = TRUE + +/obj/item/weapon/telecube/randomized/mated + start_paired = TRUE + +/obj/item/weapon/telecube/precursor + glow_color = "#FF1D8E" + shell_color = "#2F1B26" + +/obj/item/weapon/telecube/precursor/mated + start_paired = TRUE + +/obj/item/weapon/telecube/precursor/mated/zone + teleport_range = 2 + +/obj/item/weapon/telecube/precursor/mated/mirrorcolor + mirror_colors = TRUE diff --git a/code/modules/catalogue/cataloguer.dm b/code/modules/catalogue/cataloguer.dm index 60e86eadee..f1c5756443 100644 --- a/code/modules/catalogue/cataloguer.dm +++ b/code/modules/catalogue/cataloguer.dm @@ -312,3 +312,15 @@ GLOBAL_LIST_EMPTY(all_cataloguers) interact(usr) // So it refreshes the window. return 1 +/obj/item/device/cataloguer/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/weapon/card/id) && !busy) + busy = TRUE + var/obj/item/weapon/card/id/ID = W + if(points_stored) + ID.survey_points += points_stored + points_stored = 0 + to_chat(user, "You swipe the id over \the [src].") + else + to_chat(user, "\The [src] has no points available.") + busy = FALSE + return ..() diff --git a/code/modules/catalogue/rewards/construction.dm b/code/modules/catalogue/rewards/construction.dm deleted file mode 100644 index 8bfca1f79d..0000000000 --- a/code/modules/catalogue/rewards/construction.dm +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef T_BOARD -#error T_BOARD macro is not defined but we need it! -#endif - -/obj/item/weapon/circuitboard/exploration_equipment_vendor - name = T_BOARD("Exploration Equipment Vendor") - board_type = new /datum/frame/frame_types/machine - build_path = /obj/machinery/equipment_vendor/exploration - origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2) - req_components = list( - /obj/item/weapon/stock_parts/console_screen = 1, - /obj/item/weapon/stock_parts/matter_bin = 3) diff --git a/code/modules/catalogue/rewards/equipment_vendor.dm b/code/modules/catalogue/rewards/equipment_vendor.dm deleted file mode 100644 index 96b636b8be..0000000000 --- a/code/modules/catalogue/rewards/equipment_vendor.dm +++ /dev/null @@ -1,177 +0,0 @@ -/**********************Exploration Equipment Vendor**************************/ - -/obj/machinery/equipment_vendor/exploration - name = "exploration equipment vendor" - desc = "An equipment vendor for explorers, points collected with cataloguers can be spent here." - icon = 'icons/obj/machines/mining_machines_vr.dmi' - icon_state = "exploration" - density = TRUE - anchored = TRUE - circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor - var/icon_deny = "exploration-deny" - var/icon_vend = "exploration-vend" - var/obj/item/device/cataloguer/inserted_cataloguer - var/list/prize_list = list( - new /datum/data/exploration_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), - new /datum/data/exploration_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), - new /datum/data/exploration_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), - new /datum/data/exploration_equipment("GPS Device", /obj/item/device/gps/explorer, 10), - new /datum/data/exploration_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), - new /datum/data/exploration_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), - new /datum/data/exploration_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), - new /datum/data/exploration_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20), - new /datum/data/exploration_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90), - new /datum/data/exploration_equipment("Plush Toy", /obj/random/plushie, 30), - new /datum/data/exploration_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50), - new /datum/data/exploration_equipment("Point Transfer Card", /obj/item/weapon/card/exploration_point_card, 50), - new /datum/data/exploration_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 50), - new /datum/data/exploration_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50), - new /datum/data/exploration_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), - new /datum/data/exploration_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50), - new /datum/data/exploration_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), - new /datum/data/exploration_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), - new /datum/data/exploration_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100), - new /datum/data/exploration_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), - new /datum/data/exploration_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100), - new /datum/data/exploration_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250), - new /datum/data/exploration_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310), - new /datum/data/exploration_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10), - new /datum/data/exploration_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station, 100), - new /datum/data/exploration_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 150), - new /datum/data/exploration_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50), - new /datum/data/exploration_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100), - new /datum/data/exploration_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750) - ) - -/datum/data/exploration_equipment - var/equipment_name = "generic" - var/equipment_path = null - var/cost = 0 - -/datum/data/exploration_equipment/New(name, path, cost) - src.equipment_name = name - src.equipment_path = path - src.cost = cost - -/obj/machinery/equipment_vendor/exploration/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() - if(inserted_cataloguer && !powered()) - visible_message("The cataloguer slot indicator light flickers on \the [src] as it spits out the device before powering down.") - inserted_cataloguer.forceMove(get_turf(src)) - -/obj/machinery/equipment_vendor/exploration/update_icon() - if(panel_open) - icon_state = "[initial(icon_state)]-open" - else if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - -/obj/machinery/equipment_vendor/exploration/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/equipment_vendor/exploration/attack_ghost(mob/user) - interact(user) - -/obj/machinery/equipment_vendor/exploration/interact(mob/user) - user.set_machine(src) - - var/dat - dat +="
" - if(istype(inserted_cataloguer)) - dat += "You have [inserted_cataloguer.points_stored] exploration points collected. Eject Cataloguer.
" - else - dat += "No Cataloguer inserted. Insert Cataloguer.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/exploration_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Exploration Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() - -/obj/machinery/equipment_vendor/exploration/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_cataloguer)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - usr.put_in_hands(inserted_cataloguer) - inserted_cataloguer = null - else if(href_list["choice"] == "insert") - var/obj/item/device/cataloguer/C = usr.get_active_hand() - if(istype(C) && !inserted_cataloguer && usr.unEquip(C)) - C.forceMove(src) - inserted_cataloguer = C - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_cataloguer)) - var/datum/data/exploration_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) - return - if(prize.cost > inserted_cataloguer.points_stored) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_cataloguer.points_stored -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - flick(icon_vend, src) - new prize.equipment_path(drop_location()) - else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() - -/obj/machinery/equipment_vendor/exploration/attackby(obj/item/I, mob/user, params) - if(default_deconstruction_screwdriver(user, I)) - updateUsrDialog() - return - if(default_part_replacement(user, I)) - return - if(default_deconstruction_crowbar(user, I)) - return - if(istype(I,/obj/item/device/cataloguer)) - if(!powered()) - return - else if(!inserted_cataloguer && user.unEquip(I)) - I.forceMove(src) - inserted_cataloguer = I - interact(user) - return - ..() - -/obj/machinery/equipment_vendor/exploration/dismantle() - if(inserted_cataloguer) - inserted_cataloguer.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it. - . = ..() - -/obj/machinery/equipment_vendor/exploration/proc/new_prize(var/name, var/path, var/cost) // Generic proc for adding new entries. Good for abusing for FUN and PROFIT. - if(!cost) - cost = 100 - if(!path) - path = /obj/item/stack/marker_beacon - if(!name) - name = "Generic Entry" - prize_list += new /datum/data/exploration_equipment(name, path, cost) - -/obj/machinery/equipment_vendor/exploration/ex_act(severity, target) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - if(prob(50 / severity) && severity < 3) - qdel(src) diff --git a/code/modules/catalogue/rewards/exp_point_items.dm b/code/modules/catalogue/rewards/exp_point_items.dm deleted file mode 100644 index 47e066763b..0000000000 --- a/code/modules/catalogue/rewards/exp_point_items.dm +++ /dev/null @@ -1,23 +0,0 @@ -/obj/item/weapon/card/exploration_point_card - name = "exploration point card" - desc = "A small card preloaded with exploration points. Swipe your Cataloguer over it to transfer the points, then discard." - icon_state = "data" - var/points = 50 - -/obj/item/weapon/card/exploration_point_card/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/device/cataloguer)) - if(points) - var/obj/item/device/cataloguer/C = I - C.points_stored += points - to_chat(user, "You transfer [points] points to [C].") - points = 0 - else - to_chat(user, "There's no points left on [src].") - ..() - -/obj/item/weapon/card/exploration_point_card/examine(mob/user) - ..(user) - to_chat(user, "There's [points] points on the card.") - -/obj/item/weapon/card/exploration_point_card/can_catalogue(mob/user) - return FALSE \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm index 3986f0dfd8..0f1ab31c6e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm @@ -40,11 +40,11 @@ allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Explorer","Pathfinder", "Blueshield Guard") /datum/gear/accessory/brown_vest - display_name = "webbing, brown" + display_name = "webbing, brown (Eng, Sec, Med, Exploration, Miner)" allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard") /datum/gear/accessory/black_vest - display_name = "webbing, black" + display_name = "webbing, black (Eng, Sec, Med, Exploration, Miner)" allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard") /datum/gear/accessory/white_vest @@ -52,11 +52,11 @@ allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic") /datum/gear/accessory/brown_drop_pouches - display_name = "drop pouches, brown" + display_name = "drop pouches, brown (Eng, Sec, Med, Exploration, Miner)" allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard") /datum/gear/accessory/black_drop_pouches - display_name = "drop pouches, black" + display_name = "drop pouches, black (Eng, Sec, Med, Exploration, Miner)" allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard") /datum/gear/accessory/white_drop_pouches diff --git a/code/modules/client/preference_setup/vore/06_vantag.dm b/code/modules/client/preference_setup/vore/06_vantag.dm index 65bc66a495..c65c379bf2 100644 --- a/code/modules/client/preference_setup/vore/06_vantag.dm +++ b/code/modules/client/preference_setup/vore/06_vantag.dm @@ -27,7 +27,7 @@ /datum/category_item/player_setup_item/vore/vantag/content(var/mob/user) . += "
" - . += "Event Volunteer: [pref.vantag_volunteer ? "Yes" : "No"]
" + . += "Event Volunteer: [pref.vantag_volunteer ? "Yes" : "No"]
" . += "Event Pref: [vantag_choices_list[pref.vantag_preference]]
" /datum/category_item/player_setup_item/vore/vantag/OnTopic(var/href, var/list/href_list, var/mob/user) diff --git a/code/modules/client/preference_setup/vore/09_misc.dm b/code/modules/client/preference_setup/vore/09_misc.dm index 951e469d8d..2911c8a10d 100644 --- a/code/modules/client/preference_setup/vore/09_misc.dm +++ b/code/modules/client/preference_setup/vore/09_misc.dm @@ -25,7 +25,7 @@ /datum/category_item/player_setup_item/vore/misc/content(var/mob/user) . += "
" . += "Appear in Character Directory: [pref.show_in_directory ? "Yes" : "No"]
" - . += "Sensor Preferences: [sensorpreflist[pref.sensorpref]]
" //TFF 5/8/19 - Allow selection of sensor settings from off, binary, vitals, tracking, or random + . += "Suit Sensors Preference: [sensorpreflist[pref.sensorpref]]
" //TFF 5/8/19 - Allow selection of sensor settings from off, binary, vitals, tracking, or random /datum/category_item/player_setup_item/vore/misc/OnTopic(var/href, var/list/href_list, var/mob/user) if(href_list["toggle_show_in_directory"]) diff --git a/code/modules/clothing/clothing_vr.dm b/code/modules/clothing/clothing_vr.dm index 9c04fc9841..b6e387c9bf 100644 --- a/code/modules/clothing/clothing_vr.dm +++ b/code/modules/clothing/clothing_vr.dm @@ -126,7 +126,7 @@ return ..() // Taur suits need to be shifted so its centered on their taur half. -/obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0) +/obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0,var/icon/clip_mask) var/image/standing = ..() if(taurized) //Special snowflake var on suits standing.pixel_x = -16 diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index b706e71e9d..a9232aa65c 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -219,7 +219,7 @@ /obj/item/clothing/head/psy_crown name = "broken crown" desc = "A crown-of-thorns with a missing gem." - var/tension_threshold = 150 + var/tension_threshold = 125 var/cooldown = null // world.time of when this was last triggered. var/cooldown_duration = 3 MINUTES // How long the cooldown should be. var/flavor_equip = null // Message displayed to someone who puts this on their head. Drones don't get a message. @@ -273,3 +273,17 @@ /obj/item/clothing/head/psy_crown/wrath/activate_ability(var/mob/living/wearer) ..() wearer.add_modifier(/datum/modifier/berserk, 30 SECONDS) + +/obj/item/clothing/head/psy_crown/gluttony + name = "green crown" + desc = "A crown-of-thorns set with a green gemstone that seems to glow unnaturally. It feels rather disturbing to touch." + description_info = "This has a chance to cause the wearer to become extremely durable, but hungry when in extreme danger." + icon_state = "gluttonycrown" + flavor_equip = "You feel a bit hungrier after putting on this crown." + flavor_unequip = "You feel sated after removing the crown." + flavor_drop = "You feel much more sated after letting go of the crown." + flavor_activate = "An otherworldly feeling seems to enter your mind, and it drives your mind into gluttony!" + +/obj/item/clothing/head/psy_crown/gluttony/activate_ability(var/mob/living/wearer) + ..() + wearer.add_modifier(/datum/modifier/gluttonyregeneration, 45 SECONDS) diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm index 83cf2e3049..0c1cfee9ca 100644 --- a/code/modules/clothing/under/accessories/storage.dm +++ b/code/modules/clothing/under/accessories/storage.dm @@ -9,12 +9,15 @@ var/obj/item/weapon/storage/internal/hold w_class = ITEMSIZE_NORMAL on_rolled = list("down" = "none") + var/hide_on_roll = FALSE /obj/item/clothing/accessory/storage/New() ..() hold = new/obj/item/weapon/storage/internal(src) hold.max_storage_space = slots * 2 hold.max_w_class = ITEMSIZE_SMALL + if (!hide_on_roll) + on_rolled["down"] = icon_state /obj/item/clothing/accessory/storage/attack_hand(mob/user as mob) if (has_suit) //if we are part of a suit diff --git a/code/modules/clothing/under/accessories/torch.dm b/code/modules/clothing/under/accessories/torch.dm index c7fe853808..7cdec72747 100644 --- a/code/modules/clothing/under/accessories/torch.dm +++ b/code/modules/clothing/under/accessories/torch.dm @@ -310,9 +310,9 @@ department tags desc = "Insignia denoting assignment to the command department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/command/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the command department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/command/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the command department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/engineering @@ -328,9 +328,9 @@ department tags desc = "Insignia denoting assignment to the engineering department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/engineering/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the engineering department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/engineering/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the engineering department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/security @@ -346,9 +346,9 @@ department tags desc = "Insignia denoting assignment to the security department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/security/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the security department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/security/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the security department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/medical @@ -364,9 +364,9 @@ department tags desc = "Insignia denoting assignment to the medical department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/medical/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the medical department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/medical/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the medical department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/supply @@ -382,9 +382,9 @@ department tags desc = "Insignia denoting assignment to the supply department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/supply/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the supply department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/supply/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the supply department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/service @@ -400,9 +400,9 @@ department tags desc = "Insignia denoting assignment to the service department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/service/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the service department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/service/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the service department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/exploration @@ -418,9 +418,9 @@ department tags desc = "Insignia denoting assignment to the exploration department. These fit Fleet uniforms." on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none") -/obj/item/clothing/accessory/solgov/department/exploration/army - icon_state = "dept_army" - desc = "Insignia denoting assignment to the exploration department. These fit Army uniforms." +/obj/item/clothing/accessory/solgov/department/exploration/marine + icon_state = "dept_marine" + desc = "Insignia denoting assignment to the exploration department. These fit marine uniforms." on_rolled = list("down" = "none") /obj/item/clothing/accessory/solgov/department/research @@ -611,103 +611,103 @@ ranks - fleet /************** ranks - marines **************/ -/obj/item/clothing/accessory/solgov/rank/army - name = "army ranks" +/obj/item/clothing/accessory/solgov/rank/marine + name = "marine ranks" desc = "Insignia denoting marine rank of some kind. These appear blank." - icon_state = "armyrank_enlisted" + icon_state = "marinerank_enlisted" on_rolled = list("down" = "none") -/obj/item/clothing/accessory/solgov/rank/army/enlisted +/obj/item/clothing/accessory/solgov/rank/marine/enlisted name = "ranks (E-1 private)" desc = "Insignia denoting the rank of Private." - icon_state = "armyrank_enlisted" + icon_state = "marinerank_enlisted" -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e2 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e2 name = "ranks (E-2 private second class)" desc = "Insignia denoting the rank of Private Second Class." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e3 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e3 name = "ranks (E-3 private first class)" desc = "Insignia denoting the rank of Private First Class." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e4 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e4 name = "ranks (E-4 corporal)" desc = "Insignia denoting the rank of Corporal." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e5 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e5 name = "ranks (E-5 sergeant)" desc = "Insignia denoting the rank of Sergeant." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e6 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e6 name = "ranks (E-6 staff sergeant)" desc = "Insignia denoting the rank of Staff Sergeant." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e7 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e7 name = "ranks (E-7 sergeant first class)" desc = "Insignia denoting the rank of Sergeant First Class." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e8 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e8 name = "ranks (E-8 master sergeant)" desc = "Insignia denoting the rank of Master Sergeant." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e8_alt +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e8_alt name = "ranks (E-8 first sergeant)" desc = "Insignia denoting the rank of First Sergeant." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e9 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e9 name = "ranks (E-9 sergeant major)" desc = "Insignia denoting the rank of Sergeant Major." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e9_alt1 +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e9_alt1 name = "ranks (E-9 command sergeant major)" desc = "Insignia denoting the rank of Command Sergeant Major." -/obj/item/clothing/accessory/solgov/rank/army/enlisted/e9_alt2 - name = "ranks (E-9 sergeant major of the Army)" - desc = "Insignia denoting the rank of Sergeant Major of the Army." +/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e9_alt2 + name = "ranks (E-9 sergeant major of the marine)" + desc = "Insignia denoting the rank of Sergeant Major of the marine." -/obj/item/clothing/accessory/solgov/rank/army/officer +/obj/item/clothing/accessory/solgov/rank/marine/officer name = "ranks (O-1 second lieutenant)" desc = "Insignia denoting the rank of Second Lieutenant." - icon_state = "armyrank_officer" + icon_state = "marinerank_officer" -/obj/item/clothing/accessory/solgov/rank/army/officer/o2 +/obj/item/clothing/accessory/solgov/rank/marine/officer/o2 name = "ranks (O-2 first lieutenant)" desc = "Insignia denoting the rank of First Lieutenant." -/obj/item/clothing/accessory/solgov/rank/army/officer/o3 +/obj/item/clothing/accessory/solgov/rank/marine/officer/o3 name = "ranks (O-3 captain)" desc = "Insignia denoting the rank of Captain." -/obj/item/clothing/accessory/solgov/rank/army/officer/o4 +/obj/item/clothing/accessory/solgov/rank/marine/officer/o4 name = "ranks (O-4 major)" desc = "Insignia denoting the rank of Major." -/obj/item/clothing/accessory/solgov/rank/army/officer/o5 +/obj/item/clothing/accessory/solgov/rank/marine/officer/o5 name = "ranks (O-5 lieutenant colonel)" desc = "Insignia denoting the rank of Lieutenant Colonel." -/obj/item/clothing/accessory/solgov/rank/army/officer/o6 +/obj/item/clothing/accessory/solgov/rank/marine/officer/o6 name = "ranks (O-6 colonel)" desc = "Insignia denoting the rank of Colonel." -/obj/item/clothing/accessory/solgov/rank/army/flag +/obj/item/clothing/accessory/solgov/rank/marine/flag name = "ranks (O-7 brigadier general)" desc = "Insignia denoting the rank of Brigadier General." - icon_state = "armyrank_command" + icon_state = "marinerank_command" -/obj/item/clothing/accessory/solgov/rank/army/flag/o8 +/obj/item/clothing/accessory/solgov/rank/marine/flag/o8 name = "ranks (O-8 major general)" desc = "Insignia denoting the rank of Major General." -/obj/item/clothing/accessory/solgov/rank/army/flag/o9 +/obj/item/clothing/accessory/solgov/rank/marine/flag/o9 name = "ranks (O-9 lieutenant general)" desc = "Insignia denoting the rank of lieutenant general." -/obj/item/clothing/accessory/solgov/rank/army/flag/o10 +/obj/item/clothing/accessory/solgov/rank/marine/flag/o10 name = "ranks (O-10 general)" desc = "Insignia denoting the rank of General." -/obj/item/clothing/accessory/solgov/rank/army/flag/o10_alt +/obj/item/clothing/accessory/solgov/rank/marine/flag/o10_alt name = "ranks (O-10 field marshal)" desc = "Insignia denoting the rank of Field Marshal." diff --git a/code/modules/clothing/under/solgov.dm b/code/modules/clothing/under/solgov.dm index 39109c480a..0859cdf1e4 100644 --- a/code/modules/clothing/under/solgov.dm +++ b/code/modules/clothing/under/solgov.dm @@ -1,7 +1,18 @@ //SolGov Uniforms +//Master +/obj/item/clothing/under/solgov + name = "master solgov uniform" + desc = "You shouldn't be seeing this." + icon = 'icons/obj/clothing/uniforms_solgov.dmi' + rolled_down = 0 + rolled_sleeves = 0 + item_icons = list(slot_w_uniform_str = 'icons/mob/uniform_solgov.dmi') + armor = list(melee = 5, bullet = 0, laser = 5, energy = 5, bomb = 0, bio = 5, rad = 5) + siemens_coefficient = 0.8 + //PT -/obj/item/clothing/under/pt +/obj/item/clothing/under/solgov/pt name = "pt uniform" desc = "Shorts! Shirt! Miami! Sexy!" icon_state = "miami" @@ -10,19 +21,19 @@ siemens_coefficient = 0.9 body_parts_covered = UPPER_TORSO|LOWER_TORSO -/obj/item/clothing/under/pt/sifguard +/obj/item/clothing/under/solgov/pt/sifguard name = "\improper SifGuard pt uniform" desc = "A baggy shirt bearing the seal of the Sif Defense Force and some dorky looking blue shorts." icon_state = "expeditionpt" worn_state = "expeditionpt" -/obj/item/clothing/under/pt/fleet +/obj/item/clothing/under/solgov/pt/fleet name = "fleet pt uniform" desc = "A pair of black shorts and two tank tops, seems impractical. Looks good though." icon_state = "fleetpt" worn_state = "fleetpt" -/obj/item/clothing/under/pt/marine +/obj/item/clothing/under/solgov/pt/marine name = "marine pt uniform" desc = "Does NOT leave much to the imagination." icon_state = "marinept" @@ -53,63 +64,62 @@ worn_state = "greyutility" //Here's the real ones -/obj/item/clothing/under/utility/sifguard +/obj/item/clothing/under/solgov/utility/sifguard name = "\improper SifGuard uniform" desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim." icon_state = "blackutility_crew" worn_state = "blackutility_crew" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 10) -/obj/item/clothing/under/utility/sifguard/medical - name = "\improper SifGuard medical uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and blue blazes." - icon_state = "blackutility_med" - worn_state = "blackutility_med" +/obj/item/clothing/under/solgov/utility/sifguard/command + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command) -/obj/item/clothing/under/utility/sifguard/medical/command - name = "\improper SifGuard medical command uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and blue blazes." - icon_state = "blackutility_medcom" - worn_state = "blackutility_medcom" +/obj/item/clothing/under/solgov/utility/sifguard/engineering + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering) -/obj/item/clothing/under/utility/sifguard/engineering - name = "\improper SifGuard engineering uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and organge blazes." - icon_state = "blackutility_eng" - worn_state = "blackutility_eng" +/obj/item/clothing/under/solgov/utility/sifguard/security + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security) -/obj/item/clothing/under/utility/sifguard/engineering/command - name = "\improper SifGuard engineering command uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and organge blazes." - icon_state = "blackutility_engcom" - worn_state = "blackutility_engcom" +/obj/item/clothing/under/solgov/utility/sifguard/medical + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical) -/obj/item/clothing/under/utility/sifguard/supply - name = "\improper SifGuard supply uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and brown blazes." - icon_state = "blackutility_sup" - worn_state = "blackutility_sup" +/obj/item/clothing/under/solgov/utility/sifguard/supply + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply) -/obj/item/clothing/under/utility/sifguard/security - name = "\improper SifGuard security uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and red blazes." - icon_state = "blackutility_sec" - worn_state = "blackutility_sec" +/obj/item/clothing/under/solgov/utility/sifguard/exploration + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration) -/obj/item/clothing/under/utility/sifguard/security/command - name = "\improper SifGuard security command uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and red blazes." - icon_state = "blackutility_seccom" - worn_state = "blackutility_seccom" +/obj/item/clothing/under/solgov/utility/sifguard/research + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research) -/obj/item/clothing/under/utility/sifguard/command - name = "\improper SifGuard command uniform" - desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and gold blazes." +/obj/item/clothing/under/solgov/utility/sifguard/officer + name = "\improper Sifuard officer's uniform" + desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim." icon_state = "blackutility_com" worn_state = "blackutility_com" +/obj/item/clothing/under/solgov/utility/sifguard/officer/command + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command) -/obj/item/clothing/under/utility/fleet +/obj/item/clothing/under/solgov/utility/sifguard/officer/engineering + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering) + +/obj/item/clothing/under/solgov/utility/sifguard/officer/security + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security) + +/obj/item/clothing/under/solgov/utility/sifguard/officer/medical + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical) + +/obj/item/clothing/under/solgov/utility/sifguard/officer/supply + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply) + +/obj/item/clothing/under/solgov/utility/sifguard/officer/exploration + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration) + +/obj/item/clothing/under/solgov/utility/sifguard/officer/research + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research) + +/obj/item/clothing/under/solgov/utility/fleet name = "fleet coveralls" desc = "The utility uniform of the SCG Fleet, made from an insulated material." icon_state = "navyutility" @@ -117,116 +127,96 @@ armor = list(melee = 0, bullet = 0, laser = 0,energy = 10, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.7 -/obj/item/clothing/under/utility/fleet/medical - name = "fleet medical coveralls" - desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has blue cuffs." - icon_state = "navyutility_med" - worn_state = "navyutility_med" +/obj/item/clothing/under/solgov/utility/fleet/command + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/fleet) -/obj/item/clothing/under/utility/fleet/engineering - name = "fleet engineering coveralls" - desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has orange cuffs." - icon_state = "navyutility_eng" - worn_state = "navyutility_eng" +/obj/item/clothing/under/solgov/utility/fleet/command/pilot + starting_accessories = list(/obj/item/clothing/accessory/solgov/specialty/pilot) -/obj/item/clothing/under/utility/fleet/supply - name = "fleet supply coveralls" - desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has brown cuffs." - icon_state = "navyutility_sup" - worn_state = "navyutility_sup" +/obj/item/clothing/under/solgov/utility/fleet/engineering + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/fleet) -/obj/item/clothing/under/utility/fleet/security - name = "fleet security coveralls" - desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has red cuffs." - icon_state = "navyutility_sec" - worn_state = "navyutility_sec" +/obj/item/clothing/under/solgov/utility/fleet/security + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/fleet) -/obj/item/clothing/under/utility/fleet/command - name = "fleet command coveralls" - desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has gold cuffs." - icon_state = "navyutility_com" - worn_state = "navyutility_com" +/obj/item/clothing/under/solgov/utility/fleet/medical + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/fleet) + +/obj/item/clothing/under/solgov/utility/fleet/supply + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/fleet) + +/obj/item/clothing/under/solgov/utility/fleet/exploration + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/fleet) -/obj/item/clothing/under/utility/marine +/obj/item/clothing/under/solgov/utility/marine name = "marine fatigues" desc = "The utility uniform of the SCG Marine Corps, made from durable material." icon_state = "greyutility" worn_state = "greyutility" armor = list(melee = 10, bullet = 0, laser = 10,energy = 0, bomb = 0, bio = 0, rad = 0) -/obj/item/clothing/under/utility/marine/green +/obj/item/clothing/under/solgov/utility/marine/command + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/marine) + +/obj/item/clothing/under/solgov/utility/marine/engineering + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/marine) + +/obj/item/clothing/under/solgov/utility/marine/security + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/marine) + +/obj/item/clothing/under/solgov/utility/marine/medical + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/marine) + +/obj/item/clothing/under/solgov/utility/marine/supply + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/marine) + +/obj/item/clothing/under/solgov/utility/marine/exploration + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/marine) + +/obj/item/clothing/under/solgov/utility/marine/green name = "green fatigues" desc = "A green version of the SCG marine utility uniform, made from durable material." icon_state = "greenutility" worn_state = "greenutility" -/obj/item/clothing/under/utility/marine/tan +/obj/item/clothing/under/solgov/utility/marine/tan name = "tan fatigues" desc = "A tan version of the SCG marine utility uniform, made from durable material." icon_state = "tanutility" worn_state = "tanutility" -/obj/item/clothing/under/utility/marine/medical - name = "marine medical fatigues" - desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has blue markings." - icon_state = "greyutility_med" - worn_state = "greyutility_med" - -/obj/item/clothing/under/utility/marine/engineering - name = "marine engineering fatigues" - desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has orange markings." - icon_state = "greyutility_eng" - worn_state = "greyutility_eng" - -/obj/item/clothing/under/utility/marine/supply - name = "marine supply fatigues" - desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has brown markings." - icon_state = "greyutility_sup" - worn_state = "greyutility_sup" - -/obj/item/clothing/under/utility/marine/security - name = "marine security fatigues" - desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has red markings." - icon_state = "greyutility_sec" - worn_state = "greyutility_sec" - -/obj/item/clothing/under/utility/marine/command - name = "marine command coveralls" - desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has gold markings." - icon_state = "greyutility_com" - worn_state = "greyutility_com" - //Service -/obj/item/clothing/under/service +/obj/item/clothing/under/solgov/service name = "service uniform" desc = "A service uniform of some kind." icon_state = "whiteservice" worn_state = "whiteservice" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + armor = list(melee = 5, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 5, rad = 0) siemens_coefficient = 0.9 -/obj/item/clothing/under/service/fleet +/obj/item/clothing/under/solgov/service/fleet name = "fleet service uniform" desc = "The service uniform of the SCG Fleet, made from immaculate white fabric." icon_state = "whiteservice" worn_state = "whiteservice" -/obj/item/clothing/under/service/marine +/obj/item/clothing/under/solgov/service/marine name = "marine service uniform" desc = "The service uniform of the SCG Marine Corps. Slimming." icon_state = "greenservice" worn_state = "greenservice" -/obj/item/clothing/under/service/marine/command +/obj/item/clothing/under/solgov/service/marine/command name = "marine command service uniform" desc = "The service uniform of the SCG Marine Corps. Slimming and stylish." icon_state = "greenservice_com" worn_state = "greenservice_com" //Dress -/obj/item/clothing/under/mildress + +/obj/item/clothing/under/solgov/mildress name = "dress uniform" desc = "A dress uniform of some kind." icon_state = "greydress" @@ -234,25 +224,71 @@ armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.9 -/obj/item/clothing/under/mildress/sifguard +/obj/item/clothing/under/solgov/mildress/sifguard name = "\improper SifGuard dress uniform" desc = "The dress uniform of the Sif Defense Force in silver trim." - icon_state = "greydress" - worn_state = "greydress" -/obj/item/clothing/under/mildress/sifguard/command +/obj/item/clothing/under/solgov/mildress/sifguard/command + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/engineering + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/security + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/medical + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/supply + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/service + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/service/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/exploration + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/research + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer name = "\improper SifGuard command dress uniform" desc = "The dress uniform of the Sif Defense Force in gold trim." icon_state = "greydress_com" worn_state = "greydress_com" -/obj/item/clothing/under/mildress/marine +/obj/item/clothing/under/solgov/mildress/sifguard/officer/command + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/engineering + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/security + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/medical + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/supply + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/service + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/service/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/exploration + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/service) + +/obj/item/clothing/under/solgov/mildress/sifguard/officer/research + starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research/service) + +/obj/item/clothing/under/solgov/mildress/marine name = "marine dress uniform" desc = "The dress uniform of the SCG Marine Corps, class given form." icon_state = "blackdress" worn_state = "blackdress" -/obj/item/clothing/under/mildress/marine/command +/obj/item/clothing/under/solgov/mildress/marine/command name = "marine command dress uniform" desc = "The dress uniform of the SCG Marine Corps, even classier in gold." icon_state = "blackdress_com" diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 6cb8c267fb..be7a6f6e79 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -11,8 +11,8 @@ description_antag = "Some fishing rods can be utilized as long-range, sharp weapons, though their pseudo ranged ability comes at the cost of slow speed." icon_state = "fishing_rod" item_state = "fishing_rod" - force_divisor = 0.25 - throwforce = 7 + force_divisor = 0.02 //VOREStation Edit + throwforce = 1 //VOREStation Edit sharp = TRUE attack_verb = list("whipped", "battered", "slapped", "fished", "hooked") hitsound = 'sound/weapons/punchmiss.ogg' diff --git a/code/modules/fishing/fishing_vr.dm b/code/modules/fishing/fishing_vr.dm index f6e7dd715e..e545cc0edf 100644 --- a/code/modules/fishing/fishing_vr.dm +++ b/code/modules/fishing/fishing_vr.dm @@ -1,3 +1,9 @@ +#define FISHING_RARE "rare" +#define FISHING_UNCOMMON "uncommon" +#define FISHING_COMMON "common" +#define FISHING_JUNK "junk" +#define FISHING_NOTHING "nothing" + GLOBAL_LIST_INIT(indoor_fishing_chance_list, list(FISHING_RARE = 5, FISHING_UNCOMMON = 20, FISHING_COMMON = 30, FISHING_JUNK = 5, FISHING_NOTHING = 50)) GLOBAL_LIST_INIT(indoor_fishing_junk_list, list( /obj/random/junk = 15, @@ -17,8 +23,8 @@ GLOBAL_LIST_INIT(indoor_fishing_junk_list, list( fishing_loot = GLOB.indoor_fishing_chance_list /turf/simulated/floor/water/deep/indoors - min_fishing_time = 45 - max_fishing_time = 120 + min_fishing_time = 33 + max_fishing_time = 99 /turf/simulated/floor/water/deep/indoors/handle_fish() if(has_fish) @@ -27,3 +33,10 @@ GLOBAL_LIST_INIT(indoor_fishing_junk_list, list( common_fish_list = GLOB.generic_fishing_common_list junk_list = GLOB.indoor_fishing_junk_list fishing_loot = GLOB.indoor_fishing_chance_list + + +#undef FISHING_RARE +#undef FISHING_UNCOMMON +#undef FISHING_COMMON +#undef FISHING_JUNK +#undef FISHING_NOTHING \ No newline at end of file diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index 90c083984c..fc37fb2064 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -754,7 +754,6 @@ /obj/item/weapon/reagent_containers/food/snacks/fishfingers/Initialize() . = ..() reagents.add_reagent("protein", 4) - reagents.add_reagent("carpotoxin", 3) bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/zestfish @@ -988,7 +987,6 @@ /obj/item/weapon/reagent_containers/food/snacks/fishburger/Initialize() . = ..() reagents.add_reagent("protein", 6) - reagents.add_reagent("carpotoxin", 3) bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/tofuburger @@ -1327,7 +1325,6 @@ /obj/item/weapon/reagent_containers/food/snacks/cubancarp/Initialize() . = ..() reagents.add_reagent("protein", 3) - reagents.add_reagent("carpotoxin", 3) reagents.add_reagent("capsaicin", 3) bitesize = 3 @@ -1988,7 +1985,6 @@ /obj/item/weapon/reagent_containers/food/snacks/fishandchips/Initialize() . = ..() reagents.add_reagent("protein", 3) - reagents.add_reagent("carpotoxin", 3) bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/sandwich @@ -3808,7 +3804,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sashimi name = "carp sashimi" - desc = "Expertly prepared. Still toxic." + desc = "Expertly prepared. Hopefully toxin got removed though." filling_color = "#FFDEFE" icon_state = "sashimi" nutriment_amt = 6 @@ -3816,7 +3812,6 @@ /obj/item/weapon/reagent_containers/food/snacks/sashimi/Initialize() . = ..() reagents.add_reagent("protein", 2) - reagents.add_reagent("carpotoxin", 2) bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/benedict @@ -4147,4 +4142,27 @@ /obj/item/weapon/reagent_containers/food/snacks/wormdeluxe/Initialize() . = ..() reagents.add_reagent("fishbait", 40) - bitesize = 5 \ No newline at end of file + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/siffruit + name = "pulsing fruit" + desc = "A blue-ish sac encased in a tough black shell." + icon = 'icons/obj/flora/foraging.dmi' + icon_state = "siffruit" + nutriment_amt = 2 + nutriment_desc = list("tart" = 1) + w_class = ITEMSIZE_TINY + +/obj/item/weapon/reagent_containers/food/snacks/siffruit/Initialize() + . = ..() + reagents.add_reagent("sifsap", 2) + +/obj/item/weapon/reagent_containers/food/snacks/siffruit/afterattack(obj/O as obj, mob/user as mob, proximity) + if(istype(O,/obj/machinery/microwave)) + return ..() + if(!(proximity && O.is_open_container())) + return + to_chat(user, "You tear \the [src]'s sac open, pouring it into \the [O].") + reagents.trans_to(O, reagents.total_volume) + user.drop_from_inventory(src) + qdel(src) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index d07a52a2f2..fa5fcc7397 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -9,7 +9,7 @@ var/global/list/total_extraction_beacons = list() var/obj/structure/extraction_point/beacon var/list/beacon_networks = list("station") var/uses_left = 3 - var/can_use_indoors + var/can_use_indoors = FALSE var/safe_for_living_creatures = 1 /obj/item/extraction_pack/examine() @@ -145,7 +145,9 @@ var/global/list/total_extraction_beacons = list() icon_state = "subspace_amplifier" /obj/item/fulton_core/attack_self(mob/user) - if(do_after(user,15,target = user) && !QDELETED(src)) + var/turf/T = get_turf(user) + var/outdoors = T.outdoors + if(do_after(user,15,target = user) && !QDELETED(src) && outdoors) new /obj/structure/extraction_point(get_turf(user)) qdel(src) diff --git a/code/modules/mining/ore_redemption_machine/construction.dm b/code/modules/mining/ore_redemption_machine/construction.dm index dbf8a96ffb..3880ef5cb8 100644 --- a/code/modules/mining/ore_redemption_machine/construction.dm +++ b/code/modules/mining/ore_redemption_machine/construction.dm @@ -10,3 +10,12 @@ req_components = list( /obj/item/weapon/stock_parts/console_screen = 1, /obj/item/weapon/stock_parts/matter_bin = 3) + +/obj/item/weapon/circuitboard/exploration_equipment_vendor + name = T_BOARD("Exploration Equipment Vendor") + board_type = new /datum/frame/frame_types/machine + build_path = /obj/machinery/mineral/equipment_vendor/survey + origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2) + req_components = list( + /obj/item/weapon/stock_parts/console_screen = 1, + /obj/item/weapon/stock_parts/matter_bin = 3) diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index bf4ef87738..3d9651c044 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -10,7 +10,7 @@ circuit = /obj/item/weapon/circuitboard/mining_equipment_vendor var/icon_deny = "mining-deny" var/obj/item/weapon/card/id/inserted_id - //VOREStation Edit - Heavily modified list + //VOREStation Edit Start - Heavily modified list var/list/prize_list = list( new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), @@ -36,11 +36,11 @@ new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900), new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200), new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), - //new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), + // new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 1000), new /datum/data/mining_equipment("Hardsuit - Control Module", /obj/item/weapon/rig/industrial, 2000), new /datum/data/mining_equipment("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), - new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/rig_module/device/drill, 2000), + new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000), new /datum/data/mining_equipment("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), new /datum/data/mining_equipment("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), new /datum/data/mining_equipment("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), @@ -50,7 +50,7 @@ new /datum/data/mining_equipment("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), - new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), + // new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), @@ -66,14 +66,13 @@ new /datum/data/mining_equipment("Fine Excavation Kit - Chisels",/obj/item/weapon/storage/excavation, 500), new /datum/data/mining_equipment("Fine Excavation Kit - Measuring Tape",/obj/item/device/measuring_tape, 125), new /datum/data/mining_equipment("Fine Excavation Kit - Hand Pick",/obj/item/weapon/pickaxe/hand, 375), - new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic, 750), + new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500), new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), - new /datum/data/mining_equipment("Misc: Graviton Visor", /obj/item/clothing/glasses/graviton, 1500), new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 100), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station, 1000), + new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 1500), new /datum/data/mining_equipment("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500), diff --git a/code/modules/mining/ore_redemption_machine/mine_point_items.dm b/code/modules/mining/ore_redemption_machine/mine_point_items.dm index da4463842a..a6a90a3bd6 100644 --- a/code/modules/mining/ore_redemption_machine/mine_point_items.dm +++ b/code/modules/mining/ore_redemption_machine/mine_point_items.dm @@ -15,19 +15,33 @@ name = "mining point card" desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard." icon_state = "data" - var/points = 500 + var/mine_points = 500 + var/survey_points = 0 /obj/item/weapon/card/mining_point_card/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/card/id)) - if(points) - var/obj/item/weapon/card/id/C = I - C.mining_points += points - to_chat(user, "You transfer [points] points to [C].") - points = 0 + var/obj/item/weapon/card/id/C = I + if(mine_points) + C.mining_points += mine_points + to_chat(user, "You transfer [mine_points] excavation points to [C].") + mine_points = 0 else - to_chat(user, "There's no points left on [src].") + to_chat(user, "There's no excavation points left on [src].") + + if(survey_points) + C.survey_points += survey_points + to_chat(user, "You transfer [survey_points] survey points to [C].") + survey_points = 0 + else + to_chat(user, "There's no survey points left on [src].") + ..() /obj/item/weapon/card/mining_point_card/examine(mob/user) ..(user) - to_chat(user, "There's [points] points on the card.") + to_chat(user, "There's [mine_points] excavation points on the card.") + to_chat(user, "There's [survey_points] survey points on the card.") + +/obj/item/weapon/card/mining_point_card/survey + mine_points = 0 + survey_points = 50 diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm new file mode 100644 index 0000000000..61f5a26962 --- /dev/null +++ b/code/modules/mining/ore_redemption_machine/survey_vendor.dm @@ -0,0 +1,110 @@ +/obj/machinery/mineral/equipment_vendor/survey + name = "exploration equipment vendor" + desc = "An equipment vendor for explorers, points collected with a survey scanner can be spent here." + icon = 'icons/obj/machines/mining_machines_vr.dmi' //VOREStation Edit + icon_state = "exploration" //VOREStation Edit + density = TRUE + anchored = TRUE + circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor + icon_deny = "exploration-deny" //VOREStation Edit + var/icon_vend = "exploration-vend" //VOREStation Add + //VOREStation Edit Start - Heavily modified list + prize_list = list( + new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), + new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), + new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), + new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/explorer, 10), + new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), + new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), + new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), + new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20), + new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90), + new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 75), + new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 30), + new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon", /obj/item/fulton_core, 300), + new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack", /obj/item/extraction_pack, 125), + new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 20), + new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50), + new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50), + new /datum/data/mining_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 50), + new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50), + new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), + new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50), + new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), + new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), + new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100), + new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), + new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100), + new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250), + new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310), + new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 300), + new /datum/data/mining_equipment("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), + new /datum/data/mining_equipment("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), + new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10), + new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 100), + new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 150), + new /datum/data/mining_equipment("Defense Equipment - Steel Machete", /obj/item/weapon/material/knife/machete, 75), + new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50), + new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100), + new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750) + ) + //VOREStation Edit End + +/obj/machinery/mineral/equipment_vendor/survey/interact(mob/user) + user.set_machine(src) + + var/dat + dat +="
" + if(istype(inserted_id)) + dat += "You have [inserted_id.survey_points] survey points collected. Eject ID.
" + else + dat += "No ID inserted. Insert ID.
" + dat += "
" + dat += "
Equipment point cost list:
" + for(var/datum/data/mining_equipment/prize in prize_list) + dat += "" + dat += "
[prize.equipment_name][prize.cost]Purchase
" + var/datum/browser/popup = new(user, "miningvendor", "Survey Equipment Vendor", 400, 600) + popup.set_content(dat) + popup.open() + +/obj/machinery/mineral/equipment_vendor/survey/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["choice"]) + if(istype(inserted_id)) + if(href_list["choice"] == "eject") + to_chat(usr, "You eject the ID from [src]'s card slot.") + usr.put_in_hands(inserted_id) + inserted_id = null + else if(href_list["choice"] == "insert") + var/obj/item/weapon/card/id/I = usr.get_active_hand() + if(istype(I) && !inserted_id && usr.unEquip(I)) + I.forceMove(src) + inserted_id = I + interact(usr) + to_chat(usr, "You insert the ID into [src]'s card slot.") + else + to_chat(usr, "No valid ID.") + flick(icon_deny, src) + + if(href_list["purchase"]) + if(istype(inserted_id)) + var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) + if (!prize || !(prize in prize_list)) + to_chat(usr, "Error: Invalid choice!") + flick(icon_deny, src) + return + if(prize.cost > inserted_id.survey_points) + to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") + flick(icon_deny, src) + else + inserted_id.survey_points -= prize.cost + to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") + flick(icon_vend, src) //VOREStation Add + new prize.equipment_path(drop_location()) + else + to_chat(usr, "Error: Please insert a valid ID!") + flick(icon_deny, src) + updateUsrDialog() diff --git a/code/modules/mob/_modifiers/medical.dm b/code/modules/mob/_modifiers/medical.dm new file mode 100644 index 0000000000..46a8877d1f --- /dev/null +++ b/code/modules/mob/_modifiers/medical.dm @@ -0,0 +1,17 @@ +/* + * Modifiers caused by chemicals or organs specifically. + */ + +/datum/modifier/cryogelled + name = "cryogelled" + desc = "Your body begins to freeze." + mob_overlay_state = "chilled" + + on_created_text = "You feel like you're going to freeze! It's hard to move." + on_expired_text = "You feel somewhat warmer and more mobile now." + stacks = MODIFIER_STACK_ALLOWED + + slowdown = 0.1 + evasion = -5 + attack_speed_percent = 1.1 + disable_duration_percent = 1.05 diff --git a/code/modules/mob/_modifiers/modifiers_misc.dm b/code/modules/mob/_modifiers/modifiers_misc.dm index e81cf0aaa8..800429de25 100644 --- a/code/modules/mob/_modifiers/modifiers_misc.dm +++ b/code/modules/mob/_modifiers/modifiers_misc.dm @@ -43,7 +43,7 @@ the artifact triggers the rage. /datum/modifier/berserk name = "berserk" desc = "You are filled with an overwhelming rage." - client_color = "#FF0000" // Make everything red! + client_color = "#FF5555" // Make everything red! mob_overlay_state = "berserk" on_created_text = "You feel an intense and overwhelming rage overtake you as you go berserk!" @@ -293,4 +293,29 @@ the artifact triggers the rage. on_expired_text = "You feel.. different." stacks = MODIFIER_STACK_EXTEND - pulse_set_level = PULSE_NORM \ No newline at end of file + pulse_set_level = PULSE_NORM + +/datum/modifier/slow_pulse + name = "slow pulse" + desc = "Your blood flows slower." + + on_created_text = "You feel sluggish." + on_expired_text = "You feel energized." + stacks = MODIFIER_STACK_EXTEND + + bleeding_rate_percent = 0.8 + + pulse_set_level = PULSE_SLOW + +// Temperature Normalizer. +/datum/modifier/homeothermic + name = "temperature resistance" + desc = "Your body normalizes to room temperature." + + on_created_text = "You feel comfortable." + on_expired_text = "You feel.. still probably comfortable." + stacks = MODIFIER_STACK_EXTEND + +/datum/modifier/homeothermic/tick() + ..() + holder.bodytemperature = round((holder.bodytemperature + T20C) / 2) diff --git a/code/modules/mob/_modifiers/unholy.dm b/code/modules/mob/_modifiers/unholy.dm index 0b6f69a21b..730e57691c 100644 --- a/code/modules/mob/_modifiers/unholy.dm +++ b/code/modules/mob/_modifiers/unholy.dm @@ -146,3 +146,55 @@ if(prob(10)) to_chat(H, "It feels as though your body is being torn apart!") L.updatehealth() + +/datum/modifier/gluttonyregeneration + name = "gluttonous regeneration" + desc = "You are filled with an overwhelming hunger." + mob_overlay_state = "electricity" + + on_created_text = "You feel an intense and overwhelming hunger overtake you as your body regenerates!" + on_expired_text = "The blaze of hunger inside you has been snuffed." + stacks = MODIFIER_STACK_EXTEND + +/datum/modifier/gluttonyregeneration/can_apply(var/mob/living/L) + if(L.stat == DEAD) + to_chat(L, "You can't be dead to consume.") + return FALSE + + if(!L.is_sentient()) + return FALSE // Drones don't feel anything, not even hunger. + + if(L.has_modifier_of_type(/datum/modifier/berserk_exhaustion)) + to_chat(L, "You recently berserked, so you are too tired to consume.") + return FALSE + + if(!ishuman(L)) // Only humanoids feel hunger. Totally. + return FALSE + + else + var/mob/living/carbon/human/H = L + if(H.species.name == "Diona") + to_chat(L, "You feel strange for a moment, but it passes.") + return FALSE // Happy trees aren't affected by incredible hunger. + + return ..() + +/datum/modifier/gluttonyregeneration/tick() + spawn() + if(ishuman(holder)) + var/mob/living/carbon/human/H = holder + var/starting_nutrition = H.nutrition + H.nutrition = max(0, H.nutrition - 10) + var/healing_amount = starting_nutrition - H.nutrition + if(healing_amount < 0) // If you are eating enough to somehow outpace this, congratulations, you are gluttonous enough to gain a boon. + healing_amount *= -2 + + H.adjustBruteLoss(-healing_amount * 0.25) + + H.adjustFireLoss(-healing_amount * 0.25) + + H.adjustOxyLoss(-healing_amount * 0.25) + + H.adjustToxLoss(-healing_amount * 0.25) + + ..() \ 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 31cbcc1f44..2c74029eb8 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -389,13 +389,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return (T && T.holy) && (is_manifest || (mind in cult.current_antagonists)) -/mob/observer/dead/verb/jumptomob(target in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak +/mob/observer/dead/verb/jumptomob(input in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" set name = "Jump to Mob" set desc = "Teleport to a mob" set popup_menu = FALSE //VOREStation Edit - Declutter. if(istype(usr, /mob/observer/dead)) //Make sure they're an observer! - + var/target = getmobs()[input] if (!target)//Make sure we actually have a target return else diff --git a/code/modules/mob/living/carbon/human/ai_controlled/ai_controlled.dm b/code/modules/mob/living/carbon/human/ai_controlled/ai_controlled.dm new file mode 100644 index 0000000000..431b7c4456 --- /dev/null +++ b/code/modules/mob/living/carbon/human/ai_controlled/ai_controlled.dm @@ -0,0 +1,143 @@ +/mob/living/carbon/human/ai_controlled + name = "Nameless Joe" + + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + + var/generate_species = SPECIES_HUMAN + var/generate_dead = FALSE + + var/generate_gender = FALSE + var/generate_id_gender = FALSE + + var/to_wear_hair = "Bald" + + var/to_wear_helmet = /obj/item/clothing/head/welding + var/to_wear_glasses = /obj/item/clothing/glasses/threedglasses + var/to_wear_mask = /obj/item/clothing/mask/gas + var/to_wear_l_radio = /obj/item/device/radio/headset + var/to_wear_r_radio = null + var/to_wear_uniform = /obj/item/clothing/under/color/grey + var/to_wear_suit = /obj/item/clothing/suit/armor/material/makeshift/glass + var/to_wear_gloves = /obj/item/clothing/gloves/ring/material/platinum + var/to_wear_shoes = /obj/item/clothing/shoes/galoshes + var/to_wear_belt = /obj/item/weapon/storage/belt/utility/full + var/to_wear_l_pocket = /obj/item/weapon/soap + var/to_wear_r_pocket = /obj/item/device/pda + var/to_wear_back = /obj/item/weapon/storage/backpack + var/to_wear_id_type = /obj/item/weapon/card/id + var/to_wear_id_job = "Assistant" + + var/to_wear_l_hand = null + var/to_wear_r_hand = /obj/item/weapon/melee/baton + +/mob/living/carbon/human/ai_controlled/Initialize() + if(generate_gender) + gender = pick(list(MALE, FEMALE, PLURAL, NEUTER)) + + if(generate_id_gender) + identifying_gender = pick(list(MALE, FEMALE, PLURAL, NEUTER)) + + ..(loc, generate_species) + + h_style = to_wear_hair + + if(to_wear_uniform) + equip_to_slot_or_del(new to_wear_uniform(src), slot_w_uniform) + + if(to_wear_suit) + equip_to_slot_or_del(new to_wear_suit(src), slot_wear_suit) + + if(to_wear_shoes) + equip_to_slot_or_del(new to_wear_shoes(src), slot_shoes) + + if(to_wear_gloves) + equip_to_slot_or_del(new to_wear_gloves(src), slot_gloves) + + if(to_wear_l_radio) + equip_to_slot_or_del(new to_wear_l_radio(src), slot_l_ear) + + if(to_wear_r_radio) + equip_to_slot_or_del(new to_wear_r_radio(src), slot_r_ear) + + if(to_wear_glasses) + equip_to_slot_or_del(new to_wear_glasses(src), slot_glasses) + + if(to_wear_mask) + equip_to_slot_or_del(new to_wear_mask(src), slot_wear_mask) + + if(to_wear_helmet) + equip_to_slot_or_del(new to_wear_helmet(src), slot_head) + + if(to_wear_belt) + equip_to_slot_or_del(new to_wear_belt(src), slot_belt) + + if(to_wear_r_pocket) + equip_to_slot_or_del(new to_wear_r_pocket(src), slot_r_store) + + if(to_wear_l_pocket) + equip_to_slot_or_del(new to_wear_l_pocket(src), slot_l_store) + + if(to_wear_back) + equip_to_slot_or_del(new to_wear_back(src), slot_back) + + if(to_wear_l_hand) + equip_to_slot_or_del(new to_wear_l_hand(src), slot_l_hand) + + if(to_wear_r_hand) + equip_to_slot_or_del(new to_wear_r_hand(src), slot_r_hand) + + if(to_wear_id_type) + var/obj/item/weapon/card/id/W = new to_wear_id_type(src) + W.name = "[real_name]'s ID Card" + var/datum/job/jobdatum + for(var/jobtype in typesof(/datum/job)) + var/datum/job/J = new jobtype + if(J.title == to_wear_id_job) + jobdatum = J + break + if(jobdatum) + W.access = jobdatum.get_access() + else + W.access = list() + if(to_wear_id_job) + W.assignment = to_wear_id_job + W.registered_name = real_name + equip_to_slot_or_del(W, slot_wear_id) + + if(generate_dead) + death() + +/* + * Subtypes. + */ + +/mob/living/carbon/human/ai_controlled/replicant + generate_species = SPECIES_REPLICANT_BETA + + generate_gender = TRUE + identifying_gender = NEUTER + + faction = "xeno" + + to_wear_helmet = /obj/item/clothing/head/helmet/dermal + to_wear_glasses = /obj/item/clothing/glasses/goggles + to_wear_mask = /obj/item/clothing/mask/gas/half + to_wear_l_radio = /obj/item/device/radio/headset/headset_rob + to_wear_r_radio = null + to_wear_uniform = /obj/item/clothing/under/color/grey + to_wear_suit = /obj/item/clothing/suit/armor/vest + to_wear_gloves = null + to_wear_shoes = /obj/item/clothing/shoes/boots/combat/changeling + to_wear_belt = /obj/item/weapon/storage/belt/utility/full + to_wear_l_pocket = /obj/item/weapon/grenade/explosive/mini + to_wear_r_pocket = /obj/item/weapon/grenade/explosive/mini + to_wear_back = /obj/item/device/radio/electropack + to_wear_id_type = /obj/item/weapon/card/id + to_wear_id_job = "Experiment" + + to_wear_r_hand = null + +/mob/living/carbon/human/ai_controlled/replicant/Initialize() + ..() + name = species.get_random_name(gender) + add_modifier(/datum/modifier/homeothermic, 0, null) diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 809a5ef8ad..a3c5e65470 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -286,8 +286,11 @@ nutrition -= 200 for(var/obj/item/organ/I in internal_organs) + if(I.robotic >= ORGAN_ROBOT) // No free robofix. + continue if(I.damage > 0) I.damage = max(I.damage - 30, 0) //Repair functionally half of a dead internal organ. + I.status = 0 // Wipe status, as it's being regenerated from possibly dead. to_chat(src, "You feel a soothing sensation within your [I.name]...") // Replace completely missing limbs. @@ -310,6 +313,15 @@ var/agony_to_apply = round(0.66 * O.max_damage) // 66% of the limb's health is converted into pain. src.apply_damage(agony_to_apply, HALLOSS) + for(var/organtype in species.has_organ) // Replace completely missing internal organs. -After- external ones, so they all should exist. + if(!src.internal_organs_by_name[organtype]) + var/organpath = species.has_organ[organtype] + var/obj/item/organ/Int = new organpath(src, TRUE) + + Int.rejuvenate(TRUE) + + handle_organs() // Update everything + update_icons_body() active_regen = FALSE else 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 bb053cf488..4ac8697e28 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -74,7 +74,13 @@ var/datum/species/shapeshifter/promethean/prometheans genders = list(MALE, FEMALE, NEUTER, PLURAL) unarmed_types = list(/datum/unarmed_attack/slime_glomp) - has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime) // Slime core. + + has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime, + O_HEART = /obj/item/organ/internal/heart/grey/colormatch/slime, + O_REGBRUTE = /obj/item/organ/internal/regennetwork, + O_REGBURN = /obj/item/organ/internal/regennetwork/burn, + O_REGOXY = /obj/item/organ/internal/regennetwork/oxy, + O_REGTOX = /obj/item/organ/internal/regennetwork/tox) dispersed_eyes = TRUE @@ -197,35 +203,71 @@ var/datum/species/shapeshifter/promethean/prometheans var/nutrition_cost = 0 // The total amount of nutrition drained every tick, when healing var/nutrition_debt = 0 // Holder variable used to store previous damage values prior to healing for use in the nutrition_cost equation. var/starve_mod = 1 // Lowering this lowers healing and increases agony multiplicatively. - if(H.nutrition <= 150) // This is when the icon goes red + + var/strain_negation = 0 // How much agony is being prevented by the + + if(H.nutrition <= 150) // This is when the icon goes red starve_mod = 0.75 if(H.nutrition <= 50) // Severe starvation. Damage repaired beyond this point will cause a stunlock if untreated. starve_mod = 0.5 + var/to_pay = 0 if(regen_brute) nutrition_debt = H.getBruteLoss() H.adjustBruteLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getBruteLoss() + + to_pay = nutrition_debt - H.getBruteLoss() + + nutrition_cost += to_pay + + var/obj/item/organ/internal/regennetwork/BrReg = H.internal_organs_by_name[O_REGBRUTE] + + if(BrReg) + strain_negation += to_pay * max(0, (1 - BrReg.get_strain_percent())) if(regen_burn) nutrition_debt = H.getFireLoss() H.adjustFireLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getFireLoss() + + to_pay = nutrition_debt - H.getFireLoss() + + nutrition_cost += to_pay + + var/obj/item/organ/internal/regennetwork/BuReg = H.internal_organs_by_name[O_REGBURN] + + if(BuReg) + strain_negation += to_pay * max(0, (1 - BuReg.get_strain_percent())) if(regen_oxy) nutrition_debt = H.getOxyLoss() H.adjustOxyLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getOxyLoss() + + to_pay = nutrition_debt - H.getOxyLoss() + + nutrition_cost += to_pay + + var/obj/item/organ/internal/regennetwork/OxReg = H.internal_organs_by_name[O_REGOXY] + + if(OxReg) + strain_negation += to_pay * max(0, (1 - OxReg.get_strain_percent())) if(regen_tox) nutrition_debt = H.getToxLoss() H.adjustToxLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getToxLoss() + + to_pay = nutrition_debt - H.getToxLoss() + + nutrition_cost += to_pay + + var/obj/item/organ/internal/regennetwork/ToxReg = H.internal_organs_by_name[O_REGTOX] + + if(ToxReg) + strain_negation += to_pay * max(0, (1 - ToxReg.get_strain_percent())) H.nutrition -= (3 * nutrition_cost) //Costs Nutrition when damage is being repaired, corresponding to the amount of damage being repaired. H.nutrition = max(0, H.nutrition) //Ensure it's not below 0. - var/agony_to_apply = ((1 / starve_mod) * nutrition_cost) //Regenerating damage causes minor pain over time. Small injures will be no issue, large ones will cause problems. + var/agony_to_apply = ((1 / starve_mod) * (nutrition_cost - strain_negation)) //Regenerating damage causes minor pain over time, if the organs responsible are nonexistant or too high on strain. Small injures will be no issue, large ones will cause problems. if((starve_mod <= 0.5 && (H.getHalLoss() + agony_to_apply) <= 90) || ((H.getHalLoss() + agony_to_apply) <= 70)) // Will max out at applying halloss at 70, unless they are starving; starvation regeneration will bring them up to a maximum of 120, the same amount of agony a human receives from three taser hits. H.apply_damage(agony_to_apply, HALLOSS) diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index 8987f246b0..7e1aaa9f25 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -96,16 +96,6 @@ excludes = list(/datum/trait/autohiss_tajaran, /datum/trait/autohiss_unathi) // YW Addition end -/datum/trait/autohiss_awootism - name = "Autohiss (Disability)" - desc = "You can't speak r's and l's properly." - cost = 0 - var_changes = list( - autohiss_basic_map = list( - "l" = list("w", "ww"), - "r" = list("w", "ww") - )) - /datum/trait/bloodsucker name = "Minor Bloodsucker" desc = "Makes you unable to gain nutrition from anything but blood. To compensate, you get fangs that can be used to drain blood from prey." diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index bb861986b8..9eff93256a 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -247,7 +247,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() for(var/organ_tag in species.has_limbs) var/obj/item/organ/external/part = organs_by_name[organ_tag] - if(isnull(part) || part.is_stump()) + if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff. icon_key += "0" continue if(part) @@ -290,7 +290,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() base_icon = chest.get_icon() for(var/obj/item/organ/external/part in organs) - if(isnull(part) || part.is_stump()) + if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff. 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 @@ -577,7 +577,15 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() return //Wearing a suit that prevents uniform rendering //Build a uniform sprite - overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER) + //VOREStation Edit start. + var/icon/c_mask = null + if(tail_style && tail_style.clip_mask_icon && tail_style.clip_mask_state) + var/obj/item/clothing/suit/S = wear_suit + if(!(wear_suit && ((wear_suit.flags_inv & HIDETAIL) || (istype(S) && S.taurized)))) //Clip the lower half of the suit off using the tail's clip mask. + c_mask = new /icon(tail_style.clip_mask_icon, tail_style.clip_mask_state) + overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER, clip_mask = c_mask) + //VOREStation Edit end. + apply_layer(UNIFORM_LAYER) /mob/living/carbon/human/update_inv_wear_id() @@ -659,6 +667,12 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(!shoes || (wear_suit && wear_suit.flags_inv & HIDESHOES) || (w_uniform && w_uniform.flags_inv & HIDESHOES)) return //Either nothing to draw, or it'd be hidden. + //VOREStation Edit + for(var/f in list(BP_L_FOOT, BP_R_FOOT)) + var/obj/item/organ/external/foot/foot = get_organ(f) + if(istype(foot) && foot.is_hidden_by_tail()) //If either foot is hidden by the tail, don't render footwear. + return + //Allow for shoe layer toggle nonsense var/shoe_layer = SHOES_LAYER if(istype(shoes, /obj/item/clothing/shoes)) @@ -742,12 +756,18 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() // Part of splitting the suit sprites up var/iconFile = INV_SUIT_DEF_ICON + var/obj/item/clothing/suit/S //VOREStation edit - break this var out a level for use below. if(istype(wear_suit, /obj/item/clothing/suit)) - var/obj/item/clothing/suit/S = wear_suit + S = wear_suit if(S.update_icon_define) iconFile = S.update_icon_define - overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = iconFile, default_layer = SUIT_LAYER) + //VOREStation Edit start. + var/icon/c_mask = null + if((tail_style && tail_style.clip_mask_icon && tail_style.clip_mask_state) && !(wear_suit.flags_inv & HIDETAIL) && !(S && S.taurized)) //Clip the lower half of the suit off using the tail's clip mask. + c_mask = new /icon(tail_style.clip_mask_icon, tail_style.clip_mask_state) + overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = iconFile, default_layer = SUIT_LAYER, clip_mask = c_mask) + //VOREStation Edit end. apply_layer(SUIT_LAYER) @@ -922,7 +942,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() var/t_state = "[species.get_tail(src)]_once" var/used_tail_layer = tail_alt ? TAIL_LAYER_ALT : TAIL_LAYER // VOREStation Edit - Alt Tail Layer - + var/image/tail_overlay = overlays_standing[used_tail_layer] // VOREStation Edit - Alt Tail Layer if(tail_overlay && tail_overlay.icon_state == t_state) return //let the existing animation finish @@ -932,7 +952,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() spawn(20) //check that the animation hasn't changed in the meantime if(overlays_standing[used_tail_layer] == tail_overlay && tail_overlay.icon_state == t_state) // VOREStation Edit - Alt Tail Layer - animate_tail_stop() + animate_tail_stop() /mob/living/carbon/human/proc/animate_tail_start() if(QDESTROYING(src)) @@ -973,7 +993,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(vr_wing_image) vr_wing_image.layer = BODY_LAYER+WING_LAYER overlays_standing[WING_LAYER] = vr_wing_image - + apply_layer(WING_LAYER) // VOREStation Edit end diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 37d9e43b37..55bddfe1bd 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -26,6 +26,9 @@ if(COLD_RESISTANCE in mutations) damage = 0 adjustFireLoss(damage * blocked) + if(SEARING) + apply_damage(damage / 3, BURN, def_zone, blocked, soaked, used_weapon, sharp, edge) + apply_damage(damage / 3 * 2, BRUTE, def_zone, blocked, soaked, used_weapon, sharp, edge) if(TOX) adjustToxLoss(damage * blocked) if(OXY) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e5dd8bf63e..e6fde9860f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1060,7 +1060,7 @@ default behaviour is: var/mob/living/carbon/human/H = src if(!H.isSynthetic()) var/obj/item/organ/internal/liver/L = H.internal_organs_by_name["liver"] - if(L.is_broken()) + if(!L || L.is_broken()) blood_vomit = 1 Stun(5) diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm index 5f352705b8..62b2c43fe8 100644 --- a/code/modules/mob/living/simple_animal/corpse.dm +++ b/code/modules/mob/living/simple_animal/corpse.dm @@ -99,7 +99,19 @@ corpseidjob = "Operative" corpseidaccess = "Syndicate" - +/obj/effect/landmark/mobcorpse/solarpeacekeeper + name = "Mercenary" + corpseuniform = /obj/item/clothing/under/syndicate + corpsesuit = /obj/item/clothing/suit/armor/pcarrier/blue/sol + corpseshoes = /obj/item/clothing/shoes/boots/swat + corpsegloves = /obj/item/clothing/gloves/swat + corpseradio = /obj/item/device/radio/headset + corpsemask = /obj/item/clothing/mask/gas + corpsehelmet = /obj/item/clothing/head/helmet/swat + corpseback = /obj/item/weapon/storage/backpack + corpseid = 1 + corpseidjob = "Peacekeeper" + corpseidaccess = "Syndicate" /obj/effect/landmark/mobcorpse/syndicatecommando name = "Syndicate Commando" diff --git a/code/modules/mob/living/simple_animal/corpse_vr.dm b/code/modules/mob/living/simple_animal/corpse_vr.dm new file mode 100644 index 0000000000..82399a8328 --- /dev/null +++ b/code/modules/mob/living/simple_animal/corpse_vr.dm @@ -0,0 +1,2 @@ +/obj/effect/landmark/mobcorpse/syndicatecommando + name = "Mercenary Commando" \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm index 32eccb00af..5f4a4dc7e0 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm @@ -72,7 +72,7 @@ attack_edge = TRUE melee_attack_delay = 1 SECOND - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/crab response_help = "pets" response_disarm = "gently pushes aside" @@ -117,4 +117,4 @@ for(var/mob/living/L in hearers(holder)) if(!istype(L, holder)) // Don't follow other hooligan crabs. holder.visible_message("\The [holder] starts to follow \the [L].") - set_follow(L, rand(20 SECONDS, 40 SECONDS)) \ No newline at end of file + set_follow(L, rand(20 SECONDS, 40 SECONDS)) diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm index 514f45df12..bddfc140d4 100644 --- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm @@ -162,6 +162,16 @@ base_attack_cooldown = 5 // Two attacks a second or so. reload_max = 20 +/mob/living/simple_mob/humanoid/merc/ranged/smg/sol + icon_state = "bluforranged_smg" + icon_living = "blueforranged_smg" + + corpse = /obj/effect/landmark/mobcorpse/solarpeacekeeper + loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100) + + base_attack_cooldown = 5 // Two attacks a second or so. + reload_max = 20 + // Laser Rifle /mob/living/simple_mob/humanoid/merc/ranged/laser icon_state = "syndicateranged_laser" diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index b335faf1d3..7ad90dfc43 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -174,6 +174,12 @@ assailant.visible_message("[assailant] covers [affecting]'s eyes!") if(affecting.eye_blind < 3) affecting.Blind(3) + //TFF 12/8/19 VoreStation Addition Start + if(BP_HEAD) + if(force_down) + if(announce) + assailant.visible_message("[assailant] sits on [target]'s head!") + //VoreStation Addition End /obj/item/weapon/grab/attack_self() return s_click(hud) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index b03649183b..e66cf6f4ac 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -84,7 +84,7 @@ /client/verb/drop_item() set hidden = 1 - if(!isrobot(mob) && mob.stat == CONSCIOUS && isturf(mob.loc)) + if(!isrobot(mob) && mob.stat == CONSCIOUS && (isturf(mob.loc) || isbelly(mob.loc))) // VOREStation Edit: dropping in bellies return mob.drop_item() return diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 579e7776b7..215ef65ced 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -78,6 +78,7 @@ var/list/organ_cache = list() if(E.internal_organs == null) E.internal_organs = list() E.internal_organs |= src + H.internal_organs_by_name[organ_tag] = src if(dna) if(!blood_DNA) blood_DNA = list() diff --git a/code/modules/organs/organ_external_vr.dm b/code/modules/organs/organ_external_vr.dm index 0e3fb07d9e..491cce9428 100644 --- a/code/modules/organs/organ_external_vr.dm +++ b/code/modules/organs/organ_external_vr.dm @@ -13,3 +13,7 @@ min_broken_damage = o_min_broken_damage else return ..() + +/obj/item/organ/external/proc/is_hidden_by_tail() + if(owner && owner.tail_style && owner.tail_style.hide_body_parts && (organ_tag in owner.tail_style.hide_body_parts)) + return 1 \ No newline at end of file diff --git a/code/modules/organs/subtypes/slime.dm b/code/modules/organs/subtypes/slime.dm index f22b90caea..5fb54a21b4 100644 --- a/code/modules/organs/subtypes/slime.dm +++ b/code/modules/organs/subtypes/slime.dm @@ -56,3 +56,89 @@ max_damage = 30 encased = 0 spread_dam = 1 + +/* + * Internal Slime organs. + */ + +/obj/item/organ/internal/heart/grey/colormatch/slime + name = "pneumatic network" + desc = "A disgusting sac of goo." + icon_state = "sac_slime" + dead_icon = null + standard_pulse_level = PULSE_NONE + +/obj/item/organ/internal/heart/grey/colormatch/slime/process() + ..() + if(!(QDELETED(src)) && src.loc != owner) + visible_message("\The [src] splatters!") + var/turf/T = get_turf(src) + var/obj/effect/decal/cleanable/blood/B = new (T) + + B.basecolor = src.color + B.update_icon() + qdel(src) + +/obj/item/organ/internal/regennetwork + name = "pneumoregenesis network" + parent_organ = BP_TORSO + organ_tag = O_REGBRUTE + + icon_state = "sac_slime" + + var/strain = 0 // The amount of stress this organ is under. Capped at min_broken_damage, usually half its max damage. + + var/last_strain_increase = 0 // World time of the last increase in strain. + var/strain_regen_cooldown = 5 MINUTES + +/obj/item/organ/internal/regennetwork/Initialize() + ..() + var/mob/living/carbon/human/H = null + spawn(15) + if(ishuman(owner)) + H = owner + color = H.species.get_blood_colour(H) + +/obj/item/organ/internal/regennetwork/proc/get_strain_percent(var/cost) + adjust_strain(cost) + + if((status & ORGAN_CUT_AWAY) || (status & ORGAN_BROKEN) || (status & ORGAN_DEAD)) + return 1 + + return round((strain / min_broken_damage) * 10) / 10 + +/obj/item/organ/internal/regennetwork/proc/adjust_strain(var/amount) + if(amount < 0 && world.time < (last_strain_increase + strain_regen_cooldown)) + return + + else if(amount > 0) + last_strain_increase = world.time + + strain = CLAMP(strain + amount, 0, min_broken_damage) + +/obj/item/organ/internal/regennetwork/process() + ..() + + if(!(QDELETED(src)) && src.loc != owner) + visible_message("\The [src] splatters!") + var/turf/T = get_turf(src) + var/obj/effect/decal/cleanable/blood/B = new (T) + + B.basecolor = src.color + B.update_icon() + qdel(src) + + if(src && !is_bruised()) + adjust_strain(-0.25 * max(0, (min_broken_damage - damage) / min_broken_damage)) // Decrease the current strain with respect to the current strain level. + +/obj/item/organ/internal/regennetwork/burn + name = "thermoregenesis network" + organ_tag = O_REGBURN + +/obj/item/organ/internal/regennetwork/oxy + name = "respiroregenesis network" + organ_tag = O_REGOXY + +/obj/item/organ/internal/regennetwork/tox + name = "toxoregenesis network" + organ_tag = O_REGTOX diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index dee4cabfa6..a481cfaf33 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -281,6 +281,28 @@ var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc) reagents.trans_to_obj(P,50) + else if (href_list["createpatch"]) + if(reagents.total_volume < 1) //Sanity checking. + return + + var/name = sanitizeSafe(input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([round(reagents.total_volume)]u)") as null|text, MAX_NAME_LEN) + + if(!name) //Blank name (sanitized to nothing, or left empty) or cancel + return + + if(reagents.total_volume < 1) //Sanity checking. + return + var/obj/item/weapon/reagent_containers/pill/patch/P = new/obj/item/weapon/reagent_containers/pill/patch(src.loc) + if(!name) name = reagents.get_master_reagent_name() + P.name = "[name] patch" + P.pixel_x = rand(-7, 7) //random position + P.pixel_y = rand(-7, 7) + + reagents.trans_to_obj(P, 60) + if(src.loaded_pill_bottle) + if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space) + P.loc = loaded_pill_bottle + else if(href_list["pill_sprite"]) pillsprite = href_list["pill_sprite"] else if(href_list["bottle_sprite"]) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 86a35c0365..94495648c9 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -16,6 +16,28 @@ M.add_chemical_effect(CE_STABLE, 15) M.add_chemical_effect(CE_PAINKILLER, 10) +/datum/reagent/inaprovaline/topical + name = "Inaprovalaze" + id = "inaprovalaze" + description = "Inaprovalaze is a topical variant of Inaprovaline." + taste_description = "bitterness" + reagent_state = LIQUID + color = "#00BFFF" + overdose = REAGENTS_OVERDOSE * 2 + metabolism = REM * 0.5 + scannable = 1 + touch_met = REM * 0.75 + +/datum/reagent/inaprovaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien != IS_DIONA) + ..() + M.adjustToxLoss(2 * removed) + +/datum/reagent/inaprovaline/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + if(alien != IS_DIONA) + M.add_chemical_effect(CE_STABLE, 20) + M.add_chemical_effect(CE_PAINKILLER, 12) + /datum/reagent/bicaridine name = "Bicaridine" id = "bicaridine" @@ -51,6 +73,33 @@ if(W.damage <= 0) O.wounds -= W +/datum/reagent/bicaridine/topical + name = "Bicaridaze" + id = "bicaridaze" + description = "Bicaridaze is a topical variant of the chemical Bicaridine." + taste_description = "bitterness" + taste_mult = 3 + reagent_state = LIQUID + color = "#BF0000" + overdose = REAGENTS_OVERDOSE * 0.75 + scannable = 1 + touch_met = REM * 0.75 + +/datum/reagent/bicaridine/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien == IS_SLIME) + chem_effective = 0.75 + if(alien != IS_DIONA) + ..(M, alien, removed * chem_effective) + M.adjustToxLoss(2 * removed) + +/datum/reagent/bicaridine/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien == IS_SLIME) + chem_effective = 0.75 + if(alien != IS_DIONA) + M.heal_organ_damage(6 * removed * chem_effective, 0) + /datum/reagent/kelotane name = "Kelotane" id = "kelotane" @@ -87,6 +136,33 @@ if(alien != IS_DIONA) M.heal_organ_damage(0, 8 * removed * chem_effective) //VOREStation edit +/datum/reagent/dermaline/topical + name = "Dermalaze" + id = "dermalaze" + description = "Dermalaze is a topical variant of the chemical Dermaline." + taste_description = "bitterness" + taste_mult = 1.5 + reagent_state = LIQUID + color = "#FF8000" + overdose = REAGENTS_OVERDOSE * 0.4 + scannable = 1 + touch_met = REM * 0.75 + +/datum/reagent/dermaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien == IS_SLIME) + chem_effective = 0.75 + if(alien != IS_DIONA) + ..(M, alien, removed * chem_effective) + M.adjustToxLoss(2 * removed) + +/datum/reagent/dermaline/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien == IS_SLIME) + chem_effective = 0.75 + if(alien != IS_DIONA) + M.heal_organ_damage(0, 12 * removed * chem_effective) + /datum/reagent/dylovene name = "Dylovene" id = "anti_toxin" @@ -203,6 +279,10 @@ M.heal_organ_damage(1.5 * removed, 1.5 * removed * chem_effective) M.adjustToxLoss(-1.5 * removed * chem_effective) +/datum/reagent/tricordrazine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + if(alien != IS_DIONA) + affect_blood(M, alien, removed * 0.4) + /datum/reagent/cryoxadone name = "Cryoxadone" id = "cryoxadone" @@ -882,6 +962,9 @@ to_chat(M, "Your senses feel unfocused, and divided.") M.add_chemical_effect(CE_ANTIBIOTIC, dose >= overdose ? ANTIBIO_OD : ANTIBIO_NORM) +/datum/reagent/spaceacillin/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + affect_blood(M, alien, removed * 0.8) // Not 100% as effective as injections, though still useful. + /datum/reagent/corophizine name = "Corophizine" id = "corophizine" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm new file mode 100644 index 0000000000..d9a7483ec1 --- /dev/null +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm @@ -0,0 +1,58 @@ +/* + * Modifier-applying chemicals. + */ + +/datum/reagent/modapplying + name = "brute juice" + id = "berserkmed" + description = "A liquid that is capable of causing a prolonged state of heightened aggression and durability." + taste_description = "metal" + reagent_state = LIQUID + color = "#ff5555" + metabolism = REM + + var/modifier_to_add = /datum/modifier/berserk + var/modifier_duration = 2 SECONDS // How long, per unit dose, will this last? + +/datum/reagent/modapplying/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_DIONA) + return + M.add_modifier(modifier_to_add, dose * modifier_duration) + +/datum/reagent/modapplying/cryofluid + name = "cryogenic slurry" + id = "cryoslurry" + description = "An incredibly strange liquid that rapidly absorbs thermal energy from materials it contacts." + taste_description = "siberian hellscape" + color = "#4CDBDB" + metabolism = REM * 0.5 + + modifier_to_add = /datum/modifier/cryogelled + modifier_duration = 3 SECONDS + +/datum/reagent/modapplying/cryofluid/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..(M, alien, removed) + M.bodytemperature -= removed * 20 + +/datum/reagent/modapplying/cryofluid/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + affect_blood(M, alien, removed * 2.5) + +/datum/reagent/modapplying/cryofluid/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + affect_blood(M, alien, removed * 0.6) + +/datum/reagent/modapplying/cryofluid/touch_mob(var/mob/M, var/amount) + if(isliving(M)) + var/mob/living/L = M + for(var/I = 1 to rand(1, round(amount + 1))) + L.add_modifier(modifier_to_add, amount * rand(modifier_duration / 2, modifier_duration * 2)) + return + +/datum/reagent/modapplying/cryofluid/touch_turf(var/turf/T, var/amount) + if(istype(T, /turf/simulated/floor/water) && prob(amount)) + T.visible_message("\The [T] crackles loudly as the cryogenic fluid causes it to boil away, leaving behind a hard layer of ice.") + T.ChangeTurf(/turf/simulated/floor/outdoors/ice, 1, 1, TRUE) + else + if(istype(T, /turf/simulated)) + var/turf/simulated/S = T + S.freeze_floor() + return diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 79304733dd..38a65a78d8 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -11,6 +11,7 @@ metabolism = REM * 0.25 // 0.05 by default. Hopefully enough to get some help, or die horribly, whatever floats your boat filtered_organs = list(O_LIVER, O_KIDNEYS) var/strength = 4 // How much damage it deals per unit + var/skin_danger = 0.2 // The multiplier for how effective the toxin is when making skin contact. /datum/reagent/toxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(strength && alien != IS_DIONA) @@ -23,6 +24,9 @@ M.heal_organ_damage((10/strength) * removed, (10/strength) * removed) //Doses of toxins below 10 units, and 10 strength, are capable of providing useful compounds for repair. M.adjustToxLoss(strength * removed) +/datum/reagent/toxin/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + affect_blood(M, alien, removed * 0.2) + /datum/reagent/toxin/plasticide name = "Plasticide" id = "plasticide" @@ -58,6 +62,7 @@ reagent_state = LIQUID color = "#005555" strength = 8 + skin_danger = 0.4 /datum/reagent/toxin/neurotoxic_protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -121,6 +126,7 @@ color = "#9D14DB" strength = 30 touch_met = 5 + skin_danger = 1 /datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount) if(istype(L)) @@ -346,6 +352,36 @@ if(alien == IS_DIONA) M.adjustToxLoss(50 * removed) +/datum/reagent/toxin/sifslurry + name = "Sivian Sap" + id = "sifsap" + description = "A natural slurry comprised of fluorescent bacteria native to Sif, in the Vir system." + taste_description = "sour" + reagent_state = LIQUID + color = "#C6E2FF" + strength = 2 + overdose = 20 + +/datum/reagent/toxin/sifslurry/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_DIONA) // Symbiotic bacteria. + M.nutrition += strength * removed + return + else + M.add_modifier(/datum/modifier/slow_pulse, 30 SECONDS) + ..() + +/datum/reagent/toxin/sifslurry/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. + if(alien == IS_DIONA) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + overdose_mod *= H.species.chemOD_mod + M.apply_effect(2 * removed,IRRADIATE, 0, 0) + M.apply_effect(5 * removed,DROWSY, 0, 0) + +/datum/reagent/toxin/sifslurry/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + affect_blood(M, alien, removed * 0.7) + /datum/reagent/acid/polyacid name = "Polytrinic acid" id = "pacid" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 5b37335647..a903454801 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -34,6 +34,7 @@ var/reaction_sound = 'sound/effects/bubbles.ogg' var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. + /datum/chemical_reaction/proc/can_happen(var/datum/reagents/holder) //check that all the required reagents are present if(!holder.has_all_reagents(required_reagents)) @@ -500,6 +501,15 @@ required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) result_amount = 2 +/datum/chemical_reaction/carpotoxin + name = "Carpotoxin" + id = "carpotoxin" + result = "carpotoxin" + required_reagents = list("spidertoxin" = 2, "biomass" = 1, "sifsap" = 2) + catalysts = list("sifsap" = 10) + inhibitors = list("radium" = 1) + result_amount = 2 + /datum/chemical_reaction/mindbreaker name = "Mindbreaker Toxin" id = "mindbreaker" @@ -2523,3 +2533,19 @@ result = "protein" required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2) result_amount = 2 + +/datum/chemical_reaction/neutralize_carpotoxin + name = "Neutralize Carpotoxin" + id = "carpotoxin_neutral" + result = "protein" + required_reagents = list("radium" = 1, "carpotoxin" = 1, "sifsap" = 1) + catalysts = list("sifsap" = 10) + result_amount = 2 + +/datum/chemical_reaction/neutralize_spidertoxin + name = "Neutralize Spidertoxin" + id = "spidertoxin_neutral" + result = "protein" + required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1) + catalysts = list("sifsap" = 10) + result_amount = 2 diff --git a/code/modules/reagents/distilling/Distilling-Recipes.dm b/code/modules/reagents/distilling/Distilling-Recipes.dm new file mode 100644 index 0000000000..f7fae18178 --- /dev/null +++ b/code/modules/reagents/distilling/Distilling-Recipes.dm @@ -0,0 +1,170 @@ +/datum/chemical_reaction/distilling +// name = null +// id = null +// result = null +// required_reagents = list() +// catalysts = list() +// inhibitors = list() +// result_amount = 0 + + //how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros. + reaction_rate = HALF_LIFE(6) + + //if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high. + //0.5 = 50% yield -> reaction will only proceed halfway until products are removed. +// yield = 1.0 + + //If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios), + //the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts. +// min_reaction = 2 + + mix_message = "The solution churns." + reaction_sound = 'sound/effects/slosh.ogg' + +// log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. + + var/list/temp_range = list(T0C, T20C) + var/temp_shift = 0 // How much the temperature changes when the reaction occurs. + +/datum/chemical_reaction/distilling/can_happen(var/datum/reagents/holder) + //check that all the required reagents are present + if(!holder.has_all_reagents(required_reagents)) + return 0 + + //check that all the required catalysts are present in the required amount + if(!holder.has_all_reagents(catalysts)) + return 0 + + //check that none of the inhibitors are present in the required amount + if(holder.has_any_reagent(inhibitors)) + return 0 + + if(!istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling)) + return 0 + + else // Super special temperature check. + var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom + var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master + if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2]) + return 0 + + return 1 + +/datum/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume) + if(istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling)) + var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom + var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master + RD.current_temp += temp_shift + return + +// Subtypes // + +// Biomass +/datum/chemical_reaction/distilling/biomass + name = "Distilling Biomass" + id = "distill_biomass" + result = "biomass" + required_reagents = list("blood" = 1, "sugar" = 1, "phoron" = 0.5) + result_amount = 1 // 40 units per sheet, requires actually using the machine, and having blood to spare. + + temp_range = list(T20C + 80, T20C + 130) + temp_shift = -2 + +// Medicinal +/datum/chemical_reaction/distilling/inaprovalaze + name = "Distilling Inaprovalaze" + id = "distill_inaprovalaze" + result = "inaprovalaze" + required_reagents = list("inaprovaline" = 2, "foaming_agent" = 1) + result_amount = 2 + + reaction_rate = HALF_LIFE(10) + + temp_range = list(T0C + 100, T0C + 120) + +/datum/chemical_reaction/distilling/bicaridaze + name = "Distilling Bicaridaze" + id = "distill_bicaridaze" + result = "bicaridaze" + required_reagents = list("bicaridine" = 2, "foaming_agent" = 1) + result_amount = 2 + + reaction_rate = HALF_LIFE(10) + + temp_range = list(T0C + 110, T0C + 130) + +/datum/chemical_reaction/distilling/dermalaze + name = "Distilling Dermalaze" + id = "distill_dermalaze" + result = "dermalaze" + required_reagents = list("dermaline" = 2, "foaming_agent" = 1) + result_amount = 2 + + reaction_rate = HALF_LIFE(10) + + temp_range = list(T0C + 115, T0C + 130) + +// Alcohol +/datum/chemical_reaction/distilling/beer + name = "Distilling Beer" + id = "distill_beer" + result = "beer" + required_reagents = list("nutriment" = 1, "water" = 1, "sugar" = 1) + result_amount = 2 + + reaction_rate = HALF_LIFE(30) + + temp_range = list(T20C, T20C + 2) + +/datum/chemical_reaction/distilling/ale + name = "Distilling Ale" + id = "distill_ale" + result = "ale" + required_reagents = list("nutriment" = 1, "beer" = 1) + inhibitors = list("water" = 1) + result_amount = 2 + + reaction_rate = HALF_LIFE(30) + + temp_shift = 0.5 + temp_range = list(T0C + 7, T0C + 13) + +// Unique +/datum/chemical_reaction/distilling/berserkjuice + name = "Distilling Brute Juice" + id = "distill_brutejuice" + result = "berserkmed" + required_reagents = list("biomass" = 1, "hyperzine" = 3, "synaptizine" = 2, "phoron" = 1) + result_amount = 3 + + temp_range = list(T0C + 600, T0C + 700) + temp_shift = 4 + +/datum/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume) + ..() + + if(prob(1)) + var/turf/T = get_turf(holder.my_atom) + explosion(T, -1, rand(-1, 1), rand(1,2), rand(3,5)) + return + +/datum/chemical_reaction/distilling/cryogel + name = "Distilling Cryogellatin" + id = "distill_cryoslurry" + result = "cryoslurry" + required_reagents = list("frostoil" = 7, "enzyme" = 3, "plasticide" = 3, "foaming_agent" = 2) + inhibitors = list("water" = 5) + result_amount = 1 + + temp_range = list(0, 15) + temp_shift = 20 + +/datum/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume) + ..() + + if(prob(1)) + var/turf/T = get_turf(holder.my_atom) + var/datum/effect/effect/system/smoke_spread/frost/F = new (holder.my_atom) + F.set_up(6, 0, T) + F.start() + return diff --git a/code/modules/reagents/distilling/distilling.dm b/code/modules/reagents/distilling/distilling.dm new file mode 100644 index 0000000000..b86bcc7435 --- /dev/null +++ b/code/modules/reagents/distilling/distilling.dm @@ -0,0 +1,317 @@ + +/* + * Distillery, used for over-time temperature-based mixes. + */ + +/obj/machinery/portable_atmospherics/powered/reagent_distillery + name = "chemical distillery" + desc = "A complex machine utilizing state-of-the-art components to mix chemicals at different temperatures." + use_power = 1 + + icon = 'icons/obj/machines/reagent.dmi' + icon_state = "distiller" + var/base_state // The string var used in update icon for overlays, either set manually or initialized. + + power_rating = 3000 + power_losses = 240 + + var/on = FALSE + + var/target_temp = T20C + + var/max_temp = T20C + 300 + var/min_temp = T0C - 10 + + var/current_temp = T20C + + var/use_atmos = FALSE // If true, this machine will be connectable to ports, and use gas mixtures as the source of heat, rather than its internal controls. + + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use") + + var/static/radial_pump = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pump") + + var/static/radial_eject_input = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_input") + var/static/radial_eject_output = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_output") + + var/static/radial_adjust_temp = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_temp") + + var/static/radial_install_input = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_add") + var/static/radial_install_output = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_add") + + var/static/radial_inspectgauges = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_lookat") + + var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") + +// Overlay holders so we don't have to constantly remake them. + var/image/overlay_output_beaker + var/image/overlay_input_beaker + var/image/overlay_off + var/image/overlay_ready + var/image/overlay_cooling + var/image/overlay_heating + var/image/overlay_dumping + var/image/overlay_connected + +// Our unique beaker, used in its unique recipes to ensure things can only react inside this machine and minimize oddities from trying to transfer to a machine and back. + var/obj/item/weapon/reagent_containers/glass/distilling/Reservoir + + var/obj/item/weapon/reagent_containers/glass/InputBeaker + var/obj/item/weapon/reagent_containers/glass/OutputBeaker + +// A multiplier for the production amount. This should really only ever be lower than one, otherwise you end up with duping. + var/efficiency = 1 + +/obj/item/weapon/reagent_containers/glass/distilling + name = "distilling chamber" + desc = "You should not be seeing this." + volume = 600 + + var/obj/machinery/portable_atmospherics/powered/reagent_distillery/Master + +/obj/item/weapon/reagent_containers/glass/distilling/Destroy() + Master = null + ..() + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/Initialize() + ..() + + Reservoir = new (src) + Reservoir.Master = src + + if(!base_state) + base_state = icon_state + + setup_overlay_vars() + + update_icon() + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/proc/setup_overlay_vars() + overlay_output_beaker = image(icon = src.icon, icon_state = "[base_state]-output") + overlay_input_beaker = image(icon = src.icon, icon_state = "[base_state]-input") + overlay_off = image(icon = src.icon, icon_state = "[base_state]-bad") + overlay_ready = image(icon = src.icon, icon_state = "[base_state]-good") + overlay_cooling = image(icon = src.icon, icon_state = "[base_state]-cool") + overlay_heating = image(icon = src.icon, icon_state = "[base_state]-heat") + overlay_dumping = image(icon = src.icon, icon_state = "[base_state]-dump") + overlay_connected = image(icon = src.icon, icon_state = "[base_state]-connector") + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/Destroy() + qdel(Reservoir) + Reservoir = null + if(InputBeaker) + qdel(InputBeaker) + InputBeaker = null + if(OutputBeaker) + qdel(OutputBeaker) + OutputBeaker = null + + ..() + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/attack_hand(mob/user) + var/list/options = list() + options["examine"] = radial_examine + options["use"] = radial_use + options["inspect gauges"] = radial_inspectgauges + options["pulse agitator"] = radial_mix + + if(InputBeaker) + options["eject input"] = radial_eject_input + if(OutputBeaker) + options["eject output"] = radial_eject_output + + if(!use_atmos) + options["adjust temp"] = radial_adjust_temp + + if(length(options) < 1) + return + + var/list/choice = list() + if(length(options) == 1) + for(var/key in options) + choice = key + else + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) + + switch(choice) + if("examine") + examine(user) + + if("use") + if(powered()) + on = !on + to_chat(user, "You turn \the [src] [on ? "on" : "off"].") + + if("inspect gauges") + to_chat(user, "\The [src]'s gauges read:") + if(!use_atmos) + to_chat(user, "- Target Temperature: [target_temp]") + to_chat(user, "- Temperature: [current_temp]") + + if("pulse agitator") + to_chat(user, "You press \the [src]'s chamber agitator button.") + if(on) + visible_message("\The [src] rattles to life.") + Reservoir.reagents.handle_reactions() + else + spawn(1 SECOND) + to_chat(user, "Nothing happens..") + + if("eject input") + if(InputBeaker) + InputBeaker.forceMove(get_turf(src)) + InputBeaker = null + + if("eject output") + if(OutputBeaker) + OutputBeaker.forceMove(get_turf(src)) + OutputBeaker = null + + if("adjust temp") + target_temp = input("Choose a target temperature.", "Temperature.", T20C) as num + target_temp = CLAMP(target_temp, min_temp, max_temp) + + update_icon() + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/attackby(obj/item/weapon/W as obj, mob/user as mob) + var/list/options = list() + if(istype(W, /obj/item/weapon/reagent_containers/glass)) + if(!InputBeaker) + options["install input"] = radial_install_input + if(!OutputBeaker) + options["install output"] = radial_install_output + + if(!options || !options.len) + update_icon() + return ..() + + var/list/choice = list() + if(length(options) == 1) + for(var/key in options) + choice = key + else + choice = show_radial_menu(user, src, options, require_near = TRUE) // No telekinetics. + + switch(choice) + if("install input") + if(!InputBeaker) + user.drop_from_inventory(W) + W.add_fingerprint(user) + W.forceMove(src) + InputBeaker = W + + if("install output") + if(!OutputBeaker) + user.drop_from_inventory(W) + W.add_fingerprint(user) + W.forceMove(src) + OutputBeaker = W + + update_icon() + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/use_power(var/amount, var/chan = -1) + last_power_draw = amount + if(use_cell && cell && cell.charge) + var/cellcharge = cell.charge + cell.use(amount) + + var/celldifference = max(0, cellcharge - cell.charge) + + amount = celldifference + + var/area/A = get_area(src) + if(!A || !isarea(A)) + return + if(chan == -1) + chan = power_channel + A.use_power(amount, chan) + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/process() + ..() + + var/run_pump = FALSE + + if(InputBeaker || OutputBeaker) + run_pump = TRUE + + var/avg_temp = 0 + var/avg_pressure = 0 + + if(connected_port && connected_port.network.line_members.len) + var/list/members = list() + var/datum/pipe_network/Net = connected_port.network + members = Net.line_members.Copy() + + for(var/datum/pipeline/Line in members) + avg_pressure += Line.air.return_pressure() + avg_temp += Line.air.temperature + + avg_temp /= members.len + avg_pressure /= members.len + + if(!powered()) + on = FALSE + + if(!on || (use_atmos && (!connected_port || avg_pressure < 1000))) + current_temp = round((current_temp + T20C) / 2) + + else if(on) + if(!use_atmos) + if(current_temp != round(target_temp)) + var/shift_mod = 0 + if(current_temp < target_temp) + shift_mod = 1 + else if(current_temp > target_temp) + shift_mod = -1 + current_temp = CLAMP(round((current_temp + 1 * shift_mod) + (rand(-5, 5) / 10)), min_temp, max_temp) + use_power(power_rating * CELLRATE) + else if(connected_port && avg_pressure > 1000) + current_temp = round((current_temp + avg_temp) / 2) + else if(!run_pump) + visible_message("\The [src]'s motors wind down.") + on = FALSE + + if(InputBeaker && Reservoir.reagents.total_volume < Reservoir.reagents.maximum_volume) + InputBeaker.reagents.trans_to_holder(Reservoir.reagents, amount = rand(10,20)) + + if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume) + use_power(power_rating * CELLRATE * 0.5) + Reservoir.reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5)) + + update_icon() + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/update_icon() + ..() + cut_overlays() + + if(InputBeaker) + add_overlay(overlay_input_beaker) + + if(OutputBeaker) + add_overlay(overlay_output_beaker) + + if(on) + if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume) + add_overlay(overlay_dumping) + else if(current_temp == round(target_temp)) + add_overlay(overlay_ready) + else if(current_temp < target_temp) + add_overlay(overlay_heating) + else + add_overlay(overlay_cooling) + + else + add_overlay(overlay_off) + + if(connected_port) + add_overlay(overlay_connected) + +/* + * Subtypes + */ + +/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial + name = "industrial chemical distillery" + desc = "A gas-operated variant of a chemical distillery. Able to reach much higher, and lower, temperatures through the use of treated gas." + + use_atmos = TRUE diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 92e01c8ede..3c9fdcba6f 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -44,7 +44,8 @@ /obj/machinery/smartfridge/, /obj/machinery/biogenerator, /obj/structure/frame, - /obj/machinery/radiocarbon_spectrometer + /obj/machinery/radiocarbon_spectrometer, + /obj/machinery/portable_atmospherics/powered/reagent_distillery ) /obj/item/weapon/reagent_containers/glass/Initialize() diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm new file mode 100644 index 0000000000..007669286e --- /dev/null +++ b/code/modules/reagents/reagent_containers/patch.dm @@ -0,0 +1,82 @@ + +/* + * Patches. A subtype of pills, in order to inherit the possible future produceability within chem-masters, and dissolving. + */ + +/obj/item/weapon/reagent_containers/pill/patch + name = "patch" + desc = "A patch." + icon = 'icons/obj/chemical.dmi' + icon_state = null + item_state = "pill" + + base_state = "patch" + + possible_transfer_amounts = null + w_class = ITEMSIZE_TINY + slot_flags = SLOT_EARS + volume = 60 + + var/pierce_material = FALSE // If true, the patch can be used through thick material. + +/obj/item/weapon/reagent_containers/pill/patch/attack(mob/M as mob, mob/user as mob) + var/mob/living/L = user + + if(M == L) + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting)) + if(!affecting) + to_chat(user, "The limb is missing!") + return + if(affecting.status >= ORGAN_ROBOT) + to_chat(user, "\The [src] won't work on a robotic limb!") + return + + if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material)) + to_chat(user, "\The [src] can't be applied through such a thick material!") + return + + to_chat(H, "\The [src] is placed on your [affecting].") + M.drop_from_inventory(src) //icon update + if(reagents.total_volume) + reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH) + qdel(src) + return 1 + + else if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting)) + if(!affecting) + to_chat(user, "The limb is missing!") + return + if(affecting.status >= ORGAN_ROBOT) + to_chat(user, "\The [src] won't work on a robotic limb!") + return + + if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material)) + to_chat(user, "\The [src] can't be applied through such a thick material!") + return + + user.visible_message("[user] attempts to place \the [src] onto [H]`s [affecting].") + + user.setClickCooldown(user.get_attack_speed(src)) + if(!do_mob(user, M)) + return + + user.drop_from_inventory(src) //icon update + user.visible_message("[user] applies \the [src] to [H].") + + var/contained = reagentlist() + add_attack_logs(user,M,"Applied a patch containing [contained]") + + to_chat(H, "\The [src] is placed on your [affecting].") + M.drop_from_inventory(src) //icon update + + if(reagents.total_volume) + reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH) + qdel(src) + + return 1 + + return 0 \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index c0b647e53b..5ca47a6d3b 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -7,6 +7,9 @@ icon = 'icons/obj/chemical.dmi' icon_state = null item_state = "pill" + + var/base_state = "pill" + possible_transfer_amounts = null w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS @@ -15,7 +18,7 @@ /obj/item/weapon/reagent_containers/pill/Initialize() . = ..() if(!icon_state) - icon_state = "pill[rand(1, 4)]" //preset pills only use colour changing or unique icons + icon_state = "[base_state][rand(1, 4)]" //preset pills only use colour changing or unique icons /obj/item/weapon/reagent_containers/pill/attack(mob/M as mob, mob/user as mob) if(M == user) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index b60b71cc4e..69b9937158 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -1,7 +1,7 @@ /obj/structure/bigDelivery desc = "A big wrapped package." name = "large parcel" - icon = 'icons/obj/storage.dmi' + icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit icon_state = "deliverycloset" var/obj/wrapped = null density = 1 @@ -109,7 +109,7 @@ /obj/item/smallDelivery desc = "A small wrapped package." name = "small parcel" - icon = 'icons/obj/storage.dmi' + icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit icon_state = "deliverycrate3" var/obj/item/wrapped = null var/sortTag = null diff --git a/code/modules/research/designs/illegal.dm b/code/modules/research/designs/illegal.dm index 4e99fc8665..f0a50fa5dd 100644 --- a/code/modules/research/designs/illegal.dm +++ b/code/modules/research/designs/illegal.dm @@ -25,3 +25,11 @@ materials = list(MAT_PLASTEEL = 3500, "glass" = 1000, MAT_LEAD = 2250, MAT_METALHYDROGEN = 500) build_path = /obj/item/weapon/melee/energy/sword/charge sort_string = "VASCA" + +/datum/design/item/weapon/eaxe + name = "Energy Axe" + id = "chargeaxe" + req_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 5, TECH_ENGINEERING = 4, TECH_ILLEGAL = 4) + materials = list(MAT_PLASTEEL = 3500, MAT_OSMIUM = 2000, MAT_LEAD = 2000, MAT_METALHYDROGEN = 500) + build_path = /obj/item/weapon/melee/energy/axe/charge + sort_string = "VASCB" diff --git a/code/modules/research/designs/mining_toys.dm b/code/modules/research/designs/mining_toys.dm index f9b76032cb..c170cb827b 100644 --- a/code/modules/research/designs/mining_toys.dm +++ b/code/modules/research/designs/mining_toys.dm @@ -45,4 +45,12 @@ req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2) materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 1000) build_path = /obj/item/device/depth_scanner - sort_string = "KAAAF" \ No newline at end of file + sort_string = "KAAAF" + +/datum/design/item/device/graviton_visor + desc = "Used to see via the complex interation of meson particles and graviton particles." + id = "graviton_goggles" + req_tech = list(TECH_MAGNET = 5, TECH_ENGINEERING = 3, TECH_BLUESPACE = 3, TECH_PHORON = 3) + materials = list(MAT_PLASTEEL = 2000, "glass" = 3000, MAT_PHORON = 1500) + build_path = /obj/item/clothing/glasses/graviton + sort_string = "KAAAG" diff --git a/code/modules/research/designs/precursor.dm b/code/modules/research/designs/precursor.dm index eaf7b3a923..bcf80b66a0 100644 --- a/code/modules/research/designs/precursor.dm +++ b/code/modules/research/designs/precursor.dm @@ -77,3 +77,12 @@ var/obj/item/I = build_path desc = initial(I.desc) ..() + +/datum/design/item/anomaly/camotrap + name = "Chameleon Trap" + desc = "A self-miraging mechanical trap, capable of producing short bursts of electric current when triggered." + id = "hunt_trap" + materials = list(MAT_DURASTEEL = 3000, MAT_METALHYDROGEN = 1000, MAT_PHORON = 2000) + req_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 2) + build_path = /obj/item/weapon/beartrap/hunting + sort_string = "ARCAT" diff --git a/code/modules/tables/presets.dm b/code/modules/tables/presets.dm index 5d568d440e..085489b26a 100644 --- a/code/modules/tables/presets.dm +++ b/code/modules/tables/presets.dm @@ -58,6 +58,23 @@ material = get_material_by_name("wood") ..() +/obj/structure/table/sifwoodentable + icon_state = "plain_preview" + color = "#824B28" + +/obj/structure/table/sifwoodentable/New() + material = get_material_by_name("alien wood") + ..() + +/obj/structure/table/sifwooden_reinforced + icon_state = "reinf_preview" + color = "#824B28" + +/obj/structure/table/sifwooden_reinforced/New() + material = get_material_by_name("alien wood") + reinforced = get_material_by_name(DEFAULT_WALL_MATERIAL) + ..() + /obj/structure/table/gamblingtable icon_state = "gamble_preview" @@ -177,6 +194,18 @@ material = get_material_by_name("wood") ..() +/obj/structure/table/bench/sifwooden + icon_state = "plain_preview" + color = "#824B28" + +/obj/structure/table/bench/sifwooden/New() + material = get_material_by_name("alien wood") + ..() + +/obj/structure/table/bench/sifwooden/padded + icon_state = "padded_preview" + carpeted = 1 + /obj/structure/table/bench/padded icon_state = "padded_preview" diff --git a/code/modules/tension/tension.dm b/code/modules/tension/tension.dm index 82151a7e78..841d691037 100644 --- a/code/modules/tension/tension.dm +++ b/code/modules/tension/tension.dm @@ -69,7 +69,7 @@ var/friendly = threatened.faction == faction - var/threat = guess_threat_level() + var/threat = guess_threat_level(threatened) // Hurt entities contribute less tension. threat *= health @@ -99,7 +99,120 @@ return threat +// Carbon / mostly Human threat check. +/mob/living/carbon/get_threat(var/mob/living/threatened) + . = ..() + if(has_AI()) + if(!ai_holder.hostile) + return 0 + + if(incapacitated(INCAPACITATION_DISABLED)) + return 0 + + var/friendly = (IIsAlly(threatened) && a_intent == I_HELP) + + var/threat = guess_threat_level(threatened) + + threat *= health + threat /= getMaxHealth() + + // Allies reduce tension instead of adding. + if(friendly) + threat = -threat + + else + if(threatened.invisibility > see_invisible) + threat /= 2 // Target cannot be seen by src. + if(invisibility > threatened.see_invisible) + threat *= 2 // Target cannot see src. + + // Handle statuses. + if(confused) + threat /= 2 + + if(has_modifier_of_type(/datum/modifier/berserk)) + threat *= 2 + + return threat + +/mob/living/carbon/guess_threat_level(var/mob/living/threatened) + var/threat_guess = 0 + + // First lets consider their attack ability. + var/will_point_blank = FALSE + if(has_AI()) + will_point_blank = ai_holder.pointblank + + . = ..() + + var/obj/item/I = get_active_hand() + if(!I || !istype(I)) + var/damage_guess = 0 + if(ishuman(src) && ishuman(threatened)) + var/mob/living/carbon/human/H = src + var/datum/unarmed_attack/attack = H.get_unarmed_attack(threatened, BP_TORSO) + if(!attack) + damage_guess += 5 + + var/punch_damage = attack.get_unarmed_damage(H) + if(H.gloves) + if(istype(H.gloves, /obj/item/clothing/gloves)) + var/obj/item/clothing/gloves/G = H.gloves + punch_damage += G.punch_force + + damage_guess += punch_damage + + else + damage_guess += 5 + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.outgoing_melee_damage_percent)) + damage_guess *= M.outgoing_melee_damage_percent + + threat_guess += damage_guess + + else + var/weapon_attack_speed = get_attack_speed(I) / (1 SECOND) + var/weapon_damage = I.force + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.outgoing_melee_damage_percent)) + weapon_damage *= M.outgoing_melee_damage_percent + + if(istype(I, /obj/item/weapon/gun)) + will_point_blank = TRUE + var/obj/item/weapon/gun/G = I + var/obj/item/projectile/P + + P = new G.projectile_type() + + if(P) // Does the gun even have a projectile type? + weapon_damage = P.damage + if(will_point_blank && a_intent == I_HURT) + weapon_damage *= 1.5 + weapon_attack_speed = G.fire_delay / (1 SECOND) + qdel(P) + + var/average_damage = weapon_damage / weapon_attack_speed + + threat_guess += average_damage + + // Consider intent. + switch(a_intent) + if(I_HELP) // Not likely to fight us. + threat_guess *= 0.4 + if(I_DISARM) // Might engage us, but unlikely to be with the intent to kill. + threat_guess *= 0.8 + if(I_GRAB) // May try to restrain us. This is here for reference, or later tweaking if needed. + threat_guess *= 1 + if(I_HURT) // May try to hurt us. + threat_guess *= 1.25 + + // Then consider their defense. + threat_guess += getMaxHealth() / 5 // 100 health translates to 20 threat. + + return threat_guess // Gives a rough idea of how much danger someone is in. Meant to be used for PvE things since PvP has too many unknown variables. /mob/living/proc/get_tension() diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index 45cbcd7a13..46e838d37a 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -1,7 +1,7 @@ /obj/vehicle/train/engine name = "cargo train tug" desc = "A ridable electric car designed for pulling cargo trolleys." - icon = 'icons/obj/vehicles.dmi' + icon = 'icons/obj/vehicles_vr.dmi' //VOREStation Edit icon_state = "cargo_engine" on = 0 powered = 1 @@ -26,7 +26,7 @@ /obj/vehicle/train/trolley name = "cargo train trolley" - icon = 'icons/obj/vehicles.dmi' + icon = 'icons/obj/vehicles_vr.dmi' //VOREStation Edit icon_state = "cargo_trailer" anchored = 0 passenger_allowed = 0 @@ -34,7 +34,7 @@ load_item_visible = 1 load_offset_x = 0 - load_offset_y = 4 + load_offset_y = 7 //VOREStation Edit mob_offset_y = 8 //------------------------------------------- @@ -44,7 +44,7 @@ ..() cell = new /obj/item/weapon/cell/high(src) key = new key_type(src) - var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs + var/image/I = new(icon = 'icons/obj/vehicles_vr.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs //VOREStation edit overlays += I turn_off() //so engine verbs are correctly set @@ -374,3 +374,17 @@ anchored = 0 else anchored = 1 + +// VOREStation Edit Start - Overlay stuff for the chair-like effect +/obj/vehicle/train/engine/update_icon() + ..() + overlays = null + var/image/O = image(icon = 'icons/obj/vehicles_vr.dmi', icon_state = "cargo_engine_overlay", dir = src.dir) + O.layer = FLY_LAYER + O.plane = MOB_PLANE + overlays += O + +/obj/vehicle/train/engine/set_dir() + ..() + update_icon() +// VOREStation Edit End - Overlay stuff for the chair-like effect diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm index 301d0841be..04e0baeaf8 100644 --- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm @@ -153,6 +153,9 @@ //Messages for smalls moving under larges var/msg_owner_stepunder = "%owner runs between your legs." //Weird becuase in the case this is used, %owner is the 'bumper' (src) var/msg_prey_stepunder = "You run between %prey's legs." //Same, inverse + hide_body_parts = list(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) //Exclude pelvis just in case. + clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi' + clip_mask_state = "taur_clip_mask_def" //Used to clip off the lower part of suits & uniforms. /datum/sprite_accessory/tail/taur/roiz_long_lizard // Not ACTUALLY a taur, but it uses 32x64 so it wouldn't fit in tails.dmi, and having it as a tail bugs up the sprite. name = "Long Lizard Tail (Roiz Lizden)" @@ -438,6 +441,7 @@ ckeys_allowed = list("natje") do_colouration = 0 can_ride = 0 + clip_mask_state = "taur_clip_mask_alraune" msg_prey_stepunder = "You run between %prey's vines." @@ -468,4 +472,26 @@ ckeys_allowed = null do_colouration = 1 extra_overlay = "alraunecolor_markings" - extra_overlay_w = "alraunecolor_closed_markings" \ No newline at end of file + extra_overlay_w = "alraunecolor_closed_markings" + clip_mask_state = "taur_clip_mask_alraune" + +/datum/sprite_accessory/tail/taur/wasp + name = "Wasp (dual color)" + icon_state = "wasp_s" + extra_overlay = "wasp_markings" + clip_mask_state = "taur_clip_mask_wasp" + + msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!" + msg_prey_disarm_run = "%owner pushes you down to the ground with their leg!" + + msg_owner_disarm_walk = "You firmly push your leg down on %prey, painfully but harmlessly pinning them to the ground!" + msg_prey_disarm_walk = "%owner firmly pushes their leg down on you, quite painfully but harmlessly pinning you to the ground!" + + msg_owner_harm_walk = "You methodically place your leg down upon %prey's body, slowly applying pressure, crushing them against the floor!" + msg_prey_harm_walk = "%owner methodically places their leg upon your body, slowly applying pressure, crushing you against the floor!" + + msg_owner_grab_success = "You pin %prey down on the ground with your front leg before using your other leg to pick them up, trapping them between two of your front legs!" + msg_prey_grab_success = "%owner pins you down on the ground with their front leg before using their other leg to pick you up, trapping you between two of their front legs!" + + msg_owner_grab_fail = "You step down onto %prey, squishing them and forcing them down to the ground!" + msg_prey_grab_fail = "%owner steps down and squishes you with their leg, forcing you down to the ground!" diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm index 50b8d763a2..89f5e9c746 100644 --- a/code/modules/vore/appearance/sprite_accessories_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_vr.dm @@ -653,6 +653,9 @@ var/desc = "You should not see this..." var/ani_state // State when wagging/animated var/extra_overlay_w // Wagging state for extra overlay + var/list/hide_body_parts = list() //Uses organ tag defines. Bodyparts in this list do not have their icons rendered, allowing for more spriter freedom when doing taur/digitigrade stuff. + var/icon/clip_mask_icon = null //Icon file used for clip mask. + var/clip_mask_state = null //Icon state to generate clip mask. Clip mask is used to 'clip' off the lower part of clothing such as jumpsuits & full suits. /datum/sprite_accessory/tail/invisible name = "hide species-sprite tail" @@ -950,6 +953,9 @@ icon_state = "satyr" color_blend_mode = ICON_MULTIPLY do_colouration = 1 + hide_body_parts = list(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) //Exclude pelvis just in case. + clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi' + clip_mask_state = "taur_mask_def" //Used to clip off the lower part of suits & uniforms. /datum/sprite_accessory/tail/tailmaw name = "tailmaw, colorable" diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index 0751209f12..da0133d719 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -2006,4 +2006,23 @@ /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask/fluff/viktor/Initialize() ..() - reagents.add_reagent("pwine", 60) \ No newline at end of file + reagents.add_reagent("pwine", 60) + +//RadiantAurora: Tiemli Kroto +/obj/item/clothing/glasses/welding/tiemgogs + name = "custom-fitted welding goggles" + desc = "A pair of thick, custom-fitted goggles with LEDs above the lenses. Ruggedly engraved below the lenses is the name 'Tiemli Kroto'." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "tiemgogs" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "tiemgogs" + +/obj/item/clothing/glasses/welding/tiemgogs/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) + if(..()) + if(H.ckey != "radiantaurora") + to_chat(H, "These don't look like they were made to fit you...") + return 0 + else + return 1 diff --git a/code/modules/xenoarcheaology/finds/find_spawning.dm b/code/modules/xenoarcheaology/finds/find_spawning.dm index 2c04d491d0..be86279b08 100644 --- a/code/modules/xenoarcheaology/finds/find_spawning.dm +++ b/code/modules/xenoarcheaology/finds/find_spawning.dm @@ -511,6 +511,16 @@ desc = new_item.desc item_type = new_item.name + if(39) + // Telecube. + if(prob(25)) + apply_prefix = FALSE + if(prob(75)) + apply_image_decorations = TRUE + if(prob(25)) + apply_material_decorations = FALSE + new_item = new /obj/item/weapon/telecube/randomized(src.loc) + if(istype(new_item, /obj/item/weapon/material)) var/new_item_mat = pickweight( DEFAULT_WALL_MATERIAL = 80, diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index 90c4941b59..833eee4b94 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -3,6 +3,7 @@ some~user - Species 911earlyarther - Xenomorph Hybrid admiraldragon - Vox aether_elemental - Daemon +A Random Alien - Xenochimera arokha - Protean aruis - Diona aruis - Xenochimera @@ -12,6 +13,7 @@ bothnevarbackwards - Diona cameron653 - Xenomorph Hybrid funnyman2003 - Xenochimera hawkerthegreat - Vox +hollifex - Diona inuzari - Diona jademanique - Xenochimera jemli - Gutter diff --git a/html/changelogs/Mechoid - ExplorerExpansion.yml b/html/changelogs/Mechoid - ExplorerExpansion.yml new file mode 100644 index 0000000000..25c5488d00 --- /dev/null +++ b/html/changelogs/Mechoid - ExplorerExpansion.yml @@ -0,0 +1,56 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Mechoid + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Exosuits are now targetted by turrets again." + - tweak: "Mining charge strength lowered, price increased. Can be upgraded through R&D laser components." + - rscadd: "Searing damage type added. Energy axe now uses searing damage." + - rscadd: "Survey points added. Vendor added for explorer use. Costs are universally 'lower' compared to the mining vendor due to the rarity of points." + - rscadd: "Swiping an ID card on a cataloguer will transfer the points to the card." + - tweak: "Any melee energy weapon can now be made to use a cell and charge." + - rscadd: "Energy Axe prototype added to R&D." + - rscadd: "Anomalous 'hunting trap' added to R&D. Useful for an initial stun on mobs for explorer scanning." + - tweak: "Beartraps now stun for a quarter of a second, so they are actually useful again, due to resistability." + - rscadd: "Emergency welding pack added. Incredibly slow, but requires no protection." + - rscadd: "Random turf modifier added for mapping use. Random humanoid remains spawner added for mapping use." + - rscadd: "Plants under obj/structure/flora now can be made to be harvestable / forage-able." + - rscadd: "Sif trees now occasionally have fruit containing useful microbes. Microbes slow blood flow resulting in slower chemical absorption and blood loss." + - tweak: "Flora by default are now under mobs, on the same layer as turf decals. Flora can now also randomize their size, previously only codified in Sivian trees." + - rscadd: "Moss tendrils added to Sif, making eye-plants more rare." + - rscadd: "Multiple PoIs added. 'Blue shuttle down' variant, 'UFO Frigate', multiple geysers, cliffs, and two variants of SFR which take drastically different approaches to the SFR standard. A vault was added, too." + - tweak: "Vault PoIs are now in a template group." + - rscadd: "Generic AI-controlled humanoids added. Subtype made for use on Sif, clad in weak armor and temperature resistance, used as 'mindless clones'." + - rscadd: "More artifice added." + - tweak: "Fultons made to be [somewhat] sane. Now only useable planetside." + - tweak: "Graviton Visor moved to R&D from the mining equipment vendor. Silver and Diamond pickaxes removed." diff --git a/html/changelogs/Mechoid - Promethean Organs.yml b/html/changelogs/Mechoid - Promethean Organs.yml new file mode 100644 index 0000000000..c579478d5a --- /dev/null +++ b/html/changelogs/Mechoid - Promethean Organs.yml @@ -0,0 +1,40 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Mechoid + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added multiple new organs for Prometheans. Removing them will cause them to take large amounts of Toxloss untill they are Regenerated using the active regeneration verb." + - rscadd: "Organ: pneumatic network, a series of skeletal tubes with high pressure used to move nutrients and waste." + - rscadd: "Organs: -regenesis systems, different 'networks' of clumped cellular matter that allow Prometheans to recover rapidly from small injuries. Large or numerous injuries cause un-needed stress, and pain." + - bugfix: "Internal organs now properly add themselves to the internal organ-by-name list, the one referenced 99.9% of the time." + - tweak: "Active regeneration will now replace internal organs if they are nonexistant, as it does for limbs." diff --git a/html/changelogs/Nalarac - Turret Shooting Downed People.yml b/html/changelogs/Nalarac - Turret Shooting Downed People.yml new file mode 100644 index 0000000000..f950bbe9a1 --- /dev/null +++ b/html/changelogs/Nalarac - Turret Shooting Downed People.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Nalarac + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added setting for turrets to fire upon downed/laying targets." diff --git a/html/changelogs/Woodrat - Uniform Fix.yml b/html/changelogs/Woodrat - Uniform Fix.yml new file mode 100644 index 0000000000..e3bdaa68e9 --- /dev/null +++ b/html/changelogs/Woodrat - Uniform Fix.yml @@ -0,0 +1,38 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Woodrat + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Made the solgov uniforms use accessories for denoting department instead of having several different sprites in the uniform dmi folder." + - tweak: "Removed redundant solgov uniforms from uniform.dmi and moved the sprites for the solgov uniforms to their own dmi." + - bugfix: "Fixed storage vests and drop pouches disappearing when one rolls down a uniform." \ No newline at end of file diff --git a/html/create_object.html b/html/create_object.html index f4e0aa8644..7ed93d9818 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -26,6 +26,7 @@
+ Type
Offset: @@ -35,7 +36,7 @@ Number: Dir: - Name:
+ Name:
Where:

-
+ Number of matches:
+

+ +
+ +
+ +