diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index bf8f5129f5..0425c3fa63 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -16,6 +16,8 @@ #define LIGHTING_SOFT_THRESHOLD 0.05 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. This also should be the transparancy of the "soft_dark" icon state. +#define LIGHTING_MULT_FACTOR 0.5 + // If I were you I'd leave this alone. #define LIGHTING_BASE_MATRIX \ list \ @@ -77,7 +79,7 @@ //Lighting values used by the station lights #define LIGHT_COLOR_FLUORESCENT_TUBE "#E0EFFF" #define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF" -#define LIGHT_COLOR_INCANDESCENT_TUBE "#FFEEDD" +#define LIGHT_COLOR_INCANDESCENT_TUBE "#FFFEB8" #define LIGHT_COLOR_INCANDESCENT_BULB "#FFDDBB" #define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66" diff --git a/code/__defines/lighting_vr.dm b/code/__defines/lighting_vr.dm new file mode 100644 index 0000000000..0cd6b060a1 --- /dev/null +++ b/code/__defines/lighting_vr.dm @@ -0,0 +1,2 @@ +#define LIGHT_COLOR_INCANDESCENT_TUBE "#E0EFF0" +#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8" \ No newline at end of file diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index e59d3765dc..2dc4afe70a 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -355,4 +355,4 @@ var/global/list/##LIST_NAME = list();\ //https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity #define MOUSE_OPACITY_TRANSPARENT 0 #define MOUSE_OPACITY_ICON 1 -#define MOUSE_OPACITY_OPAQUE 2 +#define MOUSE_OPACITY_OPAQUE 2 diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm index 4adeb85760..a049a4456c 100644 --- a/code/datums/autolathe/autolathe.dm +++ b/code/datums/autolathe/autolathe.dm @@ -6,7 +6,8 @@ var/datum/category_collection/autolathe/autolathe_recipes if(I.matter && !resources) resources = list() for(var/material in I.matter) - resources[material] = I.matter[material]*1.25 // More expensive to produce than they are to recycle. + var/coeff = (no_scale ? 1 : 1.25) //most objects are more expensive to produce than to recycle + resources[material] = I.matter[material]*coeff // but if it's a sheet or RCD cartridge, it's 1:1 if(is_stack && istype(I, /obj/item/stack)) var/obj/item/stack/IS = I max_stack = IS.max_amount @@ -66,6 +67,7 @@ var/datum/category_collection/autolathe/autolathe_recipes var/power_use = 0 var/is_stack var/max_stack + var/no_scale /datum/category_item/autolathe/dd_SortValue() return name \ No newline at end of file diff --git a/code/datums/autolathe/engineering.dm b/code/datums/autolathe/engineering.dm index ca40b4a6a9..fd907ba5f8 100644 --- a/code/datums/autolathe/engineering.dm +++ b/code/datums/autolathe/engineering.dm @@ -93,6 +93,7 @@ /datum/category_item/autolathe/engineering/rcd_ammo name = "matter cartridge" path =/obj/item/weapon/rcd_ammo + no_scale = TRUE //prevents material duplication exploits /datum/category_item/autolathe/engineering/rcd name = "rapid construction device" diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm index f354583318..2e2fa3c6fb 100644 --- a/code/datums/autolathe/general.dm +++ b/code/datums/autolathe/general.dm @@ -73,22 +73,26 @@ /datum/category_item/autolathe/general/metal name = "steel sheets" path =/obj/item/stack/material/steel - is_stack = 1 + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits /datum/category_item/autolathe/general/glass name = "glass sheets" path =/obj/item/stack/material/glass - is_stack = 1 + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits /datum/category_item/autolathe/general/rglass name = "reinforced glass sheets" path =/obj/item/stack/material/glass/reinforced - is_stack = 1 + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits /datum/category_item/autolathe/general/rods name = "metal rods" path =/obj/item/stack/rods - is_stack = 1 + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits /datum/category_item/autolathe/general/knife name = "kitchen knife" diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 541ba77194..089a6be722 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -205,7 +205,7 @@ if(telemob.can_be_drop_prey && telenommer.can_be_drop_pred) return 1 obstructed = 1 - else if(!isturf(destination.loc) || !destination.x || !destination.y || !destination.z) //If we're inside something or outside universe + else if(!((isturf(destination) && !destination.density) || (isturf(destination.loc) && !destination.loc.density)) || !destination.x || !destination.y || !destination.z) //If we're inside something or outside universe obstructed = 1 to_chat(teleatom, "Something is blocking way on the other side!") if(obstructed) diff --git a/code/datums/riding.dm b/code/datums/riding.dm index 746cc6dcf7..4f9513397a 100644 --- a/code/datums/riding.dm +++ b/code/datums/riding.dm @@ -101,7 +101,7 @@ if(keycheck(user)) if(!Process_Spacemove(direction) || !isturf(ridden.loc)) return - step(ridden, direction) + ridden.Move(get_step(ridden, direction)) handle_vehicle_layer() handle_vehicle_offsets() diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm index 555df731c4..5596d95f03 100644 --- a/code/datums/supplypacks/medical.dm +++ b/code/datums/supplypacks/medical.dm @@ -62,7 +62,7 @@ /obj/item/weapon/surgical/circular_saw ) cost = 25 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Surgery crate" access = access_medical @@ -73,7 +73,7 @@ /obj/item/weapon/storage/box/cdeathalarm_kit ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Death Alarm crate" access = access_medical @@ -83,7 +83,7 @@ /obj/item/weapon/storage/firstaid/clotting ) cost = 100 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Clotting Medicine crate" access = access_medical @@ -97,7 +97,7 @@ /obj/item/weapon/storage/belt/medical = 3 ) cost = 10 - containertype = "/obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Sterile equipment crate" /datum/supply_pack/med/extragear @@ -109,7 +109,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3 ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical surplus equipment" access = access_medical @@ -133,7 +133,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Chief medical officer equipment" access = access_cmo @@ -156,7 +156,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical Doctor equipment" access = access_medical_equip @@ -179,7 +179,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Chemist equipment" access = access_chemistry @@ -207,7 +207,7 @@ /obj/item/clothing/accessory/storage/white_vest ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Paramedic equipment" access = access_medical_equip @@ -226,7 +226,7 @@ /obj/item/weapon/cartridge/medical ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Psychiatrist equipment" access = access_psychiatrist @@ -247,7 +247,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical scrubs crate" access = access_medical_equip @@ -264,7 +264,7 @@ /obj/item/weapon/pen ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Autopsy equipment crate" access = access_morgue @@ -291,7 +291,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical uniform crate" access = access_medical_equip @@ -309,7 +309,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical biohazard equipment" access = access_medical_equip @@ -317,7 +317,7 @@ name = "Portable freezers crate" contains = list(/obj/item/weapon/storage/box/freezer = 7) cost = 25 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Portable freezers" access = access_medical_equip @@ -325,7 +325,7 @@ name = "Virus sample crate" contains = list(/obj/item/weapon/virusdish/random = 4) cost = 25 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Virus sample crate" access = access_cmo diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm index 5a080c5e9f..344e2bbdbd 100644 --- a/code/datums/supplypacks/medical_vr.dm +++ b/code/datums/supplypacks/medical_vr.dm @@ -25,7 +25,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Virology biohazard equipment" access = access_medical_equip @@ -33,6 +33,6 @@ name = "Virus sample crate" contains = list(/obj/item/weapon/virusdish/random = 4) cost = 25 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Virus sample crate" access = access_medical_equip \ No newline at end of file diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm index c4cd4992c1..b77d442e82 100644 --- a/code/datums/supplypacks/misc.dm +++ b/code/datums/supplypacks/misc.dm @@ -103,7 +103,7 @@ /obj/item/weapon/storage/fancy/candle_box = 3 ) cost = 10 - containertype = "/obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Chaplain equipment crate" /datum/supply_pack/misc/hoverpod @@ -126,7 +126,7 @@ /obj/item/clothing/accessory/storage/webbing ) cost = 10 - containertype = "/obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Webbing crate" /datum/supply_pack/misc/holoplant @@ -142,5 +142,5 @@ /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5 ) cost = 25 - containertype = "obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Glucose Hypo Crate" \ No newline at end of file diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index 7059e43755..9c12c17a14 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -55,7 +55,7 @@ /obj/item/weapon/wrapping_paper = 3 ) cost = 10 - containertype = "/obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Arts and Crafts crate" /datum/supply_pack/recreation/painters diff --git a/code/datums/supplypacks/recreation_vr.dm b/code/datums/supplypacks/recreation_vr.dm index c4d7ee0ccc..2e61f93473 100644 --- a/code/datums/supplypacks/recreation_vr.dm +++ b/code/datums/supplypacks/recreation_vr.dm @@ -40,11 +40,11 @@ containertype = /obj/structure/closet/crate containername = "wolfgirl cosplay crate" -/datum/supply_pack/randomised/recreation/figures_vr +/datum/supply_pack/randomised/recreation/figures name = "Action figures crate" num_contained = 5 contains = list( - /obj/random/action_figure + /obj/random/action_figure/supplypack ) cost = 200 containertype = /obj/structure/closet/crate diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm index 83407c2866..ab55b8571e 100644 --- a/code/datums/supplypacks/science.dm +++ b/code/datums/supplypacks/science.dm @@ -56,3 +56,25 @@ cost = 30 containertype = /obj/structure/closet/crate containername = "Integrated circuit crate" + +/datum/supply_pack/sci/xenoarch + name = "Xenoarchaeology Tech crate" + contains = list( + /obj/item/weapon/pickaxe/excavationdrill, + /obj/item/device/xenoarch_multi_tool, + /obj/item/clothing/suit/space/anomaly, + /obj/item/clothing/head/helmet/space/anomaly, + /obj/item/weapon/storage/belt/archaeology, + /obj/item/device/flashlight/lantern, + /obj/item/device/core_sampler, + /obj/item/device/gps, + /obj/item/device/beacon_locator, + /obj/item/device/radio/beacon, + /obj/item/clothing/glasses/meson, + /obj/item/weapon/pickaxe, + /obj/item/weapon/storage/bag/fossils, + /obj/item/weapon/hand_labeler) + cost = 100 + containertype = /obj/structure/closet/crate/secure/science + containername = "Xenoarchaeology Tech crate" + access = access_research \ No newline at end of file diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm index 4e4c8c1311..6e9e82bdde 100644 --- a/code/datums/supplypacks/security.dm +++ b/code/datums/supplypacks/security.dm @@ -124,6 +124,30 @@ /obj/item/clothing/gloves/black ) */ + +/datum/supply_pack/security/flexitac + name = "Armor - Tactical Light" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Tactical Light armor crate" + cost = 75 + access = access_armory + contains = list( + /obj/item/clothing/suit/storage/vest/heavy/flexitac, + /obj/item/clothing/head/helmet/flexitac, + /obj/item/clothing/shoes/leg_guard/flexitac, + /obj/item/clothing/gloves/arm_guard/flexitac, + /obj/item/clothing/mask/balaclava/tactical, + /obj/item/clothing/glasses/sunglasses/sechud/tactical, + /obj/item/weapon/storage/belt/security/tactical, + /obj/item/clothing/suit/storage/vest/heavy/flexitac, + /obj/item/clothing/head/helmet/flexitac, + /obj/item/clothing/shoes/leg_guard/flexitac, + /obj/item/clothing/gloves/arm_guard/flexitac, + /obj/item/clothing/mask/balaclava/tactical, + /obj/item/clothing/glasses/sunglasses/sechud/tactical, + /obj/item/weapon/storage/belt/security/tactical + ) + /datum/supply_pack/security/securitybarriers name = "Misc - Security Barriers" contains = list(/obj/machinery/deployable/barrier = 4) @@ -372,4 +396,4 @@ cost = 25 containertype = /obj/structure/closet/crate/secure containername = "Security biohazard gear" - access = access_security \ No newline at end of file + access = access_security diff --git a/code/datums/supplypacks/supply.dm b/code/datums/supplypacks/supply.dm index e8f26993ff..c0db598cc4 100644 --- a/code/datums/supplypacks/supply.dm +++ b/code/datums/supplypacks/supply.dm @@ -61,7 +61,7 @@ /obj/item/weapon/tool/wirecutters, /obj/item/weapon/tape_roll = 2) cost = 10 - containertype = "/obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Shipping supplies crate" /datum/supply_pack/supply/bureaucracy @@ -111,7 +111,7 @@ /obj/item/clothing/glasses/meson ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Shaft miner equipment" access = access_mining /* //VOREStation Edit - Pointless on Tether. diff --git a/code/datums/supplypacks/voidsuits.dm b/code/datums/supplypacks/voidsuits.dm index 42fca890a6..8cb3b1738a 100644 --- a/code/datums/supplypacks/voidsuits.dm +++ b/code/datums/supplypacks/voidsuits.dm @@ -17,7 +17,7 @@ /obj/item/weapon/tank/oxygen = 2, ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Atmospheric voidsuit crate" access = access_atmospherics @@ -31,7 +31,7 @@ /obj/item/weapon/tank/oxygen = 2, ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Heavy Duty Atmospheric voidsuit crate" access = access_atmospherics @@ -45,7 +45,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Engineering voidsuit crate" access = access_engine_equip @@ -59,7 +59,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Engineering Construction voidsuit crate" access = access_engine_equip @@ -73,7 +73,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 45 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Engineering Hazmat voidsuit crate" access = access_engine_equip @@ -87,7 +87,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Reinforced Engineering voidsuit crate" access = access_engine_equip @@ -101,7 +101,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical voidsuit crate" access = access_medical_equip @@ -115,7 +115,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical EMT voidsuit crate" access = access_medical_equip @@ -129,7 +129,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 45 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Medical Biohazard voidsuit crate" access = access_medical_equip @@ -143,7 +143,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 60 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Vey-Med Medical voidsuit crate" access = access_medical_equip @@ -157,7 +157,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Security voidsuit crate" /datum/supply_pack/voidsuits/security/crowd @@ -170,7 +170,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Security Crowd Control voidsuit crate" access = access_armory @@ -184,7 +184,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Security EVA Riot voidsuit crate" access = access_armory @@ -197,7 +197,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Mining voidsuit crate" access = access_mining @@ -210,7 +210,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Frontier Mining voidsuit crate" access = access_mining @@ -221,7 +221,7 @@ /obj/item/clothing/mask/gas/zaddat = 1 ) cost = 30 - containertype = "/obj/structure/closet/crate" + containertype = /obj/structure/closet/crate containername = "Zaddat Shroud crate" access = access_mining diff --git a/code/datums/supplypacks/voidsuits_vr.dm b/code/datums/supplypacks/voidsuits_vr.dm index 8fcfd8ae50..cfadfcf213 100644 --- a/code/datums/supplypacks/voidsuits_vr.dm +++ b/code/datums/supplypacks/voidsuits_vr.dm @@ -79,7 +79,7 @@ /obj/item/weapon/tank/oxygen = 3 ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Exploration voidsuit crate" access = access_explorer @@ -93,6 +93,6 @@ /obj/item/weapon/tank/oxygen = 1 ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Pilot voidsuit crate" access = access_pilot \ No newline at end of file diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 5bd34e704b..8699f11920 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -718,7 +718,7 @@ desc = "Instant research tool. For testing purposes only." icon = 'icons/obj/stock_parts.dmi' icon_state = "smes_coil" - origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19) + origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19, TECH_PRECURSOR = 19) // Additional construction stock parts diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7154b9f47d..adaabce442 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -68,40 +68,51 @@ if(!newloc.Enter(src, src.loc)) return + + if(!check_multi_tile_move_density_dir(direct, locs)) // We're big, and we can't move that way. + return + // Past this is the point of no return - var/atom/oldloc = loc - var/area/oldarea = get_area(oldloc) - var/area/newarea = get_area(newloc) - loc = newloc - . = TRUE - oldloc.Exited(src, newloc) - if(oldarea != newarea) - oldarea.Exited(src, newloc) + if(!locs || locs.len <= 1) // We're not a multi-tile object. + var/atom/oldloc = loc + var/area/oldarea = get_area(oldloc) + var/area/newarea = get_area(newloc) + loc = newloc + . = TRUE + oldloc.Exited(src, newloc) + if(oldarea != newarea) + oldarea.Exited(src, newloc) - for(var/i in oldloc) - if(i == src) // Multi tile objects - continue - var/atom/movable/thing = i - thing.Uncrossed(src) + for(var/i in oldloc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Uncrossed(src) - newloc.Entered(src, oldloc) - if(oldarea != newarea) - newarea.Entered(src, oldloc) + newloc.Entered(src, oldloc) + if(oldarea != newarea) + newarea.Entered(src, oldloc) + + for(var/i in loc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Crossed(src) + + else if(newloc) // We're a multi-tile object. + . = doMove(newloc) - for(var/i in loc) - if(i == src) // Multi tile objects - continue - var/atom/movable/thing = i - thing.Crossed(src) // //////////////////////////////////////// -/atom/movable/Move(atom/newloc, direct) +/atom/movable/Move(atom/newloc, direct = 0) if(!loc || !newloc) return FALSE var/atom/oldloc = loc if(loc != newloc) + if(!direct) + direct = get_dir(oldloc, newloc) if (!(direct & (direct - 1))) //Cardinal move . = ..() else //Diagonal move, split it into cardinal moves @@ -197,6 +208,13 @@ . = TRUE return CanPass(AM, loc) +/atom/movable/CanPass(atom/movable/mover, turf/target) + . = ..() + if(locs && locs.len >= 2) // If something is standing on top of us, let them pass. + if(mover.loc in locs) + . = TRUE + return . + //oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! /atom/movable/Crossed(atom/movable/AM, oldloc) return diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm index ed27a49ba0..947f06cee4 100644 --- a/code/game/gamemodes/changeling/powers/armblade.dm +++ b/code/game/gamemodes/changeling/powers/armblade.dm @@ -32,7 +32,7 @@ genomecost = 1 verbpath = /mob/proc/changeling_claw -//Grows a scary, and powerful arm blade. +//Grows a scary, and powerful claw. /mob/proc/changeling_claw() set category = "Changeling" set name = "Claw (15)" @@ -62,6 +62,9 @@ var/weapType = "weapon" var/weapLocation = "arm" + defend_chance = 40 // The base chance for the weapon to parry. + projectile_parry_chance = 15 // The base chance for a projectile to be deflected. + /obj/item/weapon/melee/changeling/New(location) ..() START_PROCESSING(SSobj, src) @@ -107,6 +110,28 @@ if(src) qdel(src) +/obj/item/weapon/melee/changeling/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(default_parry_check(user, attacker, damage_source) && prob(defend_chance)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/slash.ogg', 50, 1) + return 1 + if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/slash.ogg', 50, 1) + return 1 + + return 0 + +/obj/item/weapon/melee/changeling/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 + /obj/item/weapon/melee/changeling/arm_blade name = "arm blade" desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter." @@ -117,11 +142,15 @@ edge = 1 pry = 1 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + defend_chance = 60 + projectile_parry_chance = 25 /obj/item/weapon/melee/changeling/arm_blade/greater name = "arm greatblade" desc = "A grotesque blade made out of bone and flesh that cleaves through people and armor as a hot knife through butter." armor_penetration = 30 + defend_chance = 70 + projectile_parry_chance = 35 /obj/item/weapon/melee/changeling/claw name = "hand claw" @@ -131,9 +160,13 @@ sharp = 1 edge = 1 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + defend_chance = 50 + projectile_parry_chance = 15 /obj/item/weapon/melee/changeling/claw/greater name = "hand greatclaw" force = 20 armor_penetration = 20 - pry = 1 \ No newline at end of file + pry = 1 + defend_chance = 60 + projectile_parry_chance = 25 diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index c04760b4ef..223a81ebfd 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -84,16 +84,17 @@ else //Make sure it's buildable and list requires resources. for(var/material in R.resources) - var/sheets = round(stored_material[material]/round(R.resources[material]*mat_efficiency)) + var/coeff = (R.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient + var/sheets = round(stored_material[material]/round(R.resources[material]*coeff)) if(isnull(max_sheets) || max_sheets > sheets) max_sheets = sheets - if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*mat_efficiency)) + if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*coeff)) can_make = 0 if(!comma) comma = 1 else material_string += ", " - material_string += "[round(R.resources[material] * mat_efficiency)] [material]" + material_string += "[round(R.resources[material] * coeff)] [material]" material_string += ".
" //Build list of multipliers for sheets. if(R.is_stack) @@ -252,15 +253,16 @@ update_use_power(2) //Check if we still have the materials. + var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient for(var/material in making.resources) if(!isnull(stored_material[material])) - if(stored_material[material] < round(making.resources[material] * mat_efficiency) * multiplier) + if(stored_material[material] < round(making.resources[material] * coeff) * multiplier) return //Consume materials. for(var/material in making.resources) if(!isnull(stored_material[material])) - stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * mat_efficiency) * multiplier) + stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * coeff) * multiplier) update_icon() // So lid closes diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 948ef595c8..31a3a74d63 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -74,7 +74,7 @@ var/egun = null //holder to handle certain guns switching bullettypes var/last_fired = 0 //1: if the turret is cooling down from a shot, 0: turret is ready to fire - var/shot_delay = 15 //1.5 seconds between each shot + var/shot_delay = 1.5 SECONDS //1.5 seconds between each shot var/check_arrest = 1 //checks if the perp is set to arrest var/check_records = 1 //checks if a security record exists at all @@ -139,7 +139,6 @@ health = 250 // Since lasers do 40 each. maxhealth = 250 - /datum/category_item/catalogue/anomalous/precursor_a/alien_turret name = "Precursor Alpha Object - Turrets" desc = "An autonomous defense turret created by unknown ancient aliens. It utilizes an \ @@ -181,6 +180,49 @@ stat = BROKEN can_salvage = FALSE // So you need to actually kill a turret to get the alien gun. +/obj/machinery/porta_turret/industrial + name = "industrial turret" + desc = "This variant appears to be much more rugged." + req_one_access = list(access_heads) + installation = /obj/item/weapon/gun/energy/phasegun + health = 200 + maxhealth = 200 + + icon_state = "turret_cover_industrial" + closed_state = "turret_cover_industrial" + raising_state = "popup_industrial" + opened_state = "open_industrial" + lowering_state = "popdown_industrial" + gun_active_state = "target_prism_industrial" + gun_disabled_state = "grey_target_prism_industrial" + gun_destroyed_state = "destroyed_target_prism_industrial" + +/obj/machinery/porta_turret/industrial/bullet_act(obj/item/projectile/Proj) + var/damage = round(Proj.get_structure_damage() * 1.33) + + if(!damage) + return + + if(enabled) + if(!attacked && !emagged) + attacked = 1 + spawn() + sleep(60) + attacked = 0 + + take_damage(damage) + +/obj/machinery/porta_turret/industrial/attack_generic(mob/living/L, damage) + return ..(L, damage * 0.8) + +/obj/machinery/porta_turret/industrial/teleport_defense + name = "defense turret" + desc = "This variant appears to be much more durable, with a rugged outer coating." + req_one_access = list(access_heads) + installation = /obj/item/weapon/gun/energy/gun/burst + health = 250 + maxhealth = 250 + /obj/machinery/porta_turret/poi //These are always angry enabled = TRUE lethal = TRUE @@ -247,6 +289,24 @@ // iconholder = 1 // eprojectile = /obj/item/projectile/beam + if(/obj/item/weapon/gun/energy/gun/burst) + iconholder = 1 + eprojectile = /obj/item/projectile/beam/burstlaser + eshot_sound = 'sound/weapons/Laser.ogg' + icon_color = "red" + projectile = /obj/item/projectile/beam/stun/weak + shot_sound = 'sound/weapons/Taser.ogg' + shot_delay = 1 SECOND + + if(/obj/item/weapon/gun/energy/phasegun) + iconholder = 1 + eprojectile = /obj/item/projectile/energy/phase/heavy + eshot_sound = 'sound/weapons/gunshot_pathetic.ogg' + icon_color = "orange" + projectile = /obj/item/projectile/energy/phase + shot_sound = 'sound/weapons/gunshot_pathetic.ogg' + shot_delay = 1 SECOND + if(/obj/item/weapon/gun/energy/retro) iconholder = 1 diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 8bf79482f2..f499c521e9 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -706,6 +706,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 15, /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider = 15, /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 5, diff --git a/code/game/machinery/vending_vr.dm b/code/game/machinery/vending_vr.dm index 6027bc5eaf..19a24e669e 100644 --- a/code/game/machinery/vending_vr.dm +++ b/code/game/machinery/vending_vr.dm @@ -6,7 +6,6 @@ /obj/machinery/vending/security/New() products += list(/obj/item/weapon/gun/energy/taser = 8,/obj/item/weapon/gun/energy/stunrevolver = 4, /obj/item/weapon/reagent_containers/spray/pepper = 6,/obj/item/taperoll/police = 6, - /obj/item/weapon/gun/projectile/sec/flash = 4, /obj/item/ammo_magazine/m45/flash = 8, /obj/item/clothing/glasses/omnihud/sec = 6) ..() diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 978bbdeda8..19564acba9 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -120,4 +120,53 @@ ..() if (href_list["toggle_leg_overload"]) src.overload() + return + +/obj/mecha/combat/gygax/serenity + desc = "A lightweight exosuit made from a modified Gygax chassis combined with proprietary VeyMed medical tech. It's faster and sturdier than most medical mechs, but much of the armor plating has been stripped out, leaving it more vulnerable than a regular Gygax." + name = "Serenity" + icon_state = "medgax" + initial_icon = "medgax" + health = 150 + maxhealth = 150 + deflect_chance = 20 + step_in = 2 + damage_absorption = list("brute"=0.9,"fire"=1,"bullet"=0.9,"laser"=0.8,"energy"=0.9,"bomb"=1) + max_temperature = 20000 + overload_coeff = 1 + wreckage = /obj/effect/decal/mecha_wreckage/gygax/serenity + max_equip = 3 + step_energy_drain = 8 + cargo_capacity = 2 + max_hull_equip = 1 + max_weapon_equip = 1 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + + var/obj/item/clothing/glasses/hud/health/mech/hud + +/obj/mecha/combat/gygax/serenity/New() + ..() + hud = new /obj/item/clothing/glasses/hud/health/mech(src) + return + +/obj/mecha/combat/gygax/serenity/moved_inside(var/mob/living/carbon/human/H as mob) + if(..()) + if(H.glasses) + occupant_message("[H.glasses] prevent you from using [src] [hud]") + else + H.glasses = hud + H.recalculate_vis() + return 1 + else + return 0 + +/obj/mecha/combat/gygax/serenity/go_out() + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant + if(H.glasses == hud) + H.glasses = null + H.recalculate_vis() + ..() return \ No newline at end of file diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 58b187670f..ffd70a8fa5 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -237,13 +237,11 @@ set_ready_state(1) return - /obj/item/mecha_parts/mecha_equipment/Topic(href,href_list) if(href_list["detach"]) src.detach() return - /obj/item/mecha_parts/mecha_equipment/proc/set_ready_state(state) equip_ready = state if(chassis) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 3ea93b6f77..5df2c54d10 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -34,11 +34,18 @@ var/turf/aimloc = targloc if(deviation) aimloc = locate(targloc.x+GaussRandRound(deviation,1),targloc.y+GaussRandRound(deviation,1),targloc.z) - if(!aimloc || aimloc == curloc) + if(!aimloc || aimloc == curloc || (locs && aimloc in locs)) break playsound(chassis, fire_sound, fire_volume, 1) projectiles-- - var/P = new projectile(curloc) + var/turf/projectile_turf + if(chassis.locs && chassis.locs.len) // Multi tile. + for(var/turf/Tloc in chassis.locs) + if(get_dist(Tloc, aimloc) < get_dist(loc, aimloc)) + projectile_turf = get_turf(Tloc) + if(!projectile_turf) + projectile_turf = get_turf(curloc) + var/P = new projectile(projectile_turf) Fire(P, target, params) if(i == 1) set_ready_state(0) @@ -61,11 +68,14 @@ return /obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, params) - var/obj/item/projectile/P = A - P.dispersion = deviation - process_accuracy(P, chassis.occupant, target) - P.preparePixelProjectile(target, chassis.occupant, params) - P.fire() + if(istype(A, /obj/item/projectile)) // Sanity. + var/obj/item/projectile/P = A + P.dispersion = deviation + process_accuracy(P, chassis.occupant, target) + P.launch_projectile_from_turf(target, chassis.occupant.zone_sel.selecting, chassis.occupant, params) + else if(istype(A, /atom/movable)) + var/atom/movable/AM = A + AM.throw_at(target, 7, 1, chassis) /obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target) var/obj/item/projectile/P = projectile @@ -416,6 +426,7 @@ var/heavy_blast = 1 var/light_blast = 2 var/flash_blast = 4 + does_spin = FALSE // No fun corkscrew missiles. /obj/item/missile/proc/warhead_special(var/target) explosion(target, devastation, heavy_blast, light_blast, flash_blast) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 9b17cb8613..b556286292 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -49,6 +49,8 @@ var/mech_faction = null var/firstactivation = 0 //It's simple. If it's 0, no one entered it yet. Otherwise someone entered it at least once. + var/stomp_sound = 'sound/mecha/mechstep.ogg' + var/swivel_sound = 'sound/mecha/mechturn.ogg' //inner atmos var/use_internal_tank = 0 @@ -441,21 +443,24 @@ /obj/mecha/proc/mechturn(direction) set_dir(direction) - playsound(src,'sound/mecha/mechturn.ogg',40,1) + if(swivel_sound) + playsound(src,swivel_sound,40,1) return 1 /obj/mecha/proc/mechstep(direction) - var/result = step(src,direction) - if(result) - playsound(src,"mechstep",40,1) + var/result = get_step(src,direction) + if(result && Move(result)) + if(stomp_sound) + playsound(src,stomp_sound,40,1) handle_equipment_movement() return result /obj/mecha/proc/mechsteprand() - var/result = step_rand(src) - if(result) - playsound(src,"mechstep",40,1) + var/result = get_step_rand(src) + if(result && Move(result)) + if(stomp_sound) + playsound(src,stomp_sound,40,1) handle_equipment_movement() return result @@ -473,9 +478,10 @@ else //I have no idea why I disabled this obstacle.Bumped(src) else if(istype(obstacle, /mob)) - step(obstacle,src.dir) + var/mob/M = obstacle + M.Move(get_step(obstacle,src.dir)) else - obstacle.Bumped(src) + . = ..(obstacle) return /////////////////////////////////// diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 9edff107b1..3cbe670a41 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -560,8 +560,294 @@ feedback_inc("mecha_gygax_created",1) return + + ////////////////////// +// Serenity +////////////////////// +/datum/construction/mecha/serenity_chassis + steps = list(list("key"=/obj/item/mecha_parts/part/gygax_torso),//1 + list("key"=/obj/item/mecha_parts/part/gygax_left_arm),//2 + list("key"=/obj/item/mecha_parts/part/gygax_right_arm),//3 + list("key"=/obj/item/mecha_parts/part/gygax_left_leg),//4 + list("key"=/obj/item/mecha_parts/part/gygax_right_leg),//5 + list("key"=/obj/item/mecha_parts/part/gygax_head) + ) + +/datum/construction/mecha/serenity_chassis/custom_action(step, obj/item/I, mob/user) + user.visible_message("[user] has connected [I] to [holder].", "You connect [I] to [holder]") + holder.overlays += I.icon_state+"+o" + qdel(I) + return 1 + +/datum/construction/mecha/serenity_chassis/action(obj/item/I,mob/user as mob) + return check_all_steps(I,user) + +/datum/construction/mecha/serenity_chassis/spawn_result() + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/serenity(const_holder) + const_holder.icon = 'icons/mecha/mech_construction.dmi' + const_holder.icon_state = "gygax0" + const_holder.density = 1 + spawn() + qdel(src) + return + + +/datum/construction/reversible/mecha/serenity + result = "/obj/mecha/combat/gygax/serenity" + steps = list( + //1 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=IS_WRENCH, + "desc"="External armor is wrenched."), + //2 + list("key"=IS_WRENCH, + "backkey"=IS_CROWBAR, + "desc"="External armor is installed."), + //3 + list("key"=/obj/item/stack/material/plasteel, + "backkey"=/obj/item/weapon/weldingtool, + "desc"="Internal armor is welded."), + //4 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=IS_WRENCH, + "desc"="Internal armor is wrenched"), + //5 + list("key"=IS_WRENCH, + "backkey"=IS_CROWBAR, + "desc"="Internal armor is installed"), + //6 + list("key"=/obj/item/stack/material/steel, + "backkey"=IS_SCREWDRIVER, + "desc"="Advanced capacitor is secured"), + //7 + list("key"=IS_SCREWDRIVER, + "backkey"=IS_CROWBAR, + "desc"="Advanced capacitor is installed"), + //8 + list("key"=/obj/item/weapon/stock_parts/capacitor/adv, + "backkey"=IS_SCREWDRIVER, + "desc"="Advanced scanner module is secured"), + //9 + list("key"=IS_SCREWDRIVER, + "backkey"=IS_CROWBAR, + "desc"="Advanced scanner module is installed"), + //10 + list("key"=/obj/item/weapon/stock_parts/scanning_module/adv, + "backkey"=IS_SCREWDRIVER, + "desc"="Medical module is secured"), + //11 + list("key"=IS_SCREWDRIVER, + "backkey"=IS_CROWBAR, + "desc"="Medical module is installed"), + //12 + list("key"=/obj/item/weapon/circuitboard/mecha/gygax/medical, + "backkey"=IS_SCREWDRIVER, + "desc"="Peripherals control module is secured"), + //13 + list("key"=IS_SCREWDRIVER, + "backkey"=IS_CROWBAR, + "desc"="Peripherals control module is installed"), + //14 + list("key"=/obj/item/weapon/circuitboard/mecha/gygax/peripherals, + "backkey"=IS_SCREWDRIVER, + "desc"="Central control module is secured"), + //15 + list("key"=IS_SCREWDRIVER, + "backkey"=IS_CROWBAR, + "desc"="Central control module is installed"), + //16 + list("key"=/obj/item/weapon/circuitboard/mecha/gygax/main, + "backkey"=IS_SCREWDRIVER, + "desc"="The wiring is adjusted"), + //17 + list("key"=/obj/item/weapon/tool/wirecutters, + "backkey"=IS_SCREWDRIVER, + "desc"="The wiring is added"), + //18 + list("key"=/obj/item/stack/cable_coil, + "backkey"=IS_SCREWDRIVER, + "desc"="The hydraulic systems are active."), + //19 + list("key"=IS_SCREWDRIVER, + "backkey"=IS_WRENCH, + "desc"="The hydraulic systems are connected."), + //20 + list("key"=IS_WRENCH, + "desc"="The hydraulic systems are disconnected.") + ) + +/datum/construction/reversible/mecha/serenity/action(obj/item/I,mob/user as mob) + return check_step(I,user) + +/datum/construction/reversible/mecha/serenity/custom_action(index, diff, obj/item/I, mob/user) + if(!..()) + return 0 + + //TODO: better messages. + switch(index) + if(20) + user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + holder.icon_state = "gygax1" + if(19) + if(diff==FORWARD) + user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + holder.icon_state = "gygax2" + else + user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + holder.icon_state = "gygax0" + if(18) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + holder.icon_state = "gygax3" + else + user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + holder.icon_state = "gygax1" + if(17) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + holder.icon_state = "gygax4" + else + user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) + coil.amount = 4 + holder.icon_state = "gygax2" + if(16) + if(diff==FORWARD) + user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + qdel(I) + holder.icon_state = "gygax5" + else + user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + holder.icon_state = "gygax3" + if(15) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + holder.icon_state = "gygax6" + else + user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + new /obj/item/weapon/circuitboard/mecha/gygax/main(get_turf(holder)) + holder.icon_state = "gygax4" + if(14) + if(diff==FORWARD) + user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + qdel(I) + holder.icon_state = "gygax7" + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + holder.icon_state = "gygax5" + if(13) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + holder.icon_state = "gygax8" + else + user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/gygax/peripherals(get_turf(holder)) + holder.icon_state = "gygax6" + if(12) + if(diff==FORWARD) + user.visible_message("[user] installs the medical control module into [holder].", "You install the medical control module into [holder].") + qdel(I) + holder.icon_state = "gygax9" + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + holder.icon_state = "gygax7" + if(11) + if(diff==FORWARD) + user.visible_message("[user] secures the medical control module.", "You secure the medical control module.") + holder.icon_state = "gygax10" + else + user.visible_message("[user] removes the medical control module from [holder].", "You remove the medical control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/gygax/medical(get_turf(holder)) + holder.icon_state = "gygax8" + if(10) + if(diff==FORWARD) + user.visible_message("[user] installs advanced scanner module to [holder].", "You install advanced scanner module to [holder].") + qdel(I) + holder.icon_state = "gygax11" + else + user.visible_message("[user] unfastens the medical control module.", "You unfasten the medical control module.") + holder.icon_state = "gygax9" + if(9) + if(diff==FORWARD) + user.visible_message("[user] secures the advanced scanner module.", "You secure the advanced scanner module.") + holder.icon_state = "gygax12" + else + user.visible_message("[user] removes the advanced scanner module from [holder].", "You remove the advanced scanner module from [holder].") + new /obj/item/weapon/stock_parts/scanning_module/adv(get_turf(holder)) + holder.icon_state = "gygax10" + if(8) + if(diff==FORWARD) + user.visible_message("[user] installs advanced capacitor to [holder].", "You install advanced capacitor to [holder].") + qdel(I) + holder.icon_state = "gygax13" + else + user.visible_message("[user] unfastens the advanced scanner module.", "You unfasten the advanced scanner module.") + holder.icon_state = "gygax11" + if(7) + if(diff==FORWARD) + user.visible_message("[user] secures the advanced capacitor.", "You secure the advanced capacitor.") + holder.icon_state = "gygax14" + else + user.visible_message("[user] removes the advanced capacitor from [holder].", "You remove the advanced capacitor from [holder].") + new /obj/item/weapon/stock_parts/capacitor/adv(get_turf(holder)) + holder.icon_state = "gygax12" + if(6) + if(diff==FORWARD) + user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + holder.icon_state = "gygax15" + else + user.visible_message("[user] unfastens the advanced capacitor.", "You unfasten the advanced capacitor.") + holder.icon_state = "gygax13" + if(5) + if(diff==FORWARD) + user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + holder.icon_state = "gygax16" + else + user.visible_message("[user] pries internal armor layer from [holder].", "You pry the internal armor layer from [holder].") + var/obj/item/stack/material/steel/MS = new /obj/item/stack/material/steel(get_turf(holder)) + MS.amount = 5 + holder.icon_state = "gygax14" + if(4) + if(diff==FORWARD) + user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + holder.icon_state = "gygax17" + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + holder.icon_state = "gygax15" + if(3) + if(diff==FORWARD) + user.visible_message("[user] installs the external armor layer to [holder].", "You install the external armor layer to [holder].") + qdel(I) + holder.icon_state = "gygax18" + else + user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + holder.icon_state = "gygax16" + if(2) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external armor layer.") + holder.icon_state = "gygax19-s" + else + user.visible_message("[user] pries the external armor layer from [holder].", "You pry the external armor layer from [holder].") + new /obj/item/mecha_parts/part/gygax_armour(get_turf(holder)) + holder.icon_state = "gygax17" + if(1) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [holder].", "You weld the external armor layer to [holder].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + holder.icon_state = "gygax18" + return 1 + +/datum/construction/reversible/mecha/serenity/spawn_result() + ..() + feedback_inc("mecha_serenity_created",1) + return + + + //////////////////////// -// Firfighter +// Firefighter //////////////////////// /datum/construction/mecha/firefighter_chassis steps = list(list("key"=/obj/item/mecha_parts/part/ripley_torso),//1 diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index 07c619b9ff..74cb1e169c 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -1,4 +1,4 @@ -///////////////////////// + ///////////////////////// ////// Mecha Parts ////// ///////////////////////// @@ -112,6 +112,14 @@ icon_state = "gygax_armour" origin_tech = list(TECH_MATERIAL = 6, TECH_COMBAT = 4, TECH_ENGINEERING = 5) +////////// Serenity + +/obj/item/mecha_parts/chassis/serenity + name = "Serenity Chassis" + + New() + ..() + construct = new /datum/construction/mecha/serenity_chassis(src) //////////// Durand diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 5a95b9017c..9894784e15 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -107,6 +107,10 @@ name = "Medgax wreckage" icon_state = "medgax-broken" +/obj/effect/decal/mecha_wreckage/gygax/serenity + name = "Serenity wreckage" + icon_state = "medgax-broken" + /obj/effect/decal/mecha_wreckage/marauder name = "Marauder wreckage" icon_state = "marauder-broken" @@ -217,3 +221,11 @@ name = "Janus wreckage" icon_state = "janus-broken" description_info = "Due to the incredibly intricate design of this exosuit, it is impossible to salvage components from it." + +/obj/effect/decal/mecha_wreckage/shuttlecraft + name = "Shuttlecraft wreckage" + desc = "Remains of some unfortunate shuttlecraft. Completely unrepairable." + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "shuttle_standard-broken" + bound_width = 64 + bound_height = 64 diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index 90ab62681a..6e9dee5047 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -5,6 +5,8 @@ max_universal_equip = 1 max_special_equip = 1 + stomp_sound = 'sound/mecha/mechmove01.ogg' + cargo_capacity = 1 /obj/mecha/medical/Initialize() @@ -13,7 +15,7 @@ if(isPlayerLevel(T.z)) new /obj/item/mecha_parts/mecha_tracking(src) - +/* // One horrific bastardization of glorious inheritence dead. A billion to go. ~Mech /obj/mecha/medical/mechturn(direction) set_dir(direction) playsound(src,'sound/mecha/mechmove01.ogg',40,1) @@ -29,4 +31,5 @@ var/result = step_rand(src) if(result) playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result \ No newline at end of file + return result +*/ diff --git a/code/game/mecha/working/hoverpod.dm b/code/game/mecha/space/hoverpod.dm similarity index 91% rename from code/game/mecha/working/hoverpod.dm rename to code/game/mecha/space/hoverpod.dm index 8c19c2b004..85fc59d564 100644 --- a/code/game/mecha/working/hoverpod.dm +++ b/code/game/mecha/space/hoverpod.dm @@ -17,6 +17,9 @@ var/datum/effect/effect/system/ion_trail_follow/ion_trail var/stabilization_enabled = 1 + stomp_sound = 'sound/machines/hiss.ogg' + swivel_sound = null + max_hull_equip = 2 max_weapon_equip = 0 max_utility_equip = 2 @@ -49,7 +52,7 @@ output += ..() return output -//No space drifting +// No space drifting /obj/mecha/working/hoverpod/check_for_support() //does the hoverpod have enough charge left to stabilize itself? if (!has_charge(step_energy_drain)) @@ -62,6 +65,11 @@ return ..() +// No falling if we've got our boosters on +/obj/mecha/working/hoverpod/can_fall() + return (stabilization_enabled && has_charge(step_energy_drain)) + +/* // One horrific bastardization of glorious inheritence dead. A billion to go. ~Mech //these three procs overriden to play different sounds /obj/mecha/working/hoverpod/mechturn(direction) set_dir(direction) @@ -80,7 +88,7 @@ if(result) playsound(src,'sound/machines/hiss.ogg',40,1) return result - +*/ //Hoverpod variants /obj/mecha/working/hoverpod/combatpod diff --git a/code/game/mecha/space/shuttle.dm b/code/game/mecha/space/shuttle.dm new file mode 100644 index 0000000000..7e361ece0c --- /dev/null +++ b/code/game/mecha/space/shuttle.dm @@ -0,0 +1,99 @@ +/obj/mecha/working/hoverpod/shuttlecraft + desc = "A more advanced variant of the hoverpod." + name = "Shuttle" + catalogue_data = list(/datum/category_item/catalogue/technology/hoverpod) + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "shuttle_standard" + initial_icon = "shuttle_standard" + internal_damage_threshold = 60 + step_in = 2 + step_energy_drain = 5 + max_temperature = 20000 + health = 300 + maxhealth = 300 + infra_luminosity = 6 + wreckage = /obj/effect/decal/mecha_wreckage/shuttlecraft + cargo_capacity = 3 + max_equip = 3 + + opacity = FALSE + + stomp_sound = 'sound/machines/generator/generator_end.ogg' + swivel_sound = 'sound/machines/hiss.ogg' + + // Paint colors! Null if not set. + var/base_paint + var/engine_paint + var/central_paint + var/front_paint + + var/image/base_paint_mask + var/image/engine_paint_mask + var/image/central_paint_mask + var/image/front_paint_mask + + bound_height = 64 + bound_width = 64 + + max_hull_equip = 2 + max_weapon_equip = 1 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + +/obj/mecha/working/hoverpod/Initialize() + ..() + ion_trail.stop() + +/obj/mecha/working/hoverpod/shuttlecraft/moved_inside(var/mob/living/carbon/human/H as mob) + . = ..(H) + if(.) + ion_trail.start() + +/obj/mecha/working/hoverpod/shuttlecraft/go_out() + . = ..() + if(!occupant) + ion_trail.stop() + +/obj/mecha/working/hoverpod/shuttlecraft/update_icon() + overlays.Cut() + ..() + + if(base_paint) + if(!base_paint_mask) + base_paint_mask = image(icon, "[initial_icon]-mask+base", src.layer + 1) + base_paint_mask.color = base_paint + overlays |= base_paint_mask + if(front_paint) + if(!front_paint_mask) + front_paint_mask = image(icon, "[initial_icon]-mask+front", src.layer + 1) + front_paint_mask.color = front_paint + overlays |= front_paint_mask + if(engine_paint) + if(!engine_paint_mask) + engine_paint_mask = image(icon, "[initial_icon]-mask+engine", src.layer + 1) + engine_paint_mask.color = engine_paint + overlays |= engine_paint_mask + if(central_paint) + if(!engine_paint_mask) + central_paint_mask = image(icon, "[initial_icon]-mask+central", src.layer + 2) + central_paint_mask.color = central_paint + overlays |= central_paint_mask + +/obj/mecha/working/hoverpod/shuttlecraft/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/device/multitool) && state == 1) + var/new_paint_location = input("Please select a target zone.", "Paint Zone", null) as null|anything in list("Central", "Engine", "Base", "Front", "CANCEL") + if(new_paint_location && new_paint_location != "CANCEL") + var/new_paint_color = input("Please select a paint color.", "Paint Color", null) as color|null + if(new_paint_color) + switch(new_paint_location) + if("Central") + central_paint = new_paint_color + if("Engine") + engine_paint = new_paint_color + if("Front") + front_paint = new_paint_color + if("Base") + base_paint = new_paint_color + update_icon() + else ..() diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index f21d6443fb..551449a8fb 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -408,6 +408,10 @@ steam.start() -- spawns the effect src.processing = 0 spawn(0) var/turf/T = get_turf(src.holder) + if(istype(holder, /atom/movable)) + var/atom/movable/AM = holder + if(AM.locs && AM.locs.len) + T = pick(AM.locs) if(T != src.oldposition) if(isturf(T)) var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition) diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 839dc7a2dc..830fa803e4 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -4,12 +4,12 @@ var/list/GPS_list = list() name = "global positioning system" desc = "Triangulates the approximate co-ordinates using a nearby satellite network. Alt+click to toggle power." icon = 'icons/obj/gps.dmi' - icon_state = "gps-c" + icon_state = "gps-gen" w_class = ITEMSIZE_TINY slot_flags = SLOT_BELT origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_MAGNET = 1) matter = list(DEFAULT_WALL_MATERIAL = 500) - var/gps_tag = "COM0" + var/gps_tag = "GEN0" var/emped = FALSE var/tracking = FALSE // Will not show other signals or emit its own signal if false. var/long_range = FALSE // If true, can see farther, depending on get_map_levels(). @@ -171,22 +171,43 @@ var/list/GPS_list = list() /obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these. tracking = TRUE +/obj/item/device/gps/command + icon_state = "gps-com" + gps_tag = "COM0" + +/obj/item/device/gps/command/on + tracking = TRUE + +/obj/item/device/gps/security + icon_state = "gps-sec" + gps_tag = "SEC0" + +/obj/item/device/gps/security/on + tracking = TRUE + +/obj/item/device/gps/medical + icon_state = "gps-med" + gps_tag = "MED0" + +/obj/item/device/gps/medical/on + tracking = TRUE + /obj/item/device/gps/science - icon_state = "gps-s" + icon_state = "gps-sci" gps_tag = "SCI0" /obj/item/device/gps/science/on tracking = TRUE /obj/item/device/gps/engineering - icon_state = "gps-e" + icon_state = "gps-eng" gps_tag = "ENG0" /obj/item/device/gps/engineering/on tracking = TRUE /obj/item/device/gps/mining - icon_state = "gps-m" + icon_state = "gps-mine" gps_tag = "MINE0" desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life. Alt+click to toggle power." @@ -194,15 +215,15 @@ var/list/GPS_list = list() tracking = TRUE /obj/item/device/gps/explorer - icon_state = "gps-ex" - gps_tag = "EX0" + icon_state = "gps-exp" + gps_tag = "EXP0" desc = "A positioning system helpful for rescuing trapped or injured explorers, keeping one on you at all times while exploring might just save your life. Alt+click to toggle power." /obj/item/device/gps/explorer/on tracking = TRUE /obj/item/device/gps/robot - icon_state = "gps-b" + icon_state = "gps-borg" gps_tag = "SYNTH0" desc = "A synthetic internal positioning system. Used as a recovery beacon for damaged synthetic assets, or a collaboration tool for mining or exploration teams. \ Alt+click to toggle power." diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 7e2b054165..4686aee807 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -121,48 +121,18 @@ /obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U) - if(target.status != LIGHT_OK) - if(CanUse(U)) - if(!Use(U)) return - U << "You replace the [target.fitting] with the [src]." + if(target.status == LIGHT_OK) + to_chat(U, "There is a working [target.get_fitting_name()] already inserted.") + else if(!CanUse(U)) + to_chat(U, failmsg) + else if(Use(U)) + to_chat(U, "You replace the [target.get_fitting_name()] with the [src].") - if(target.status != LIGHT_EMPTY) + if(target.status != LIGHT_EMPTY) + target.remove_bulb() - var/obj/item/weapon/light/L1 = new target.light_type(target.loc) - L1.status = target.status - L1.rigged = target.rigged - L1.brightness_range = target.brightness_range - L1.brightness_power = target.brightness_power - L1.brightness_color = target.brightness_color - L1.switchcount = target.switchcount - target.switchcount = 0 - L1.update() - - target.status = LIGHT_EMPTY - target.update() - - var/obj/item/weapon/light/L2 = new target.light_type() - - target.status = L2.status - target.switchcount = L2.switchcount - target.rigged = emagged - target.brightness_range = L2.brightness_range - target.brightness_power = L2.brightness_power - target.brightness_color = L2.brightness_color - target.on = target.has_power() - target.update() - qdel(L2) - - if(target.on && target.rigged) - target.explode() - return - - else - U << failmsg - return - else - U << "There is a working [target.fitting] already inserted." - return + var/obj/item/weapon/light/L = new target.light_type() + target.insert_bulb(L) /obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user) emagged = !emagged diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index b155a1fb54..ec121bfed2 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -211,7 +211,7 @@ HALOGEN COUNTER - Radcount on mobs continue // Broken limbs if(e.status & ORGAN_BROKEN) - if((e.name in list("l_arm", "r_arm", "l_leg", "r_leg")) && (!e.splinted)) + if((e.name in list("l_arm", "r_arm", "l_leg", "r_leg", "head", "chest", "groin")) && (!e.splinted)) fracture_dat += "Unsecured fracture in subject [e.name]. Splinting recommended for transport.
" else if(advscan >= 1 && showadvscan == 1) fracture_dat += "Bone fractures detected in subject [e.name].
" diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index fe09f30410..6a51e9eb17 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -270,12 +270,12 @@ /obj/item/stack/medical/splint name = "medical splints" singular_name = "medical splint" - desc = "Modular splints capable of supporting and immobilizing bones in both limbs and appendages." + desc = "Modular splints capable of supporting and immobilizing bones in all areas of the body." icon_state = "splint" amount = 5 max_amount = 5 - var/list/splintable_organs = list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT) //List of organs you can splint, natch. + var/list/splintable_organs = list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO) //List of organs you can splint, natch. /obj/item/stack/medical/splint/attack(mob/living/carbon/M as mob, mob/living/user as mob) if(..()) diff --git a/code/game/objects/items/weapons/circuitboards/mecha.dm b/code/game/objects/items/weapons/circuitboards/mecha.dm index fd351f8587..777146f385 100644 --- a/code/game/objects/items/weapons/circuitboards/mecha.dm +++ b/code/game/objects/items/weapons/circuitboards/mecha.dm @@ -32,6 +32,11 @@ icon_state = "mcontroller" origin_tech = list(TECH_DATA = 4, TECH_COMBAT = 4) +/obj/item/weapon/circuitboard/mecha/gygax/medical + name = T_BOARD_MECHA("Serenity medical control") + icon_state = "mcontroller" + origin_tech = list(TECH_DATA = 4, TECH_BIO = 4) + /obj/item/weapon/circuitboard/mecha/gygax/main name = T_BOARD_MECHA("Gygax central control") icon_state = "mainboard" diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 9efe911360..46551e588a 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -11,8 +11,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' /obj/item/weapon/material/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") - - if(default_parry_check(user, attacker, damage_source) && prob(50)) + if(unique_parry_check(user, attacker, damage_source) && prob(50)) user.visible_message("\The [user] parries [attack_text] with \the [src]!") playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) return 1 diff --git a/code/game/objects/items/weapons/melee/deflect.dm b/code/game/objects/items/weapons/melee/deflect.dm new file mode 100644 index 0000000000..293d2b9e29 --- /dev/null +++ b/code/game/objects/items/weapons/melee/deflect.dm @@ -0,0 +1,31 @@ +/* + * The home of basic deflect / defense code. + */ + +/obj/item/weapon/melee + var/defend_chance = 5 // The base chance for the weapon to parry. + var/projectile_parry_chance = 0 // The base chance for a projectile to be deflected. + +/obj/item/weapon/melee/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(.) + return . + if(default_parry_check(user, attacker, damage_source) && prob(defend_chance)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + return 1 + if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + return 1 + + return 0 + +/obj/item/weapon/melee/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + if(.) + return . + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 72fe26da36..f825577d6f 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -127,6 +127,8 @@ var/random_color = TRUE var/active_state = "sword" + projectile_parry_chance = 65 + /obj/item/weapon/melee/energy/sword/dropped(var/mob/user) ..() if(!istype(loc,/mob)) @@ -173,7 +175,7 @@ icon_state = initial(icon_state) /obj/item/weapon/melee/energy/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") - if(active && default_parry_check(user, attacker, damage_source) && prob(50)) + if(active && default_parry_check(user, attacker, damage_source) && prob(60)) user.visible_message("\The [user] parries [attack_text] with \the [src]!") var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() @@ -181,8 +183,27 @@ spark_system.start() playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) return 1 + if(active && unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, user.loc) + spark_system.start() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + return 0 +/obj/item/weapon/melee/energy/sword/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile/)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 + /obj/item/weapon/melee/energy/sword/pirate name = "energy cutlass" desc = "Arrrr matey." @@ -215,6 +236,7 @@ lpower = 2 lcolor = "#0000FF" active_state = "ionic_rapier" + projectile_parry_chance = 30 // It's not specifically designed for cutting and slashing, but it can still, maybe, save your life. /obj/item/weapon/melee/energy/sword/ionic_rapier/afterattack(var/atom/movable/AM, var/mob/living/user, var/proximity) if(istype(AM, /obj) && proximity && active) @@ -250,6 +272,7 @@ origin_tech = list(TECH_COMBAT = 5, TECH_MAGNET = 3, TECH_ILLEGAL = 4) active_force = 25 armor_penetration = 25 + projectile_parry_chance = 40 var/hitcost = 75 var/obj/item/weapon/cell/bcell = null @@ -336,6 +359,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/mob/living/creator var/datum/effect/effect/system/spark_spread/spark_system + projectile_parry_chance = 60 lcolor = "#00FF00" /obj/item/weapon/melee/energy/blade/New() @@ -373,6 +397,37 @@ host.drop_from_inventory(src) spawn(1) if(src) qdel(src) +/obj/item/weapon/melee/energy/blade/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(default_parry_check(user, attacker, damage_source) && prob(60)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, user.loc) + spark_system.start() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + if(unique_parry_check(user, attacker, damage_source) && prob(projectile_parry_chance)) + user.visible_message("\The [user] deflects [attack_text] with \the [src]!") + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, user.loc) + spark_system.start() + playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) + return 1 + + return 0 + +/obj/item/weapon/melee/energy/blade/unique_parry_check(mob/user, mob/attacker, atom/damage_source) + + if(user.incapacitated() || !istype(damage_source, /obj/item/projectile/)) + return 0 + + var/bad_arc = reverse_direction(user.dir) + if(!check_shield_arc(user, bad_arc, damage_source, attacker)) + return 0 + + return 1 + /* *Energy Spear */ diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index a1a2756eca..5ea586f43d 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -29,6 +29,9 @@ return 1 +/obj/item/proc/unique_parry_check(mob/user, mob/attacker, atom/damage_source) // An overrideable version of the above proc. + return default_parry_check(user, attacker, damage_source) + /obj/item/weapon/shield name = "shield" var/base_block_chance = 50 diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 9b323c3b68..3555a314f7 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -160,6 +160,12 @@ max_storage_space = ITEMSIZE_COST_SMALL * 7 starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting = 8) +/obj/item/weapon/storage/firstaid/bonemed + name = "bone repair kit" + desc = "Contains chemicals to mend broken bones." + max_storage_space = ITEMSIZE_COST_SMALL * 7 + starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed = 8) + /* * Pill Bottles */ diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm index aba62d0806..eb5741c6a1 100644 --- a/code/game/objects/random/mapping.dm +++ b/code/game/objects/random/mapping.dm @@ -70,6 +70,11 @@ id = "Captain's spare id" item_path = /obj/item/weapon/card/id/gold/captain/spare +/obj/random_multi/single_item/hand_tele + name = "Multi Point - Hand Teleporter" + id = "hand tele" + item_path = /obj/item/weapon/hand_tele + /obj/random_multi/single_item/sfr_headset name = "Multi Point - headset" id = "SFR headset" diff --git a/code/game/objects/random/mob_vr.dm b/code/game/objects/random/mob_vr.dm index 62e3e376c7..c1ce7aaf15 100644 --- a/code/game/objects/random/mob_vr.dm +++ b/code/game/objects/random/mob_vr.dm @@ -229,3 +229,6 @@ prob(50);/obj/random/soap, prob(60);/obj/random/drinkbottle, prob(500);/obj/random/maintenance/clean) + +/obj/random/action_figure/supplypack + drop_get_turf = FALSE \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 66c219293e..4234c99391 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -385,7 +385,7 @@ if(!opened) icon_state = icon_closed if(sealed) - overlays += "sealed" + overlays += "welded" else icon_state = icon_opened diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo_vr.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo_vr.dm new file mode 100644 index 0000000000..332b629d7b --- /dev/null +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo_vr.dm @@ -0,0 +1,3 @@ +/obj/structure/closet/secure_closet/miner/Initialize() + starts_with += /obj/item/device/gps/mining + return ..() \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical_vr.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical_vr.dm new file mode 100644 index 0000000000..e47f835891 --- /dev/null +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical_vr.dm @@ -0,0 +1,3 @@ +/obj/structure/closet/secure_closet/paramedic/Initialize() + starts_with += /obj/item/device/gps/medical + return ..() \ No newline at end of file diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index a5ad07213d..d4cf8f63b3 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -298,6 +298,14 @@ /obj/structure/flora/sif icon = 'icons/obj/flora/sifflora.dmi' +/obj/structure/flora/sif/attack_hand(mob/user) + if (user.a_intent == I_HURT) + if(do_after(user, 5 SECONDS)) + user.visible_message("\The [user] digs up \the [src.name].", "You dig up \the [src.name].") + qdel(src) + else + user.visible_message("\The [user] pokes \the [src.name].", "You poke \the [src.name].") + /datum/category_item/catalogue/flora/subterranean_bulbs name = "Sivian Flora - Subterranean Bulbs" desc = "A plant which is native to Sif, it continues the trend of being a bioluminescent specimen. These plants \ @@ -340,4 +348,4 @@ /obj/structure/flora/sif/eyes/Initialize() icon_state = "[initial(icon_state)][rand(1,3)]" - . = ..() + . = ..() \ No newline at end of file diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index c94003e9fb..f74770664b 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -340,7 +340,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/weapon/stock_parts/subspace/transmitter, /obj/item/weapon/stock_parts/subspace/treatment, /obj/item/frame, - /obj/item/broken_device, + /obj/item/broken_device/random, /obj/item/borg/upgrade/restart, /obj/item/weapon/cell, /obj/item/weapon/cell/high, diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index b615c0cc42..606c0b2bb9 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -43,6 +43,9 @@ set_flooring(get_flooring_data(floortype)) else footstep_sounds = base_footstep_sounds + if(can_dirty) + if(prob(2)) + new /obj/effect/decal/cleanable/dirt(src) //5% chance to start with dirt on a floor tile- give the janitor something to do /turf/simulated/floor/proc/set_flooring(var/decl/flooring/newflooring) make_plating(defer_icon_update = 1) diff --git a/code/game/turfs/simulated/outdoors/grass.dm b/code/game/turfs/simulated/outdoors/grass.dm index 67aa054b46..72b2ee7e57 100644 --- a/code/game/turfs/simulated/outdoors/grass.dm +++ b/code/game/turfs/simulated/outdoors/grass.dm @@ -29,7 +29,7 @@ var/list/grass_types = list( name = "growth" icon_state = "grass_sif" edge_blending_priority = 4 - grass_chance = 0 + grass_chance = 5 var/tree_chance = 2 grass_types = list( diff --git a/code/modules/blob2/blobs/core.dm b/code/modules/blob2/blobs/core.dm index 17ecd2429f..f43ec7ad6f 100644 --- a/code/modules/blob2/blobs/core.dm +++ b/code/modules/blob2/blobs/core.dm @@ -6,6 +6,7 @@ var/list/blob_cores = list() icon = 'icons/mob/blob.dmi' icon_state = "blank_blob" desc = "A huge, pulsating yellow mass." + density = TRUE //bandaid fix for PolarisSS13/6173 max_integrity = 150 point_return = -1 health_regen = 0 //we regen in Life() instead of when pulsed diff --git a/code/modules/catalogue/rewards/equipment_vendor.dm b/code/modules/catalogue/rewards/equipment_vendor.dm index 655675dfe5..d5c6574e05 100644 --- a/code/modules/catalogue/rewards/equipment_vendor.dm +++ b/code/modules/catalogue/rewards/equipment_vendor.dm @@ -12,17 +12,18 @@ 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("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("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), + 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("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("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), new /datum/data/exploration_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100), 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 e5abb1e0eb..0f186f5dfc 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm @@ -30,6 +30,11 @@ display_name = "collar, holo" path = /obj/item/clothing/accessory/collar/holo +//TFF 17/6/19 - public loadout addition: Indigestible Holocollar +/datum/gear/collar/holo/indigestible + display_name = "collar, holo (indigestible)" + path = /obj/item/clothing/accessory/collar/holo/indigestible + /datum/gear/accessory/holster display_name = "holster selection (Security, CD, HoP, Exploration)" allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Explorer","Pathfinder") diff --git a/code/modules/clothing/gloves/arm_guards.dm b/code/modules/clothing/gloves/arm_guards.dm index d258cb5b63..21e7a99b35 100644 --- a/code/modules/clothing/gloves/arm_guards.dm +++ b/code/modules/clothing/gloves/arm_guards.dm @@ -44,4 +44,14 @@ icon_state = "arm_guards_combat" item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") siemens_coefficient = 0.6 - armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 30, bio = 0, rad = 0) \ No newline at end of file + armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 30, bio = 0, rad = 0) + +/obj/item/clothing/gloves/arm_guard/flexitac + name = "tactical arm guards" + desc = "These arm guards will protect your hands and arms from a variety of weapons while still allowing mobility." + icon_state = "arm_guards_flexitac" + item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") + siemens_coefficient = 0.6 + armor = list(melee = 40, bullet = 40, laser = 60, energy = 35, bomb = 30, bio = 0, rad = 0) + min_cold_protection_temperature = T0C - 20 + cold_protection = ARMS \ No newline at end of file diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 70c19a1260..f246a8563c 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -103,6 +103,18 @@ siemens_coefficient = 0.6 valid_accessory_slots = null +/obj/item/clothing/head/helmet/flexitac + name = "tactical light helmet" + desc = "A tan helmet made from advanced ceramic with an integrated tactical flashlight." + icon_state = "flexitac" + armor = list(40, bullet = 40, laser = 60, energy = 35, bomb = 30, bio = 0, rad = 0) + siemens_coefficient = 0.6 + brightness_on = 6 + light_overlay = "helmet_light_dual_green" + action_button_name = "Toggle Head-light" + min_cold_protection_temperature = T0C - 20 + cold_protection = HEAD + /obj/item/clothing/head/helmet/swat name = "\improper SWAT helmet" desc = "They're often used by highly trained SWAT Officers." diff --git a/code/modules/clothing/shoes/leg_guards.dm b/code/modules/clothing/shoes/leg_guards.dm index da38116537..fba1c2cd3f 100644 --- a/code/modules/clothing/shoes/leg_guards.dm +++ b/code/modules/clothing/shoes/leg_guards.dm @@ -6,6 +6,7 @@ species_restricted = null //Unathi and Taj can wear leg armor now w_class = ITEMSIZE_NORMAL step_volume_mod = 1.3 + can_hold_knife = TRUE /obj/item/clothing/shoes/leg_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(..()) //This will only run if no other problems occured when equiping. @@ -46,3 +47,14 @@ item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") siemens_coefficient = 0.6 armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 30, bio = 0, rad = 0) + +/obj/item/clothing/shoes/leg_guard/flexitac + name = "tactical leg guards" + desc = "These will protect your legs and feet from a variety of weapons while still allowing mobility." + icon_state = "leg_guards_flexitac" + item_state_slots = list(slot_r_hand_str = "jackboots", slot_l_hand_str = "jackboots") + siemens_coefficient = 0.6 + slowdown = SHOES_SLOWDOWN+0.2 + armor = list(melee = 40, bullet = 40, laser = 60, energy = 35, bomb = 30, bio = 0, rad = 0) + min_cold_protection_temperature = T0C - 20 + cold_protection = LEGS \ No newline at end of file diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index db33ec9662..9df94753e6 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -378,6 +378,16 @@ item_state = "tacwebvest" armor = list(melee = 40, bullet = 40, laser = 60, energy = 35, bomb = 30, bio = 0, rad = 0) +/obj/item/clothing/suit/storage/vest/heavy/flexitac //a reskin of the above to have a matching armor set + name = "tactical light vest" + desc = "An armored vest made from advanced flexible ceramic plates. It's surprisingly mobile, if a little unfashionable." + icon_state = "flexitac" + item_state = "flexitac" + armor = list(melee = 40, bullet = 40, laser = 60, energy = 35, bomb = 30, bio = 0, rad = 0) + cold_protection = UPPER_TORSO|LOWER_TORSO + min_cold_protection_temperature = T0C - 20 + slowdown = 0.3 + /obj/item/clothing/suit/storage/vest/detective name = "detective armor vest" desc = "A simple kevlar plate carrier in a vintage brown, it has a badge clipped to the chest that reads, 'Private investigator'." diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index cebf3ee3b8..5dc05b44c8 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -183,6 +183,16 @@ overlay_state = "collar_holo_overlay" matter = list(DEFAULT_WALL_MATERIAL = 50) +//TFF 17/6/19 - public loadout addition: Indigestible Holocollar +/obj/item/clothing/accessory/collar/holo/indigestible + name = "Holo-collar" + desc = "A special variety of the holo-collar that seems to be made of a very durable fabric that fits around the neck." + icon_state = "collar_holo" + item_state = "collar_holo_overlay" + overlay_state = "collar_holo_overlay" +//Make indigestible +/obj/item/clothing/accessory/collar/holo/indigestible/digest_act(var/atom/movable/item_storage = null) + return FALSE /obj/item/clothing/accessory/collar/attack_self(mob/user as mob) if(istype(src,/obj/item/clothing/accessory/collar/holo)) @@ -211,23 +221,23 @@ /obj/item/clothing/accessory/collar/attackby(obj/item/I, mob/user) if(istype(src,/obj/item/clothing/accessory/collar/holo)) return - + if(istype(I,/obj/item/weapon/tool/screwdriver)) update_collartag(user, I, "scratched out", "scratch out", "engraved") return - + if(istype(I,/obj/item/weapon/pen)) update_collartag(user, I, "crossed out", "cross out", "written") return - + to_chat(user,"You need a pen or a screwdriver to edit the tag on this collar.") - + /obj/item/clothing/accessory/collar/proc/update_collartag(mob/user, obj/item/I, var/erasemethod, var/erasing, var/writemethod) if(!(istype(user.get_active_hand(),I)) || !(istype(user.get_inactive_hand(),src)) || (user.stat)) return - + var/str = copytext(reject_bad_text(input(user,"Tag text?","Set tag","")),1,MAX_NAME_LEN) - + if(!str || !length(str)) if(!writtenon) to_chat(user,"You don't write anything.") diff --git a/code/modules/fishing/fishing_rod_vr.dm b/code/modules/fishing/fishing_rod_vr.dm new file mode 100644 index 0000000000..e802507b9b --- /dev/null +++ b/code/modules/fishing/fishing_rod_vr.dm @@ -0,0 +1,5 @@ +/obj/item/weapon/material/fishing_rod/modern/strong + desc = "A extremely refined rod for catching fish." + default_material = "durasteel" + + toolspeed = 0.5 \ No newline at end of file diff --git a/code/modules/food/drinkingglass/metaglass.dm b/code/modules/food/drinkingglass/metaglass.dm index babb71df8b..0b64df0af9 100644 --- a/code/modules/food/drinkingglass/metaglass.dm +++ b/code/modules/food/drinkingglass/metaglass.dm @@ -546,3 +546,7 @@ Drinks Data /datum/reagent/drink/eggnog glass_icon_state = "eggnog" glass_center_of_mass = list("x"=16, "y"=8) + +/datum/reagent/drink/cider + glass_icon_state = "ciderglass" + glass_center_of_mass = list("x"=16, "y"=8) diff --git a/code/modules/food/food/drinks/bottle.dm b/code/modules/food/food/drinks/bottle.dm index d2506132fd..4888bc8124 100644 --- a/code/modules/food/food/drinks/bottle.dm +++ b/code/modules/food/food/drinks/bottle.dm @@ -520,6 +520,17 @@ . = ..() reagents.add_reagent("beer", 30) +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider + name = "Crisp's Cider" + desc = "Fermented apples never tasted this good." + icon_state = "cider" + center_of_mass = list("x"=16, "y"=12) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider/Initialize() + . = ..() + reagents.add_reagent("cider", 30) + + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale name = "\improper Magm-Ale" desc = "A true dorf's drink of choice." diff --git a/code/modules/gamemaster/actions/atmos_leak.dm b/code/modules/gamemaster/actions/atmos_leak.dm index 6506f77f95..ab3947cb15 100644 --- a/code/modules/gamemaster/actions/atmos_leak.dm +++ b/code/modules/gamemaster/actions/atmos_leak.dm @@ -6,6 +6,7 @@ var/gas_type // Chosen gas to release // Exclude these types and sub-types from targeting eligibilty var/list/area/excluded = list( + /area/submap, /area/shuttle, /area/crew_quarters, /area/holodeck, diff --git a/code/modules/gamemaster/actions/electrified_door.dm b/code/modules/gamemaster/actions/electrified_door.dm index bc5bf35ae0..d5365d50aa 100644 --- a/code/modules/gamemaster/actions/electrified_door.dm +++ b/code/modules/gamemaster/actions/electrified_door.dm @@ -3,7 +3,9 @@ departments = list(ROLE_ENGINEERING, ROLE_MEDICAL) chaotic = 10 var/obj/machinery/door/airlock/chosen_door + var/area/target_area var/list/area/excluded = list( + /area/submap, /area/shuttle, /area/crew_quarters ) @@ -19,9 +21,9 @@ //try 10 times for(var/i in 1 to 10) - var/area/A = pick(grand_list_of_areas) + target_area = pick(grand_list_of_areas) var/list/obj/machinery/door/airlock/target_doors = list() - for(var/obj/machinery/door/airlock/target_door in A.contents) + for(var/obj/machinery/door/airlock/target_door in target_area.contents) target_doors += target_door target_doors = shuffle(target_doors) @@ -34,11 +36,15 @@ ..() if(!chosen_door) return - if(prob(33)) - chosen_door.visible_message("\The [chosen_door]'s panel sparks!") + command_announcement.Announce("An electrical issue has been detected in your area, please repair potential electronic overloads.", "Electrical Alert") + chosen_door.visible_message("\The [chosen_door]'s panel sparks!") chosen_door.set_safeties(0) + playsound(get_turf(chosen_door), 'sound/machines/buzz-sigh.ogg', 50, 1) if(severity >= EVENT_LEVEL_MODERATE) chosen_door.electrify(-1) + spawn(rand(10 SECONDS, 2 MINUTES)) + if(chosen_door && chosen_door.arePowerSystemsOn() && prob(25 + 25 * severity)) + command_announcement.Announce("Overload has been localized to \the [target_area].", "Electrical Alert") if(severity >= EVENT_LEVEL_MAJOR) // New Major effect. Hydraulic boom. spawn() diff --git a/code/modules/gamemaster/actions/planet_weather_change.dm b/code/modules/gamemaster/actions/planet_weather_change.dm new file mode 100644 index 0000000000..e0f2e754e9 --- /dev/null +++ b/code/modules/gamemaster/actions/planet_weather_change.dm @@ -0,0 +1,29 @@ +/datum/gm_action/planet_weather_shift + name = "sudden weather shift" + enabled = TRUE + departments = list(ROLE_EVERYONE) + reusable = TRUE + var/datum/planet/target_planet + + var/list/banned_weathers = list() //VOREStation Temp Edit + var/list/possible_weathers = list() + +/datum/gm_action/planet_weather_shift/set_up() + if(!target_planet || isnull(target_planet)) + target_planet = pick(SSplanets.planets) + possible_weathers |= target_planet.weather_holder.allowed_weather_types + possible_weathers -= banned_weathers + return + +/datum/gm_action/planet_weather_shift/get_weight() + return max(0, -15 + (metric.count_all_outdoor_mobs() * 20)) + +/datum/gm_action/planet_weather_shift/start() + ..() + var/new_weather = pick(possible_weathers) + target_planet.weather_holder.change_weather(new_weather) + +/datum/gm_action/planet_weather_shift/announce() + spawn(rand(3 SECONDS, 2 MINUTES)) + command_announcement.Announce("Local weather patterns on [target_planet.name] suggest that a sudden atmospheric fluctuation has occurred. All groundside personnel should be wary of rapidly deteriorating conditions.", "Weather Alert") + return diff --git a/code/modules/gamemaster/actions/spontaneous_appendicitis.dm b/code/modules/gamemaster/actions/spontaneous_appendicitis.dm index 9742b4615e..1758709164 100644 --- a/code/modules/gamemaster/actions/spontaneous_appendicitis.dm +++ b/code/modules/gamemaster/actions/spontaneous_appendicitis.dm @@ -10,4 +10,4 @@ break /datum/gm_action/spontaneous_appendicitis/get_weight() - return 5 + (metric.count_people_in_department(ROLE_MEDICAL) * 10) + return max(0, -5 + (metric.count_people_in_department(ROLE_MEDICAL) * 10)) diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index f12db3f76b..c11c7e963a 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -14,7 +14,7 @@ can_be_asked_input = 1 inputs = list() outputs = list() - activators = list("on pressed" = IC_PINTYPE_PULSE_IN) + activators = list("on pressed" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -31,7 +31,7 @@ can_be_asked_input = 1 inputs = list() outputs = list("on" = IC_PINTYPE_BOOLEAN) - activators = list("on toggle" = IC_PINTYPE_PULSE_IN) + activators = list("on toggle" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto. @@ -48,7 +48,7 @@ can_be_asked_input = 1 inputs = list() outputs = list("number entered" = IC_PINTYPE_NUMBER) - activators = list("on entered" = IC_PINTYPE_PULSE_IN) + activators = list("on entered" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 @@ -67,7 +67,7 @@ can_be_asked_input = 1 inputs = list() outputs = list("string entered" = IC_PINTYPE_STRING) - activators = list("on entered" = IC_PINTYPE_PULSE_IN) + activators = list("on entered" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 @@ -86,7 +86,7 @@ can_be_asked_input = 1 inputs = list() outputs = list("color entered" = IC_PINTYPE_COLOR) - activators = list("on entered" = IC_PINTYPE_PULSE_IN) + activators = list("on entered" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 088c53e521..30230a69e0 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -99,9 +99,9 @@ /datum/lighting_corner/proc/update_overlays() // Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually. - var/lum_r = src.lum_r - var/lum_g = src.lum_g - var/lum_b = src.lum_b + var/lum_r = src.lum_r > 0 ? LIGHTING_MULT_FACTOR * sqrt(src.lum_r) : src.lum_r + var/lum_g = src.lum_g > 0 ? LIGHTING_MULT_FACTOR * sqrt(src.lum_g) : src.lum_g + var/lum_b = src.lum_b > 0 ? LIGHTING_MULT_FACTOR * sqrt(src.lum_b) : src.lum_b var/mx = max(lum_r, lum_g, lum_b) // Scale it so 1 is the strongest lum, if it is above 1. . = 1 // factor if (mx > 1) diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index d878d8c4b6..451b8273c8 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -189,7 +189,7 @@ ); // This is the define used to calculate falloff. -#define LUM_FALLOFF(C, T)(1 - CLAMP01(sqrt((C.x - T.x) ** 2 +(C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range))) +#define LUM_FALLOFF(C, T)(1 - CLAMP01(((C.x - T.x) ** 2 +(C.y - T.y) ** 2 + LIGHTING_HEIGHT) ** 0.6 / max(1, light_range))) /datum/light_source/proc/apply_lum() var/static/update_gen = 1 diff --git a/code/modules/lore_codex/news_data/main.dm b/code/modules/lore_codex/news_data/main.dm index ee41280d6f..a2f5f43043 100644 --- a/code/modules/lore_codex/news_data/main.dm +++ b/code/modules/lore_codex/news_data/main.dm @@ -4,6 +4,27 @@ region. Each is labeled by date of publication and title. This list is self-updating, and from time to time the publisher will push new \ articles. You are encouraged to check back frequently." children = list( + /datum/lore/codex/page/article53, + /datum/lore/codex/page/article52, + /datum/lore/codex/page/article51, + /datum/lore/codex/page/article50, + /datum/lore/codex/page/article49, + /datum/lore/codex/page/article48, + /datum/lore/codex/page/article47, + /datum/lore/codex/page/article46, + /datum/lore/codex/page/article45, + /datum/lore/codex/page/article44, + /datum/lore/codex/page/article43, + /datum/lore/codex/page/article42, + /datum/lore/codex/page/article41, + /datum/lore/codex/page/article40, + /datum/lore/codex/page/article39, + /datum/lore/codex/page/keldowinterview, + /datum/lore/codex/category/article38, + /datum/lore/codex/page/article37, + /datum/lore/codex/page/article36, + /datum/lore/codex/page/article35, + /datum/lore/codex/page/article34, /datum/lore/codex/page/article33, /datum/lore/codex/page/article32, /datum/lore/codex/page/bjornretirement, @@ -401,3 +422,232 @@ Vani Jee is running on a platform of free access to education, Sivian self-determination, and isolationist foreign policy. She has refused to make any strong statements regarding hot-button issues such as the Five Points.\

\ She intends to resume her scheduled tour after a three day break." + +/datum/lore/codex/page/article34 + name = "02/05/63 - Angessa Martei to Take Control of Eponymous Colony" + data = "Coming out of retirement and displacing the nameless Exalt of the Starlit Path, religious demagogue Angessa Martei has returned to the throne of the colony that bears her name. \ +

\ + 'I had retired because of senescence brought on by my old age, high-stress lifestyle, and multiple resurrective clonings. As you may know, I recently had a procedure that renders these difficulties obsolete. Hereafter I will continue to control the automated facilities of the Pearl and claim responsibility for the collective action of my followers. Those who oppose my decision may oppose all they want. Feelings do not move mountains. I do. We shall seize the stars in our own hands. May you become who you wish to be, and grind all obstacles to dust, as I have done.'\ +

\ + Purportedly, this address was met with a standing ovation from the population of Angessa's Pearl. In a separate dispatch, Martei stated her intention to tour SolGov as a foreign dignitary protected by the Respect for Diplomats Act." + +/datum/lore/codex/page/article35 + name = "02/07/63 - Vir Gubernatorial Candidate Barred from Breakfast TV" + data = "Infamously hot-headed Shadow Coalition candidate Phaedrus has reportedly been blacklisted from future appearances on morning television by several major networks. The ban comes after an advertised chat segment between Phaedrus and hosts of the West Sif Wakeup breakfast programme had to be pulled from broadcast after the candidate 'Flew into a expletive-laden mercurial rant' at the expense of rival candidate Mehmet Sao of the Icarus Front.\ +

\ + Recordings of the outburst quickly made their way onto social media, sparking outrage from opponents and network executives alike, prompting Occulum Media to issue a rare blacklist from major media outlets, restricting Phaedrus to 'appearances on alternative news sources' owned by the company.\ +

\ + Phaedrus, a long-time Vir Mercurial Progress Party member running for a major party for the first time, is said to have taken issue with candidate Sao's 'Blatant anti-synthetic' policies, though he did not use the word 'policies'." + +/datum/lore/codex/page/article36 + name = "02/09/63 - SEO Candidate Embarks on Wilderness Tour" + data = "In an effort to stir up support for his promotion of natural resource extraction industries, Sol Economic Organization candidate Mason Keldow has embarked on an unorthodox tour of resource-rich sites across central Sif. Keldow has described the tour as an 'Old fashioned expedition', invoking images of hardy prospectors of centuries past, and intends to make the journey entirely by ground with only a small party of 'Adventurous outdoorspeople' to support his trek.\ +

\ + Critics of the plan have pointed out that the earliest surveys of Sif were largely performed by aerial drones, and the idea of ground-based survey teams is 'Frankly anachronistic'. Rival Shadow Coalition candidate Selma Jorg - a staunch planetary environmentalist - has described the tour as 'Irresponsible and insane'.\ +

\ + The candidate intends to visit both unexploited sites and current corporate extraction facilities in order to 'Better understand the folks helping dig out Sif's hidden wealth' over the coming two weeks." + +/datum/lore/codex/page/article37 + name = "02/09/63 - Zaddat Colony 'Bright' To Enter Vir" + data = "After several months of talks with Nanotrasen and other corporations in the system, the Colony Bright is to begin orbiting Sif and hardsuited Zaddat are to enter the Virite workforce. Executives in Nanotrasen Vir cite the reduction of their drone-automated and positronic workforce as a result of the Gray Hour as cause for them to reverse their previous decision against allowing the migrants into the system. Icarus officials within VGA are concerned that, if other Colonies are to follow the Bright, the native industry of Sif may be disrupted or suborned by Zaddat and Hegemony interests, and have made it clear that the Bright's presence in the system is highly conditional." + +/datum/lore/codex/category/article38 + name = "02/11/63 - Mason Keldow in Ullran Expanse Close Call" + data = "Sol Economic Organization candidate Mason Keldow was rushed to nearby corporate medical facilities after a death-defying encounter with local wildlife in the Ullran Expanse this morning. The candidate had been planning to visit the nearby NanoTrasen mining facilities as part of his much publicized 'Wilderness Tour' when he and a local guide were set upon by the notoriously savage Sivian Savik. The animal was killed in the encounter, but not before Mr. Keldow suffered life-threatening injuries and had to be recovered by crew from the NLS Southern Cross, the closest facility on hand.\ +

\ + Following emergency surgery, Keldow was happy to provide news sources with a 'Good-natured' interview, in which he highlighted the dangers faced by rural workers on Sif and his plans to tackle them, as well as slamming rival Shadow Coalition candidate Selma Jorg for lacking tangible plans for the future.\ +

\ + Candidate Keldow is reported to have made a miraculous recovery, and is 'in good spirits'. Aides state that he is unlikely to suffer any long term effects from the injuries, in part thanks for the skilful work of NanoTrasen's Dr. Fuerte.\ +

\ + A full transcript of the interview follows:" + children = list( + /datum/lore/codex/page/keldowinterview + ) + +/datum/lore/codex/page/keldowinterview + name = "Mason Keldow Interview Transcript" + data = "Blip asks, 'Subject Keldow. Pleasantries first. How do you feel after your ordeal on the planet's surface?'\ +

\ + Mason Keldow says, 'Ah that? You know I'd love to downplay it and pretend that it was just a walk in the park... But NT's medical staff probably will tell you otherwise, so there's no reason to hide it; things went pretty far south.'\ +

\ + Mason Keldow says, 'But that's how it goes, working on the surface of Sif isn't pleasant at times.'\ +

\ + Blip asks, 'Candidate Keldow, you have placed yourself quite firmly in the boots of the local TSC's explorer contingents today. Do you feel you will be attempting to live the life of any other labour intensive roles in the near future?'\ +

\ + Mason Keldow says, 'Blip, Let me tell you I do try to get a taste for a lot of the work done by these people... But admittedly this isn't the job I do every day. These are hard working fellows who do there damnedest day in and day out... I could try spending a week just working the mines, But-'\ +

\ + Mason Keldow says, 'As I was saying.. Many of the folks, Miners, Explorers, The work in and around the Ullran Expanse. They work in the mountains, Out in the fields.. It's a dangerous place and frankly its not a place average people wanna go too.'\ +

\ + Mason Keldow says, 'They told me on the way here. 'Keldow you're an idiot''\ +

\ + Mason Keldow says, 'Hell, Even Basman over here was wondering why I didn't ask for a detail.'\ +

\ + Mason Keldow says, 'So it's not a safe route... But when's the last time any of the other candidates actually came down to these outer stretches and tried earning their sweat.'\ +

\ + Blip asks, 'You indeed seem to be attempting to gain a unique, and firm understanding of the daily struggles of the working populace. How do you intend to translate this newfound knowledge into policy and direction if you take the Governorship in Vir?'\ +

\ + Mason Keldow says, 'You see, getting a grasp of the struggle is only step one, I paint myself as an every-man but that doesn't mean core issues aren't the problem either; Vir's economics, The small pay that sometimes offered. There is a lot to be tapped into.'\ +

\ + Mason Keldow says, 'Let's take for instance the spiders I've been hearing about.'\ +

\ + Mason Keldow says, 'People working in orbit say 'Don't go to the surface, Spiders are down there.''\ +

\ + Mason Keldow says, 'And apparently there was a big ol' purple one sitting right by a camp we had set up. A giant mother who'd - if I hadn't met that lovely mass of fur and ice instead - would have probably said its “hello” in the worst possible way.'\ +

\ + Mason Keldow says, 'They are a species that prevents anyone from actually working or otherwise making use of all that land. If I were in office, I'd make an effort to clear out the dangerous species that surround the outer regions of Sif – relocate them if possible - and use that territory for something productive.'\ +

\ + Mason Keldow says, 'New forms of Transit, new buildings, new jobs.'\ +

\ + Blip asks, 'Such implementation of infrastructure and security is not a cheap measure. How do you intend to find funds for such an endeavour?'\ +

\ + Mason Keldow says, 'Now obviously Vir is in a very interesting position, But thankfully it's in a wonderful position where business and partnerships are more than happy to come in and assist. The bottom line would make sure the average Taxpayer doesn't feel a dent, only the dividends.'\ +

\ + Mason Keldow says, 'If we break this down into economic plans, using new yet relatively safe tools being put out by Hepheastus, you could safely clear swaths of territory in the Expanse.'\ +

\ + Blip says, 'Thank you for your insight into your economic policies and plans. As a final question;'\ +

\ + Blip asks, 'A puff-piece question. Do you have anything positive to say about your rivals in the political race?'\ +

\ + Mason Keldow says, 'Ah yes, yes well... As for any candidate they need to show they're worth. Not simply as a politician but as a person who believes what they will do for for the betterment of Sif, And Vir as a whole.'\ +

\ + Mason Keldow says, 'Let's take a look Ms. Jorg.'\ +

\ + Mason Keldow says, 'She has LONG called me a Corporate sell-out, Saying I would poison the planet and other awful mudslinging.'\ +

\ + Mason Keldow says, 'She loves to claim she's here for the better of the misrepresented.'\ +

\ + Mason Keldow says, 'But when is the last time she's talked to a Tajaran and told them how they will help put food on the table, and money into their pockets.'\ +

\ + Mason Keldow says, 'When has she came and told the Unathi Exile, Your worth more than what the Hegemony is trying to convince you you're worth.'\ +

\ + Mason Keldow says, 'There's blood in the grass out there showing what I'm willing to do to make Sif and Vir a better more prosperous system. I wanna see what the other Candidates will do.'\ +

\ + Blip pings!\ +

\ + Blip says, 'Thank you for your time, Candidate Keldow. Unit looks forward to seeing where this race ends, and wishes Candidate the best of luck in his endeavours.'\ +

\ + Mason Keldow says, 'It's been a pleasure Blip.'" + +/datum/lore/codex/page/article39 + name = "02/12/63 - VirGov Launches Election Website" + data = "The Vir Governmental Authority has launched this year's election information exonet site, unusually several months after campaigning began. The government election agency states that the delay was caused by an usually long process of finalizing candidates this cycle, and did not want to confuse voters with incorrect or outdated information.\ +

\ + The newly updated site includes information on candidates and political parties, and is planned to include information on local voting rights at a future date. It can be found at:\ +

\ + your-choice-vir.virgov.xo.vr\ +

\ + (( https://your-choice-vir.weebly.com/ ))" + +/datum/lore/codex/page/article40 + name = "02/14/63 - Ultimatum Unmet: War With Almach!" + data = "The Solar Confederate Government has resumed a state of war against the secessionist Almach Association, after 4 months of tense ceasefire. The re-declaration comes after the Association failed to meet requirements set forth by the Colonial Assembly last November, which called for the cessation and destruction of all research that did not meet standards established by the Five Points of Human Sanctity.\ +

\ + The past few weeks have been marked by an increasing buildup of military forces on the Almach border as it became apparent that Almach had no intention of meeting Sol's demands. At 9am this morning, the deadline was met and initial reports from the frontline suggest relatively little action besides the destruction of pre-existing Almach scout drones that had been placed on the border several months prior. The exact plans of the fleet going forward have not been made public, but civilian traffic to and from the Saint Columbia system has been entirely suspended.\ +

\ + How this development will influence the coming Vir election remains to be seen, though SEO candidate Mason Keldow has reportedly ended his planetary tour 10 days earlier than planned due to the tense political situation." + +/datum/lore/codex/page/article41 + name = "02/22/63 - Militia Retreats: First Solar Victory" + data = "After a week of tense stand-offs and increasingly frequent skirmishes, the Association Militia has begun moving from their position around Saint Columbia further into the Almach Rim. The inciting incident for this shift seems to have been the first use of the MJOLNIR system, which instantly destroyed a large Almachi warship from half a system away. This demonstration was met with a standing ovation from much of Iserlohn, and Militia forces disengaged almost immediately. Admiral McMullen is unwilling to elaborate on pursuit or invasion plans at this moment, but 'hope(s) the MJOLNIR will continue to be a valuable asset for national defense.'" + +/datum/lore/codex/page/article42 + name = "03/04/63 - Savik Slams Local Chat Host" + data = "Television sweetheart Sally, host of Chat With Sally has come under harsh criticism from independent Vir gubernatorial candidate Yole Savik after his 'humiliating' appearance on the show yesterday morning alongside Sol Economic Organization candidate Calvert Moravec. Savik - who is campaigning for Vir independence from both the SCG and corporate interests - alleges that the show, which has run for 13 years on select networks, is 'little more than a propaganda piece for high powered executives.' and that his appearance had been part of a 'smear campaign' against non-SEO candidates.\ +

\ + NanoTrasen, who have openly sponsored Sally since her inception deny these accusations. Jan Bhatt of the NT marketing division stated 'Chat With Sally has always been intended as light morning entertainment, and Sally a personality we can all relate to. The fact that Mr. Savik was unable to have a sense of humour about the whole thing and took the show as an opportunity to bloviate about dry politics is not an indictment of Sally, nor the corporation but rather a simple misunderstanding of the purpose of the segment. We had hoped Mr. Savik's appearance would help dismiss any claims of political bias in our programming and hope to host more civil candidates in the future.'\ +

\ + Catch Chat With Sally weekly at 5am SST." + +/datum/lore/codex/page/article43 + name = "03/06/63 - Dark Triangle Goes Dark!" + data = "As of 0352 this morning, New Reykjavik time, SolGov officials confirmed that all communications coming from the so-called 'Dark Triangle' had ceased. The Dark Triangle is a disputed region of space home to the independent world Natuna, which has maintained a more or less neutral relationship with SolGov for a little more than a decade.\ +

\ + The announcement gives no cause for the communications blackout, though sources with inside knowledge claim that it was completely unforeseen. Some speculate that Natuna, who became an 'observer nation' of the Almach Association last November, is making a political statement, though experts in the telecommunications field are uncertain as to how such a complete blackout is possible.\ +

\ + Dr. Ina Lai from the Kara Interstellar Observatory states, 'we've never seen anything like this outside of the (Skrellian) Far Kingdoms, and frankly we're at a loss for who might be responsible,' adding that 'the tachyon signatures from the whole region are masked, even those from stellar phenomena or normal bluespace travel.' Independent explorers from the FTU have set out to the region in an attempt to re-establish communication with Natuna and smaller human settlements nearby." + +/datum/lore/codex/page/article44 + name = "03/08/63 - Dark Triangle Overrun By Hegemony" + data = "FTU explorers have re-established exonet communications with the ruling bodies of Natuna and the Dark Triangle. Unfortunately, they also discovered that Natuna's previously autonomous townships have been subsumed into the Moghes Hegemony. \ +

\ + Bluespace-lensed telescopes throughout SolGov, including the Vir-based Kara Interstellar Observatory, can once again pick up on tachyon signatures in the region. Traffic has been described as 'lower than usual' and no significant fleet assets are believed to be present in the region, though fixed-placement Hegemony installations now litter the Triangle's major star systems. Systems with significant Hegemony presence include Natuna and Ukupanipo, home to the primitive Uehshad species. Some have speculated that the presence of the Uehshad is the reason for the unexpected Hegemony takeover, though Icarus Front General Secretary Mackenzie West was quick to decry the move as 'an obvious imperial land-grab.'\ +

\ + Hegemony diplomats on Luna and elsewhere have been quick to justify their actions. 'The Dark Triangle has been home to various criminal elements for several centuries,' says Aksere Eko Azaris, a major Hegemony diplomat since the early post-war years. 'Neither the Skrell nor the Solar Confederacy have proven any willingness to bring stability to the region. Local governments such as Natuna have actively encouraged piracy, smuggling, and other acts of banditry, instead of making any moves to legitimize themselves. This instability proved detrimental to the health and wellbeing of all living within striking distance of the pirates of Ue-Orsi, and it was deemed unfortunate, but necessary, that we step in and provide the guiding hand by which this region might be brought back into the fold of civilization, as is our duty as sapients.'\ +

\ + In a statement closer to home,Commander Iheraer Saelho of the Zaddat Escort Fleet has assured VirGov that 'we only took action to protect the innocents of the Dark Triangle and of neighboring systems'.He asserts that Hegemony rule will ultimately benefit all races of people within the Triangle, and promises that, 'the people of Vir, of Oasis, of the Golden Crescent writ large, have nothing to fear from our clients the Zaddat, or from the Hegemony vessels assigned to their protection.'\ +

\ + Only time will tell if Saelho's promised peace and stability will manifest in truth. \ +

\ + This newfound militancy of the Hegemony is likely to become a major campaign issue in the upcoming Vir elections, alongside involvement in the war with the Almach Association and traditionally Virite issues of corporate authority, minority-friendly infrastructure, and taxation." + +/datum/lore/codex/page/article45 + name = "03/12/63 - Ue-Orsi Escapes Hegemony Triangle" + data = "The lawless 'Ue-Orsi' flotilla, home to hundreds of thousands of outcast Skrellian pirates, has departed from the Hegemony-controlled Dark Triangle after what appears to be a brief battle with several Unathi warships. The action damaged several important Orsian ships, including their massive and venerable solar array 'Suqot-Thoo'm', a development which is likely to increase the pirates' aggression in the coming months as they search for additional power sources. It is unclear exactly where the flotilla has fled, though best guesses indicate that they are presently in Skrell space, likely near the lightly-patrolled Xe'Teq system. The Moghes Hegemony is in negotiations with several Skrellian states to arrange for military action against their escaped subjects, but little headway has been made thus far.\ +

\ + This revelation has added more fuel to already heated Assembly arguments about SolGov response to the Unathi takeover. 'This is a prelude to invasion, nothing more and nothing less,' says New Seoul Representative Collin So-Yung, a noted Iconoclast. 'We must make it absolutely clear to the Hegemony that this is a threat we will not bow to, even in our present state of internal weakness. I suggest we pursue a fair peace with the Association, one where we can keep them as allies against this sort of encroachment instead of shattering our fleets during such a pivotal moment.'\ +

\ + Others took a more nuanced approach, including VGA Governor Bjorn Arielsson. 'What we have here is our punishment for how badly we've treated the people of the Triangle. I don't really see why we should have let the tired old racism of some Qerr-Katish oligarchs stop us from offering aid to their tired and huddled masses, such as it is. And because we have had a full century of ignoring their plight, they were defenceless to resist the Hegemony. I say we fling the doors open, let (the Orsians) settle some rock here, and show the unaligned powers of the galaxy that the Hegemony's way isn't the only way.'\ +

\ + Even more conciliatory was Speaker ISA-5, who Arielsson blames for mistreatment of the Ue-Katish. 'Our policy has always been that our defence budget cannot adequately defend the Dark Triangle from internal piracy, that Ue-Orsi is a criminal organization using their refugee status as a shield, and that we cannot lift the blockade of Natuna until they stop hosting these criminals and transition to a more sustainable economy. If Moghes has the power and the inclination to administer the Triangle, I see no reason why this state of affairs isn't better than the alternatives.'" + +/datum/lore/codex/page/article46 + name = "03/26/63 - Almach Routed from Saint Columbia" + data = "The Saint Columbia system has been declared free of Association forces following a renewed SCG offensive in the region. Admiral McMullen of the Saint Columbia garrison - who has reportedly reclaimed his post at the system's naval base despite the facility suffering moderate damage in this week's fighting - says that the last secessionist vessels were driven from the system just over 24 hours ago, and remaining pockets of resistance have been quick to lay down their arms. At least 20 enemy vessels - mostly converted civilian ships - have been confirmed disabled or destroyed in-system, thanks in no small part to the deployment of the state-of-the-art MJOLNIR weapons system.\ +

\ + This more aggressive approach to the Almach front comes on the tail of aggressive Hegemony deployments in the Dark Triangle, which SolGov has conceded was 'Immediately threatening, but after some deliberation, has brought some form of policing to a lawless region.'.\ +

\ + Despite assurances, this recent action would appear to many to be an effort to quash the Association threat and return fleet forces to the now extended Hegemony border, and some critics of the Almach War have called for a second ceasefire 'In order to focus on the real threat to mankind.'" + +/datum/lore/codex/page/article47 + name = "04/28/63 - Representative Hainirsdottir Reaffirms Pro-Vey Medical Manifesto" + data = "Incumbent Vir Representative Lusia Hainirsdottir has restated her dedication to advanced medical research at a public appearance at a Vey Medical facility in downtown New Reykjavik. Vey Medical has come under some criticism locally in the past year due to its 'accelerated' sapient trials, which Representative Hainirsdottir has strongly endorsed in her current term of office.\ +

\ + In her statement to staff at the New Reykjavik facility, Lusia promised that under her governorship, the company would not be reprimanded for the deadly Holburn's Disease outbreak in rural Sif this past June which claimed fifteen lives, and in which Vey-Med's involvement was only confirmed this week - as the outbreak 'directly lead' to the development of a new life-saving inoculation which has seen success galaxy-wide.\ +

\ + Hainirsdottir has long advocated for the promotion of scientific achievements that have taken place in, and undertaken by the people of Vir." + +/datum/lore/codex/page/article48 + name = "05/06/63 - Isak Spar Withdraws from Vir Election" + data = "Independent gubernatorial candidate Isak Spar has withdrawn his name from the running following a 'Public Relations disaster' aboard an orbital NanoTrasen logistics facility. According to witnesses, Spar acted belligerently towards staff members and engaged in vandalism and assault with a deadly weapon during his scheduled visit to the station, which the candidate had opted to undertake alone due to the temporary illness of his campaign manager.\ +

\ + In a statement just hours after the alleged incident, Isak announced that he would no longer be pursuing Vir Governorship, due to 'The unexpected stresses of a political career.' before plugging his upcoming album, C*** End Savage Turbo Death A** Destruction. The NanoTrasen corporation has decided not to press charges due to Mr. Spar 'Suffering the consequences on a far more significant level than a mere fine.' but will not be inviting Spar back for future visitation.\ +

\ + Spar's label, Skull Wreck Music has declined to comment at this time but has agreed to pay damages to the victims on behalf of the self-described 'post-pseudo electro-death superstar'." + +/datum/lore/codex/page/article49 + name = "05/15/63 - Solar Fleet Launches Offensive Against Almach" + data = "The first vessels of an SCG Fleet invasion force arrived in the Relan system this morning after a month-long intelligence operation to establish the Almach Association's most vulnerable positions, according to an announcement by Admiral McMullen just hours ago. Relan, which has long been fragmented between the neutral Republic of Taron and the once insurrectory Free Relan Federation - who now control the majority of the system and declared allegiance with Almach early in the crisis - is expected to fall to Confederate forces within 'a matter of weeks' due to its fractious political situation, and relative insignificance to Almach interests.\ +

\ + According to McMullen, the system's most populous habitat, the Carter Interstellar Spaceport is already under blockade and local resistance has thus far been minimal. The capture of Relan is expected to provide our forces with a major foothold in Almach territory and further advances are expected to be 'trivial', bypassing the Association's defensive positions in Angessa's Pearl.\ +

\ + The offensive comes weeks after sizable portions of the Fleet were publicly withdrawn from the frontline in order to reinforce the extended border with the Hegemony following their annexation of the Dark Triangle, and is a clear sign that - despite reduced numbers - Fleet command remains confident of Solar victory against the Mercurial rogue state." + +/datum/lore/codex/page/article50 + name = "05/19/63 - 'Drone Operated' Shelfican Ships Storm Sol Siege" + data = "Blockading Solar vessels in the Relan system came under fire today from automated craft originating from the Shelf fleet. The flotilla of drones, described by one survivor as a 'swarm', launched electromagnetic pulse and so-called 'hatch buster' precision missiles against three SCG Defense vessels, inflicting systems damage, and casualties 'in the hundreds' with at least eight service people already confirmed killed in action. The drones are reported to have withdrawn after 'only a few minutes of protracted fire from both sides.'\ +

\ + The Shelf telops fleet, which was spotted by Fleet forces but not identified as an immediate threat, entered the system early this morning and were understood to be acting as observers to the ongoing battle for the Relan system due to Shelf's official stance of non-aggression -- despite aligning itself with the Association. Shelf has reportedly been unable to be reached for comment on their actions, and their alleged neutrality in matters of war has been seriously called into question by many in the Colonial Assembly.\ +

\ + The SCG-D Krishna and SCG-D Mogwai of the SCG fleet, and the assisting Oasis logistical vessel, the OG-L Cloud Nine have been withdrawn to an unspecified location for immediate medical assistance and repairs." + +/datum/lore/codex/page/article51 + name = "05/20/63 - Fleet Withdraws - Sol On The Back Foot?" + data = "The Solar Colonial Assembly has confirmed that the Solar Fleet has withdrawn from the contested Relan system due to 'unexpected resistance' from Shelf tele-operated forces. This comes less than 24 hours after three Solar vessels were seriously damaged in an 'ambush' by a large number of Almach-aligned military drones. According to the Fleet, they were unprepared for any significant ship-to-ship combat in the system and will be consolidating their forces. 'This is not a defeat', according to Captain Silvain Astier of the SCG-R Hanoi, speaking unofficially to Occulum News sources 'This is merely a tactical withdrawal in order to reconvene and reassess our plans to restore order to the Almach Rim.'\ +

\ + A spokesperson for Shelf was quick to contact Fleet forces following the withdrawal with a formal apology for yesterday's incident, describing the previous day's attack as 'A terrible mistake.', blaming 'a miscommunication between our people in telops and the trigger-happy robots', though the veracity of their claims cannot be confirmed." + +/datum/lore/codex/page/article52 + name = "05/21/63 - NanoTrasen Station to Host Major Election Debate" + data = "As the Vir Gubernatorial elections approach, and with several high-profile debates lined up between the leading candidates in the polls, the NanoTrasen corporation is set to host its very own televised event live from one of its major logistical stations in Vir. The NLS Southern Cross, primarily a traffic control outpost managing shipping in Sif orbit, has been selected by the company to host the debate - funded in full by the corporation - due to a series of minor political scandals that have taken place on the platform, and the suitability of unused space onboard.\ +

\ + Early in the election cycle, NanoTrasen came under fire for its alleged 'manhandling' of Icarus Front candidate Vani Jee, and the confiscation of to-be-televised recordings taken by a party drone. While the company apologised for the incident shortly thereafter, the corporation hopes to mend ties with the potential future representatives by showing that they are capable of hosting civil discourse. More recently, the NLS Southern Cross played host to the 'breakdown' of disgraced former candidate Isak Spar - an episode which was not addressed in NanoTrasen's official statement on the planned debate event." + +/datum/lore/codex/page/article53 + name = "05/26/63 - SEO Candidate Advocates Murder On Live TV!" + data = "Sol Economic Organization candidate Freya Singh has been caught live on camera admitting that she would like to throw an innocent individual out of an airlock for a minor slight. During this afternoon's debate hosted aboard the NLS Southern Cross. Singh is quoted as having said that the event was 'the silliest concept for a debate I've encountered yet, and whoever came up with it should get a promotion, and then be fired out of an airlock.', a clear incitement of violence against Oculum Broadcast staff.\ +

\ + Magnus Dugal, 48 works for the Oculum Broadcast corporation and is credited with creating the concept for today's debate, the highest rated for this cycle so far. The father of three, who enjoys hoverboarding in his free time, says that he feels 'Threatened' by Singh's comments, and hopes that she will, 'at the bare minimum', issue an official apology to the company and himself.\ +

\ + Candidate Freya Singh, a career investment banker, spent much of today's debate advocating for reduced safety regulations and the apparent overturning of the Five Points, raising eyebrows across the system. Singh's office claims that her statements were 'a joke', but we do not feel that this is a laughing matter.\ +

\ + In related news, Shadow Coalition candidate Phaedrus remains under a profanity filter 'house arrest' for the remainder of the election." \ No newline at end of file diff --git a/code/modules/materials/material_recipes_vr.dm b/code/modules/materials/material_recipes_vr.dm index 9f8a323407..3278ca17d3 100644 --- a/code/modules/materials/material_recipes_vr.dm +++ b/code/modules/materials/material_recipes_vr.dm @@ -2,3 +2,7 @@ /material/steel/generate_recipes() . = ..() recipes += new/datum/stack_recipe("light switch frame", /obj/item/frame/lightswitch, 2) + +/material/durasteel/generate_recipes() + . = ..() + recipes += new/datum/stack_recipe("durasteel fishing rod", /obj/item/weapon/material/fishing_rod/modern/strong, 2) \ No newline at end of file diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm index 1fbecaec7e..4ca50889ea 100644 --- a/code/modules/materials/material_sheets.dm +++ b/code/modules/materials/material_sheets.dm @@ -99,7 +99,7 @@ icon_state = "sheet-adamantine" default_type = "lead" apply_colour = 1 - no_variants = TRUE + no_variants = FALSE /obj/item/stack/material/sandstone name = "sandstone brick" diff --git a/code/modules/metric/activity.dm b/code/modules/metric/activity.dm index c4acdc57ec..5bdc33f47a 100644 --- a/code/modules/metric/activity.dm +++ b/code/modules/metric/activity.dm @@ -80,3 +80,14 @@ num++ if(num) . = round(. / num, 0.1) + +/datum/metric/proc/assess_all_outdoor_mobs() + . = 0 + var/num = 0 + for(var/mob/living/L in player_list) + var/turf/T = get_turf(L) + if(istype(T) && !istype(T, /turf/space) && T.outdoors) + . += assess_player_activity(L) + num++ + if(num) + . = round(. / num, 0.1) diff --git a/code/modules/metric/count.dm b/code/modules/metric/count.dm new file mode 100644 index 0000000000..430f2fdd93 --- /dev/null +++ b/code/modules/metric/count.dm @@ -0,0 +1,21 @@ +/* + * Procs for counting active players in different situations. Returns the number of active players within the given cutoff. + */ + +/datum/metric/proc/count_all_outdoor_mobs(var/cutoff = 75) + var/num = 0 + for(var/mob/living/L in player_list) + var/turf/T = get_turf(L) + if(istype(T) && !istype(T, /turf/space) && T.outdoors) + if(assess_player_activity(L) >= cutoff) + num++ + return num + +/datum/metric/proc/count_all_space_mobs(var/cutoff = 75) + var/num = 0 + for(var/mob/living/L in player_list) + var/turf/T = get_turf(L) + if(istype(T, /turf/space)) + if(assess_player_activity(L) >= cutoff) + num++ + return num diff --git a/code/modules/metric/department.dm b/code/modules/metric/department.dm index ef146de506..b6996d229c 100644 --- a/code/modules/metric/department.dm +++ b/code/modules/metric/department.dm @@ -69,4 +69,4 @@ for(var/mob/M in player_list) if(guess_department(M) != department) // Ignore people outside the department we're counting. continue - . += 1 \ No newline at end of file + . += 1 diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index 1f4391a67b..e857e97c5e 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -21,6 +21,7 @@ new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200), new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900), new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300), + new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/mining, 100), // TODO new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800), new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500), new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 500), @@ -55,7 +56,8 @@ new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), new /datum/data/mining_equipment("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500), - new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000) + new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), + new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500) ) //VOREStation Edit End diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index a3bf0d5465..31cbcc1f44 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -399,7 +399,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if (!target)//Make sure we actually have a target return else - var/mob/M = getmobs()[target] //Destination mob + var/mob/M = target //Destination mob var/turf/T = get_turf(M) //Turf of the destination mob if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 5408742654..693b2129e1 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -33,7 +33,7 @@ if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages if(!say_understands(speaker,language)) if(language) - message = language.scramble(message) + message = language.scramble(message, languages) else message = stars(message) @@ -165,7 +165,7 @@ if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages if(!say_understands(speaker,language)) if(language) - message = language.scramble(message) + message = language.scramble(message, languages) else message = stars(message) diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index 5a46a72038..8fa9efcd73 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -32,6 +32,7 @@ syllables = list( "vol", "zum", "coo","zoo","bi","do","ooz","ite","og","re","si","ite","ish", "ar","at","on","ee","east","ma","da", "rim") + partial_understanding = list(LANGUAGE_SKRELLIAN = 30, LANGUAGE_SOL_COMMON = 30) //TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. /datum/language/common/get_spoken_verb(var/msg_end) @@ -64,6 +65,7 @@ colour = "terminus" key = "4" // flags = WHITELISTED (VOREstation edit) + // partial_understanding = list(LANGUAGE_SOL_COMMON = 20) (VOREStation Edit: It is a Zorren language now) syllables = list (".a", "spa", "pan", "blaif", "stra", "!u", "!ei", "!am", "by", ".y", "gry", "zbly", "!y", "fl", "sm", "rn", "cpi", "ku", "koi", "pr", "glau", "stu", "ved", "ki", "tsa", "xau", "jbu", "sny", "stro", "nu", "uan", "ju", "!i", "ge", "luk", "an", "ar", "at", "es", "et", "bel", "ki", "jaa", "ch", "ki", "gh", "ll", "uu", "wat") @@ -76,6 +78,7 @@ colour = "rough" key = "3" space_chance = 45 + partial_understanding = list(LANGUAGE_GALCOM = 10, LANGUAGE_TRADEBAND = 20, LANGUAGE_SOL_COMMON = 20) syllables = list ( "gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra", "a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", @@ -211,4 +214,4 @@ ) /datum/language/gibberish/can_speak_special(var/mob/speaker) - return TRUE //Anyone can speak gibberish \ No newline at end of file + return TRUE //Anyone can speak gibberish diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 4822f46a16..f558301b15 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -19,6 +19,7 @@ var/list/syllables // Used when scrambling text for a non-speaker. var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string var/machine_understands = 1 // Whether machines can parse and understand this language + var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2) if(!syllables || !syllables.len) @@ -41,8 +42,42 @@ /datum/language var/list/scramble_cache = list() -/datum/language/proc/scramble(var/input) +/datum/language/proc/scramble(var/input, var/list/known_languages) + var/understand_chance = 0 + for(var/datum/language/L in known_languages) + if(partial_understanding && partial_understanding[L.name]) + understand_chance += partial_understanding[L.name] + if(L.partial_understanding && L.partial_understanding[name]) + understand_chance += L.partial_understanding[name] * 0.5 + var/scrambled_text = "" + var/list/words = splittext(input, " ") + for(var/w in words) + if(prob(understand_chance)) + scrambled_text += " [w] " + else + var/nword = scramble_word(w) + var/ending = copytext(scrambled_text, length(scrambled_text)-1) + if(findtext(ending,".")) + nword = capitalize(nword) + else if(findtext(ending,"!")) + nword = capitalize(nword) + else if(findtext(ending,"?")) + nword = capitalize(nword) + scrambled_text += nword + scrambled_text = replacetext(scrambled_text," "," ") + scrambled_text = capitalize(scrambled_text) + scrambled_text = trim(scrambled_text) + var/ending = copytext(scrambled_text, length(scrambled_text)) + if(ending == ".") + scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) + var/input_ending = copytext(input, length(input)) + if(input_ending in list("!","?",".")) + scrambled_text += input_ending + + return scrambled_text + +/datum/language/proc/scramble_word(var/input) if(!syllables || !syllables.len) return stars(input) @@ -55,7 +90,7 @@ var/input_size = length(input) var/scrambled_text = "" - var/capitalize = 1 + var/capitalize = 0 while(length(scrambled_text) < input_size) var/next = pick(syllables) @@ -70,14 +105,6 @@ else if(chance > 5 && chance <= space_chance) scrambled_text += " " - scrambled_text = trim(scrambled_text) - var/ending = copytext(scrambled_text, length(scrambled_text)) - if(ending == ".") - scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) - var/input_ending = copytext(input, input_size) - if(input_ending in list("!","?",".")) - scrambled_text += input_ending - // Add it to cache, cutting old entries if the list is too long scramble_cache[input] = scrambled_text if(scramble_cache.len > SCRAMBLE_CACHE_LEN) diff --git a/code/modules/mob/language/monkey.dm b/code/modules/mob/language/monkey.dm index c6024d346b..782c5bcf24 100644 --- a/code/modules/mob/language/monkey.dm +++ b/code/modules/mob/language/monkey.dm @@ -5,24 +5,28 @@ ask_verb = "chimpers" exclaim_verb = "screeches" key = "6" + syllables = list("ook","eek") machine_understands = 0 /datum/language/skrell/monkey name = "Neaera" desc = "Squik squik squik." key = "8" + syllables = list("hiss","gronk") machine_understands = 0 /datum/language/unathi/monkey name = "Stok" desc = "Hiss hiss hiss." key = "7" + syllables = list("squick","croak") machine_understands = 0 /datum/language/tajaran/monkey name = "Farwa" desc = "Meow meow meow." key = "9" + syllables = list("meow","mew") machine_understands = 0 /datum/language/corgi diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index bfff010d03..882a7d934b 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -208,6 +208,18 @@ name = "broken component" icon = 'icons/obj/robot_component.dmi' icon_state = "broken" + matter = list(DEFAULT_WALL_MATERIAL = 1000) + +/obj/item/broken_device/random + var/list/possible_icons = list("binradio_broken", + "motor_broken", + "armor_broken", + "camera_broken", + "analyser_broken", + "radio_broken") + +/obj/item/broken_device/random/Initialize() + icon_state = pick(possible_icons) /obj/item/robot_parts/robot_component icon = 'icons/obj/robot_component.dmi' diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm index 31a7301d9f..25c0ca1a07 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm @@ -181,6 +181,7 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb + R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() /obj/item/weapon/robot_module/robot/knine/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) @@ -256,6 +257,7 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb + R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() /obj/item/weapon/robot_module/robot/ert @@ -303,6 +305,7 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb + R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() /obj/item/weapon/robot_module/robot/scrubpup @@ -383,6 +386,7 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb + R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() /obj/item/weapon/robot_module/robot/science @@ -428,6 +432,7 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb + R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() /obj/item/weapon/robot_module/robot/engiedog @@ -554,6 +559,7 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb + R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() /obj/item/weapon/robot_module/Reset(var/mob/living/silicon/robot/R) @@ -568,4 +574,5 @@ R.verbs -= /mob/living/silicon/robot/proc/ex_reserve_refill R.verbs -= /mob/living/silicon/robot/proc/robot_mount R.verbs -= /mob/living/proc/shred_limb + R.verbs -= /mob/living/silicon/robot/proc/rest_style ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_vr.dm b/code/modules/mob/living/silicon/robot/robot_vr.dm index 33e7cc4796..e66ad05ec9 100644 --- a/code/modules/mob/living/silicon/robot/robot_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_vr.dm @@ -12,6 +12,8 @@ var/notransform var/original_icon = 'icons/mob/robots.dmi' var/ui_style_vr = FALSE //Do we use our hud icons? + var/sitting = FALSE + var/bellyup = FALSE does_spin = FALSE var/vr_icons = list( "handy-hydro", @@ -50,6 +52,21 @@ return return feed_grabbed_to_self(src,T) +/mob/living/silicon/robot/proc/rest_style() + set name = "Switch Rest Style" + set category = "IC" + set desc = "Select your resting pose." + sitting = FALSE + bellyup = FALSE + var/choice = alert(src, "Select resting pose", "", "Resting", "Sitting", "Belly up") + switch(choice) + if("Resting") + return 0 + if("Sitting") + sitting = TRUE + if("Belly up") + bellyup = TRUE + /mob/living/silicon/robot/updateicon() vr_sprite_check() ..() @@ -66,7 +83,12 @@ add_overlay("eyes-[module_sprites[icontype]]-lights") if(resting) cut_overlays() // Hide that gut for it has no ground sprite yo. - icon_state = "[module_sprites[icontype]]-rest" + if(sitting) + icon_state = "[module_sprites[icontype]]-sit" + if(bellyup) + icon_state = "[module_sprites[icontype]]-bellyup" + else if(!sitting && !bellyup) + icon_state = "[module_sprites[icontype]]-rest" else icon_state = "[module_sprites[icontype]]" if(dogborg == TRUE && stat == DEAD) diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm index 5e554a0f8a..140deb0b24 100644 --- a/code/modules/mob/living/simple_animal/animals/cat.dm +++ b/code/modules/mob/living/simple_animal/animals/cat.dm @@ -1,198 +1,193 @@ -//Cat -/mob/living/simple_mob/cat - name = "cat" - desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." - tt_desc = "E Felis silvestris catus" - intelligence_level = SA_ANIMAL - icon_state = "cat2" - item_state = "cat2" - icon_living = "cat2" - icon_dead = "cat2_dead" - icon_rest = "cat2_rest" - - investigates = 1 - specific_targets = 1 //Only targets with Found() - run_at_them = 0 //DOMESTICATED - view_range = 5 - - turns_per_move = 5 - see_in_dark = 6 - - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - - min_oxy = 16 //Require atleast 16kPA oxygen - minbodytemp = 223 //Below -50 Degrees Celcius - maxbodytemp = 323 //Above 50 Degrees Celcius - - holder_type = /obj/item/weapon/holder/cat - mob_size = MOB_SMALL - - has_langs = list("Cat") - speak_chance = 1 - speak = list("Meow!","Esp!","Purr!","HSSSSS") - speak_emote = list("purrs", "meows") - emote_hear = list("meows","mews") - emote_see = list("shakes their head", "shivers") - say_maybe_target = list("Meow?","Mew?","Mao?") - say_got_target = list("MEOW!","HSSSS!","REEER!") - - meat_amount = 1 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat - - var/turns_since_scan = 0 - var/mob/flee_target - -/mob/living/simple_mob/cat/Life() - . = ..() - if(!.) return - - if(prob(2)) //spooky - var/mob/observer/dead/spook = locate() in range(src,5) - if(spook) - var/turf/T = spook.loc - var/list/visible = list() - for(var/obj/O in T.contents) - if(!O.invisibility && O.name) - visible += O - if(visible.len) - var/atom/A = pick(visible) - visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].") - - handle_flee_target() - -/mob/living/simple_mob/cat/PunchTarget() - if(ismouse(target_mob)) - var/mob/living/simple_mob/animal/passive/mouse/mouse = target_mob - mouse.splat() - visible_emote(pick("bites \the [mouse]!","toys with \the [mouse].","chomps on \the [mouse]!")) - return mouse - else - ..() - -/mob/living/simple_mob/cat/Found(var/atom/found_atom) - if(ismouse(found_atom) && SA_attackable(found_atom)) - return found_atom - -/mob/living/simple_mob/cat/proc/handle_flee_target() - //see if we should stop fleeing - if (flee_target && !(flee_target in ListTargets(view_range))) - flee_target = null - GiveUpMoving() - - if (flee_target && !stat && !buckled) - if (resting) - lay_down() - if(prob(25)) say("HSSSSS") - stop_automated_movement = 1 - walk_away(src, flee_target, 7, 2) - -/mob/living/simple_mob/cat/react_to_attack(var/atom/A) - if(A == src) return - flee_target = A - turns_since_scan = 5 - -/mob/living/simple_mob/cat/ex_act() - . = ..() - react_to_attack(src.loc) - -//Basic friend AI -/mob/living/simple_mob/cat/fluff - var/mob/living/carbon/human/friend - var/befriend_job = null - -/mob/living/simple_mob/cat/fluff/Life() - . = ..() - if(!. || ai_inactive || !friend) return - - var/friend_dist = get_dist(src,friend) - - if (friend_dist <= 4) - if(stance == STANCE_IDLE) - if(set_follow(friend)) - handle_stance(STANCE_FOLLOW) - - if (friend_dist <= 1) - if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) - if (prob((friend.stat < DEAD)? 50 : 15)) - var/verb = pick("meows", "mews", "mrowls") - audible_emote(pick("[verb] in distress.", "[verb] anxiously.")) - else - if (prob(5)) - visible_emote(pick("nuzzles [friend].", - "brushes against [friend].", - "rubs against [friend].", - "purrs.")) - else if (friend.health <= 50) - if (prob(10)) - var/verb = pick("meows", "mews", "mrowls") - audible_emote("[verb] anxiously.") - -/mob/living/simple_mob/cat/fluff/verb/become_friends() - set name = "Become Friends" - set category = "IC" - set src in view(1) - - if(!friend) - var/mob/living/carbon/human/H = usr - if(istype(H) && (!befriend_job || H.job == befriend_job)) - friend = usr - . = 1 - else if(usr == friend) - . = 1 //already friends, but show success anyways - - if(.) - set_dir(get_dir(src, friend)) - visible_emote(pick("nuzzles [friend].", - "brushes against [friend].", - "rubs against [friend].", - "purrs.")) - else - usr << "[src] ignores you." - return - -//RUNTIME IS ALIVE! SQUEEEEEEEE~ -/mob/living/simple_mob/cat/fluff/Runtime - name = "Runtime" - desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." - tt_desc = "E Felis silvestris medicalis" //a hypoallergenic breed produced by NT for... medical purposes? Sure. - gender = FEMALE - icon_state = "cat" - item_state = "cat" - icon_living = "cat" - icon_dead = "cat_dead" - icon_rest = "cat_rest" - befriend_job = "Chief Medical Officer" - -/mob/living/simple_mob/cat/kitten - name = "kitten" - desc = "D'aaawwww" - icon_state = "kitten" - item_state = "kitten" - icon_living = "kitten" - icon_dead = "kitten_dead" - gender = NEUTER - -// Leaving this here for now. -/obj/item/weapon/holder/cat/fluff/bones - name = "Bones" - desc = "It's Bones! Meow." - gender = MALE - icon_state = "cat3" - -/mob/living/simple_mob/cat/fluff/bones - name = "Bones" - desc = "That's Bones the cat. He's a laid back, black cat. Meow." - gender = MALE - icon_state = "cat3" - item_state = "cat3" - icon_living = "cat3" - icon_dead = "cat3_dead" - icon_rest = "cat3_rest" - holder_type = /obj/item/weapon/holder/cat/fluff/bones - var/friend_name = "Erstatz Vryroxes" - -/mob/living/simple_mob/cat/kitten/New() - gender = pick(MALE, FEMALE) - ..() \ No newline at end of file +//Cat +/mob/living/simple_animal/cat + name = "cat" + desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." + tt_desc = "E Felis silvestris catus" + intelligence_level = SA_ANIMAL + icon_state = "cat2" + item_state = "cat2" + icon_living = "[initial(icon_state)]" + icon_dead = "[initial(icon_state)]_dead" + icon_rest = "[initial(icon_state)]_rest" + + investigates = 1 + specific_targets = 1 //Only targets with Found() + run_at_them = 0 //DOMESTICATED + view_range = 5 + + turns_per_move = 5 + see_in_dark = 6 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + min_oxy = 16 //Require atleast 16kPA oxygen + minbodytemp = 223 //Below -50 Degrees Celcius + maxbodytemp = 323 //Above 50 Degrees Celcius + + holder_type = /obj/item/weapon/holder/cat + mob_size = MOB_SMALL + + has_langs = list("Cat") + speak_chance = 1 + speak = list("Meow!","Esp!","Purr!","HSSSSS") + speak_emote = list("purrs", "meows") + emote_hear = list("meows","mews") + emote_see = list("shakes their head", "shivers") + say_maybe_target = list("Meow?","Mew?","Mao?") + say_got_target = list("MEOW!","HSSSS!","REEER!") + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/turns_since_scan = 0 + var/mob/flee_target + +/mob/living/simple_animal/cat/Life() + . = ..() + if(!.) return + + if(prob(2)) //spooky + var/mob/observer/dead/spook = locate() in range(src,5) + if(spook) + var/turf/T = spook.loc + var/list/visible = list() + for(var/obj/O in T.contents) + if(!O.invisibility && O.name) + visible += O + if(visible.len) + var/atom/A = pick(visible) + visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].") + + handle_flee_target() + +/mob/living/simple_animal/cat/PunchTarget() + if(ismouse(target_mob)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = target_mob + mouse.splat() + visible_emote(pick("bites \the [mouse]!","toys with \the [mouse].","chomps on \the [mouse]!")) + return mouse + else + ..() + +/mob/living/simple_animal/cat/Found(var/atom/found_atom) + if(ismouse(found_atom) && SA_attackable(found_atom)) + return found_atom + +/mob/living/simple_animal/cat/proc/handle_flee_target() + //see if we should stop fleeing + if (flee_target && !(flee_target in ListTargets(view_range))) + flee_target = null + GiveUpMoving() + + if (flee_target && !stat && !buckled) + if (resting) + lay_down() + if(prob(25)) say("HSSSSS") + stop_automated_movement = 1 + walk_away(src, flee_target, 7, 2) + +/mob/living/simple_animal/cat/react_to_attack(var/atom/A) + if(A == src) return + flee_target = A + turns_since_scan = 5 + +/mob/living/simple_animal/cat/ex_act() + . = ..() + react_to_attack(src.loc) + +//Basic friend AI +/mob/living/simple_animal/cat/fluff + var/mob/living/carbon/human/friend + var/befriend_job = null + var/friend_name = null + +/mob/living/simple_animal/cat/fluff/Life() + . = ..() + if(!. || ai_inactive || !friend) return + + var/friend_dist = get_dist(src,friend) + + if (friend_dist <= 4) + if(stance == STANCE_IDLE) + if(set_follow(friend)) + handle_stance(STANCE_FOLLOW) + + if (friend_dist <= 1) + if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) + if (prob((friend.stat < DEAD)? 50 : 15)) + var/verb = pick("meows", "mews", "mrowls") + audible_emote(pick("[verb] in distress.", "[verb] anxiously.")) + else + if (prob(5)) + visible_emote(pick("nuzzles [friend].", + "brushes against [friend].", + "rubs against [friend].", + "purrs.")) + else if (friend.health <= 50) + if (prob(10)) + var/verb = pick("meows", "mews", "mrowls") + audible_emote("[verb] anxiously.") + +/mob/living/simple_animal/cat/fluff/verb/become_friends() + set name = "Become Friends" + set category = "IC" + set src in view(1) + + if(!friend) + var/mob/living/carbon/human/H = usr + if(istype(H) && (!befriend_job || H.job == befriend_job) && (!friend_name || H.real_name == friend_name)) + friend = usr + . = 1 + else if(usr == friend) + . = 1 //already friends, but show success anyways + + if(.) + set_dir(get_dir(src, friend)) + visible_emote(pick("nuzzles [friend].", + "brushes against [friend].", + "rubs against [friend].", + "purrs.")) + else + usr << "[src] ignores you." + return + +//RUNTIME IS ALIVE! SQUEEEEEEEE~ +/mob/living/simple_animal/cat/fluff/Runtime + name = "Runtime" + desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." + tt_desc = "E Felis silvestris medicalis" //a hypoallergenic breed produced by NT for... medical purposes? Sure. + gender = FEMALE + icon_state = "cat" + item_state = "cat" + befriend_job = "Chief Medical Officer" + +/mob/living/simple_animal/cat/kitten + name = "kitten" + desc = "D'aaawwww" + icon_state = "kitten" + item_state = "kitten" + icon_living = "kitten" + icon_dead = "kitten_dead" + gender = NEUTER + +// Leaving this here for now. +/obj/item/weapon/holder/cat/fluff/bones + name = "Bones" + desc = "It's Bones! Meow." + gender = MALE + icon_state = "cat3" + +/mob/living/simple_animal/cat/fluff/bones + name = "Bones" + desc = "That's Bones the cat. He's a laid back, black cat. Meow." + gender = MALE + icon_state = "cat3" + item_state = "cat3" + holder_type = /obj/item/weapon/holder/cat/fluff/bones + friend_name = "Erstatz Vryroxes" + +/mob/living/simple_animal/cat/kitten/New() + gender = pick(MALE, FEMALE) + ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm index 3f6bba4846..11d1c0e504 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm @@ -1,147 +1,181 @@ -/mob/living/simple_mob/animal/passive/cat - name = "cat" - desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." - tt_desc = "E Felis silvestris catus" - icon_state = "cat2" - item_state = "cat2" - icon_living = "cat2" - icon_dead = "cat2_dead" - icon_rest = "cat2_rest" - - movement_cooldown = 0.5 SECONDS - - see_in_dark = 6 // Not sure if this actually works. - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - - holder_type = /obj/item/weapon/holder/cat - mob_size = MOB_SMALL - - has_langs = list("Cat") - - var/mob/living/friend = null // Our best pal, who we'll follow. Meow. - var/friend_name = null //VOREStation Edit - Lock befriending to this character - -/mob/living/simple_mob/animal/passive/cat/handle_special() - if(!stat && prob(2)) // spooky - var/mob/observer/dead/spook = locate() in range(src, 5) - if(spook) - var/turf/T = get_turf(spook) - var/list/visible = list() - for(var/obj/O in T.contents) - if(!O.invisibility && O.name) - visible += O - if(visible.len) - var/atom/A = pick(visible) - visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].") - -// Instakills mice. -/mob/living/simple_mob/animal/passive/cat/apply_melee_effects(var/atom/A) - if(ismouse(A)) - var/mob/living/simple_mob/animal/passive/mouse/mouse = A - if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something. - mouse.splat() - visible_emote(pick("bites \the [mouse]!", "toys with \the [mouse].", "chomps on \the [mouse]!")) - else - ..() - -/mob/living/simple_mob/animal/passive/cat/IIsAlly(mob/living/L) - if(L == friend) // Always be pals with our special friend. - return TRUE - - . = ..() - - if(.) // We're pals, but they might be a dirty mouse... - if(ismouse(L)) - return FALSE // Cats and mice can never get along. - -/mob/living/simple_mob/animal/passive/cat/verb/become_friends() - set name = "Become Friends" - set category = "IC" - set src in view(1) - - var/mob/living/L = usr - if(!istype(L)) - return // Fuck off ghosts. - - if(friend) - if(friend == usr) - to_chat(L, span("notice", "\The [src] is already your friend! Meow!")) - return - else - to_chat(L, span("warning", "\The [src] ignores you.")) - return - - //VOREStation Edit Start - Adds friend_name var checks - if(!friend_name || L.real_name == friend_name) - friend = L - face_atom(L) - to_chat(L, span("notice", "\The [src] is now your friend! Meow.")) - visible_emote(pick("nuzzles [friend].", "brushes against [friend].", "rubs against [friend].", "purrs.")) - - if(has_AI()) - var/datum/ai_holder/AI = ai_holder - AI.set_follow(friend) - else - to_chat(L, span("notice", "[src] ignores you.")) - //VOREStation Edit End - -//RUNTIME IS ALIVE! SQUEEEEEEEE~ -/mob/living/simple_mob/animal/passive/cat/runtime - name = "Runtime" - desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." - tt_desc = "E Felis silvestris medicalis" // a hypoallergenic breed produced by NT for... medical purposes? Sure. - gender = FEMALE - icon_state = "cat" - item_state = "cat" - icon_living = "cat" - icon_dead = "cat_dead" - icon_rest = "cat_rest" - makes_dirt = FALSE //VOREStation edit: no more dirt - -/mob/living/simple_mob/animal/passive/cat/kitten - name = "kitten" - desc = "D'aaawwww" - icon_state = "kitten" - item_state = "kitten" - icon_living = "kitten" - icon_dead = "kitten_dead" - gender = NEUTER - holder_type = /obj/item/weapon/holder/cat/kitten //VOREStation Edit - -/mob/living/simple_mob/animal/passive/cat/kitten/Initialize() - if(gender == NEUTER) - gender = pick(MALE, FEMALE) - return ..() - -// Leaving this here for now. -/obj/item/weapon/holder/cat/fluff/bones - name = "Bones" - desc = "It's Bones! Meow." - gender = MALE - icon_state = "cat3" - -/mob/living/simple_mob/animal/passive/cat/bones - name = "Bones" - desc = "That's Bones the cat. He's a laid back, black cat. Meow." - gender = MALE - icon_state = "cat3" - item_state = "cat3" - icon_living = "cat3" - icon_dead = "cat3_dead" - icon_rest = "cat3_rest" - holder_type = /obj/item/weapon/holder/cat/fluff/bones - - -/datum/say_list/cat - speak = list("Meow!","Esp!","Purr!","HSSSSS") - emote_hear = list("meows","mews") - emote_see = list("shakes their head", "shivers") - say_maybe_target = list("Meow?","Mew?","Mao?") - say_got_target = list("MEOW!","HSSSS!","REEER!") - -// VOREStation Edit - Adds generic tactical kittens -/obj/item/weapon/holder/cat/kitten - icon_state = "kitten" - w_class = ITEMSIZE_SMALL +/mob/living/simple_mob/animal/passive/cat + name = "cat" + desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." + tt_desc = "E Felis silvestris catus" + icon_state = "cat2" + item_state = "cat2" + + movement_cooldown = 0.5 SECONDS + + see_in_dark = 6 // Not sure if this actually works. + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + holder_type = /obj/item/weapon/holder/cat + mob_size = MOB_SMALL + + has_langs = list("Cat") + + var/mob/living/friend = null // Our best pal, who we'll follow. Meow. + var/named = FALSE //have I been named yet? + var/friend_name = null //VOREStation Edit - Lock befriending to this character + +/mob/living/simple_mob/animal/passive/cat/Initialize() + icon_living = "[initial(icon_state)]" + icon_dead = "[initial(icon_state)]_dead" + icon_rest = "[initial(icon_state)]_rest" + update_icon() + return ..() + +/mob/living/simple_mob/animal/passive/cat/handle_special() + if(!stat && prob(2)) // spooky + var/mob/observer/dead/spook = locate() in range(src, 5) + if(spook) + var/turf/T = get_turf(spook) + var/list/visible = list() + for(var/obj/O in T.contents) + if(!O.invisibility && O.name) + visible += O + if(visible.len) + var/atom/A = pick(visible) + visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].") + +// Instakills mice. +/mob/living/simple_mob/animal/passive/cat/apply_melee_effects(var/atom/A) + if(ismouse(A)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = A + if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something. + mouse.splat() + visible_emote(pick("bites \the [mouse]!", "toys with \the [mouse].", "chomps on \the [mouse]!")) + else + ..() + +/mob/living/simple_mob/animal/passive/cat/IIsAlly(mob/living/L) + if(L == friend) // Always be pals with our special friend. + return TRUE + + . = ..() + + if(.) // We're pals, but they might be a dirty mouse... + if(ismouse(L)) + return FALSE // Cats and mice can never get along. + +/mob/living/simple_mob/animal/passive/cat/verb/become_friends() + set name = "Become Friends" + set category = "IC" + set src in view(1) + + var/mob/living/L = usr + if(!istype(L)) + return // Fuck off ghosts. + + if(friend) + if(friend == usr) + to_chat(L, span("notice", "\The [src] is already your friend! Meow!")) + return + else + to_chat(L, span("warning", "\The [src] ignores you.")) + return + + //VOREStation Edit Start - Adds friend_name var checks + if(!friend_name || L.real_name == friend_name) + friend = L + face_atom(L) + to_chat(L, span("notice", "\The [src] is now your friend! Meow.")) + visible_emote(pick("nuzzles [friend].", "brushes against [friend].", "rubs against [friend].", "purrs.")) + + if(has_AI()) + var/datum/ai_holder/AI = ai_holder + AI.set_follow(friend) + else + to_chat(L, span("notice", "[src] ignores you.")) + //VOREStation Edit End + + +//RUNTIME IS ALIVE! SQUEEEEEEEE~ +/mob/living/simple_mob/animal/passive/cat/runtime + name = "Runtime" + desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." + tt_desc = "E Felis silvestris medicalis" // a hypoallergenic breed produced by NT for... medical purposes? Sure. + gender = FEMALE + icon_state = "cat" + item_state = "cat" + named = TRUE + +/mob/living/simple_mob/animal/passive/cat/kitten + name = "kitten" + desc = "D'aaawwww!" + icon_state = "kitten" + item_state = "kitten" + gender = NEUTER + holder_type = /obj/item/weapon/holder/cat/kitten //VOREStation Edit + +/mob/living/simple_mob/animal/passive/cat/kitten/Initialize() + if(gender == NEUTER) + gender = pick(MALE, FEMALE) + return ..() + +/mob/living/simple_mob/animal/passive/cat/black + icon_state = "cat" + item_state = "cat" + +// Leaving this here for now. +/obj/item/weapon/holder/cat/fluff/bones + name = "Bones" + desc = "It's Bones! Meow." + gender = MALE + icon_state = "cat3" + +/mob/living/simple_mob/animal/passive/cat/bones + name = "Bones" + desc = "That's Bones the cat. He's a laid back, black cat. Meow." + gender = MALE + icon_state = "cat3" + item_state = "cat3" + named = TRUE + holder_type = /obj/item/weapon/holder/cat/fluff/bones + +// VOREStation Edit - Adds generic tactical kittens +/obj/item/weapon/holder/cat/kitten + icon_state = "kitten" + w_class = ITEMSIZE_SMALL + +/datum/say_list/cat + speak = list("Meow!","Esp!","Purr!","HSSSSS") + emote_hear = list("meows","mews") + emote_see = list("shakes their head", "shivers") + say_maybe_target = list("Meow?","Mew?","Mao?") + say_got_target = list("MEOW!","HSSSS!","REEER!") + +/mob/living/simple_mob/animal/passive/cat/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) + if(named) + to_chat(user, "\the [name] already has a name!") + else + var/tmp_name = sanitizeSafe(input(user, "Give \the [name] a name", "Name"), MAX_NAME_LEN) + if(length(tmp_name) > 50) + to_chat(user, "The name can be at most 50 characters long.") + else + to_chat(user, "You name \the [name]. Meow!") + name = tmp_name + named = TRUE + else + ..() + +/obj/item/weapon/cat_box + name = "faintly purring box" + desc = "This box is purring faintly. You're pretty sure there's a cat inside it." + icon = 'icons/obj/storage.dmi' + icon_state = "box" + var/cattype = /mob/living/simple_mob/animal/passive/cat + +/obj/item/weapon/cat_box/attack_self(var/mob/user) + var/turf/catturf = get_turf(src) + to_chat(user, "You peek into \the [name]-- and a cat jumps out!") + new cattype(catturf) + new /obj/item/stack/material/cardboard(catturf) //if i fits i sits + qdel(src) + +/obj/item/weapon/cat_box/black + cattype = /mob/living/simple_mob/animal/passive/cat/black diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm index c7fc27e56e..a63140ac8a 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm @@ -44,8 +44,6 @@ icon = 'icons/mob/custom_items_mob.dmi' icon_state = "kitten" item_state = "kitten" - icon_living = "kitten" - icon_dead = "kitten" //Teleports out gender = MALE holder_type = /obj/item/weapon/holder/cat/fluff/tabiranth friend_name = "Ascian" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm index 3f04c0d28a..b06f5ed4f9 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm @@ -138,9 +138,10 @@ var/global/list/grub_machine_overlays = list() sparks.start() if(machine_effect) QDEL_NULL(machine_effect) - set_AI_busy(FALSE) ai_holder.target = null powermachine.draining = 1 + spawn(30) + set_AI_busy(FALSE) /mob/living/simple_mob/animal/solargrub_larva/proc/do_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent) if(!vent) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8bc63b8c7a..40aeeff408 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -730,7 +730,7 @@ listed_turf = null else if(statpanel("Turf")) - stat("\icon[listed_turf]", listed_turf.name) + stat(listed_turf) for(var/atom/A in listed_turf) if(!A.mouse_opacity) continue diff --git a/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm index 86ccaa73bc..c769fe21e2 100644 --- a/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm +++ b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm @@ -42,6 +42,10 @@ for(var/z in (data["map_levels"] | T.z)) // Always show crew from the current Z even if we can't show a map data["crewmembers"] += crew_repository.health_data(z) + if(!data["map_levels"].len) + to_chat(user, "The crew monitor doesn't seem like it'll work here.") + return + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800, state = state) diff --git a/code/modules/multi-tile/multi-tile.dm b/code/modules/multi-tile/multi-tile.dm new file mode 100644 index 0000000000..b8dd9ef512 --- /dev/null +++ b/code/modules/multi-tile/multi-tile.dm @@ -0,0 +1,28 @@ +/* + * This is the home of multi-tile movement checks, and thus here be dragons. You are warned. + */ + +/atom/movable/proc/check_multi_tile_move_density_dir(var/stepdir) + if(!locs || !locs.len) + return TRUE + + if(bound_height > 32 || bound_width > 32) + var/safe_move = TRUE + var/list/checked_turfs = list() + for(var/turf/T in locs) + var/turf/Tcheck = get_step(T, stepdir) + if(Tcheck in checked_turfs) + continue + if(Tcheck in locs) + checked_turfs |= Tcheck + continue + if(!(Tcheck in locs)) + if(!T.Exit(src, Tcheck)) + safe_move = FALSE + if(!Tcheck.Enter(src, T)) + safe_move = FALSE + checked_turfs |= Tcheck + if(!safe_move) + break + return safe_move + return TRUE diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index fd59a97d07..8f0ef8174c 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -129,7 +129,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ icon = 'icons/mob/human_races/cyberlimbs/grayson/grayson_main.dmi' unavailable_to_build = 1 monitor_styles = "blank=grayson_off;\ + red=grayson_red;\ green=grayson_green;\ + blue=grayson_blue;\ rgb=grayson_rgb" /datum/robolimb/grayson_alt1 @@ -177,7 +179,8 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ desc = "This rather thick limb has a militaristic green plating." icon = 'icons/mob/human_races/cyberlimbs/hephaestus/hephaestus_alt2.dmi' unavailable_to_build = 1 - + monitor_styles = "red=athena_red;\ + blank=athena_off" /datum/robolimb/hephaestus_monitor company = "Hephaestus Monitor" @@ -266,7 +269,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ icon = 'icons/mob/human_races/cyberlimbs/xion/xion_alt2.dmi' unavailable_to_build = 1 monitor_styles = "blank=xion_off;\ + red=xion_red;\ green=xion_green;\ + blue=xion_blue;\ rgb=xion_rgb" /datum/robolimb/xion_alt3 diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 3b7855c66e..26cba414b9 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -9,6 +9,14 @@ #define LIGHT_BROKEN 2 #define LIGHT_BURNED 3 #define LIGHT_BULB_TEMPERATURE 400 //K - used value for a 60W bulb +#define LIGHTING_POWER_FACTOR 5 //5W per luminosity * range + +var/global/list/light_type_cache = list() +/proc/get_light_type_instance(var/light_type) + . = light_type_cache[light_type] + if(!.) + . = new light_type + light_type_cache[light_type] = . /obj/machinery/light_construct name = "light fixture frame" @@ -19,16 +27,28 @@ plane = MOB_PLANE layer = ABOVE_MOB_LAYER var/stage = 1 - var/fixture_type = "tube" + var/fixture_type = /obj/machinery/light var/sheets_refunded = 2 - var/obj/machinery/light/newlight = null -/obj/machinery/light_construct/New() - ..() - if (fixture_type == "bulb") - icon_state = "bulb-construct-stage1" - if (fixture_type == "flamp") - icon_state = "flamp-construct-stage1" +/obj/machinery/light_construct/New(var/atom/newloc, var/newdir, var/building = 0, var/datum/frame/frame_types/frame_type, var/obj/machinery/light/fixture = null) + ..(newloc) + if(fixture) + fixture_type = fixture.type + fixture.transfer_fingerprints_to(src) + set_dir(fixture.dir) + stage = 2 + else if(newdir) + set_dir(newdir) + update_icon() + +/obj/machinery/light_construct/update_icon() + switch(stage) + if(1) + icon_state = "tube-construct-stage1" + if(2) + icon_state = "tube-construct-stage2" + if(3) + icon_state = "tube-empty" /obj/machinery/light_construct/examine(mob/user) if(!..(user, 2)) @@ -36,21 +56,18 @@ switch(src.stage) if(1) - user << "It's an empty frame." - return + to_chat(user, "It's an empty frame.") if(2) - user << "It's wired." - return + to_chat(user, "It's wired.") if(3) - user << "The casing is closed." - return + to_chat(user, "The casing is closed.") /obj/machinery/light_construct/attackby(obj/item/weapon/W as obj, mob/user as mob) src.add_fingerprint(user) if (W.is_wrench()) if (src.stage == 1) playsound(src, W.usesound, 75, 1) - usr << "You begin deconstructing [src]." + to_chat(usr, "You begin deconstructing [src].") if (!do_after(usr, 30 * W.toolspeed)) return new /obj/item/stack/material/steel( get_turf(src.loc), sheets_refunded ) @@ -59,23 +76,17 @@ playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1) qdel(src) if (src.stage == 2) - usr << "You have to remove the wires first." + to_chat(usr, "You have to remove the wires first.") return if (src.stage == 3) - usr << "You have to unscrew the case first." + to_chat(usr, "You have to unscrew the case first.") return if(W.is_wirecutter()) if (src.stage != 2) return src.stage = 1 - switch(fixture_type) - if ("tube") - src.icon_state = "tube-construct-stage1" - if("bulb") - src.icon_state = "bulb-construct-stage1" - if("flamp") - src.icon_state = "flamp-construct-stage1" + src.update_icon() new /obj/item/stack/cable_coil(get_turf(src.loc), 1, "red") user.visible_message("[user.name] removes the wiring from [src].", \ "You remove the wiring from [src].", "You hear a noise.") @@ -86,42 +97,22 @@ if (src.stage != 1) return var/obj/item/stack/cable_coil/coil = W if (coil.use(1)) - switch(fixture_type) - if ("tube") - src.icon_state = "tube-construct-stage2" - if("bulb") - src.icon_state = "bulb-construct-stage2" - if("flamp") - src.icon_state = "flamp-construct-stage2" src.stage = 2 + src.update_icon() user.visible_message("[user.name] adds wires to [src].", \ "You add wires to [src].") return if(W.is_screwdriver()) if (src.stage == 2) - switch(fixture_type) - if ("tube") - src.icon_state = "tube-empty" - if("bulb") - src.icon_state = "bulb-empty" - if("flamp") - src.icon_state = "flamp-empty" src.stage = 3 + src.update_icon() user.visible_message("[user.name] closes [src]'s casing.", \ "You close [src]'s casing.", "You hear a noise.") playsound(src, W.usesound, 75, 1) - switch(fixture_type) - - if("tube") - newlight = new /obj/machinery/light/built(src.loc) - if ("bulb") - newlight = new /obj/machinery/light/small/built(src.loc) - if ("flamp") - newlight = new /obj/machinery/light/flamp/built(src.loc) - - newlight.dir = src.dir + var/obj/machinery/light/newlight = new fixture_type(src.loc, src) + newlight.set_dir(src.dir) src.transfer_fingerprints_to(newlight) qdel(src) return @@ -134,9 +125,18 @@ icon_state = "bulb-construct-stage1" anchored = 1 stage = 1 - fixture_type = "bulb" + fixture_type = /obj/machinery/light/small sheets_refunded = 1 +/obj/machinery/light_construct/small/update_icon() + switch(stage) + if(1) + icon_state = "bulb-construct-stage1" + if(2) + icon_state = "bulb-construct-stage2" + if(3) + icon_state = "bulb-empty" + /obj/machinery/light_construct/flamp name = "floor light fixture frame" desc = "A floor light fixture under construction." @@ -146,13 +146,22 @@ plane = OBJ_PLANE layer = OBJ_LAYER stage = 1 - fixture_type = "flamp" + fixture_type = /obj/machinery/light/flamp sheets_refunded = 2 +/obj/machinery/light_construct/flamp/update_icon() + switch(stage) + if(1) + icon_state = "flamp-construct-stage1" + if(2) + icon_state = "flamp-construct-stage2" + if(3) + icon_state = "flamp-empty" + // the standard tube light fixture /obj/machinery/light name = "light fixture" - icon = 'icons/obj/lighting_vr.dmi' + icon = 'icons/obj/lighting_vr.dmi' //VOREStation Edit var/base_state = "tube" // base description and icon_state icon_state = "tube1" desc = "A lighting fixture." @@ -164,20 +173,22 @@ active_power_usage = 20 // VOREStation Edit - Keep lights at 20 power power_channel = LIGHT //Lights are calc'd via area so they dont need to be in the machine list var/on = 0 // 1 if on, 0 if off - var/brightness_range = 10 // luminosity when on, also used in power calculation //VOREStation Edit - 8->10 - var/brightness_power = 0.8 - var/brightness_color = LIGHT_COLOR_FLUORESCENT_TUBE //VOREStation Edit - Our tubes are whiter + var/brightness_range + var/brightness_power + var/brightness_color var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN var/flickering = 0 var/light_type = /obj/item/weapon/light/tube // the type of light item - var/fitting = "tube" + var/construct_type = /obj/machinery/light_construct var/switchcount = 0 // count of number of times switched on/off // this is used to calc the probability the light burns out var/rigged = 0 // true if rigged to explode + //VOREStation Edit Start var/needsound = FALSE // Flag to prevent playing turn-on sound multiple times, and from playing at roundstart var/shows_alerts = TRUE // Flag for if this fixture should show alerts. Make sure icon states exist! var/current_alert = null // Which alert are we showing right now? + //VOREStation Edit End var/auto_flicker = FALSE // If true, will constantly flicker, so long as someone is around to see it (otherwise its a waste of CPU). @@ -189,91 +200,74 @@ /obj/machinery/light/small icon_state = "bulb1" base_state = "bulb" - fitting = "bulb" - brightness_range = 5 //VOREStation Edit - 4->5 - brightness_color = LIGHT_COLOR_INCANDESCENT_BULB desc = "A small lighting fixture." light_type = /obj/item/weapon/light/bulb - shows_alerts = FALSE + construct_type = /obj/machinery/light_construct/small + shows_alerts = FALSE //VOREStation Edit /obj/machinery/light/small/flicker auto_flicker = TRUE /obj/machinery/light/flamp - icon = 'icons/obj/lighting.dmi' + icon = 'icons/obj/lighting.dmi' //VOREStation Edit icon_state = "flamp1" base_state = "flamp" - fitting = "bulb" - brightness_range = 8 //VOREStation Edit - 4->8 plane = OBJ_PLANE layer = OBJ_LAYER - brightness_color = LIGHT_COLOR_INCANDESCENT_BULB desc = "A floor lamp." light_type = /obj/item/weapon/light/bulb - shows_alerts = FALSE + construct_type = /obj/machinery/light_construct/flamp + shows_alerts = FALSE //VOREStation Edit var/lamp_shade = 1 +/obj/machinery/light/flamp/New(atom/newloc, obj/machinery/light_construct/construct = null) + ..(newloc, construct) + + if(construct) + lamp_shade = 0 + update_icon() + /obj/machinery/light/flamp/flicker auto_flicker = TRUE - /obj/machinery/light/small/emergency - brightness_range = 4 - brightness_color = "#da0205" + light_type = /obj/item/weapon/light/bulb/red /obj/machinery/light/small/emergency/flicker auto_flicker = TRUE - /obj/machinery/light/spot name = "spotlight" - fitting = "large tube" light_type = /obj/item/weapon/light/tube/large - shows_alerts = FALSE - brightness_range = 12 - brightness_power = 0.9 + shows_alerts = FALSE //VOREStation Edit /obj/machinery/light/spot/flicker auto_flicker = TRUE - -/obj/machinery/light/built/New() - status = LIGHT_EMPTY - update(0) - ..() - -/obj/machinery/light/small/built/New() - status = LIGHT_EMPTY - update(0) - ..() - -/obj/machinery/light/flamp/built/New() - status = LIGHT_EMPTY - lamp_shade = 0 - update(0) - ..() //VOREStation Add - Shadeless! /obj/machinery/light/flamp/noshade/New() lamp_shade = 0 update(0) ..() //VOREStation Add End + // create a new lighting fixture -/obj/machinery/light/New() - ..() +/obj/machinery/light/New(atom/newloc, obj/machinery/light_construct/construct = null) + ..(newloc) - spawn(2) - on = has_power() + if(construct) + status = LIGHT_EMPTY + construct_type = construct.type + construct.transfer_fingerprints_to(src) + set_dir(construct.dir) + else + var/obj/item/weapon/light/L = get_light_type_instance(light_type) + update_from_bulb(L) + if(prob(L.broken_chance)) + broken(1) - switch(fitting) - if("tube") - if(prob(2)) - broken(1) - if("bulb") - if(prob(5)) - broken(1) - spawn(1) - update(0) + on = powered() + update(0) /obj/machinery/light/Destroy() var/area/A = get_area(src) @@ -286,10 +280,12 @@ switch(status) // set icon_states if(LIGHT_OK) + //VOREStation Edit Start if(shows_alerts && current_alert && on) icon_state = "[base_state]-alert-[current_alert]" else icon_state = "[base_state][on]" + //VOREStation Edit End if(LIGHT_EMPTY) icon_state = "[base_state]-empty" on = 0 @@ -320,7 +316,7 @@ else base_state = "flamp" ..() - +//VOREStation Edit Start /obj/machinery/light/proc/set_alert_atmos() if(shows_alerts) current_alert = "atmos" @@ -341,15 +337,17 @@ brightness_color = initial(brightness_color) || "" // Workaround for BYOND stupidity. Can't set it to null or it won't clear. if(on) update() - -// update the icon_state and luminosity of the light depending on its state +//VOREstation Edit End +// update lighting /obj/machinery/light/proc/update(var/trigger = 1) update_icon() + //VOREStation Edit Start if(!on) needsound = TRUE // Play sound next time we turn on else if(needsound) playsound(src.loc, 'sound/effects/lighton.ogg', 65, 1) needsound = FALSE // Don't play sound again until we've been turned off + //VOREStation Edit End if(on) if(light_range != brightness_range || light_power != brightness_power || light_color != brightness_color) @@ -375,14 +373,14 @@ use_power = 1 set_light(0) - active_power_usage = light_range * light_power + active_power_usage = ((light_range * light_power) * LIGHTING_POWER_FACTOR) /obj/machinery/light/attack_generic(var/mob/user, var/damage) if(!damage) return if(status == LIGHT_EMPTY||status == LIGHT_BROKEN) - user << "That object is useless to you." + to_chat(user, "That object is useless to you.") return if(!(status == LIGHT_OK||status == LIGHT_BURNED)) return @@ -402,20 +400,52 @@ // examine verb /obj/machinery/light/examine(mob/user) + var/fitting = get_fitting_name() switch(status) if(LIGHT_OK) - user << "[desc] It is turned [on? "on" : "off"]." + to_chat(user, "[desc] It is turned [on? "on" : "off"].") if(LIGHT_EMPTY) - user << "[desc] The [fitting] has been removed." + to_chat(user, "[desc] The [fitting] has been removed.") if(LIGHT_BURNED) - user << "[desc] The [fitting] is burnt out." + to_chat(user, "[desc] The [fitting] is burnt out.") if(LIGHT_BROKEN) - user << "[desc] The [fitting] has been smashed." + to_chat(user, "[desc] The [fitting] has been smashed.") +/obj/machinery/light/proc/get_fitting_name() + var/obj/item/weapon/light/L = light_type + return initial(L.name) +/obj/machinery/light/proc/update_from_bulb(obj/item/weapon/light/L) + status = L.status + switchcount = L.switchcount + rigged = L.rigged + brightness_range = L.brightness_range + brightness_power = L.brightness_power + brightness_color = L.brightness_color // attack with item - insert light (if right type), otherwise try to break the light +/obj/machinery/light/proc/insert_bulb(obj/item/weapon/light/L) + update_from_bulb(L) + qdel(L) + + on = powered() + update() + + if(on && rigged) + + log_admin("LOG: Rigged light explosion, last touched by [fingerprintslast]") + message_admins("LOG: Rigged light explosion, last touched by [fingerprintslast]") + + explode() + +/obj/machinery/light/proc/remove_bulb() + . = new light_type(src.loc, src) + + switchcount = 0 + status = LIGHT_EMPTY + update() + /obj/machinery/light/attackby(obj/item/W, mob/user) //Light replacer code @@ -429,34 +459,15 @@ // attempt to insert light if(istype(W, /obj/item/weapon/light)) if(status != LIGHT_EMPTY) - user << "There is a [fitting] already inserted." + to_chat(user, "There is a [get_fitting_name()] already inserted.") + return + if(!istype(W, light_type)) + to_chat(user, "This type of light requires a [get_fitting_name()].") return - else - src.add_fingerprint(user) - var/obj/item/weapon/light/L = W - if(istype(L, light_type)) - status = L.status - user << "You insert the [L.name]." - switchcount = L.switchcount - rigged = L.rigged - brightness_range = L.brightness_range - brightness_power = L.brightness_power - brightness_color = L.brightness_color - on = has_power() - update() - user.drop_item() //drop the item to update overlays and such - qdel(L) - - if(on && rigged) - - log_admin("LOG: Rigged light explosion, last touched by [fingerprintslast]") - message_admins("LOG: Rigged light explosion, last touched by [fingerprintslast]") - - explode() - else - user << "This type of light requires a [fitting]." - return + to_chat(user, "You insert [W].") + insert_bulb(W) + src.add_fingerprint(user) // attempt to break the light //If xenos decide they want to smash a light bulb with a toolbox, who am I to stop them? /N @@ -466,7 +477,7 @@ if(prob(1+W.force * 5)) - user << "You hit the light, and it smashes!" + to_chat(user, "You hit the light, and it smashes!") for(var/mob/M in viewers(src)) if(M == user) continue @@ -478,7 +489,7 @@ broken() else - user << "You hit the light!" + to_chat(user, "You hit the light!") // attempt to stick weapon into light socket else if(status == LIGHT_EMPTY) @@ -486,29 +497,11 @@ playsound(src, W.usesound, 75, 1) user.visible_message("[user.name] opens [src]'s casing.", \ "You open [src]'s casing.", "You hear a noise.") - var/obj/machinery/light_construct/newlight = null - switch(fitting) - if("tube") - newlight = new /obj/machinery/light_construct(src.loc) - newlight.icon_state = "tube-construct-stage2" - - if("bulb") - newlight = new /obj/machinery/light_construct/small(src.loc) - newlight.icon_state = "bulb-construct-stage2" - - if("flamp") - newlight = new /obj/machinery/light_construct/flamp(src.loc) - newlight.icon_state = "flamp-construct-stage2" - - newlight.dir = src.dir - newlight.stage = 2 - newlight.fingerprints = src.fingerprints - newlight.fingerprintshidden = src.fingerprintshidden - newlight.fingerprintslast = src.fingerprintslast + new construct_type(src.loc, fixture = src) qdel(src) return - user << "You stick \the [W] into the light socket!" + to_chat(user, "You stick \the [W] into the light socket!") if(has_power() && !(W.flags & NOCONDUCT)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) @@ -521,7 +514,7 @@ if(W.is_wrench()) anchored = !anchored playsound(src, W.usesound, 50, 1) - user << "You [anchored ? "wrench" : "unwrench"] \the [src]." + to_chat(user, "You [anchored ? "wrench" : "unwrench"] \the [src].") if(!lamp_shade) if(istype(W, /obj/item/weapon/lampshade)) @@ -586,7 +579,7 @@ add_fingerprint(user) if(status == LIGHT_EMPTY) - user << "There is no [fitting] in this light." + to_chat(user, "There is no [get_fitting_name()] in this light.") return if(istype(user,/mob/living/carbon/human)) @@ -615,39 +608,22 @@ prot = 1 if(prot > 0 || (COLD_RESISTANCE in user.mutations)) - user << "You remove the light [fitting]" + to_chat(user, "You remove the light [get_fitting_name()]") else if(TK in user.mutations) - user << "You telekinetically remove the light [fitting]." + to_chat(user, "You telekinetically remove the light [get_fitting_name()].") else - user << "You try to remove the light [fitting], but it's too hot and you don't want to burn your hand." + to_chat(user, "You try to remove the light [get_fitting_name()], but it's too hot and you don't want to burn your hand.") return // if burned, don't remove the light else - user << "You remove the light [fitting]." + to_chat(user, "You remove the light [get_fitting_name()].") // create a light tube/bulb item and put it in the user's hand - var/obj/item/weapon/light/L = new light_type() - L.status = status - L.rigged = rigged - L.brightness_range = brightness_range - L.brightness_power = brightness_power - L.brightness_color = brightness_color - - // light item inherits the switchcount, then zero it - L.switchcount = switchcount - switchcount = 0 - - L.update() - L.add_fingerprint(user) - - user.put_in_active_hand(L) //puts it in our active hand - - status = LIGHT_EMPTY - update() + user.put_in_active_hand(remove_bulb()) //puts it in our active hand /obj/machinery/light/flamp/attack_hand(mob/user) if(lamp_shade) if(status == LIGHT_EMPTY) - user << "There is no [fitting] in this light." + to_chat(user, "There is no [get_fitting_name()] in this light.") return if(on) @@ -662,28 +638,11 @@ /obj/machinery/light/attack_tk(mob/user) if(status == LIGHT_EMPTY) - user << "There is no [fitting] in this light." + to_chat(user, "There is no [get_fitting_name()] in this light.") return - user << "You telekinetically remove the light [fitting]." - // create a light tube/bulb item and put it in the user's hand - var/obj/item/weapon/light/L = new light_type() - L.status = status - L.rigged = rigged - L.brightness_range = brightness_range - L.brightness_power = brightness_power - L.brightness_color = brightness_color - - // light item inherits the switchcount, then zero it - L.switchcount = switchcount - switchcount = 0 - - L.update() - L.add_fingerprint(user) - L.loc = loc - - status = LIGHT_EMPTY - update() + to_chat(user, "You telekinetically remove the light [get_fitting_name()].") + remove_bulb() // break the light and make sparks if was on @@ -730,13 +689,7 @@ // timed process // use power -#define LIGHTING_POWER_FACTOR 20 //20W per unit luminosity - - /obj/machinery/light/process() - if(on) - use_power(light_range * LIGHTING_POWER_FACTOR, LIGHT) - if(auto_flicker && !flickering) if(check_for_player_proximity(src, radius = 12, ignore_ghosts = FALSE, ignore_afk = TRUE)) seton(TRUE) // Lights must be on to flicker. @@ -744,7 +697,6 @@ else seton(FALSE) // Otherwise keep it dark and spooky for when someone shows up. - // called when area power state changes /obj/machinery/light/power_change() spawn(10) @@ -781,8 +733,10 @@ var/switchcount = 0 // number of times switched matter = list(DEFAULT_WALL_MATERIAL = 60) var/rigged = 0 // true if rigged to explode + var/broken_chance = 2 + var/brightness_range = 2 //how much light it gives off - var/brightness_power = 0.8 + var/brightness_power = 1 var/brightness_color = LIGHT_COLOR_INCANDESCENT_TUBE /obj/item/weapon/light/tube @@ -792,13 +746,14 @@ base_state = "ltube" item_state = "c_tube" matter = list("glass" = 100) - brightness_range = 8 + brightness_range = 10 // luminosity when on, also used in power calculation //VOREStation Edit + brightness_power = 6 /obj/item/weapon/light/tube/large w_class = ITEMSIZE_SMALL name = "large light tube" brightness_range = 15 - brightness_power = 0.9 + brightness_power = 9 /obj/item/weapon/light/bulb name = "light bulb" @@ -808,12 +763,18 @@ item_state = "contvapour" matter = list("glass" = 100) brightness_range = 5 + brightness_power = 4 brightness_color = LIGHT_COLOR_INCANDESCENT_BULB /obj/item/weapon/light/throw_impact(atom/hit_atom) ..() shatter() +/obj/item/weapon/light/bulb/red + brightness_range = 4 + color = "#da0205" + brightness_color = "#da0205" + /obj/item/weapon/light/bulb/fire name = "fire bulb" desc = "A replacement fire bulb." @@ -821,11 +782,9 @@ base_state = "fbulb" item_state = "egg4" matter = list("glass" = 100) - brightness_range = 5 // update the icon state and description of the light - -/obj/item/weapon/light/proc/update() +/obj/item/weapon/light/update_icon() switch(status) if(LIGHT_OK) icon_state = base_state @@ -838,14 +797,19 @@ desc = "A broken [name]." -/obj/item/weapon/light/New() +/obj/item/weapon/light/New(atom/newloc, obj/machinery/light/fixture = null) ..() - switch(name) - if("light tube") - brightness_range = rand(6,9) - if("light bulb") - brightness_range = rand(4,6) - update() + if(fixture) + status = fixture.status + rigged = fixture.rigged + switchcount = fixture.switchcount + fixture.transfer_fingerprints_to(src) + + //shouldn't be necessary to copy these unless someone varedits stuff, but just in case + brightness_range = fixture.brightness_range + brightness_power = fixture.brightness_power + brightness_color = fixture.brightness_color + update_icon() // attack bulb/tube with object @@ -855,7 +819,7 @@ if(istype(I, /obj/item/weapon/reagent_containers/syringe)) var/obj/item/weapon/reagent_containers/syringe/S = I - user << "You inject the solution into the [src]." + to_chat(user, "You inject the solution into the [src].") if(S.reagents.has_reagent("phoron", 5)) @@ -889,7 +853,7 @@ force = 5 sharp = 1 playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) - update() + update_icon() //Lamp Shade /obj/item/weapon/lampshade diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index c41d49aff5..cbbd9e193d 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -99,6 +99,7 @@ return ..() /obj/machinery/power/supermatter/Destroy() + STOP_PROCESSING(SSobj, src) QDEL_NULL(soundloop) return ..() @@ -150,6 +151,8 @@ H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) ) spawn(pull_time) explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1) + spawn(5) //to allow the explosion to finish + new /obj/item/broken_sm(TS) qdel(src) return @@ -447,3 +450,21 @@ /obj/machinery/power/supermatter/shard/announce_warning() //Shards don't get announcements return + +/obj/item/broken_sm + name = "shattered supermatter plinth" + desc = "The shattered remains of a supermatter shard plinth. It doesn't look safe to be around." + icon = 'icons/obj/engine.dmi' + icon_state = "darkmatter_broken" + +/obj/item/broken_sm/New() + message_admins("Broken SM shard created at ([x],[y],[z] - JMP)",0,1) + START_PROCESSING(SSobj, src) + return ..() + +/obj/item/broken_sm/process() + radiation_repository.radiate(src, 50) + +/obj/item/broken_sm/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 85d8d5ecdf..ee04e27653 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -109,6 +109,8 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() options["H&K PT"] = "detective_panther" options["Vintage LeMat"] = "lemat_old" options["Webley MKVI "] = "webley" + options["Lombardi Buzzard"] = "detective_buzzard" + options["Constable Deluxe 2502"] = "detective_constable" var/choice = input(M,"Choose your sprite!","Resprite Gun") in options if(src && choice && !M.stat && in_range(M,src)) icon_state = options[choice] @@ -275,4 +277,4 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() desc = "A shiny Mosley Autococker automatic revolver, with black accents. Marketed as the 'Revolver for the Modern Era'. Uses .44 magnum rounds." fire_delay = 5.7 //Autorevolver. Also synced with the animation fire_anim = "mosley_fire" - origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) \ No newline at end of file + origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e180ac271c..d74bfb9caf 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -346,10 +346,18 @@ /obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0) var/turf/curloc = get_turf(source) var/turf/targloc = get_turf(target) + + if(istype(source, /atom/movable)) + var/atom/movable/MT = source + if(MT.locs && MT.locs.len) // Multi tile! + for(var/turf/T in MT.locs) + if(get_dist(T, target) < get_turf(curloc)) + curloc = get_turf(T) + trajectory_ignore_forcemove = TRUE forceMove(get_turf(source)) trajectory_ignore_forcemove = FALSE - starting = get_turf(source) + starting = curloc original = target if(targloc || !params) yo = targloc.y - curloc.y @@ -651,3 +659,14 @@ silenced = launcher.silenced return launch_projectile(target, target_zone, user, params, angle_override, forced_spread) + +/obj/item/projectile/proc/launch_projectile_from_turf(atom/target, target_zone, mob/user, params, angle_override, forced_spread = 0) + original = target + def_zone = check_zone(target_zone) + firer = user + var/direct_target + if(get_turf(target) == get_turf(src)) + direct_target = target + + preparePixelProjectile(target, get_turf(src), params, forced_spread) + return fire(angle_override, direct_target) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 9b8970c2b7..13edff9fc7 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -1854,6 +1854,7 @@ glass_name = "cider" glass_desc = "The second most Irish drink." + glass_special = list(DRINK_FIZZ) // Cocktails @@ -3207,4 +3208,4 @@ strength = 9 glass_name = "fusionnaire" - glass_desc = "A relatively new cocktail, mostly served in the bars of NanoTrasen owned stations." \ No newline at end of file + glass_desc = "A relatively new cocktail, mostly served in the bars of NanoTrasen owned stations." diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm index a29d7ac9f8..40181b81c4 100644 --- a/code/modules/reagents/dispenser/cartridge_presets.dm +++ b/code/modules/reagents/dispenser/cartridge_presets.dm @@ -45,6 +45,7 @@ ale spawn_reagent = "ale" mead spawn_reagent = "mead" bitters spawn_reagent = "bitters" + cider spawn_reagent = "cider" // Bar, soft ice spawn_reagent = "ice" diff --git a/code/modules/reagents/dispenser/dispenser2_energy.dm b/code/modules/reagents/dispenser/dispenser2_energy.dm index c889b2fe9d..ee5f0b9484 100644 --- a/code/modules/reagents/dispenser/dispenser2_energy.dm +++ b/code/modules/reagents/dispenser/dispenser2_energy.dm @@ -52,11 +52,11 @@ /obj/machinery/chemical_dispenser/bar_alc dispense_reagents = list( "lemon_lime", "sugar", "orangejuice", "limejuice", "sodawater", "tonic", "beer", "kahlua", - "whiskey", "wine", "vodka", "gin", "rum", "tequilla", "vermouth", "cognac", "ale", "mead", "bitters" + "whiskey", "wine", "vodka", "cider", "gin", "rum", "tequilla", "vermouth", "cognac", "ale", "mead", "bitters" ) /obj/machinery/chemical_dispenser/bar_coffee dispense_reagents = list( "coffee", "cafe_latte", "soy_latte", "hot_coco", "milk", "cream", "tea", "ice", "orangejuice", "lemonjuice", "limejuice", "berryjuice", "mint" - ) \ No newline at end of file + ) diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm index 05477d9cdd..08741412f1 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/dispenser/dispenser_presets.dm @@ -111,6 +111,7 @@ /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cider, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead ) @@ -139,4 +140,4 @@ /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, - ) \ No newline at end of file + ) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 8781caf10e..f8c51eef9e 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -135,7 +135,7 @@ recharge_time = 3 volume = 60 possible_transfer_amounts = list(5, 10, 20, 30) - reagent_ids = list("ale", "beer", "berryjuice", "bitters", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "gingerale", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sake", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine") + reagent_ids = list("ale", "cider", "beer", "berryjuice", "bitters", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "gingerale", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sake", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine") /obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user) return diff --git a/code/modules/research/designs/circuits.dm b/code/modules/research/designs/circuits.dm index 28fcff85dd..e2824361bf 100644 --- a/code/modules/research/designs/circuits.dm +++ b/code/modules/research/designs/circuits.dm @@ -467,7 +467,14 @@ CIRCUITS BELOW req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) build_path = /obj/item/weapon/circuitboard/mecha/gygax/targeting sort_string = "NAACC" - +/* //Uncomment me to allow Serenity construction +/datum/design/circuit/mecha/gygax_medical + name = "'Serenity' medical control" + id = "gygax_medical" + req_tech = list(TECH_DATA = 4, TECH_BIO = 2) + build_path = /obj/item/weapon/circuitboard/mecha/gygax/medical + sort_string = "NAACD" +*/ /datum/design/circuit/mecha/durand_main name = "'Durand' central control" id = "durand_main" diff --git a/code/modules/research/designs/misc.dm b/code/modules/research/designs/misc.dm index 29231a7cd9..f14b73d2e6 100644 --- a/code/modules/research/designs/misc.dm +++ b/code/modules/research/designs/misc.dm @@ -19,23 +19,28 @@ id = "health_hud" req_tech = list(TECH_BIO = 2, TECH_MAGNET = 3) build_path = /obj/item/clothing/glasses/hud/health - sort_string = "GAAAA" + sort_string = "GBAAA" /datum/design/item/hud/security name = "security records" id = "security_hud" req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 2) build_path = /obj/item/clothing/glasses/hud/security - sort_string = "GAAAB" + sort_string = "GBAAB" /datum/design/item/hud/mesons - name = "Optical meson scanners design" - desc = "Using the meson-scanning technology those glasses allow you to see through walls, floor or anything else." + name = "optical meson scanner" id = "mesons" req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) build_path = /obj/item/clothing/glasses/meson - sort_string = "GAAAC" + sort_string = "GBAAC" + +/datum/design/item/hud/material + name = "optical material scanner" + id = "material" + req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3) + build_path = /obj/item/clothing/glasses/material + sort_string = "GBAAD" /datum/design/item/device/ano_scanner name = "Alden-Saraspova counter" @@ -80,22 +85,65 @@ datum/design/item/laserpointer build_path = /obj/item/device/communicator sort_string = "VABAJ" +/datum/design/item/gps + req_tech = list(TECH_MATERIAL = 2, TECH_DATA = 2, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 500) + +/datum/design/item/gps/generic + name = "Triangulating device design (GEN)" + id = "gps_gen" + build_path = /obj/item/device/gps + sort_string = "VADAA" + +/datum/design/item/gps/comand + name = "Triangulating device design (COM)" + id = "gps_com" + build_path = /obj/item/device/gps/command + sort_string = "VADAB" + +/datum/design/item/gps/security + name = "Triangulating device design (SEC)" + id = "gps_sec" + build_path = /obj/item/device/gps/security + sort_string = "VADAC" + +/datum/design/item/gps/medical + name = "Triangulating device design (MED)" + id = "gps_med" + build_path = /obj/item/device/gps/medical + sort_string = "VADAD" + +/datum/design/item/gps/engineering + name = "Triangulating device design (ENG)" + id = "gps_eng" + build_path = /obj/item/device/gps/engineering + sort_string = "VADAE" + +/datum/design/item/gps/science + name = "Triangulating device design (SCI)" + id = "gps_sci" + build_path = /obj/item/device/gps/science + sort_string = "VADAF" + +/datum/design/item/gps/mining + name = "Triangulating device design (MINE)" + id = "gps_mine" + build_path = /obj/item/device/gps/mining + sort_string = "VADAG" + +/datum/design/item/gps/explorer + name = "Triangulating device design (EXP)" + id = "gps_exp" + build_path = /obj/item/device/gps/explorer + sort_string = "VADAH" + /datum/design/item/beacon name = "Bluespace tracking beacon design" id = "beacon" req_tech = list(TECH_BLUESPACE = 1) materials = list (DEFAULT_WALL_MATERIAL = 20, "glass" = 10) build_path = /obj/item/device/radio/beacon - sort_string = "VADAA" - -/datum/design/item/gps - name = "Triangulating device design" - desc = "Triangulates approximate co-ordinates using a nearby satellite network." - id = "gps" - req_tech = list(TECH_MATERIAL = 2, TECH_DATA = 2, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 500) - build_path = /obj/item/device/gps - sort_string = "VADAB" + sort_string = "VADBA" /datum/design/item/beacon_locator name = "Beacon tracking pinpointer" @@ -104,7 +152,7 @@ datum/design/item/laserpointer req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3) materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 500) build_path = /obj/item/device/beacon_locator - sort_string = "VADAC" + sort_string = "VADBB" /datum/design/item/bag_holding name = "'Bag of Holding', an infinite capacity bag prototype" diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index bba633c6bc..e67172fa94 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -107,7 +107,13 @@ /datum/design/item/mechfab/gygax category = "Gygax" - +/* //uncomment me to make the Serenity produceable in Robotics +/datum/design/item/mechfab/gygax/chassis/serenity + name = "Serenity Chassis" + id = "serenity_chassis" + build_path = /obj/item/mecha_parts/chassis/serenity + materials = list(DEFAULT_WALL_MATERIAL = 18750, "phoron" = 4000) +*/ /datum/design/item/mechfab/gygax/chassis name = "Gygax Chassis" id = "gygax_chassis" diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 1bef7d41ea..606735f36f 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -81,7 +81,6 @@ if(riding_datum) riding_datum.handle_ride(user, direction) - /obj/vehicle/Moved() . = ..() if(riding_datum) diff --git a/code/modules/xenoarcheaology/tools/tools_pickaxe.dm b/code/modules/xenoarcheaology/tools/tools_pickaxe.dm index d911843cca..778a204387 100644 --- a/code/modules/xenoarcheaology/tools/tools_pickaxe.dm +++ b/code/modules/xenoarcheaology/tools/tools_pickaxe.dm @@ -5,6 +5,8 @@ item_state = "syringe_0" slot_flags = SLOT_EARS digspeed = 20 + force = 0 + throwforce = 0 desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)." excavation_amount = 1 drill_sound = 'sound/weapons/thudswoosh.ogg' @@ -16,6 +18,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick1" item_state = "syringe_0" + force = 2 digspeed = 20 desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)." excavation_amount = 2 @@ -28,6 +31,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick2" item_state = "syringe_0" + force = 2 digspeed = 20 desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)." excavation_amount = 4 @@ -40,6 +44,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick3" item_state = "syringe_0" + force = 3 digspeed = 20 desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)." excavation_amount = 6 @@ -52,6 +57,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick4" item_state = "syringe_0" + force = 3 digspeed = 20 desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)." excavation_amount = 8 @@ -64,6 +70,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick5" item_state = "syringe_0" + force = 5 digspeed = 20 desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)." excavation_amount = 10 @@ -76,6 +83,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick6" item_state = "syringe_0" + force = 5 digspeed = 20 desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)." excavation_amount = 12 @@ -88,6 +96,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "pick_hand" item_state = "syringe_0" + force = 10 digspeed = 30 desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)." excavation_amount = 30 diff --git a/html/changelog.html b/html/changelog.html index d2898f86e3..33a35b4ea5 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,63 @@ -->
+

23 June 2019

+

Mechoid updated:

+ +

Novacat updated:

+ +

TheFurryFeline updated:

+ +

Woodrat updated:

+ +

mistyLuminescence updated:

+ +

04 June 2019

Chaoko99 updated: