diff --git a/code/__defines/holomap.dm b/code/__defines/holomap.dm
index 53584a56487..2cb576c0ef5 100644
--- a/code/__defines/holomap.dm
+++ b/code/__defines/holomap.dm
@@ -62,6 +62,7 @@
#define HOLOMAP_AREACOLOR_ARRIVALS "#0000FFCC"
#define HOLOMAP_AREACOLOR_ESCAPE "#FF0000CC"
#define HOLOMAP_AREACOLOR_DORMS "#CCCC0099"
+#define HOLOMAP_AREACOLOR_CIV "#3ea800" //VOREStation Addition
#define LIST_NUMERIC_SET(L, I, V) if(!L) { L = list(); } if (L.len < I) { L.len = I; } L[I] = V
diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm
index 07c25a40ab5..0fbcd3c719f 100644
--- a/code/__defines/is_helpers.dm
+++ b/code/__defines/is_helpers.dm
@@ -13,7 +13,7 @@
#define isitem(D) istype(D, /obj/item)
-#define isradio(A) istype(A, /obj/item/device/radio)
+#define isradio(A) istype(A, /obj/item/device/radio)
#define isairlock(A) istype(A, /obj/machinery/door/airlock)
@@ -23,6 +23,8 @@
#define ismecha(A) istype(A, /obj/mecha)
+#define isstructure(A) istype(A, /obj/structure)
+
//---------------
//#define isarea(D) istype(D, /area) //Built in
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index 44037305dda..14feaf1b5f8 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -103,6 +103,12 @@
#define ui_alien_fire "EAST-1:28,NORTH-3:25"
#define ui_alien_oxygen "EAST-1:28,NORTH-4:25"
+// Goes above HUD, mid-right
+#define ui_ammo_hud1 "EAST-1:28,CENTER+1:25"
+#define ui_ammo_hud2 "EAST-1:28,CENTER+2:27"
+#define ui_ammo_hud3 "EAST-1:28,CENTER+3:29"
+#define ui_ammo_hud4 "EAST-1:28,CENTER+4:31"
+
//Middle right (status indicators)
#define ui_temp "EAST-1:28,CENTER-2:13"
#define ui_health "EAST-1:28,CENTER-1:15"
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 6cb86b152fa..988c11df10d 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -39,6 +39,7 @@
alert.icon_state = "itembased"
var/image/I = image(icon = new_master.icon, icon_state = new_master.icon_state, dir = SOUTH)
I.plane = PLANE_PLAYER_HUD_ABOVE
+ I.color = new_master.color
alert.add_overlay(I)
alert.master = new_master
else
@@ -471,6 +472,7 @@ so as to remain in compliance with the most up-to-date laws."
return
if(master)
return usr.client.Click(master, location, control, params)
+ ..() // VOREStation Edit: Pass through to click_vr
/obj/screen/alert/Destroy()
..()
diff --git a/code/_onclick/hud/alert_vr.dm b/code/_onclick/hud/alert_vr.dm
index 19310ad3150..da56de56854 100644
--- a/code/_onclick/hud/alert_vr.dm
+++ b/code/_onclick/hud/alert_vr.dm
@@ -23,3 +23,31 @@
/obj/screen/alert/starving/synth
name = "Low Power"
desc = "Your battery is very low! Low power mode makes all movements slower."
+
+/obj/screen/alert/xenochimera/reconstitution
+ name = "Reconstructing Form"
+ desc = "You're still rebuilding your body! Click the alert to find out how long you have left."
+ icon_state = "regenerating"
+
+/* // Commenting this out for now, will revisit later once I can figure out how to override Click() appropriately.
+/obj/screen/alert/xenochimera/reconstitution/Click(mob/usr)
+ var/mob/living/carbon/human/H = usr
+ if(istype(H) && istype(H.species, /datum/species/xenochimera)) // If you're somehow able to click this while not a chimera, this should prevent weird runtimes. Will need changing if regeneration is ever opened to non-chimera using the same alert.
+ if(H.revive_ready == REVIVING_NOW)
+ to_chat(usr, "We are currently reviving, and will be done in [(H.revive_finished - world.time) / 10] seconds.")
+ else if(H.revive_ready == REVIVING_DONE)
+ to_chat(usr, "You should have a notification + alert for this! Bug report that this is still here!")
+*/
+
+/obj/screen/alert/xenochimera/readytohatch
+ name = "Ready to Hatch"
+ desc = "You're done reconstructing your cells! Click me to Hatch!"
+ icon_state = "hatch_ready"
+
+/* // Commenting this out for now, will revisit later once I can figure out how to override Click() appropriately.
+/obj/screen/alert/xenochimera/readytohatch/Click(mob/usr)
+ var/mob/living/carbon/human/H = usr
+ if(istype(H) && istype(H.species, /datum/species/xenochimera)) // If you're somehow able to click this while not a chimera, this should prevent weird runtimes. Will need changing if regeneration is ever opened to non-chimera using the same alert.
+ if(H.revive_ready == REVIVING_DONE) // Sanity check.
+ H.hatch() // Hatch.
+*/
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 98c187fc97d..aef10cd9797 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -1,3 +1,4 @@
+#define MAX_AMMO_HUD_POSSIBLE 4 // Cap the amount of HUDs at 4.
/*
The global hud:
Uses the same visual objects for all players.
@@ -191,6 +192,9 @@ var/list/global_huds = list(
var/icon/ui_style
var/ui_color
var/ui_alpha
+
+ // TGMC Ammo HUD Port
+ var/list/obj/screen/ammo_hud_list = list()
var/list/minihuds = list()
@@ -220,6 +224,7 @@ var/list/global_huds = list(
other_important = null
hotkeybuttons = null
// item_action_list = null // ?
+ QDEL_LIST(ammo_hud_list)
mymob = null
/datum/hud/proc/hidden_inventory_update()
@@ -460,4 +465,37 @@ var/list/global_huds = list(
client.screen += client.void
/mob/new_player/add_click_catcher()
- return
\ No newline at end of file
+ return
+
+/* TGMC Ammo HUD Port
+ * These procs call to screen_objects.dm's respective procs.
+ * All these do is manage the amount of huds on screen and set the HUD.
+*/
+///Add an ammo hud to the user informing of the ammo count of G
+/datum/hud/proc/add_ammo_hud(mob/living/user, obj/item/weapon/gun/G)
+ if(length(ammo_hud_list) >= MAX_AMMO_HUD_POSSIBLE)
+ return
+ var/obj/screen/ammo/ammo_hud = new
+ ammo_hud_list[G] = ammo_hud
+ ammo_hud.screen_loc = ammo_hud.ammo_screen_loc_list[length(ammo_hud_list)]
+ ammo_hud.add_hud(user, G)
+ ammo_hud.update_hud(user, G)
+
+///Remove the ammo hud related to the gun G from the user
+/datum/hud/proc/remove_ammo_hud(mob/living/user, obj/item/weapon/gun/G)
+ var/obj/screen/ammo/ammo_hud = ammo_hud_list[G]
+ if(isnull(ammo_hud))
+ return
+ ammo_hud.remove_hud(user, G)
+ qdel(ammo_hud)
+ ammo_hud_list -= G
+ var/i = 1
+ for(var/key in ammo_hud_list)
+ ammo_hud = ammo_hud_list[key]
+ ammo_hud.screen_loc = ammo_hud.ammo_screen_loc_list[i]
+ i++
+
+///Update the ammo hud related to the gun G
+/datum/hud/proc/update_ammo_hud(mob/living/user, obj/item/weapon/gun/G)
+ var/obj/screen/ammo/ammo_hud = ammo_hud_list[G]
+ ammo_hud?.update_hud(user, G)
\ No newline at end of file
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 00446add6df..a06df0c0822 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -898,3 +898,80 @@
icon_state = null
plane = PLANE_HOLOMAP_ICONS
appearance_flags = KEEP_TOGETHER
+
+// Begin TGMC Ammo HUD Port
+/obj/screen/ammo
+ name = "ammo"
+ icon = 'icons/mob/screen_ammo.dmi'
+ icon_state = "ammo"
+ screen_loc = ui_ammo_hud1
+ var/warned = FALSE
+ var/static/list/ammo_screen_loc_list = list(ui_ammo_hud1, ui_ammo_hud2, ui_ammo_hud3 ,ui_ammo_hud4)
+
+/obj/screen/ammo/proc/add_hud(var/mob/living/user, var/obj/item/weapon/gun/G)
+
+ if(!user?.client)
+ return
+
+ if(!G)
+ CRASH("/obj/screen/ammo/proc/add_hud() has been called from [src] without the required param of G")
+
+ if(!G.has_ammo_counter())
+ return
+
+ user.client.screen += src
+
+/obj/screen/ammo/proc/remove_hud(var/mob/living/user)
+ user?.client?.screen -= src
+
+/obj/screen/ammo/proc/update_hud(var/mob/living/user, var/obj/item/weapon/gun/G)
+ if(!user?.client?.screen.Find(src))
+ return
+
+ if(!G || !istype(G) || !G.has_ammo_counter() || !G.get_ammo_type() || isnull(G.get_ammo_count()))
+ remove_hud()
+ return
+
+ var/list/ammo_type = G.get_ammo_type()
+ var/rounds = G.get_ammo_count()
+
+ var/hud_state = ammo_type[1]
+ var/hud_state_empty = ammo_type[2]
+
+ overlays.Cut()
+
+ var/empty = image('icons/mob/screen_ammo.dmi', src, "[hud_state_empty]")
+
+ if(rounds == 0)
+ if(warned)
+ overlays += empty
+ else
+ warned = TRUE
+ var/obj/screen/ammo/F = new /obj/screen/ammo(src)
+ F.icon_state = "frame"
+ user.client.screen += F
+ flick("[hud_state_empty]_flash", F)
+ spawn(20)
+ user.client.screen -= F
+ qdel(F)
+ overlays += empty
+ else
+ warned = FALSE
+ overlays += image('icons/mob/screen_ammo.dmi', src, "[hud_state]")
+
+ rounds = num2text(rounds)
+ //Handle the amount of rounds
+ switch(length(rounds))
+ if(1)
+ overlays += image('icons/mob/screen_ammo.dmi', src, "o[rounds[1]]")
+ if(2)
+ overlays += image('icons/mob/screen_ammo.dmi', src, "o[rounds[2]]")
+ overlays += image('icons/mob/screen_ammo.dmi', src, "t[rounds[1]]")
+ if(3)
+ overlays += image('icons/mob/screen_ammo.dmi', src, "o[rounds[3]]")
+ overlays += image('icons/mob/screen_ammo.dmi', src, "t[rounds[2]]")
+ overlays += image('icons/mob/screen_ammo.dmi', src, "h[rounds[1]]")
+ else //"0" is still length 1 so this means it's over 999
+ overlays += image('icons/mob/screen_ammo.dmi', src, "o9")
+ overlays += image('icons/mob/screen_ammo.dmi', src, "t9")
+ overlays += image('icons/mob/screen_ammo.dmi', src, "h9")
\ No newline at end of file
diff --git a/code/_onclick/hud/screen_objects_vr.dm b/code/_onclick/hud/screen_objects_vr.dm
index 1d8df98a38b..4d837803279 100644
--- a/code/_onclick/hud/screen_objects_vr.dm
+++ b/code/_onclick/hud/screen_objects_vr.dm
@@ -45,11 +45,26 @@
var/turf/T = get_turf(H)
if(T.get_lumcount() <= 0.1)
to_chat(usr, "You are slowly calming down in darkness' safety...")
+ else if(isbelly(H.loc)) // Safety message for if inside a belly.
+ to_chat(usr, "You are slowly calming down within the darkness of something's belly, listening to their body as it moves around you. ...safe...")
else
to_chat(usr, "You are slowly calming down... But safety of darkness is much preferred.")
else
if(H.nutrition < 150)
to_chat(usr, "Your hunger is slowly making you unstable.")
+ if("Reconstructing Form") // Allow Viewing Reconstruction Timer + Hatching for 'chimera
+ var/mob/living/carbon/human/H = usr
+ if(istype(H) && istype(H.species, /datum/species/xenochimera)) // If you're somehow able to click this while not a chimera, this should prevent weird runtimes. Will need changing if regeneration is ever opened to non-chimera using the same alert.
+ if(H.revive_ready == REVIVING_NOW)
+ to_chat(usr, "We are currently reviving, and will be done in [round((H.revive_finished - world.time) / 10)] seconds, or [round(((H.revive_finished - world.time) * 0.1) / 60)] minutes.")
+ else if(H.revive_ready == REVIVING_DONE)
+ to_chat(usr, "You should have a notification + alert for this! Bug report that this is still here!")
+
+ if("Ready to Hatch") // Allow Viewing Reconstruction Timer + Hatching for 'chimera
+ var/mob/living/carbon/human/H = usr
+ if(istype(H) && istype(H.species, /datum/species/xenochimera)) // If you're somehow able to click this while not a chimera, this should prevent weird runtimes. Will need changing if regeneration is ever opened to non-chimera using the same alert.
+ if(H.revive_ready == REVIVING_DONE) // Sanity check.
+ H.hatch() // Hatch.
else
return 0
diff --git a/code/datums/autolathe/engineering_vr.dm b/code/datums/autolathe/engineering_vr.dm
index 90970c6e481..577d9febd2c 100644
--- a/code/datums/autolathe/engineering_vr.dm
+++ b/code/datums/autolathe/engineering_vr.dm
@@ -24,4 +24,52 @@
/datum/category_item/autolathe/engineering/candymachine
name = "candy machine electronics"
- path =/obj/item/weapon/circuitboard/candymachine
\ No newline at end of file
+ path =/obj/item/weapon/circuitboard/candymachine
+
+/datum/category_item/autolathe/engineering/battle_arcade
+ name = "battle arcade machine electronics"
+ path =/obj/item/weapon/circuitboard/arcade/battle
+
+/datum/category_item/autolathe/engineering/orion_trail
+ name = "orion trail aracade machine electronics"
+ path =/obj/item/weapon/circuitboard/arcade/orion_trail
+
+/datum/category_item/autolathe/engineering/clawmachine
+ name = "claw machine electronics"
+ path =/obj/item/weapon/circuitboard/arcade/clawmachine
+
+/datum/category_item/autolathe/engineering/jukebox
+ name = "jukebox electronics"
+ path =/obj/item/weapon/circuitboard/jukebox
+
+/datum/category_item/autolathe/engineering/mech_recharger
+ name = "mech recharging station electronics"
+ path =/obj/item/weapon/circuitboard/mech_recharger
+
+/datum/category_item/autolathe/engineering/recharge_station
+ name = "cyborg recharging station electronics"
+ path =/obj/item/weapon/circuitboard/recharge_station
+
+/datum/category_item/autolathe/engineering/batteryrack
+ name = "battery rack electronics"
+ path =/obj/item/weapon/circuitboard/batteryrack
+
+/datum/category_item/autolathe/engineering/grid_checker
+ name = "grid checker electronics"
+ path =/obj/item/weapon/circuitboard/grid_checker
+
+/datum/category_item/autolathe/engineering/breakerbox
+ name = "breaker box electronics"
+ path =/obj/item/weapon/circuitboard/breakerbox
+
+/datum/category_item/autolathe/engineering/gas_heater
+ name = "gas heater electronics"
+ path =/obj/item/weapon/circuitboard/unary_atmos/heater
+
+/datum/category_item/autolathe/engineering/gas_cooler
+ name = "gas cooler electronics"
+ path =/obj/item/weapon/circuitboard/unary_atmos/cooler
+
+/datum/category_item/autolathe/engineering/arf_generator
+ name = "atmospheric field generator electronics"
+ path =/obj/item/weapon/circuitboard/arf_generator
\ No newline at end of file
diff --git a/code/datums/components/crafting/recipes/primitive.dm b/code/datums/components/crafting/recipes/primitive.dm
index 97f6be5e395..ce268e893a5 100644
--- a/code/datums/components/crafting/recipes/primitive.dm
+++ b/code/datums/components/crafting/recipes/primitive.dm
@@ -1,3 +1,6 @@
+/*
+ * Misc
+ */
/datum/crafting_recipe/cloth
name = "Cloth bolt"
result = /obj/item/stack/material/cloth
@@ -13,9 +16,8 @@
category = CAT_PRIMAL
/*
- * Clothing
+ * Primitive Clothing
*/
-
/datum/crafting_recipe/primitive_clothes
name = "primitive clothes"
result = /obj/item/clothing/under/primitive
diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm
index 3630b9bea0d..a18b6308923 100644
--- a/code/datums/supplypacks/atmospherics.dm
+++ b/code/datums/supplypacks/atmospherics.dm
@@ -106,3 +106,16 @@
cost = 35
containertype = /obj/structure/closet/crate/aether
containername = "Emergency crate"
+
+/datum/supply_pack/atmos/firefighting
+ name = "Firefighting equipment"
+ contains = list(
+ /obj/item/clothing/suit/fire/heavy = 2,
+ /obj/item/weapon/tank/oxygen/red = 2,
+ /obj/item/weapon/watertank/atmos = 2,
+ /obj/item/device/flashlight = 2,
+ /obj/item/clothing/head/hardhat/firefighter/atmos = 2
+ )
+ cost = 35
+ containertype = /obj/structure/closet/crate/aether
+ containername = "Firefighting crate"
\ No newline at end of file
diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm
index c19c4b00970..18cc82af767 100644
--- a/code/datums/supplypacks/security.dm
+++ b/code/datums/supplypacks/security.dm
@@ -288,6 +288,16 @@
containername = "Riot armor crate"
access = access_armory
+/datum/supply_pack/security/riot_sprayer
+ name = "Gear - Riot sprayer"
+ contains = list(
+ /obj/item/weapon/watertank/pepperspray
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate/secure/lawson
+ containername = "Riot sprayer crate"
+ access = access_armory
+
/datum/supply_pack/security/ablative_armor
name = "Armor - Ablative"
contains = list(
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 96ce6d73565..efb84bbc858 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -702,7 +702,7 @@
desc = "Spooky!"
gender = PLURAL
icon = 'icons/obj/wizard.dmi'
- icon_state = "ectoplasm"
+ icon_state = "ectoplasm2"
/obj/item/weapon/research
name = "research debugging device"
diff --git a/code/game/area/Space Station 13 areas_vr.dm b/code/game/area/Space Station 13 areas_vr.dm
index f25c8e5f5f2..1c9ff79460f 100644
--- a/code/game/area/Space Station 13 areas_vr.dm
+++ b/code/game/area/Space Station 13 areas_vr.dm
@@ -50,3 +50,6 @@
/area/holodeck/source_patient_ward
name = "\improper Holodeck - Patient Ward"
+
+/area/holodeck/the_uwu_zone
+ name = "\improper Holodeck - Inside"
diff --git a/code/game/area/areas_vr.dm b/code/game/area/areas_vr.dm
index 371701e5b65..e356063e2ab 100644
--- a/code/game/area/areas_vr.dm
+++ b/code/game/area/areas_vr.dm
@@ -3,6 +3,7 @@
var/exit_message
var/limit_mob_size = TRUE //If mob size is limited in the area.
var/block_suit_sensors = FALSE //If mob size is limited in the area.
+ var/turf/ceiling_type
/area/Entered(var/atom/movable/AM, oldLoc)
. = ..()
@@ -13,3 +14,18 @@
. = ..()
if(exit_message && isliving(AM))
to_chat(AM, exit_message)
+
+/area/Initialize(mapload)
+ apply_ceiling()
+ . = ..()
+
+/area/proc/apply_ceiling()
+ if(!ceiling_type)
+ return
+ for(var/turf/T in contents)
+ if(T.outdoors >= 0)
+ continue
+ if(HasAbove(T.z))
+ var/turf/TA = GetAbove(T)
+ if(isopenspace(TA))
+ TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index f9484599700..c0c23f9420c 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -185,6 +185,7 @@
icon_state = "cryo_rear"
anchored = TRUE
dir = WEST
+ density = TRUE
//Cryopods themselves.
/obj/machinery/cryopod
@@ -522,13 +523,13 @@
control_computer.frozen_crew += "[to_despawn.real_name], [to_despawn.mind.role_alt_title] - [stationtime2text()]"
control_computer._admin_logs += "[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) at [stationtime2text()]"
log_and_message_admins("[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) entered cryostorage.")
-
+
//VOREStation Edit Start
var/depart_announce = TRUE
if(istype(to_despawn, /mob/living/dominated_brain))
depart_announce = FALSE
-
+
if(depart_announce)
announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
visible_message("\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2]", 3)
diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index 84f228c6abe..e68ce7aa4ed 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -128,3 +128,17 @@
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
+
+/obj/effect/decal/cleanable/confetti
+ name = "confetti"
+ desc = "Tiny bits of colored paper thrown about for the janitor to enjoy!"
+ gender = PLURAL
+ density = FALSE
+ anchored = TRUE
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "confetti"
+
+/obj/effect/decal/cleanable/confetti/attack_hand(mob/user)
+ to_chat(user, "You start to meticulously pick up the confetti.")
+ if(do_after(user, 60))
+ qdel(src)
diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm
index 160e337ceab..b7d6d5278c5 100644
--- a/code/game/objects/items/devices/defib.dm
+++ b/code/game/objects/items/devices/defib.dm
@@ -497,6 +497,11 @@
M.Weaken(rand(10,25))
M.updatehealth()
apply_brain_damage(M)
+ // VOREStation Edits Start: Defib pain
+ if(istype(M.species, /datum/species/xenochimera)) // Only do the following to Xenochimera. Handwave this however you want, this is to balance defibs on an alien race.
+ M.adjustHalLoss(220) // This hurts a LOT, stacks on top of the previous halloss.
+ M.feral += 100 // If they somehow weren't already feral, force them feral by increasing ferality var directly, to avoid any messy checks. handle_feralness() will immediately set our feral properly according to halloss anyhow.
+ // VOREStation Edits End
// SSgame_master.adjust_danger(-20) // VOREStation Edit - We don't use SSgame_master yet.
/obj/item/weapon/shockpaddles/proc/apply_brain_damage(mob/living/carbon/human/H)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 1fac4f32265..21e190cad11 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -278,6 +278,18 @@ HALOGEN COUNTER - Radcount on mobs
else
dat += "Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]
"
dat += "Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm."
+ if(istype(H.species, /datum/species/xenochimera)) // VOREStation Edit Start: Visible feedback for medmains on Xenochimera.
+ if(H.stat == DEAD && H.revive_ready == REVIVING_READY && !H.hasnutriment())
+ dat += "WARNING: Protein levels low. Subject incapable of reconstitution."
+ else if(H.revive_ready == REVIVING_NOW)
+ dat += "Subject is undergoing form reconstruction. Estimated time to finish is in: [round((H.revive_finished - world.time) / 10)] seconds."
+ else if(H.revive_ready == REVIVING_DONE)
+ dat += "Subject is ready to hatch. Transfer to dark room for holding with food available."
+ else if(H.stat == DEAD)
+ dat+= "WARNING: Defib will cause extreme pain and set subject feral. Sedation recommended prior to defibrillation."
+ else // If they bop them and they're not dead or reviving, give 'em a little notice.
+ dat += "Subject is a Xenochimera. Treat accordingly."
+ // VOREStation Edit End
user.show_message(dat, 1)
/obj/item/device/healthanalyzer/verb/toggle_mode()
diff --git a/code/game/objects/items/stacks/stack_vr.dm b/code/game/objects/items/stacks/stack_vr.dm
new file mode 100644
index 00000000000..25ea848ffbd
--- /dev/null
+++ b/code/game/objects/items/stacks/stack_vr.dm
@@ -0,0 +1,20 @@
+// Porting stack dragging/auto stacking from TG.
+
+/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
+ if(uses_charge || S.uses_charge) // This should realistically never happen, but in case it does lets avoid breaking things.
+ return
+
+ var/transfer = get_amount()
+ transfer = min(transfer, S.max_amount - S.amount)
+ if(pulledby)
+ pulledby.start_pulling(S)
+ transfer_fingerprints_to(S)
+ if(blood_DNA)
+ S.blood_DNA |= blood_DNA
+ use(transfer)
+ S.add(transfer)
+
+/obj/item/stack/Crossed(var/atom/movable/AM)
+ if(AM != src && istype(AM, src.type) && !AM.throwing)
+ merge(AM)
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/toys/toys_vr.dm b/code/game/objects/items/toys/toys_vr.dm
index a13046dc63c..8a3f59feaed 100644
--- a/code/game/objects/items/toys/toys_vr.dm
+++ b/code/game/objects/items/toys/toys_vr.dm
@@ -22,6 +22,7 @@
* Professor Who universal ID
* Professor Who sonic driver
* Action figures
+ * Desk toys
*/
@@ -962,3 +963,114 @@
icon = 'icons/obj/toy_vr.dmi'
icon_state = "prisoner"
toysay = "I did not hit her! I did not!"
+
+/obj/item/toy/figure/error
+ name = "completely glitched action figure"
+ desc = "A \"Space Life\" brand... wait, what the hell is this thing? It seems to be requesting the sweet release of death."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "glitched"
+ toysay = "AaAAaAAAaAaaaAAA!!!!!"
+
+/*
+ * Desk toys
+ */
+/obj/item/weapon/toy/desk
+ icon = 'icons/obj/toy_vr.dmi'
+ var/on = FALSE
+ var/activation_sound = 'sound/machines/click.ogg'
+
+/obj/item/weapon/toy/desk/update_icon()
+ if(on)
+ icon_state = "[initial(icon_state)]-on"
+ else
+ icon_state = "[initial(icon_state)]"
+
+/obj/item/weapon/toy/desk/proc/activate(mob/user as mob)
+ on = !on
+ playsound(src.loc, activation_sound, 75, 1)
+ update_icon()
+ return 1
+
+/obj/item/weapon/toy/desk/attack_self(mob/user)
+ activate(user)
+
+/obj/item/weapon/toy/desk/AltClick(mob/user)
+ activate(user)
+
+/obj/item/weapon/toy/desk/MouseDrop(mob/user as mob) // Code from Paper bin, so you can still pick up the deck
+ if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr))))))
+ if(!istype(usr, /mob/living/simple_mob))
+ if( !usr.get_active_hand() ) //if active hand is empty
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
+
+ if (H.hand)
+ temp = H.organs_by_name["l_hand"]
+ if(temp && !temp.is_usable())
+ to_chat(user,"You try to move your [temp.name], but cannot!")
+ return
+
+ to_chat(user,"You pick up [src].")
+ user.put_in_hands(src)
+
+ return
+
+/obj/item/weapon/toy/desk/newtoncradle
+ name = "\improper Newton's cradle"
+ desc = "A ancient 21th century super-weapon model demonstrating that Sir Isaac Newton is the deadliest sonuvabitch in space."
+ description_fluff = "Aside from car radios, Eridanian Dregs are reportedly notorious for stealing these things. It is often \
+ theorized that the very same ball bearings are used in black-market cybernetics."
+ icon_state = "newtoncradle"
+
+/obj/item/weapon/toy/desk/fan
+ name = "office fan"
+ desc = "Your greatest fan."
+ description_fluff = "For weeks, the atmospherics department faced a conundrum on how to lower temperatures in a localized \
+ area through complicated pipe channels and ventilation systems. The problem was promptly solved by ordering several desk fans."
+ icon_state = "fan"
+
+/obj/item/weapon/toy/desk/officetoy
+ name = "office toy"
+ desc = "A generic microfusion powered office desk toy. Only generates magnetism and ennui."
+ description_fluff = "The mechanism inside is a Hephasteus trade secret. No peeking!"
+ icon_state = "desktoy"
+
+/obj/item/weapon/toy/desk/dippingbird
+ name = "dipping bird toy"
+ desc = "Engineers marvel at this scale model of a primitive thermal engine. It's highly debated why the majority of owners \
+ were in low-level bureaucratic jobs."
+ description_fluff = "One of the key essentials for every Eridanian suit - it's practically a rite of passage to own one \
+ of these things."
+ icon_state = "dippybird"
+
+/obj/item/weapon/toy/desk/stellardelight
+ name = "\improper Stellar Delight model"
+ desc = "A scale model of the Stellar Delight. Includes flashing lights!"
+ icon_state = "stellar_delight"
+
+/*
+ * Party popper
+ */
+/obj/item/weapon/toy/partypopper
+ name = "party popper"
+ desc = "Instructions : Aim away from face. Wait for appropriate timing. Pull cord, enjoy confetti."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "partypopper"
+ w_class = ITEMSIZE_TINY
+ drop_sound = 'sound/items/drop/cardboardbox.ogg'
+ pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
+
+/obj/item/weapon/toy/partypopper/attack_self(mob/user as mob)
+ if(icon_state == "partypopper")
+ user.visible_message("[user] pulls on the string, releasing a burst of confetti!", "You pull on the string, releasing a burst of confetti!")
+ playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
+ var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread
+ s.set_up(5, 1, src)
+ s.start()
+ icon_state = "partypopper_e"
+ var/turf/T = get_step(src, user.dir)
+ if(!turf_clear(T))
+ T = get_turf(src)
+ new /obj/effect/decal/cleanable/confetti(T)
+ else
+ to_chat(user, "The [src] is already spent!")
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/chewables.dm b/code/game/objects/items/weapons/chewables.dm
index 181db77e91b..a715fee32cb 100644
--- a/code/game/objects/items/weapons/chewables.dm
+++ b/code/game/objects/items/weapons/chewables.dm
@@ -167,10 +167,43 @@
storage_slots = 6
drop_sound = 'sound/items/drop/box.ogg'
use_sound = 'sound/items/storage/box.ogg'
+ var/open = 0
+ var/open_state
+ var/closed_state
-/obj/item/weapon/storage/box/fancy/chewables/tobacco/update_icon()
- icon_state = "[initial(icon_state)][contents.len]"
+/obj/item/weapon/storage/box/fancy/chewables/tobacco/nico/New()
+ if(!open_state)
+ open_state = "[initial(icon_state)]0"
+ if(!closed_state)
+ closed_state = "[initial(icon_state)]"
+ ..()
+/obj/item/weapon/storage/box/fancy/chewables/tobacco/nico/update_icon()
+ cut_overlays()
+ if(open)
+ icon_state = open_state
+ if(contents.len >= 1)
+ add_overlay("chew_nico[contents.len]")
+ else
+ icon_state = closed_state
+
+/obj/item/weapon/storage/box/fancy/chewables/tobacco/nico/open(mob/user as mob)
+ if(open)
+ return
+ open = TRUE
+ if(contents.len == 0)
+ icon_state = "[initial(icon_state)]_empty"
+ else
+ update_icon()
+ ..()
+
+/obj/item/weapon/storage/box/fancy/chewables/tobacco/nico/close(mob/user as mob)
+ open = FALSE
+ if(contents.len == 0)
+ icon_state = "[initial(icon_state)]_empty"
+ else
+ update_icon()
+ ..()
/obj/item/clothing/mask/chewable/candy
name = "wad"
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 5a751e35277..7f7bdbca039 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -1,5 +1,3 @@
-//cleansed 9/15/2012 17:48
-
/*
CONTAINS:
MATCHES
@@ -473,6 +471,17 @@ CIGARETTE PACKETS ARE IN FANCY.DM
item_state = "cobpipe"
chem_volume = 35
+/obj/item/clothing/mask/smokable/pipe/bonepipe
+ name = "Europan bone pipe"
+ desc = "A smoking pipe made out of the bones of the Europan bone whale."
+ description_fluff = "While most commonly associated with bone charms, bones from various sea creatures on Europa are used in a \
+ variety of goods, such as this smoking pipe. While smoking in submarines is often an uncommon occurrence, due to a lack of \
+ available air or space, these pipes are a common sight in the many stations of Europa. Higher-quality pipes typically have \
+ scenes etched into their bones, and can tell the story of their owner's time on Europa."
+ icon_state = "bonepipe"
+ item_state = "bonepipe"
+ chem_volume = 30
+
///////////////
//CUSTOM CIGS//
///////////////
diff --git a/code/game/objects/items/weapons/grenades/explosive.dm b/code/game/objects/items/weapons/grenades/explosive.dm
index 076a7acccea..77e07e2c5f0 100644
--- a/code/game/objects/items/weapons/grenades/explosive.dm
+++ b/code/game/objects/items/weapons/grenades/explosive.dm
@@ -12,6 +12,7 @@
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
var/spread_range = 7
loadable = null
+ hud_state = "grenade_frag" // TGMC Ammo HUD Port
/obj/item/weapon/grenade/explosive/detonate()
..()
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 209e47b2532..9bdf650c64d 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -13,6 +13,8 @@
var/det_time = 50
var/loadable = TRUE
var/arm_sound = 'sound/weapons/armbomb.ogg'
+ var/hud_state = "grenade_he" // TGMC Ammo HUD Port
+ var/hud_state_empty = "grenade_empty" // TGMC Ammo HUD Port
/obj/item/weapon/grenade/proc/clown_check(var/mob/living/user)
if((CLUMSY in user.mutations) && prob(50))
diff --git a/code/game/objects/items/weapons/grenades/smokebomb.dm b/code/game/objects/items/weapons/grenades/smokebomb.dm
index 75c0e6a299a..1cb98be61a8 100644
--- a/code/game/objects/items/weapons/grenades/smokebomb.dm
+++ b/code/game/objects/items/weapons/grenades/smokebomb.dm
@@ -6,6 +6,7 @@
det_time = 20
item_state = "flashbang"
slot_flags = SLOT_BELT
+ hud_state = "grenade_smoke"
var/datum/effect/effect/system/smoke_spread/bad/smoke
var/smoke_color
var/smoke_strength = 8
diff --git a/code/game/objects/items/weapons/manuals_vr.dm b/code/game/objects/items/weapons/manuals_vr.dm
index 9eaaa56265f..1325a0e1ca7 100644
--- a/code/game/objects/items/weapons/manuals_vr.dm
+++ b/code/game/objects/items/weapons/manuals_vr.dm
@@ -342,3 +342,395 @@
This all may seem daunting at a glance; so many recipes to learn, and a "lot" to keep in mind. But really it's not - tending the Bar is mostly about going with the flow of things and providing a good times, and drinks just provide liquid courage to make a good time easier. Take a deep breath if you ever feel overwhelmed, and handle one order at a time. You can do it! Don't feel the need to know every recipe, just learn your favorites and go from there; the rest is here or online if someone asks for it! If somebody asks you to give them anything without a specific request, don't panic: evalulate their likes and tolerance level, and try your best to give them something nice!