diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml
new file mode 100644
index 00000000000..9b91ddc846c
--- /dev/null
+++ b/.github/workflows/autochangelog.yml
@@ -0,0 +1,39 @@
+name: Autochangelog
+on:
+ pull_request_target:
+ types: closed
+ branches:
+ - master
+
+env:
+ BASENAME: "polaris"
+
+jobs:
+ autochangelog:
+ name: Autochangelog
+ runs-on: ubuntu-16.04
+ if: github.event.pull_request.merged == true
+ steps:
+ - uses: /actions/checkout@v2
+ - name: Ensure +x on CI directory
+ run: |
+ chmod -R +x ./tools/ci
+ - uses: actions/setup-python@v2
+ with:
+ python-version: '3.7'
+ - name: Generate Changelog
+ run: |
+ pip install pyyaml
+ python tools/GenerateChangelog/ss13_autochangelog.py \
+ html/changelogs \
+ ${{ github.event.pull_request.number }} \
+ "${{ github.event.pull_request.user.login }}" \
+ "${{ github.event.pull_request.body }}"
+ python tools/GenerateChangelog/ss13_genchangelog.py \
+ html/changelog.html \
+ html/changelogs
+ - uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ commit_message: Automatic changelog generation for ${{ github.events.pull_request.number }}
+ branch: ${{ github.events.pull_request.base }}
+ commit_user_name: Autochangelog Bot
diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm
index 4e9d7fd6ad7..a2e15e6890e 100644
--- a/code/__defines/_planes+layers.dm
+++ b/code/__defines/_planes+layers.dm
@@ -173,6 +173,5 @@ What is the naming convention for planes or layers?
plane = initial(plane)
layer = initial(layer)
-
// Check if a mob can "logically" see an atom plane
#define MOB_CAN_SEE_PLANE(M, P) (P <= PLANE_WORLD || (P in M.planes_visible))
diff --git a/code/__defines/belly_modes_vr.dm b/code/__defines/belly_modes_vr.dm
index ccffcf43416..d497391d3fc 100644
--- a/code/__defines/belly_modes_vr.dm
+++ b/code/__defines/belly_modes_vr.dm
@@ -9,30 +9,17 @@
#define DM_SIZE_STEAL "Size Steal"
#define DM_HEAL "Heal"
#define DM_EGG "Encase In Egg"
-#define DM_TRANSFORM "Transform"
//#define DM_ITEMWEAK "Digest (Item Friendly)"
//#define DM_STRIPDIGEST "Strip Digest (Items Only)"
//#define DM_DIGEST_NUMB "Digest (Numbing)"
-//TF modes
-#define DM_TRANSFORM_HAIR_AND_EYES "Transform (Hair and eyes)"
-#define DM_TRANSFORM_MALE "Transform (Male)"
-#define DM_TRANSFORM_FEMALE "Transform (Female)"
-#define DM_TRANSFORM_KEEP_GENDER "Transform (Keep Gender)"
-#define DM_TRANSFORM_REPLICA "Transform (Replica Of Self)"
-#define DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR "Transform (Change Species and Taur)"
-#define DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG "Transform (Change Species and Taur) (EGG)"
-#define DM_TRANSFORM_REPLICA_EGG "Transform (Replica Of Self) (EGG)"
-#define DM_TRANSFORM_KEEP_GENDER_EGG "Transform (Keep Gender) (EGG)"
-#define DM_TRANSFORM_MALE_EGG "Transform (Male) (EGG)"
-#define DM_TRANSFORM_FEMALE_EGG "Transform (Female) (EGG)"
-
//Addon mode flags
#define DM_FLAG_NUMBING 0x1
#define DM_FLAG_STRIPPING 0x2
#define DM_FLAG_LEAVEREMAINS 0x4
#define DM_FLAG_THICKBELLY 0x8
+#define DM_FLAG_AFFECTWORN 0x10
//Item related modes
#define IM_HOLD "Hold"
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 3e86c138560..a7b3bd86f8f 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -157,6 +157,8 @@
#define MAT_GRAPHITE "graphite"
#define MAT_LEATHER "leather"
#define MAT_CHITIN "chitin"
+#define MAT_CLOTH "cloth"
+#define MAT_SYNCLOTH "syncloth"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
@@ -480,4 +482,15 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
VOLUME_CHANNEL_ALARMS,
VOLUME_CHANNEL_VORE,
VOLUME_CHANNEL_DOORS,
-))
\ No newline at end of file
+))
+
+#define APPEARANCECHANGER_CHANGED_RACE "Race"
+#define APPEARANCECHANGER_CHANGED_GENDER "Gender"
+#define APPEARANCECHANGER_CHANGED_GENDER_ID "Gender Identity"
+#define APPEARANCECHANGER_CHANGED_SKINTONE "Skin Tone"
+#define APPEARANCECHANGER_CHANGED_SKINCOLOR "Skin Color"
+#define APPEARANCECHANGER_CHANGED_HAIRSTYLE "Hair Style"
+#define APPEARANCECHANGER_CHANGED_HAIRCOLOR "Hair Color"
+#define APPEARANCECHANGER_CHANGED_F_HAIRSTYLE "Facial Hair Style"
+#define APPEARANCECHANGER_CHANGED_F_HAIRCOLOR "Facial Hair Color"
+#define APPEARANCECHANGER_CHANGED_EYES "Eye Color"
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index 34c68ebd089..f6ca0ea5655 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -68,7 +68,7 @@
#define LANGUAGE_ALAI "Alai"
#define LANGUAGE_ZADDAT "Vedahq"
#define LANGUAGE_PROMETHEAN "Promethean Biolinguistics"
-#define LANGUAGE_BLOB "Blob"
+#define LANGUAGE_BLOB "Chemosense Transmission"
#define LANGUAGE_GIBBERISH "Babel"
// Language flags.
diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm
index 8909238db2d..78054e6ba86 100644
--- a/code/__defines/species_languages_vr.dm
+++ b/code/__defines/species_languages_vr.dm
@@ -10,6 +10,7 @@
#define LANGUAGE_ENOCHIAN "Enochian"
#define LANGUAGE_VESPINAE "Vespinae"
#define LANGUAGE_SPACER "Spacer"
+#define LANGUAGE_CLOWNISH "Coulrian"
#define LANGUAGE_CHIMPANZEE "Chimpanzee"
#define LANGUAGE_NEAERA "Neaera"
diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm
index e02c99290c7..742708face2 100644
--- a/code/_global_vars/lists/misc.dm
+++ b/code/_global_vars/lists/misc.dm
@@ -5,4 +5,7 @@ GLOBAL_LIST_EMPTY(meteor_list)
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
-GLOBAL_LIST_EMPTY(tagger_locations)
\ No newline at end of file
+GLOBAL_LIST_EMPTY(tagger_locations)
+
+GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Prey", "Switch", "Non-Vore", "Unset"))
+GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
\ No newline at end of file
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 371f35b0515..0d10e33b492 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -94,13 +94,13 @@ var/global/list/string_slot_flags = list(
"holster" = SLOT_HOLSTER
)
-/proc/get_mannequin(var/ckey)
- if(!mannequins_)
- mannequins_ = new()
- . = mannequins_[ckey]
- if(!.)
- . = new/mob/living/carbon/human/dummy/mannequin()
- mannequins_[ckey] = .
+GLOBAL_LIST_EMPTY(mannequins)
+/proc/get_mannequin(var/ckey = "NULL")
+ var/mob/living/carbon/human/dummy/mannequin/M = GLOB.mannequins[ckey]
+ if(!istype(M))
+ GLOB.mannequins[ckey] = new /mob/living/carbon/human/dummy/mannequin(null)
+ M = GLOB.mannequins[ckey]
+ return M
//////////////////////////
/////Initial Building/////
@@ -215,7 +215,7 @@ var/global/list/string_slot_flags = list(
GLOB.closet_appearances[T] = app
// VOREStation Add - Vore Modes!
- paths = typesof(/datum/digest_mode) - /datum/digest_mode/transform
+ paths = typesof(/datum/digest_mode)
for(var/T in paths)
var/datum/digest_mode/DM = new T
GLOB.digest_modes[DM.id] = DM
diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm
index 0406099616a..d45406225c1 100644
--- a/code/_helpers/global_lists_vr.dm
+++ b/code/_helpers/global_lists_vr.dm
@@ -8,9 +8,11 @@ var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail
var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
var/global/list/negative_traits = list() // Negative custom species traits, indexed by path
var/global/list/neutral_traits = list() // Neutral custom species traits, indexed by path
+var/global/list/everyone_traits = list() // Neutral traits available to all species, indexed by path
var/global/list/positive_traits = list() // Positive custom species traits, indexed by path
var/global/list/traits_costs = list() // Just path = cost list, saves time in char setup
var/global/list/all_traits = list() // All of 'em at once (same instances)
+var/global/list/active_ghost_pods = list()
var/global/list/sensorpreflist = list("Off", "Binary", "Vitals", "Tracking", "No Preference") //TFF 5/8/19 - Suit Sensors global list
@@ -106,30 +108,74 @@ var/global/list/fancy_release_sounds = list(
)
var/global/list/global_vore_egg_types = list(
- "Unathi" = UNATHI_EGG,
- "Tajaran" = TAJARAN_EGG,
- "Akula" = AKULA_EGG,
- "Skrell" = SKRELL_EGG,
- "Nevrean" = NEVREAN_EGG,
- "Sergal" = SERGAL_EGG,
- "Human" = HUMAN_EGG,
- "Slime" = SLIME_EGG,
- "Egg" = EGG_EGG,
- "Xenochimera" = XENOCHIMERA_EGG,
- "Xenomorph" = XENOMORPH_EGG)
+ "Unathi",
+ "Tajara",
+ "Akula",
+ "Skrell",
+ "Sergal",
+ "Nevrean",
+ "Human",
+ "Slime",
+ "Egg",
+ "Xenochimera",
+ "Xenomorph",
+ "Chocolate",
+ "Boney",
+ "Slime glob",
+ "Chicken",
+ "Synthetic",
+ "Bluespace Floppy",
+ "Bluespace Compressed File",
+ "Bluespace CD",
+ "Escape pod",
+ "Cooking error",
+ "Web cocoon",
+ "Honeycomb",
+ "Bug cocoon",
+ "Rock",
+ "Yellow",
+ "Blue",
+ "Green",
+ "Orange",
+ "Purple",
+ "Red",
+ "Rainbow",
+ "Spotted pink")
var/global/list/tf_vore_egg_types = list(
- "Unathi" = /obj/structure/closet/secure_closet/egg/unathi,
- "Tajara" = /obj/structure/closet/secure_closet/egg/tajaran,
- "Akula" = /obj/structure/closet/secure_closet/egg/shark,
- "Skrell" = /obj/structure/closet/secure_closet/egg/skrell,
- "Sergal" = /obj/structure/closet/secure_closet/egg/sergal,
- "Nevrean" = /obj/structure/closet/secure_closet/egg/nevrean,
- "Human" = /obj/structure/closet/secure_closet/egg/human,
- "Slime" = /obj/structure/closet/secure_closet/egg/slime,
- "Egg" = /obj/structure/closet/secure_closet/egg,
- "Xenochimera" = /obj/structure/closet/secure_closet/egg/scree,
- "Xenomorph" = /obj/structure/closet/secure_closet/egg/xenomorph)
+ "Unathi" = /obj/item/weapon/storage/vore_egg/unathi,
+ "Tajara" = /obj/item/weapon/storage/vore_egg/tajaran,
+ "Akula" = /obj/item/weapon/storage/vore_egg/shark,
+ "Skrell" = /obj/item/weapon/storage/vore_egg/skrell,
+ "Sergal" = /obj/item/weapon/storage/vore_egg/sergal,
+ "Nevrean" = /obj/item/weapon/storage/vore_egg/nevrean,
+ "Human" = /obj/item/weapon/storage/vore_egg/human,
+ "Slime" = /obj/item/weapon/storage/vore_egg/slime,
+ "Egg" = /obj/item/weapon/storage/vore_egg,
+ "Xenochimera" = /obj/item/weapon/storage/vore_egg/scree,
+ "Xenomorph" = /obj/item/weapon/storage/vore_egg/xenomorph,
+ "Chocolate" = /obj/item/weapon/storage/vore_egg/chocolate,
+ "Boney" = /obj/item/weapon/storage/vore_egg/owlpellet,
+ "Slime glob" = /obj/item/weapon/storage/vore_egg/slimeglob,
+ "Chicken" = /obj/item/weapon/storage/vore_egg/chicken,
+ "Synthetic" = /obj/item/weapon/storage/vore_egg/synthetic,
+ "Bluespace Floppy" = /obj/item/weapon/storage/vore_egg/floppy,
+ "Bluespace Compressed File" = /obj/item/weapon/storage/vore_egg/file,
+ "Bluespace CD" = /obj/item/weapon/storage/vore_egg/cd,
+ "Escape pod" = /obj/item/weapon/storage/vore_egg/escapepod,
+ "Cooking error" = /obj/item/weapon/storage/vore_egg/badrecipe,
+ "Web cocoon" = /obj/item/weapon/storage/vore_egg/cocoon,
+ "Honeycomb" = /obj/item/weapon/storage/vore_egg/honeycomb,
+ "Bug cocoon" = /obj/item/weapon/storage/vore_egg/bugcocoon,
+ "Rock" = /obj/item/weapon/storage/vore_egg/rock,
+ "Yellow" = /obj/item/weapon/storage/vore_egg/yellow,
+ "Blue" = /obj/item/weapon/storage/vore_egg/blue,
+ "Green" = /obj/item/weapon/storage/vore_egg/green,
+ "Orange" = /obj/item/weapon/storage/vore_egg/orange,
+ "Purple" = /obj/item/weapon/storage/vore_egg/purple,
+ "Red" = /obj/item/weapon/storage/vore_egg/red,
+ "Rainbow" = /obj/item/weapon/storage/vore_egg/rainbow,
+ "Spotted pink" = /obj/item/weapon/storage/vore_egg/pinkspots)
var/global/list/edible_trash = list(/obj/item/broken_device,
/obj/item/clothing/accessory/collar, //TFF 10/7/19 - add option to nom collars,
@@ -180,7 +226,8 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
/obj/item/weapon/storage/fancy/cigarettes,
/obj/item/weapon/storage/fancy/crayons,
/obj/item/weapon/storage/fancy/egg_box,
- /obj/item/weapon/storage/wallet)
+ /obj/item/weapon/storage/wallet,
+ /obj/item/weapon/storage/vore_egg)
var/global/list/contamination_flavors = list(
"Generic" = contamination_flavors_generic,
@@ -457,7 +504,7 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
for(var/path in paths)
var/datum/sprite_accessory/hair_accessory/instance = new path()
hair_accesories_list[path] = instance
-
+
// Custom species traits
paths = typesof(/datum/trait) - /datum/trait
for(var/path in paths)
@@ -472,6 +519,8 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
negative_traits[path] = instance
if(0)
neutral_traits[path] = instance
+ if(!(instance.custom_only))
+ everyone_traits[path] = instance
if(0.1 to INFINITY)
positive_traits[path] = instance
@@ -488,4 +537,22 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
for(var/species_name in whitelisted_icons)
custom_species_bases += species_name
+ // Weaver recipe stuff
+ paths = typesof(/datum/weaver_recipe/structure) - /datum/weaver_recipe/structure
+ for(var/path in paths)
+ var/datum/weaver_recipe/instance = new path()
+ if(!instance.title)
+ continue //A prototype or something
+ weavable_structures[instance.title] = instance
+
+ paths = typesof(/datum/weaver_recipe/item) - /datum/weaver_recipe/item
+ for(var/path in paths)
+ var/datum/weaver_recipe/instance = new path()
+ if(!instance.title)
+ continue //A prototype or something
+ weavable_items[instance.title] = instance
+
return 1 // Hooks must return 1
+
+var/global/list/weavable_structures = list()
+var/global/list/weavable_items = list()
\ No newline at end of file
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index bc7dca1d749..10fcc662f14 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1290,6 +1290,9 @@ var/mob/dview/dview_mob = new
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
if(!center)
return
+ if(!dview_mob) //VOREStation Add: Debugging
+ dview_mob = new
+ log_error("Had to recreate the dview mob!")
dview_mob.loc = center
@@ -1613,6 +1616,46 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
/proc/href(href_src, list/href_params, href_text)
return "[href_text]"
+// This is a helper for anything that wants to render the map in TGUI
+/proc/get_tgui_plane_masters()
+ . = list()
+ // 'Utility' planes
+ . += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects)
+ . += new /obj/screen/plane_master/lighting //Lighting system (but different!)
+ . += new /obj/screen/plane_master/ghosts //Ghosts!
+ . += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
+
+ . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS} //Status is the synth/human icon left side of medhuds
+ . += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH} //Health bar
+ . += new /obj/screen/plane_master{plane = PLANE_CH_LIFE} //Alive-or-not icon
+ . += new /obj/screen/plane_master{plane = PLANE_CH_ID} //Job ID icon
+ . += new /obj/screen/plane_master{plane = PLANE_CH_WANTED} //Wanted status
+ . += new /obj/screen/plane_master{plane = PLANE_CH_IMPLOYAL} //Loyalty implants
+ . += new /obj/screen/plane_master{plane = PLANE_CH_IMPTRACK} //Tracking implants
+ . += new /obj/screen/plane_master{plane = PLANE_CH_IMPCHEM} //Chemical implants
+ . += new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff
+ . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD
+
+ . += new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use
+ . += new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use
+ . += new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use
+
+ . += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
+ . += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
+
+ // Real tangible stuff planes
+ . += new /obj/screen/plane_master/main{plane = TURF_PLANE}
+ . += new /obj/screen/plane_master/main{plane = OBJ_PLANE}
+ . += new /obj/screen/plane_master/main{plane = MOB_PLANE}
+ . += new /obj/screen/plane_master/cloaked //Cloaked atoms!
+
+ //VOREStation Add - Random other plane masters
+ . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_R} //Right-side status icon
+ . += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH_VR} //Health bar but transparent at 100
+ . += new /obj/screen/plane_master{plane = PLANE_CH_BACKUP} //Backup implant status
+ . += new /obj/screen/plane_master{plane = PLANE_CH_VANTAG} //Vore Antags
+ . += new /obj/screen/plane_master{plane = PLANE_AUGMENTED} //Augmented reality
+ //VOREStation Add End
/proc/CallAsync(datum/source, proctype, list/arguments)
set waitfor = FALSE
- return call(source, proctype)(arglist(arguments))
\ No newline at end of file
+ return call(source, proctype)(arglist(arguments))
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 6a4579f1919..b29a1192d9b 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -354,19 +354,13 @@
facedir(direction)
/obj/screen/click_catcher
+ name = "Darkness"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "click_catcher"
plane = CLICKCATCHER_PLANE
+ layer = LAYER_HUD_UNDER
mouse_opacity = 2
- screen_loc = "CENTER-7,CENTER-7"
-
-/obj/screen/click_catcher/proc/MakeGreed()
- . = list()
- for(var/i = 0, i<15, i++)
- for(var/j = 0, j<15, j++)
- var/obj/screen/click_catcher/CC = new()
- CC.screen_loc = "NORTH-[i],EAST-[j]"
- . += CC
+ screen_loc = "SOUTHWEST to NORTHEAST"
/obj/screen/click_catcher/Click(location, control, params)
var/list/modifiers = params2list(params)
@@ -374,7 +368,8 @@
var/mob/living/carbon/C = usr
C.swap_hand()
else
- var/turf/T = screen_loc2turf(screen_loc, get_turf(usr))
+ var/list/P = params2list(params)
+ var/turf/T = screen_loc2turf(P["screen-loc"], get_turf(usr))
if(T)
T.Click(location, control, params)
. = 1
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index d31a64dcda6..247d1d3f8bf 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -161,6 +161,13 @@
#define ui_ghost_pai "SOUTH: 6,CENTER+2:24"
#define ui_ghost_updown "SOUTH: 6,CENTER+3:24"
+// NIF Soulcatcher guest ones
+#define ui_nifsc_reenter "SOUTH:6,CENTER-3:24"
+#define ui_nifsc_arproj "SOUTH:6,CENTER-2:24"
+#define ui_nifsc_jumptoowner "SOUTH:6,CENTER-1:24"
+#define ui_nifsc_nme "SOUTH:6,CENTER:24"
+#define ui_nifsc_nsay "SOUTH:6,CENTER+1:24"
+
// Rig panel
#define ui_rig_deco1 "WEST:-7, SOUTH+5"
#define ui_rig_deco2 "WEST:-7, SOUTH+6"
diff --git a/code/_onclick/hud/_defines_vr.dm b/code/_onclick/hud/_defines_vr.dm
index 2b4f4fb85e2..b419c6bd7f8 100644
--- a/code/_onclick/hud/_defines_vr.dm
+++ b/code/_onclick/hud/_defines_vr.dm
@@ -1,3 +1,2 @@
-#define ui_shadekin_dark_display "EAST-1:28,CENTER-3:15"
-#define ui_shadekin_energy_display "EAST-1:28,CENTER-4:15"
+#define ui_shadekin_display "EAST-1:28,CENTER-3:15"
#define ui_xenochimera_danger_display "EAST-1:28,CENTER-3:15"
\ No newline at end of file
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 6387f40d9ec..22e8e459fc5 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -14,7 +14,7 @@
var/other = list()
var/hotkeybuttons = list()
var/slot_info = list()
-
+
HUD.adding = adding
HUD.other = other
HUD.hotkeybuttons = hotkeybuttons //These can be disabled for hotkey users
@@ -258,15 +258,10 @@
hud_elements |= healths
//VOREStation Addition begin
- shadekin_dark_display = new /obj/screen/shadekin/darkness()
- shadekin_dark_display.screen_loc = ui_shadekin_dark_display
- shadekin_dark_display.icon_state = "dark"
- hud_elements |= shadekin_dark_display
-
- shadekin_energy_display = new /obj/screen/shadekin/energy()
- shadekin_energy_display.screen_loc = ui_shadekin_energy_display
- shadekin_energy_display.icon_state = "energy0"
- hud_elements |= shadekin_energy_display
+ shadekin_display = new /obj/screen/shadekin()
+ shadekin_display.screen_loc = ui_shadekin_display
+ shadekin_display.icon_state = "shadekin"
+ hud_elements |= shadekin_display
xenochimera_danger_display = new /obj/screen/xenochimera/danger_level()
xenochimera_danger_display.screen_loc = ui_xenochimera_danger_display
diff --git a/code/_onclick/hud/screen_objects_vr.dm b/code/_onclick/hud/screen_objects_vr.dm
index b3388f7bf76..1d8df98a38b 100644
--- a/code/_onclick/hud/screen_objects_vr.dm
+++ b/code/_onclick/hud/screen_objects_vr.dm
@@ -11,6 +11,11 @@
var/mob/living/simple_mob/shadekin/SK = usr
if(istype(SK))
to_chat(usr,"Energy: [SK.energy] ([SK.dark_gains])")
+ if("shadekin status")
+ var/turf/T = get_turf(usr)
+ if(T)
+ var/darkness = round(1 - T.get_lumcount(),0.1)
+ to_chat(usr,"Darkness: [darkness]")
var/mob/living/carbon/human/H = usr
if(istype(H) && istype(H.species, /datum/species/shadekin))
to_chat(usr,"Energy: [H.shadekin_get_energy(H)]")
diff --git a/code/_onclick/hud/soulcatcher_guest.dm b/code/_onclick/hud/soulcatcher_guest.dm
new file mode 100644
index 00000000000..555bcb8ebaf
--- /dev/null
+++ b/code/_onclick/hud/soulcatcher_guest.dm
@@ -0,0 +1,102 @@
+/obj/screen/nifsc
+ icon = 'icons/mob/screen_nifsc.dmi'
+
+/obj/screen/nifsc/MouseEntered(location,control,params)
+ flick(icon_state + "_anim", src)
+ openToolTip(usr, src, params, title = name, content = desc)
+
+/obj/screen/nifsc/MouseExited()
+ closeToolTip(usr)
+
+/obj/screen/nifsc/Click()
+ closeToolTip(usr)
+
+/obj/screen/nifsc/reenter
+ name = "Re-enter NIF"
+ desc = "Return into the NIF"
+ icon_state = "reenter"
+
+/obj/screen/nifsc/reenter/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.reenter_soulcatcher()
+
+/obj/screen/nifsc/arproj
+ name = "AR project"
+ desc = "Project your form into Augmented Reality for those around your predator with the appearance of your loaded character."
+ icon_state = "arproj"
+
+/obj/screen/nifsc/arproj/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.ar_project()
+
+/obj/screen/nifsc/jumptoowner
+ name = "Jump back to host"
+ desc = "Jumb back to the Soulcather host"
+ icon_state = "jump"
+
+/obj/screen/nifsc/jumptoowner/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.jump_to_owner()
+
+/obj/screen/nifsc/nme
+ name = "Emote into Soulcatcher"
+ desc = "Emote into the NIF's Soulcatcher (circumventing AR emoting)"
+ icon_state = "nme"
+
+/obj/screen/nifsc/nme/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.nme()
+
+/obj/screen/nifsc/nsay
+ name = "Speak into Soulcatcher"
+ desc = "Speak into the NIF's Soulcatcher (circumventing AR speaking)"
+ icon_state = "nsay"
+
+/obj/screen/nifsc/nsay/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.nsay()
+
+
+/mob/living/carbon/brain/caught_soul/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
+ ..()
+
+ var/list/adding = list()
+ HUD.adding = adding
+
+ var/obj/screen/using
+
+ using = new /obj/screen/nifsc/reenter()
+ using.screen_loc = ui_nifsc_reenter
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/arproj()
+ using.screen_loc = ui_nifsc_arproj
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/jumptoowner()
+ using.screen_loc = ui_nifsc_jumptoowner
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/nme()
+ using.screen_loc = ui_nifsc_nme
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/nsay()
+ using.screen_loc = ui_nifsc_nsay
+ using.hud = src
+ adding += using
+
+
+ if(client && apply_to_client)
+ client.screen = list()
+ client.screen += HUD.adding
+ client.screen += client.void
diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm
index 60b08c71d2c..77c9d3ab94a 100644
--- a/code/controllers/subsystems/overlays.dm
+++ b/code/controllers/subsystems/overlays.dm
@@ -5,7 +5,6 @@ SUBSYSTEM_DEF(overlays)
priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
- var/initialized = FALSE
var/list/queue // Queue of atoms needing overlay compiling (TODO-VERIFY!)
var/list/stats
var/list/overlay_icon_state_caches // Cache thing
@@ -22,7 +21,6 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
stats = list()
/datum/controller/subsystem/overlays/Initialize()
- initialized = TRUE
fire(mc_check = FALSE)
..()
diff --git a/code/controllers/subsystems/processing/chemistry.dm b/code/controllers/subsystems/processing/chemistry.dm
index 7f4fd9c42b6..b4641ba7e00 100644
--- a/code/controllers/subsystems/processing/chemistry.dm
+++ b/code/controllers/subsystems/processing/chemistry.dm
@@ -22,6 +22,7 @@ PROCESSING_SUBSYSTEM_DEF(chemistry)
/datum/controller/subsystem/processing/chemistry/Initialize()
initialize_chemical_reactions()
initialize_chemical_reagents()
+ ..()
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
// It is filtered into multiple lists within a list.
diff --git a/code/controllers/subsystems/shuttles.dm b/code/controllers/subsystems/shuttles.dm
index 0bce9403851..40039edceb5 100644
--- a/code/controllers/subsystems/shuttles.dm
+++ b/code/controllers/subsystems/shuttles.dm
@@ -4,9 +4,6 @@
// Also handles initialization and processing of overmap sectors.
//
-// This global variable exists for legacy support so we don't have to rename every shuttle_controller to SSshuttles yet.
-var/global/datum/controller/subsystem/shuttles/shuttle_controller
-
SUBSYSTEM_DEF(shuttles)
name = "Shuttles"
wait = 2 SECONDS
@@ -35,9 +32,6 @@ SUBSYSTEM_DEF(shuttles)
var/tmp/list/current_run // Shuttles remaining to process this fire() tick
-/datum/controller/subsystem/shuttles/PreInit()
- global.shuttle_controller = src // TODO - Remove this! Change everything to point at SSshuttles intead
-
/datum/controller/subsystem/shuttles/Initialize(timeofday)
last_landmark_registration_time = world.time
// Find all declared shuttle datums and initailize them. (Okay, queue them for initialization a few lines further down)
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index cdb2adefde3..750f6807cca 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -49,10 +49,7 @@ var/global/datum/controller/subsystem/ticker/ticker
/datum/controller/subsystem/ticker/Initialize()
pregame_timeleft = config.pregame_time
send2mainirc("Server lobby is loaded and open at byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]")
-
- // Set up the global announcer
- GLOB.autospeaker = new (null, null, null, 1)
-
+ GLOB.autospeaker = new (null, null, null, 1) //Set up Global Announcer
return ..()
/datum/controller/subsystem/ticker/fire(resumed = FALSE)
@@ -186,11 +183,6 @@ var/global/datum/controller/subsystem/ticker/ticker
if(adm["total"] == 0)
send2adminirc("A round has started with no admins online.")
-/* supply_controller.process() //Start the supply shuttle regenerating points -- TLE // handled in scheduler
- master_controller.process() //Start master_controller.process()
- lighting_controller.process() //Start processing DynamicAreaLighting updates
- */
-
current_state = GAME_STATE_PLAYING
Master.SetRunLevel(RUNLEVEL_GAME)
diff --git a/code/datums/autolathe/devices.dm b/code/datums/autolathe/devices.dm
index 9c6ab5bb97e..eed4839159c 100644
--- a/code/datums/autolathe/devices.dm
+++ b/code/datums/autolathe/devices.dm
@@ -26,6 +26,12 @@
name = "mechanical trap"
path =/obj/item/weapon/beartrap
+/datum/category_item/autolathe/devices/barbedwire
+ name = "barbed wire"
+ path = /obj/item/weapon/material/barbedwire
+ hidden = 1
+ resources = list(DEFAULT_WALL_MATERIAL = 10000)
+
/datum/category_item/autolathe/devices/electropack
name = "electropack"
path =/obj/item/device/radio/electropack
diff --git a/code/datums/autolathe/tools.dm b/code/datums/autolathe/tools.dm
index 9e9a87ea71f..9b88a496fa9 100644
--- a/code/datums/autolathe/tools.dm
+++ b/code/datums/autolathe/tools.dm
@@ -48,6 +48,11 @@
path = /obj/item/weapon/reagent_containers/spray
resources = list(MAT_PLASTIC = 2000)
+/datum/category_item/autolathe/devices/slowwire
+ name = "snare wire"
+ path = /obj/item/weapon/material/barbedwire/plastic
+ resources = list(MAT_PLASTIC = 10000)
+
/datum/category_item/autolathe/tools/spraynozzle
name = "spray nozzle"
path = /obj/item/weapon/reagent_containers/spray
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index bca9df5ae1e..82e5f1f78bd 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -55,6 +55,9 @@
var/rev_cooldown = 0
var/tcrystals = 0
+ var/list/purchase_log = new
+ var/used_TC = 0
+
// the world.time since the mob has been brigged, or -1 if not at all
var/brigged_since = -1
@@ -73,7 +76,7 @@
/datum/mind/New(var/key)
src.key = key
-
+ purchase_log = list()
..()
/datum/mind/proc/transfer_to(mob/living/new_character)
@@ -510,8 +513,9 @@
//HUMAN
/mob/living/carbon/human/mind_initialize()
- ..()
- if(!mind.assigned_role) mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
+ . = ..()
+ if(!mind.assigned_role)
+ mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
//slime
/mob/living/simple_mob/slime/mind_initialize()
diff --git a/code/datums/outfits/jobs/special_vr.dm b/code/datums/outfits/jobs/special_vr.dm
index 89c4883e92a..010010291dd 100644
--- a/code/datums/outfits/jobs/special_vr.dm
+++ b/code/datums/outfits/jobs/special_vr.dm
@@ -15,11 +15,14 @@
shoes = /obj/item/clothing/shoes/boots/swat
gloves = /obj/item/clothing/gloves/swat
l_ear = /obj/item/device/radio/headset/ert
- belt = /obj/item/weapon/gun/energy/gun
glasses = /obj/item/clothing/glasses/sunglasses
back = /obj/item/weapon/storage/backpack/satchel
id_type = /obj/item/weapon/card/id/centcom/ERT
pda_type = /obj/item/device/pda/centcom
+
+ post_equip(var/mob/living/carbon/human/H)
+ ..()
+ ert.add_antagonist(H.mind)
/decl/hierarchy/outfit/job/clown
name = OUTFIT_JOB_NAME("Clown")
diff --git a/code/datums/roundstats/_defines_local.dm b/code/datums/roundstats/_defines_local.dm
new file mode 100644
index 00000000000..951d7118ff8
--- /dev/null
+++ b/code/datums/roundstats/_defines_local.dm
@@ -0,0 +1,7 @@
+
+#define GOAL_GENERAL "Common Goal"
+#define GOAL_MEDICAL "Medical Goal"
+#define GOAL_SECURITY "Security Goal"
+#define GOAL_ENGINEERING "Engineering Goal"
+#define GOAL_CARGO "Cargo Goal"
+#define GOAL_RESEARCH "Research Goal"
diff --git a/code/datums/roundstats/departmentgoal.dm b/code/datums/roundstats/departmentgoal.dm
new file mode 100644
index 00000000000..333e6c03963
--- /dev/null
+++ b/code/datums/roundstats/departmentgoal.dm
@@ -0,0 +1,101 @@
+
+GLOBAL_LIST(department_goals)
+GLOBAL_LIST(active_department_goals)
+
+/hook/startup/proc/initializeDepartmentGoals()
+ GLOB.department_goals = list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH)
+ GLOB.active_department_goals = list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH)
+
+ for(var/category in GLOB.department_goals)
+ GLOB.department_goals[category] = list()
+
+ for(var/subtype in subtypesof(/datum/goal))
+ var/datum/goal/SG = new subtype()
+
+ if(SG.name == "goal")
+ continue
+
+ if(SG.category == category)
+ GLOB.department_goals[category] |= SG
+
+ for(var/category in GLOB.active_department_goals)
+ GLOB.active_department_goals[category] = list()
+ var/list/cat_goals = GLOB.department_goals[category]
+
+ var/goal_count = rand(2,4)
+
+ for(var/count = 1 to goal_count)
+ var/datum/goal/G
+
+ if(LAZYLEN(cat_goals))
+ G = pick(cat_goals)
+
+ if(G)
+ G.active_goal = TRUE
+ cat_goals -= G
+
+ GLOB.active_department_goals[category] |= G
+ return 1
+
+/hook/roundend/proc/checkDepartmentGoals()
+ for(var/category in GLOB.active_department_goals)
+ var/list/cat_goals = GLOB.active_department_goals[category]
+
+ to_world("[category]")
+
+ if(!LAZYLEN(cat_goals))
+ to_world("There were no assigned goals!")
+
+ else
+ for(var/datum/goal/G in cat_goals)
+ var/success = G.check_completion()
+ to_world("[success ? "[G.name]" : "[G.name]"]")
+ to_world("[G.goal_text]")
+ return 1
+
+/datum/goal
+ var/name = "goal"
+
+ var/goal_text = "Do nothing! Congratulations."
+
+ var/active_goal = FALSE
+
+ var/category = GOAL_GENERAL
+
+/datum/goal/proc/check_completion()
+ return FALSE
+
+/datum/goal/common
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+
+/datum/goal/medical
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_MEDICAL
+
+/datum/goal/security
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_SECURITY
+
+/datum/goal/engineering
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_ENGINEERING
+
+/datum/goal/cargo
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_CARGO
+
+/datum/goal/research
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_RESEARCH
diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm
index 165c5fbfef2..28a7431ec16 100644
--- a/code/datums/supplypacks/engineering.dm
+++ b/code/datums/supplypacks/engineering.dm
@@ -77,6 +77,14 @@
containertype = /obj/structure/closet/crate/focalpoint
containername = "advanced hull shield generator crate"
+/datum/supply_pack/eng/pointdefense
+ name = "Point Defense Turret"
+ contains = list(/obj/machinery/porta_turret/pointdefense/orderable)
+ cost = 70
+ containertype = /obj/structure/closet/crate/large/secure/heph
+ containername = "point defense crate"
+ access = access_security
+
/datum/supply_pack/eng/electrical
name = "Electrical maintenance crate"
contains = list(
diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm
index 0aa29b7b9c9..ed528d3bdd0 100644
--- a/code/datums/supplypacks/misc.dm
+++ b/code/datums/supplypacks/misc.dm
@@ -84,7 +84,8 @@
/obj/item/toy/plushie/borgplushie/scrubpuppy,
/obj/item/toy/plushie/foxbear,
/obj/item/toy/plushie/nukeplushie,
- /obj/item/toy/plushie/otter)
+ /obj/item/toy/plushie/otter,
+ /obj/item/toy/plushie/vox)
//VOREStation Add End
name = "Plushies Crate"
cost = 15
diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm
index 9bb6b1a4429..eae37c5869b 100644
--- a/code/datums/supplypacks/recreation.dm
+++ b/code/datums/supplypacks/recreation.dm
@@ -51,7 +51,7 @@
/obj/item/weapon/reagent_containers/glass/paint/purple,
/obj/item/weapon/reagent_containers/glass/paint/black,
/obj/item/weapon/reagent_containers/glass/paint/white,
- /obj/item/weapon/contraband/poster,
+ /obj/item/weapon/contraband/poster/custom,
/obj/item/weapon/wrapping_paper = 3
)
cost = 10
diff --git a/code/datums/underwear/undershirts.dm b/code/datums/underwear/undershirts.dm
index 7da82fa5801..6b2cc3d10f6 100644
--- a/code/datums/underwear/undershirts.dm
+++ b/code/datums/underwear/undershirts.dm
@@ -186,4 +186,14 @@
/datum/category_item/underwear/undershirt/pinkblack_tshirt
name = "Pink and Black T-Shirt"
- icon_state = "pinkblack_tshirt"
\ No newline at end of file
+ icon_state = "pinkblack_tshirt"
+
+/datum/category_item/underwear/undershirt/turtle
+ name = "Turtleneck"
+ icon_state = "turtleneck"
+ has_color = TRUE
+
+/datum/category_item/underwear/undershirt/sleevelessturtle
+ name = "Turtleneck, Sleeveless"
+ icon_state = "sleevelessturtle"
+ has_color = TRUE
\ No newline at end of file
diff --git a/code/datums/uplink/ammunition_vr.dm b/code/datums/uplink/ammunition_vr.dm
index 3235bb7311f..18235e53432 100644
--- a/code/datums/uplink/ammunition_vr.dm
+++ b/code/datums/uplink/ammunition_vr.dm
@@ -18,3 +18,5 @@
name = "Void cell"
path = /obj/item/weapon/cell/device/weapon/recharge/alien/hybrid
item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("ert")
+ blacklisted = 1
diff --git a/code/datums/uplink/backup.dm b/code/datums/uplink/backup.dm
index 40f2a468f67..3e21676da3b 100644
--- a/code/datums/uplink/backup.dm
+++ b/code/datums/uplink/backup.dm
@@ -11,7 +11,7 @@
This type comes with a directional shield projector, a supressive fire energy weapon, \
a stunbaton, handcuffs, an agent ID, energy sword, pinpointer, and a jetpack."
item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
- antag_roles = list("mercenary")
+ antag_roles = list("mercenary", "ert") //VOREStation Edit
path = /obj/item/weapon/antag_spawner/syndicate_drone/protector
/datum/uplink_item/item/backup/syndicate_drone_combat_medic
@@ -21,7 +21,7 @@
a powerful hypospray that can create many potent chemicals, an agent ID, energy \
sword, pinpointer, and a jetpack."
item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
- antag_roles = list("mercenary")
+ antag_roles = list("mercenary", "ert") //VOREStation Edit
path = /obj/item/weapon/antag_spawner/syndicate_drone/combat_medic
/datum/uplink_item/item/backup/syndicate_drone_mechanist
@@ -31,5 +31,5 @@
a cryptographic sequencer, an AI detector, the ability to analyze and repair full-body prosthetics, \
a set of construction materials, an ionic rapier, an agent ID, energy sword, pinpointer, and a jetpack."
item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
- antag_roles = list("mercenary")
+ antag_roles = list("mercenary", "ert") //VOREStation Edit
path = /obj/item/weapon/antag_spawner/syndicate_drone/mechanist
\ No newline at end of file
diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm
index 65f71f25847..8addcc3f64e 100644
--- a/code/datums/uplink/badassery.dm
+++ b/code/datums/uplink/badassery.dm
@@ -22,22 +22,22 @@
desc = "Buys you one random item."
/datum/uplink_item/item/badassery/random_one/buy(var/obj/item/device/uplink/U, var/mob/user)
- var/datum/uplink_item/item = default_uplink_selection.get_random_item(U.uses)
+ var/datum/uplink_item/item = default_uplink_selection.get_random_item((user ? user.mind.tcrystals : DEFAULT_TELECRYSTAL_AMOUNT), U)
return item.buy(U, user)
-/datum/uplink_item/item/badassery/random_one/can_buy(obj/item/device/uplink/U)
- return default_uplink_selection.get_random_item(U.uses, U) != null
+/datum/uplink_item/item/badassery/random_one/can_buy(var/obj/item/device/uplink/U, var/telecrystals)
+ return default_uplink_selection.get_random_item(telecrystals, U) != null
/datum/uplink_item/item/badassery/random_many
name = "Random Items"
desc = "Buys you as many random items you can afford. Convenient packaging NOT included."
-/datum/uplink_item/item/badassery/random_many/cost(var/telecrystals)
+/datum/uplink_item/item/badassery/random_many/cost(obj/item/device/uplink/U, var/telecrystals)
return max(1, telecrystals)
-/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc)
+/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/M)
var/list/bought_items = list()
- for(var/datum/uplink_item/UI in get_random_uplink_items(U, U.uses, loc))
+ for(var/datum/uplink_item/UI in get_random_uplink_items(U, M.mind.tcrystals, loc))
UI.purchase_log(U)
var/obj/item/I = UI.get_goods(U, loc)
if(istype(I))
@@ -47,7 +47,7 @@
/datum/uplink_item/item/badassery/random_many/purchase_log(obj/item/device/uplink/U)
feedback_add_details("traitor_uplink_items_bought", "[src]")
- log_and_message_admins("used \the [U.loc] to buy \a [src]")
+ log_and_message_admins("used \the [U.loc] to buy \a [src] at random")
/****************
* Surplus Crate *
diff --git a/code/datums/uplink/medical_vr.dm b/code/datums/uplink/medical_vr.dm
index 8f0264d3e9d..5b4a0f31ccc 100644
--- a/code/datums/uplink/medical_vr.dm
+++ b/code/datums/uplink/medical_vr.dm
@@ -100,3 +100,66 @@
name = "Healing Nanite pill bottle"
item_cost = 30
path = /obj/item/weapon/storage/pill_bottle/healing_nanites
+
+/datum/uplink_item/item/medical/vermicetol
+ name = "Vermicetol Bottle"
+ item_cost = 30
+ path = /obj/item/weapon/reagent_containers/glass/bottle/vermicetol
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/dermaline
+ name = "Dermaline Bottle"
+ item_cost = 30
+ path = /obj/item/weapon/reagent_containers/glass/bottle/dermaline
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/carthatoline
+ name = "Carthatoline Bottle"
+ item_cost = 30
+ path = /obj/item/weapon/reagent_containers/glass/bottle/carthatoline
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/dexalinp
+ name = "Dexalin Plus Bottle"
+ item_cost = 30
+ path = /obj/item/weapon/reagent_containers/glass/bottle/dexalinp
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/tramadol
+ name = "Tramadol Bottle"
+ item_cost = 30
+ path = /obj/item/weapon/reagent_containers/glass/bottle/tramadol
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/arithrazine
+ name = "Arithrazine Bottle"
+ item_cost = 50
+ path = /obj/item/weapon/reagent_containers/glass/bottle/arithrazine
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/corophizine
+ name = "Corophizine Bottle"
+ item_cost = 50
+ path = /obj/item/weapon/reagent_containers/glass/bottle/corophizine
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/rezadone
+ name = "Rezadone Bottle"
+ item_cost = 50
+ path = /obj/item/weapon/reagent_containers/glass/bottle/rezadone
+ antag_roles = list("ert")
+ blacklisted = 1
+
+/datum/uplink_item/item/medical/defib
+ name = "Combat Defibrilator"
+ item_cost = 90
+ path = /obj/item/device/defib_kit/compact/combat
+ antag_roles = list("mercenary", "ert")
+ blacklisted = 1
diff --git a/code/datums/uplink/telecrystals.dm b/code/datums/uplink/telecrystals.dm
index f814b55232d..66a099581ee 100644
--- a/code/datums/uplink/telecrystals.dm
+++ b/code/datums/uplink/telecrystals.dm
@@ -5,8 +5,8 @@
category = /datum/uplink_category/telecrystals
blacklisted = 1
-/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc)
- return new /obj/item/stack/telecrystal(loc, cost(U.uses))
+/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/M)
+ return new /obj/item/stack/telecrystal(loc, cost(U, M.mind.tcrystals))
/datum/uplink_item/item/telecrystal/one
name = "Telecrystal - 01"
@@ -35,5 +35,5 @@
/datum/uplink_item/item/telecrystal/all
name = "Telecrystals - Empty Uplink"
-/datum/uplink_item/item/telecrystal/all/cost(var/telecrystals)
- return max(1, telecrystals)
\ No newline at end of file
+/datum/uplink_item/item/telecrystal/all/cost(obj/item/device/uplink/U, mob/M)
+ return max(1, M.mind.tcrystals)
\ No newline at end of file
diff --git a/code/datums/uplink/tools.dm b/code/datums/uplink/tools.dm
index 51d7ec7cd22..eee41e96993 100644
--- a/code/datums/uplink/tools.dm
+++ b/code/datums/uplink/tools.dm
@@ -92,6 +92,12 @@
desc = "A device which is capable of disrupting subspace communications, preventing the use of headsets, PDAs, and communicators within \
a radius of seven meters. It runs off weapon cells, which can be replaced as needed. One cell will last for approximately ten minutes."
+/datum/uplink_item/item/tools/wall_elecrtifier
+ name = "Wall Electrifier"
+ item_cost = 10
+ path = /obj/item/weapon/cell/spike
+ desc = "A modified powercell which will electrify walls and reinforced floors in a 3x3 tile range around it. Always active."
+
/datum/uplink_item/item/tools/emag
name = "Cryptographic Sequencer"
item_cost = 30
diff --git a/code/datums/uplink/tools_vr.dm b/code/datums/uplink/tools_vr.dm
index 30b2cd725e0..ad68f769229 100644
--- a/code/datums/uplink/tools_vr.dm
+++ b/code/datums/uplink/tools_vr.dm
@@ -26,6 +26,11 @@
item_cost = 5
path = /obj/item/device/survivalcapsule
+/datum/uplink_item/item/tools/popcabin
+ name = "Cabin Capsule"
+ item_cost = 5
+ path = /obj/item/device/survivalcapsule/popcabin
+
/datum/uplink_item/item/tools/nanopaste
name = "Nanopaste (Advanced)"
item_cost = 10
@@ -36,11 +41,26 @@
item_cost = 10
path = /obj/item/clothing/suit/space/void/autolok
+/datum/uplink_item/item/tools/inflatable
+ name = "Inflatables"
+ item_cost = 10
+ path = /obj/item/weapon/storage/briefcase/inflatable
+
/datum/uplink_item/item/tools/elitetablet
name = "Tablet (Advanced)"
item_cost = 15
path = /obj/item/modular_computer/tablet/preset/custom_loadout/advanced
+/datum/uplink_item/item/tools/metal
+ name = "Metal (50 sheets)"
+ item_cost = 15
+ path = /obj/fiftyspawner/steel
+
+/datum/uplink_item/item/tools/glass
+ name = "Glass (50 sheets)"
+ item_cost = 15
+ path = /obj/fiftyspawner/glass
+
/datum/uplink_item/item/tools/elitelaptop
name = "Laptop (Advanced)"
item_cost = 20
diff --git a/code/datums/uplink/uplink_categories.dm b/code/datums/uplink/uplink_categories.dm
index d9e6d84db7d..f7236ddbb08 100644
--- a/code/datums/uplink/uplink_categories.dm
+++ b/code/datums/uplink/uplink_categories.dm
@@ -6,12 +6,6 @@
..()
items = list()
-/datum/uplink_category/proc/can_view(obj/item/device/uplink/U)
- for(var/datum/uplink_item/item in items)
- if(item.can_view(U))
- return 1
- return 0
-
datum/uplink_category/ammunition
name = "Ammunition"
diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm
index 8d9de8f7321..e02e604984f 100644
--- a/code/datums/uplink/uplink_items.dm
+++ b/code/datums/uplink/uplink_items.dm
@@ -31,7 +31,7 @@ var/datum/uplink/uplink = new()
var/item_cost = 0
var/datum/uplink_category/category // Item category
var/list/datum/antagonist/antag_roles // Antag roles this item is displayed to. If empty, display to all.
- var/blacklisted = 0
+ var/blacklisted = FALSE
/datum/uplink_item/item
var/path = null
@@ -48,50 +48,34 @@ var/datum/uplink/uplink = new()
if(!extra_args)
return
- if(!can_buy(U))
+ if(!can_buy(U, user.mind.tcrystals))
return
- if(U.CanUseTopic(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE)
+ if(U.tgui_status(user, GLOB.tgui_deep_inventory_state) != STATUS_INTERACTIVE)
return
- var/cost = cost(U.uses, U)
+ var/cost = cost(U, user.mind.tcrystals)
var/goods = get_goods(U, get_turf(user), user, extra_args)
if(!goods)
return
- purchase_log(U)
+ purchase_log(user)
user.mind.tcrystals -= cost
- U.used_TC += cost
+ user.mind.used_TC += cost
return goods
// Any additional arguments you wish to send to the get_goods
/datum/uplink_item/proc/extra_args(var/mob/user)
- return 1
+ return TRUE
-/datum/uplink_item/proc/can_buy(obj/item/device/uplink/U)
- if(cost(U.uses, U) > U.uses)
- return 0
+/datum/uplink_item/proc/can_buy(var/obj/item/device/uplink/U, var/telecrystals)
+ if(cost(U, telecrystals) > telecrystals)
+ return FALSE
- return can_view(U)
+ return TRUE
-/datum/uplink_item/proc/can_view(obj/item/device/uplink/U)
- // Making the assumption that if no uplink was supplied, then we don't care about antag roles
- if(!U || !antag_roles.len)
- return 1
-
- // With no owner, there's no need to check antag status.
- if(!U.uplink_owner)
- return 0
-
- for(var/antag_role in antag_roles)
- var/datum/antagonist/antag = all_antag_types[antag_role]
- if(!isnull(antag))
- if(antag.is_antagonist(U.uplink_owner))
- return 1
- return 0
-
-/datum/uplink_item/proc/cost(var/telecrystals, obj/item/device/uplink/U)
+/datum/uplink_item/proc/cost(obj/item/device/uplink/U, mob/M)
. = item_cost
if(U)
. = U.get_item_cost(src, .)
@@ -100,19 +84,19 @@ var/datum/uplink/uplink = new()
return desc
// get_goods does not necessarily return physical objects, it is simply a way to acquire the uplink item without paying
-/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc)
- return 0
+/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc, mob/user)
+ return FALSE
/datum/uplink_item/proc/log_icon()
return
-/datum/uplink_item/proc/purchase_log(obj/item/device/uplink/U)
+/datum/uplink_item/proc/purchase_log(mob/M)
feedback_add_details("traitor_uplink_items_bought", "[src]")
- log_and_message_admins("used \the [U.loc] to buy \a [src]")
- U.purchase_log[src] = U.purchase_log[src] + 1
+ log_and_message_admins("\the [M] bought \a [src] through the uplink")
+ M.mind.purchase_log[src] += 1
datum/uplink_item/dd_SortValue()
- return cost(INFINITY)
+ return item_cost
/********************************
* *
@@ -133,7 +117,7 @@ datum/uplink_item/dd_SortValue()
A.put_in_any_hand_if_possible(I)
return I
-/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc)
+/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user)
var/obj/item/I = new path(loc)
return I
@@ -208,7 +192,7 @@ datum/uplink_item/dd_SortValue()
/proc/get_surplus_items(var/obj/item/device/uplink/U, var/remaining_TC, var/loc)
var/list/bought_items = list()
- var/override = 1
+ var/override = TRUE
while(remaining_TC)
var/datum/uplink_item/I = all_uplink_selection.get_random_item(remaining_TC, U, bought_items, override)
if(!I)
diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm
index d3ed1dcec34..b939e953de3 100644
--- a/code/datums/uplink/visible_weapons.dm
+++ b/code/datums/uplink/visible_weapons.dm
@@ -103,7 +103,7 @@
name = "Anti-Materiel Rifle (14.5mm)"
item_cost = DEFAULT_TELECRYSTAL_AMOUNT
path = /obj/item/weapon/gun/projectile/heavysniper
- antag_roles = list("mercenary")
+ antag_roles = list("mercenary", "ert") //VOREStation Edit
/datum/uplink_item/item/visible_weapons/heavysnipertraitor
name = "Anti-Materiel Rifle (14.5mm)"
diff --git a/code/datums/wires/mines.dm b/code/datums/wires/mines.dm
index 209fcc4c307..5e757ad16c3 100644
--- a/code/datums/wires/mines.dm
+++ b/code/datums/wires/mines.dm
@@ -1,5 +1,5 @@
/datum/wires/mines
- wire_count = 6
+ wire_count = 7
randomize = TRUE
holder_type = /obj/effect/mine
proper_name = "Explosive Wires"
@@ -7,6 +7,7 @@
/datum/wires/mines/New(atom/_holder)
wires = list(WIRE_EXPLODE, WIRE_EXPLODE_DELAY, WIRE_DISARM, WIRE_BADDISARM)
return ..()
+#define WIRE_TRAP 64
/datum/wires/mines/get_status()
. = ..()
@@ -29,7 +30,13 @@
if(WIRE_DISARM)
C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
- new C.mineitemtype(get_turf(C))
+ var/obj/effect/mine/MI = new C.mineitemtype(get_turf(C))
+
+ if(C.trap)
+ MI.trap = C.trap
+ C.trap = null
+ MI.trap.forceMove(MI)
+
spawn(0)
qdel(C)
@@ -37,6 +44,15 @@
C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
spawn(20)
C.explode()
+
+ if(WIRE_TRAP)
+ C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
+
+ if(mend)
+ C.visible_message("[bicon(C)] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]")
+
+ C.alpha = 255
+
..()
/datum/wires/mines/on_pulse(wire)
@@ -57,6 +73,10 @@
if(WIRE_BADDISARM)
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
+
+ if(WIRE_TRAP)
+ C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
+
..()
/datum/wires/mines/interactable(mob/user)
diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm
index efcd5955f74..99216b9ef55 100644
--- a/code/game/antagonist/antagonist_print.dm
+++ b/code/game/antagonist/antagonist_print.dm
@@ -1,7 +1,7 @@
/datum/antagonist/proc/print_player_summary()
if(!current_antagonists.len)
- return 0
+ return FALSE
var/text = "
The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:"
for(var/datum/mind/P in current_antagonists)
@@ -21,7 +21,7 @@
else
text += "Fail."
feedback_add_details(feedback_tag,"[O.type]|FAIL")
- failed = 1
+ failed = TRUE
num++
if(failed)
text += "
The [role_text] has failed."
@@ -32,7 +32,7 @@
text += "
Their objectives were:"
var/num = 1
for(var/datum/objective/O in global_objectives)
- text += print_objective(O, num, 1)
+ text += print_objective(O, num, TRUE)
num++
// Display the results.
@@ -68,14 +68,14 @@
/datum/antagonist/proc/print_player_full(var/datum/mind/ply)
var/text = print_player_lite(ply)
- var/TC_uses = 0
- var/uplink_true = 0
+ var/TC_uses = FALSE
+ var/uplink_true = FALSE
var/purchases = ""
- for(var/obj/item/device/uplink/H in world_uplinks)
- if(H && H.uplink_owner && H.uplink_owner == ply)
- TC_uses += H.used_TC
- uplink_true = 1
- purchases += get_uplink_purchases(H)
+ for(var/mob/M in player_list)
+ if(M.mind && M.mind.used_TC)
+ TC_uses += M.mind.used_TC
+ uplink_true = TRUE
+ purchases += get_uplink_purchases(M.mind)
if(uplink_true)
text += " (used [TC_uses] TC)"
if(purchases)
@@ -83,18 +83,8 @@
return text
-/proc/print_ownerless_uplinks()
- var/has_printed = 0
- for(var/obj/item/device/uplink/H in world_uplinks)
- if(isnull(H.uplink_owner) && H.used_TC)
- if(!has_printed)
- has_printed = 1
- to_world("Ownerless Uplinks")
- to_world("[H.loc] (used [H.used_TC] TC)")
- to_world(get_uplink_purchases(H))
-
-/proc/get_uplink_purchases(var/obj/item/device/uplink/H)
+/proc/get_uplink_purchases(var/datum/mind/M)
var/list/refined_log = new()
- for(var/datum/uplink_item/UI in H.purchase_log)
- refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
+ for(var/datum/uplink_item/UI in M.purchase_log)
+ refined_log.Add("[M.purchase_log[UI]]x[UI.log_icon()][UI.name]")
. = english_list(refined_log, nothing_text = "")
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 04075fe8255..9c8bbccc798 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -50,13 +50,12 @@
var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf
var/forbid_events = FALSE // If true, random events will not start inside this area.
var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons.
+ var/soundproofed = FALSE // If true, blocks sounds from other areas and prevents hearers on other areas from hearing the sounds within.
/area/Initialize()
. = ..()
-
luminosity = !(dynamic_lighting)
icon_state = ""
-
return INITIALIZE_HINT_LATELOAD // Areas tradiationally are initialized AFTER other atoms.
/area/LateInitialize()
@@ -67,7 +66,6 @@
power_change() // all machines set to current power level, also updates lighting icon
if(no_spoilers)
set_spoiler_obfuscation(TRUE)
- return INITIALIZE_HINT_LATELOAD
// Changes the area of T to A. Do not do this manually.
// Area is expected to be a non-null instance.
@@ -379,9 +377,9 @@ var/list/mob/living/forced_ambiance_list = new
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance)))
return
-
+
var/volume_mod = L.get_preference_volume_channel(VOLUME_CHANNEL_AMBIENCE)
-
+
// If we previously were in an area with force-played ambiance, stop it.
if((L in forced_ambiance_list) && initial)
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index bf5fc0ab18c..510b8bf7620 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -134,7 +134,7 @@
for(var/i in loc)
var/atom/movable/thing = i
// We don't call parent so we are calling this for byond
- thing.Crossed(src)
+ thing.Crossed(src, oldloc)
// We're a multi-tile object (multiple locs)
else if(. && newloc)
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 4141281df9d..fccf178af9c 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -202,23 +202,9 @@ var/global/list/datum/dna/gene/dna_genes[0]
// Technically custom_species is not part of the UI, but this place avoids merge problems.
src.custom_species = character.custom_species
- if(istype(character.species,/datum/species/custom))
- var/datum/species/custom/CS = character.species
- src.species_traits = CS.traits.Copy()
- src.base_species = CS.base_species
- src.blood_color = CS.blood_color
-
- if(istype(character.species,/datum/species/xenochimera))
- var/datum/species/xenochimera/CS = character.species
- //src.species_traits = CS.traits.Copy() //No traits
- src.base_species = CS.base_species
- src.blood_color = CS.blood_color
-
- if(istype(character.species,/datum/species/alraune))
- var/datum/species/alraune/CS = character.species
- //src.species_traits = CS.traits.Copy() //No traits
- src.base_species = CS.base_species
- src.blood_color = CS.blood_color
+ src.base_species = character.species.base_species
+ src.blood_color = character.species.blood_color
+ src.species_traits = character.species.traits.Copy()
// +1 to account for the none-of-the-above possibility
SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1)
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 0edc6bb636b..758f74d8737 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -237,20 +237,9 @@
// Technically custom_species is not part of the UI, but this place avoids merge problems.
H.custom_species = dna.custom_species
- if(istype(H.species,/datum/species/custom))
- var/datum/species/custom/CS = H.species
- var/datum/species/custom/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
- new_CS.blood_color = dna.blood_color
-
- if(istype(H.species,/datum/species/xenochimera))
- var/datum/species/xenochimera/CS = H.species
- var/datum/species/xenochimera/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
- new_CS.blood_color = dna.blood_color
-
- if(istype(H.species,/datum/species/alraune))
- var/datum/species/alraune/CS = H.species
- var/datum/species/alraune/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
- new_CS.blood_color = dna.blood_color
+ H.species.blood_color = dna.blood_color
+ var/datum/species/S = H.species
+ S.produceCopy(dna.base_species,dna.species_traits,src)
// VOREStation Edit End
H.force_update_organs() //VOREStation Add - Gotta do this too
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index bbf4bfb3437..241d6132756 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -34,7 +34,7 @@
var/last_activation = 0
/obj/structure/cult/pylon/Initialize()
- ..()
+ . = ..()
START_PROCESSING(SSobj, src)
/obj/structure/cult/pylon/attack_hand(mob/M as mob)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 42e6a6ddd00..18d58a33ae8 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -292,7 +292,6 @@ var/global/list/additional_antag_types = list()
antag.check_victory()
antag.print_player_summary()
sleep(10)
- print_ownerless_uplinks()
var/clients = 0
var/surviving_humans = 0
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 0b0b8d014c7..a6ceb219c84 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -13,7 +13,7 @@
/obj/effect/meteor/big=3,
/obj/effect/meteor/flaming=1,
/obj/effect/meteor/irradiated=3
- )
+ )
//for threatening meteor event
/var/list/meteors_threatening = list(
@@ -206,6 +206,21 @@
return
..()
+/obj/effect/meteor/bullet_act(var/obj/item/projectile/Proj)
+ if(Proj.excavation_amount)
+ get_hit()
+ if(!QDELETED(src))
+ wall_power -= Proj.excavation_amount + Proj.damage + (Proj.hitscan * 25) // Instant-impact projectiles are inherently better at dealing with meteors.
+ wall_power = max(1, wall_power)
+
+ if(wall_power < Proj.excavation_amount)
+ if(prob(min(90, 100 - Proj.damage)))
+ die(TRUE)
+ else
+ die(FALSE)
+ return
+ return
+
/obj/effect/meteor/proc/make_debris()
for(var/throws = dropamt, throws > 0, throws--)
var/obj/item/O = new meteordrop(get_turf(src))
diff --git a/code/game/jobs/access_datum_vr.dm b/code/game/jobs/access_datum_vr.dm
index 16038248d01..bd3906f16c5 100644
--- a/code/game/jobs/access_datum_vr.dm
+++ b/code/game/jobs/access_datum_vr.dm
@@ -27,4 +27,22 @@ var/const/access_pilot = 67
/datum/access/entertainment
id = access_entertainment
desc = "Entertainment Backstage"
- region = ACCESS_REGION_GENERAL
\ No newline at end of file
+ region = ACCESS_REGION_GENERAL
+
+/var/const/access_mime = 138
+/datum/access/mime
+ id = access_mime
+ desc = "Mime Office"
+ region = ACCESS_REGION_GENERAL
+
+/var/const/access_clown = 136
+/datum/access/clown
+ id = access_clown
+ desc = "Clown Office"
+ region = ACCESS_REGION_GENERAL
+
+/var/const/access_tomfoolery = 137
+/datum/access/tomfoolery
+ id = access_tomfoolery
+ desc = "Tomfoolery Closet"
+ region = ACCESS_REGION_GENERAL
diff --git a/code/game/jobs/job/captain_vr.dm b/code/game/jobs/job/captain_vr.dm
index d2b830ad7ba..4062775846d 100644
--- a/code/game/jobs/job/captain_vr.dm
+++ b/code/game/jobs/job/captain_vr.dm
@@ -26,13 +26,13 @@
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth)
+ access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth)
minimal_access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth)
+ access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth)
/datum/alt_title/deputy_manager
title = "Deputy Manager"
diff --git a/code/game/jobs/job/special_vr.dm b/code/game/jobs/job/special_vr.dm
index dcb6a51521a..34cc2321ce8 100644
--- a/code/game/jobs/job/special_vr.dm
+++ b/code/game/jobs/job/special_vr.dm
@@ -56,14 +56,14 @@
departments = list(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
- total_positions = -1
- spawn_positions = -1
+ total_positions = 1
+ spawn_positions = 1
supervisors = "the spirit of laughter"
selection_color = "#515151"
economic_modifier = 1
job_description = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!"
whitelist_only = 1
- latejoin_only = 1
+ latejoin_only = 0
outfit_type = /decl/hierarchy/outfit/job/clown
pto_type = PTO_CIVILIAN
alt_titles = list("Jester" = /datum/alt_title/jester, "Fool" = /datum/alt_title/fool)
@@ -76,9 +76,9 @@
/datum/job/clown/get_access()
if(config.assistant_maint)
- return list(access_maint_tunnels, access_entertainment)
+ return list(access_maint_tunnels, access_entertainment, access_clown, access_tomfoolery)
else
- return list(access_entertainment)
+ return list(access_entertainment, access_clown, access_tomfoolery)
/datum/job/mime
title = "Mime"
@@ -86,15 +86,15 @@
departments = list(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
- total_positions = -1
- spawn_positions = -1
+ total_positions = 1
+ spawn_positions = 1
supervisors = "the spirit of performance"
selection_color = "#515151"
economic_modifier = 1
job_description = "A Mime is there to entertain the crew and keep high morale using unbelievable performances and acting skills!"
alt_titles = list("Poseur" = /datum/alt_title/poseur)
whitelist_only = 1
- latejoin_only = 1
+ latejoin_only = 0
outfit_type = /decl/hierarchy/outfit/job/mime
pto_type = PTO_CIVILIAN
@@ -103,6 +103,6 @@
/datum/job/mime/get_access()
if(config.assistant_maint)
- return list(access_maint_tunnels, access_entertainment)
+ return list(access_maint_tunnels, access_entertainment, access_tomfoolery, access_mime)
else
- return list(access_entertainment)
+ return list(access_entertainment, access_tomfoolery, access_mime)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index a97fbf986f7..e0ff3a6086c 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -529,5 +529,5 @@
stasis_level = 100 //Just one setting
/obj/machinery/sleeper/survival_pod/Initialize()
- ..()
+ . = ..()
RefreshParts(1)
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 7ff97c83e85..25299dcda8c 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -1,4 +1,4 @@
-/obj/machinery/computer/arcade/
+/obj/machinery/computer/arcade
name = "random arcade"
desc = "random arcade machine"
icon_state = "arcade"
@@ -25,15 +25,15 @@
/obj/item/toy/stickhorse = 2
)
-/obj/machinery/computer/arcade/New()
- ..()
+/obj/machinery/computer/arcade/Initialize()
+ . = ..()
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
if(!circuit)
var/choice = pick(subtypesof(/obj/item/weapon/circuitboard/arcade) - /obj/item/weapon/circuitboard/arcade/clawmachine)
var/obj/item/weapon/circuitboard/CB = new choice()
new CB.build_path(loc, CB)
- qdel(src)
+ return INITIALIZE_HINT_QDEL
/obj/machinery/computer/arcade/proc/prizevend()
if(!(contents-circuit).len)
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index cc05d632176..8d4202d4213 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -26,7 +26,7 @@
light_color = "#315ab4"
/obj/machinery/computer/cloning/Initialize()
- ..()
+ . = ..()
pods = list()
records = list()
set_scan_temp("Scanner ready.", "good")
diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm
index 5fc8c77bd0e..20fd6991a01 100644
--- a/code/game/machinery/computer/guestpass.dm
+++ b/code/game/machinery/computer/guestpass.dm
@@ -168,9 +168,9 @@
if(reas)
reason = reas
if("duration")
- var/dur = input("Duration (in minutes) during which pass is valid (up to 120 minutes).", "Duration") as num|null
+ var/dur = input("Duration (in minutes) during which pass is valid (up to 360 minutes).", "Duration") as num|null //VOREStation Edit
if(dur)
- if(dur > 0 && dur <= 120)
+ if(dur > 0 && dur <= 360) //VOREStation Edit
duration = dur
else
to_chat(usr, "Invalid duration.")
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index adf53c80a8e..680ce44345f 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -29,7 +29,7 @@
/obj/machinery/computer/med_data/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"sex" = "Please select new sex:",
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 1caa7b61a4d..430b42591cf 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -335,7 +335,7 @@
name = "Monitor Decryption Key"
/obj/item/weapon/paper/monitorkey/Initialize()
- ..() //Late init
+ ..()
return INITIALIZE_HINT_LATELOAD
/obj/item/weapon/paper/monitorkey/LateInitialize()
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index dbd5ba8383f..5eae5e82d08 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -13,7 +13,7 @@
var/title = "Mass Driver Controls"
/obj/machinery/computer/pod/Initialize()
- ..() //Not returning parent because lateload
+ ..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/pod/LateInitialize()
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 0b6ab77d7a2..40a4d594cbd 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -25,7 +25,7 @@
var/static/list/field_edit_choices
/obj/machinery/computer/secure_data/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"name" = "Please enter new name:",
@@ -317,16 +317,16 @@
if(!length(t1))
return
- for(var/datum/data/record/R in data_core.security)
- if(t1 == lowertext(R.fields["name"]) || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))
- active2 = R
+ for(var/datum/data/record/R in data_core.general)
+ if(t1 == lowertext(R.fields["name"]) || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["fingerprint"]))
+ active1 = R
break
- if(!active2)
- set_temp("Security record not found. You must enter the person's exact name, ID or DNA.", "danger")
+ if(!active1)
+ set_temp("Security record not found. You must enter the person's exact name, ID, or fingerprint.", "danger")
return
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == active2.fields["name"] && E.fields["id"] == active2.fields["id"])
- active1 = E
+ for(var/datum/data/record/E in data_core.security)
+ if(E.fields["name"] == active1.fields["name"] && E.fields["id"] == active1.fields["id"])
+ active2 = E
break
screen = SEC_DATA_RECORD
if("print_p")
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 47b9e8ce256..e11f404b165 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -30,7 +30,7 @@
var/static/list/field_edit_choices
/obj/machinery/computer/skills/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"name" = "Please input new name:",
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index db275597960..64a3cc1fc78 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -1,111 +1,8 @@
/*
CONTAINS:
Deployable items
-Barricades
*/
-//Barricades!
-/obj/structure/barricade
- name = "barricade"
- desc = "This space is blocked off by a barricade."
- icon = 'icons/obj/structures.dmi'
- icon_state = "barricade"
- anchored = 1.0
- density = 1.0
- var/health = 100
- var/maxhealth = 100
- var/datum/material/material
-
-/obj/structure/barricade/New(var/newloc, var/material_name)
- ..(newloc)
- if(!material_name)
- material_name = "wood"
- material = get_material_by_name("[material_name]")
- if(!material)
- qdel(src)
- return
- name = "[material.display_name] barricade"
- desc = "This space is blocked off by a barricade made of [material.display_name]."
- color = material.icon_colour
- maxhealth = material.integrity
- health = maxhealth
-
-/obj/structure/barricade/get_material()
- return material
-
-/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
- user.setClickCooldown(user.get_attack_speed(W))
- if(istype(W, /obj/item/stack))
- var/obj/item/stack/D = W
- if(D.get_material_name() != material.name)
- return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
- if(health < maxhealth)
- if(D.get_amount() < 1)
- to_chat(user, "You need one sheet of [material.display_name] to repair \the [src].")
- return
- visible_message("[user] begins to repair \the [src].")
- if(do_after(user,20) && health < maxhealth)
- if(D.use(1))
- health = maxhealth
- visible_message("[user] repairs \the [src].")
- return
- return
- else
- switch(W.damtype)
- if("fire")
- health -= W.force * 1
- if("brute")
- health -= W.force * 0.75
- if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
- playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
- else
- playsound(src, 'sound/weapons/smash.ogg', 50, 1)
- CheckHealth()
- ..()
-
-/obj/structure/barricade/proc/CheckHealth()
- if(health <= 0)
- dismantle()
- return
-
-/obj/structure/barricade/take_damage(var/damage)
- health -= damage
- CheckHealth()
- return
-
-/obj/structure/barricade/attack_generic(var/mob/user, var/damage, var/attack_verb)
- visible_message("[user] [attack_verb] the [src]!")
- if(material == get_material_by_name("resin"))
- playsound(src, 'sound/effects/attackblob.ogg', 100, 1)
- else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
- playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
- else
- playsound(src, 'sound/weapons/smash.ogg', 50, 1)
- user.do_attack_animation(src)
- health -= damage
- CheckHealth()
- return
-
-/obj/structure/barricade/proc/dismantle()
- material.place_dismantled_product(get_turf(src))
- visible_message("\The [src] falls apart!")
- qdel(src)
- return
-
-/obj/structure/barricade/ex_act(severity)
- switch(severity)
- if(1.0)
- dismantle()
- if(2.0)
- health -= 25
- CheckHealth()
-
-/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return TRUE
- return FALSE
-
-//Actual Deployable machinery stuff
/obj/machinery/deployable
name = "deployable"
desc = "deployable"
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index 08e0979ed57..8526820c33b 100644
--- a/code/game/machinery/doors/blast_door.dm
+++ b/code/game/machinery/doors/blast_door.dm
@@ -29,6 +29,7 @@
var/close_sound = 'sound/machines/door/blastdoorclose.ogg'
var/damage = BLAST_DOOR_CRUSH_DAMAGE
var/multiplier = 1 // The multiplier for how powerful our YEET is.
+ var/istransparent = 0
closed_layer = ON_WINDOW_LAYER // Above airlocks when closed
var/id = 1.0
@@ -108,10 +109,13 @@
src.density = 1
update_nearby_tiles()
src.update_icon()
- src.set_opacity(1)
+ if(src.istransparent)
+ src.set_opacity(0)
+ else
+ src.set_opacity(1)
sleep(15)
src.operating = 0
-
+
// Blast door crushing.
for(var/turf/turf in locs)
for(var/atom/movable/AM in turf)
@@ -276,10 +280,11 @@
// Parameters: None
// Description: Closes the door. Does necessary checks.
/obj/machinery/door/blast/close()
+
if (src.operating || (stat & BROKEN || stat & NOPOWER))
return
- force_close()
+ force_close()
// Proc: repair()
// Parameters: None
@@ -323,5 +328,52 @@ obj/machinery/door/blast/regular/open
icon_state = "shutter1"
damage = SHUTTER_CRUSH_DAMAGE
+// SUBTYPE: Transparent
+// Not technically a blast door but operates like one. Allows air and light.
+obj/machinery/door/blast/gate
+ name = "thick gate"
+ icon_state_open = "tshutter0"
+ icon_state_opening = "tshutterc0"
+ icon_state_closed = "tshutter1"
+ icon_state_closing = "tshutterc1"
+ icon_state = "tshutter1"
+ damage = SHUTTER_CRUSH_DAMAGE
+ maxhealth = 400
+ block_air_zones = 0
+ opacity = 0
+ istransparent = 1
+
+obj/machinery/door/blast/gate/open
+ icon_state = "tshutter0"
+ density = 0
+
+/obj/machinery/door/blast/gate/thin
+ name = "thin gate"
+ icon_state_open = "shutter2_0"
+ icon_state_opening = "shutter2_c0"
+ icon_state_closed = "shutter2_1"
+ icon_state_closing = "shutter2_c1"
+ icon_state = "shutter2_1"
+ maxhealth = 200
+ opacity = 0
+
+/obj/machinery/door/blast/gate/thin/open
+ icon_state = "shutter2_1"
+ density = 0
+
+/obj/machinery/door/blast/gate/bars
+ name = "prison bars"
+ icon_state_open = "bars_0"
+ icon_state_opening = "bars_c0"
+ icon_state_closed = "bars_1"
+ icon_state_closing = "bars_c1"
+ icon_state = "bars_1"
+ maxhealth = 600
+ opacity = 0
+
+/obj/machinery/door/blast/gate/bars/open
+ icon_state = "bars_1"
+ density = 0
+
#undef BLAST_DOOR_CRUSH_DAMAGE
#undef SHUTTER_CRUSH_DAMAGE
\ No newline at end of file
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index f4d9c900ed3..fdd526039b3 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -40,7 +40,6 @@
/obj/machinery/door_timer/Initialize()
..()
- //Doors need to go first, and can't rely on init order, so come back to me.
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door_timer/LateInitialize()
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index a208e6eefd2..c078b854d0c 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -68,6 +68,7 @@
L.updateicon()
area.power_change()
+ GLOB.lights_switched_on_roundstat++
/obj/machinery/light_switch/power_change()
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index c23d02f4d01..a1798ea5e42 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -164,7 +164,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
securityCaster = 1
/obj/machinery/newscaster/Initialize()
- ..() //Not returning . because lateload below
+ ..()
allCasters += src
unit_no = ++unit_no_cur
paper_remaining = 15
diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm
index 5b10e398a3b..51f48c416b0 100644
--- a/code/game/machinery/pointdefense.dm
+++ b/code/game/machinery/pointdefense.dm
@@ -371,10 +371,13 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
/obj/effect/projectile/tracer/pointdefense
+ icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "beam_pointdef"
/obj/effect/projectile/muzzle/pointdefense
+ icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "muzzle_pointdef"
/obj/effect/projectile/impact/pointdefense
+ icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "impact_pointdef"
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 01a890bd79d..8e9e6da8f71 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -74,6 +74,7 @@
var/check_anomalies = TRUE //checks if it can shoot at unidentified lifeforms (ie xenos)
var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg
var/check_all = FALSE //If active, will fire on anything, including synthetics.
+ var/fire_at_movement = FALSE // If active, will fire on the most recent thing to move in range, as soon as possible.
var/ailock = FALSE // AI cannot use this
var/check_down = FALSE //If active, will shoot to kill when lethals are also on
var/faction = null //if set, will not fire at people in the same faction for any reason.
@@ -95,6 +96,8 @@
var/timeout = 10 // When a turret pops up, then finds nothing to shoot at, this number decrements until 0, when it pops down.
var/can_salvage = TRUE // If false, salvaging doesn't give you anything.
+ var/stay_up = FALSE // If true, the turret will remain open while it is powered.
+
/obj/machinery/porta_turret/crescent
req_one_access = list(access_cent_specops)
enabled = FALSE
@@ -276,6 +279,31 @@
)
return data
+/obj/machinery/porta_turret/pointdefense
+ name = "point-defense turret"
+ turret_type = "core"
+ desc = "A basic ship-mounted rock-breaker."
+ description_info = "This turret is capable of blasting incoming meteors into gravel, but it is very limited in range."
+
+ installation = /obj/item/weapon/gun/energy/mininglaser
+
+ check_arrest = FALSE
+ check_records = FALSE
+ check_weapons = FALSE
+ check_access = FALSE
+ check_anomalies = FALSE
+ check_synth = FALSE
+ check_all = FALSE
+ fire_at_movement = TRUE
+ stay_up = TRUE
+ ailock = FALSE
+ check_down = FALSE
+
+/obj/machinery/porta_turret/pointdefense/orderable
+ enabled = FALSE
+ anchored = FALSE
+ locked = FALSE
+
/obj/machinery/porta_turret/Initialize()
//Sets up a spark system
spark_system = new /datum/effect/effect/system/spark_spread
@@ -322,6 +350,8 @@
var/obj/item/projectile/P = initial(E.projectile_type)
//var/obj/item/ammo_casing/shottype = E.projectile_type
+ //GLOB.moved_event.register_global(src, /obj/machinery/porta_turret/proc/point_defense) //VOREStation Removal
+
projectile = P
lethal_projectile = projectile
shot_sound = initial(P.fire_sound)
@@ -377,11 +407,18 @@
lethal_shot_sound = 'sound/weapons/eluger.ogg'
shot_sound = 'sound/weapons/Taser.ogg'
-/obj/machinery/porta_turret/proc/HasController()
- var/area/A = get_area(src)
- return A && A.turret_controls.len > 0
+ if(/obj/item/weapon/gun/energy/mininglaser)
+ lethal_icon_color = "green"
+ lethal_projectile = /obj/item/projectile/beam/mininglaser
+ lethal_shot_sound = 'sound/weapons/eluger.ogg'
+ icon_color = "red"
+ projectile = /obj/item/projectile/beam/weaklaser
+ shot_sound = 'sound/weapons/Laser.ogg'
/obj/machinery/porta_turret/proc/isLocked(mob/user)
+ if(locked && !issilicon(user))
+ to_chat(user, "Controls locked.")
+ return 1
if(HasController())
return TRUE
if(isrobot(user) || isAI(user))
@@ -409,6 +446,10 @@
/obj/machinery/porta_turret/attack_hand(mob/user)
tgui_interact(user)
+/obj/machinery/porta_turret/proc/HasController()
+ var/area/A = get_area(src)
+ return A && A.turret_controls.len > 0
+
/obj/machinery/porta_turret/tgui_interact(mob/user, datum/tgui/ui = null)
if(HasController())
to_chat(user, "[src] can only be controlled using the assigned turret controller.")
@@ -671,6 +712,10 @@
popDown()
return
+ if(stay_up)
+ timeout = 10
+ popUp()
+
var/list/targets = list() //list of primary targets
var/list/secondarytargets = list() //targets that are least important
@@ -693,7 +738,7 @@
if(!tryToShootAt(targets))
if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets
timeout--
- if(timeout <= 0)
+ if(timeout <= 0 && !stay_up)
spawn()
popDown() // no valid targets, close the cover
@@ -701,6 +746,14 @@
use_power(20000)
health = min(health+1, maxhealth) // 1HP for 20kJ
+// We're expecting the first arg to be a target, for this we don't care about previous and next turfs.
+/obj/machinery/porta_turret/proc/point_defense(var/atom/movable/Targ)
+ if((stat & (NOPOWER|BROKEN)) || !fire_at_movement) // Are we even able or supposed to fire at non-moving targets?
+ return
+
+ if((isliving(Targ) && assess_living(Targ)) || ((istype(Targ, /obj/item) || istype(Targ, /obj/effect/meteor)) && Targ.invisibility < INVISIBILITY_LEVEL_ONE && Targ in view(7,src))) // Is the target a living thing, if so, is it a valid target? Or if it's not living, is it in sight?
+ target(Targ) // Yes? Blast it.
+
/obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets)
switch(assess_living(L))
if(TURRET_PRIORITY_TARGET)
@@ -727,10 +780,10 @@
if(L.stat == DEAD && !emagged) //if the perp is dead, no need to bother really
return TURRET_NOT_TARGET //move onto next potential victim!
- if(get_dist(src, L) > 7) //if it's too far away, why bother?
+ if(get_dist(src, get_turf(L)) > 7) //if it's too far away, why bother?
return TURRET_NOT_TARGET
- if(!(L in check_trajectory(L, src))) //check if we have true line of sight
+ if(!(L in check_trajectory(get_turf(L), src))) //check if we have true line of sight
return TURRET_NOT_TARGET
if(emagged) // If emagged not even the dead get a rest
@@ -837,8 +890,9 @@
last_target = target
spawn()
popUp() //pop the turret up if it's not already up.
- set_dir(get_dir(src, target)) //even if you can't shoot, follow the target
- playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound
+ if(dir != get_dir(src, target))
+ set_dir(get_dir(src, target)) //even if you can't shoot, follow the target
+ playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound
spawn()
shootAt(target)
return 1
@@ -903,6 +957,8 @@
var/check_anomalies
var/check_all
var/check_down
+ var/fire_at_movement
+ var/stay_up
var/ailock
/obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC)
@@ -919,6 +975,8 @@
check_anomalies = TC.check_anomalies
check_all = TC.check_all
check_down = TC.check_down
+ fire_at_movement = TC.fire_at_movement
+ stay_up = TC.stay_up
ailock = TC.ailock
power_change()
diff --git a/code/game/machinery/syndicatebeacon_vr.dm b/code/game/machinery/syndicatebeacon_vr.dm
index ef6b3da0bbf..668b36dcb70 100644
--- a/code/game/machinery/syndicatebeacon_vr.dm
+++ b/code/game/machinery/syndicatebeacon_vr.dm
@@ -25,7 +25,7 @@
updateUsrDialog()
return
var/mob/M = locate(href_list["traitormob"])
- if(M.mind.special_role || jobban_isbanned(M, "Syndicate"))
+ if(M.mind.tcrystals > 0 || jobban_isbanned(M, "Syndicate"))
temptext = "We have no need for you at this time. Have a pleasant day.
"
updateUsrDialog()
return
@@ -33,7 +33,9 @@
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/N = M
to_chat(N, "Access granted, here are the supplies!")
- traitors.equip(N)
+ traitors.spawn_uplink(N)
+ N.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT
+ N.mind.accept_tcrystals = 1
message_admins("[N]/([N.ckey]) has recieved an uplink and telecrystals from the syndicate beacon.")
updateUsrDialog()
diff --git a/code/game/machinery/transportpod.dm b/code/game/machinery/transportpod.dm
index 0b499096fea..4a43cb18904 100644
--- a/code/game/machinery/transportpod.dm
+++ b/code/game/machinery/transportpod.dm
@@ -32,7 +32,7 @@
sleep(2)
go_out()
sleep(2)
- del(src)
+ qdel(src)
/obj/machinery/transportpod/relaymove(mob/user as mob)
if(user.stat)
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index ad55fe14a17..7f5a1d8e567 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -28,9 +28,12 @@
var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg
var/check_all = FALSE //If active, will shoot at anything.
var/check_down = TRUE //If active, won't shoot laying targets.
+ var/stay_up = FALSE //If active, the turret will not pop-down unless it loses power or is disabled.
+ var/fire_at_movement = FALSE //If active, the turret will prioritize objects or creatures that move in its range.
var/ailock = FALSE //Silicons cannot use this
var/syndicate = FALSE
+
req_access = list(access_ai_upload)
/obj/machinery/turretid/stun
@@ -194,6 +197,8 @@
TC.check_anomalies = check_anomalies
TC.check_all = check_all
TC.check_down = check_down
+ TC.stay_up = stay_up
+ TC.fire_at_movement = fire_at_movement
TC.ailock = ailock
if(istype(control_area))
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 4f3d532c279..58107d9d0b4 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -572,7 +572,7 @@ GLOBAL_LIST_EMPTY(vending_products)
vend_ready = 1
currently_vending = null
SStgui.update_uis(src)
-
+ GLOB.items_sold_shift_roundstat++
/obj/machinery/vending/proc/do_logging(datum/stored_item/vending_product/R, mob/user, var/vending = 0)
if(user.GetIdCard())
diff --git a/code/game/machinery/vending_machines.dm b/code/game/machinery/vending_machines.dm
index e04568c1d08..098d231ce77 100644
--- a/code/game/machinery/vending_machines.dm
+++ b/code/game/machinery/vending_machines.dm
@@ -753,7 +753,9 @@
/obj/item/toy/plushie/borgplushie/scrubpuppy = 1,
/obj/item/toy/plushie/foxbear = 1,
/obj/item/toy/plushie/nukeplushie = 1,
- /obj/item/toy/plushie/otter = 1)
+ /obj/item/toy/plushie/otter = 1,
+ /obj/item/toy/plushie/vox = 1,
+ /obj/item/toy/mistletoe = 1)
//VOREStation Add End
premium = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne = 1,
/obj/item/weapon/storage/trinketbox = 2)
@@ -793,7 +795,9 @@
/obj/item/toy/plushie/borgplushie/scrubpuppy = 50,
/obj/item/toy/plushie/foxbear = 50,
/obj/item/toy/plushie/nukeplushie = 50,
- /obj/item/toy/plushie/otter = 50)
+ /obj/item/toy/plushie/otter = 50,
+ /obj/item/toy/plushie/vox = 50,
+ /obj/item/toy/mistletoe = 50)
//VOREStation Add End
diff --git a/code/game/machinery/vending_machines_vr.dm b/code/game/machinery/vending_machines_vr.dm
index fd113ee799b..c4c4e663d4b 100644
--- a/code/game/machinery/vending_machines_vr.dm
+++ b/code/game/machinery/vending_machines_vr.dm
@@ -1446,7 +1446,7 @@
/obj/item/seeds/riceseed = 3,
/obj/item/seeds/rose = 3,
/obj/item/seeds/soyaseed = 3,
- /obj/item/seeds/spineapple = 3,
+ /obj/item/seeds/pineapple = 3,
/obj/item/seeds/sugarcaneseed = 3,
/obj/item/seeds/sunflowerseed = 3,
/obj/item/seeds/shandseed = 2,
@@ -3940,7 +3940,7 @@
/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/peanutcake = 10,
- /obj/item/weapon/reagent_containers/food/snacks/slice/pineapple = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/pineappleslice = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread = 10,
@@ -4404,7 +4404,7 @@
/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/peanutcake = 10,
- /obj/item/weapon/reagent_containers/food/snacks/slice/pineapple = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/pineappleslice = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread = 10,
@@ -4576,7 +4576,7 @@
/obj/item/seeds/riceseed = 3,
/obj/item/seeds/rose = 3,
/obj/item/seeds/soyaseed = 3,
- /obj/item/seeds/spineapple = 3,
+ /obj/item/seeds/pineapple = 3,
/obj/item/seeds/sugarcaneseed = 3,
/obj/item/seeds/sunflowerseed = 3,
/obj/item/seeds/shandseed = 2,
diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm
index aa5a9e000c1..19bd2b9c53e 100644
--- a/code/game/mecha/combat/durand.dm
+++ b/code/game/mecha/combat/durand.dm
@@ -33,6 +33,9 @@
defence_mode_possible = 1
+ icon_scale_x = 1.5
+ icon_scale_y = 1.5
+
/*
/obj/mecha/combat/durand/New()
..()
diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm
index 4052afe8e6a..fecb361f1a2 100644
--- a/code/game/mecha/combat/gorilla.dm
+++ b/code/game/mecha/combat/gorilla.dm
@@ -31,7 +31,7 @@
thrusters_possible = 1
/obj/mecha/combat/gorilla/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply.
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src)
diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index 0323124c479..1f9d4a0b6e3 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -31,6 +31,9 @@
overload_possible = 1
+ icon_scale_x = 1.35
+ icon_scale_y = 1.35
+
//Not quite sure how to move those yet.
/obj/mecha/combat/gygax/get_commands()
var/output = {"