diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index a1e4140588..9320446e31 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -60,8 +60,8 @@ Then in our `handle_grabs_vr()` proc, if we want to avoid performing the stock g
### Pull Requests
-* Your submission must pass Travis CI checking. The checks are important, prevent many common mistakes, and even experienced coders get caught by it sometimes. If you think there is a bug in Travis, open an issue. (One known Travis issue is comments in the middle of multi-line lists, just don't do it)
-* Your PR should not have an excessive number of commits unless it is a large project or includes many separate remote commits (such as a pull from Polaris). If you need to keep tweaking your PR to pass Travis or to satisfy a maintainer's requests and are making many commits, you should squash them in the end and update your PR accordingly so these commits don't clog up the history.
+* Your submission must pass CI checking. The checks are important, prevent many common mistakes, and even experienced coders get caught by it sometimes. If you think there is a bug in CI, open an issue. (One known CI issue is comments in the middle of multi-line lists, just don't do it)
+* Your PR should not have an excessive number of commits unless it is a large project or includes many separate remote commits (such as a pull from Polaris). If you need to keep tweaking your PR to pass CI or to satisfy a maintainer's requests and are making many commits, you should squash them in the end and update your PR accordingly so these commits don't clog up the history.
* You can create a WIP PR, and if so, please mark it with [WIP] in the title so it can be labeled appropriately. These can't sit forever, though.
* If your pull request has many no-conflict merge commits ('merge from master' into your PR branch), it cannot be merged. Squash and make a new PR/forcepush to your PR branch.
diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml
new file mode 100644
index 0000000000..7953929ce5
--- /dev/null
+++ b/.github/workflows/autochangelog.yml
@@ -0,0 +1,43 @@
+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
+ with:
+ ref: master
+ - name: Update repository to master
+ run: git pull "origin" master
+ - 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/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000000..f6e206bc33
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,69 @@
+name: CI
+on:
+ pull_request:
+ branches:
+ - master
+
+env:
+ BASENAME: "vorestation"
+
+jobs:
+ file_tests:
+ name: Run Linters
+ runs-on: ubuntu-16.04
+ steps:
+ - uses: actions/checkout@v2
+ - name: Ensure +x on CI directory
+ run: |
+ chmod -R +x ./tools/ci
+ - name: Install Tools
+ run: |
+ bash tools/ci/install_build_deps.sh
+ - name: Run Tests
+ run: |
+ tools/ci/validate_files.sh
+ tools/ci/build_tgui.sh
+
+ unit_tests:
+ name: Integration Tests
+ runs-on: ubuntu-16.04
+ steps:
+ - uses: actions/checkout@v2
+ - name: Ensure +x on CI directory
+ run: |
+ chmod -R +x ./tools/ci
+ - name: Setup Cache
+ uses: actions/cache@v2
+ with:
+ path: $HOME/BYOND
+ key: ${{ runner.os }}-byond
+ - name: Install RUST_G Dependencies
+ run: |
+ sudo dpkg --add-architecture i386
+ sudo apt update || true
+ sudo apt install libc6:i386 libgcc1:i386 libstdc++6:i386 libssl1.0.0:i386 g++-7 g++-7-multilib gcc-multilib zlib1g:i386
+ ldd librust_g.so
+ - name: Unit Tests
+ run: |
+ tools/ci/install_byond.sh
+ tools/ci/compile_and_run.sh
+ env:
+ TEST_DEFINE: "UNIT_TEST"
+ TEST_FILE: "code/_unit_tests.dm"
+ RUN: "1"
+ - name: Compile POIs (no run)
+ run: |
+ tools/ci/install_byond.sh
+ tools/ci/compile_and_run.sh
+ env:
+ TEST_DEFINE: "MAP_TEST"
+ TEST_FILE: "code/_map_tests.dm"
+ RUN: "0"
+ - name: Compile away missions (no run)
+ run: |
+ tools/ci/install_byond.sh
+ tools/ci/compile_and_run.sh
+ env:
+ TEST_DEFINE: "AWAY_MISSION_TEST"
+ TEST_FILE: "code/_away_mission_tests.dm"
+ RUN: "0"
diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml
index 6b58c9e8e0..f3a50a5e94 100644
--- a/.github/workflows/render_nanomaps.yml
+++ b/.github/workflows/render_nanomaps.yml
@@ -6,7 +6,8 @@
name: 'Render Nanomaps'
on:
push:
- branches: master
+ branches:
+ - master
paths:
- 'maps/**'
@@ -15,21 +16,37 @@ jobs:
name: 'Generate NanoMaps'
runs-on: ubuntu-18.04
steps:
- - name: 'Update Branch'
+ - name: Clone
uses: actions/checkout@v2
- with:
- fetch-depth: 1
- - name: 'Generate Maps'
+ - name: Branch
+ run: |
+ git fetch origin
+ git branch -f nanomaps_generation
+ git checkout nanomaps_generation
+ git reset --hard origin/master
+
+ - name: Ensure +x on github-actions directory
+ run: chmod -R +x ./tools/github-actions
+
+ - name: Generate Maps
run: './tools/github-actions/nanomap-renderer-invoker.sh'
- - name: 'Commit Maps'
+ - name: Commit Maps
run: |
git config --local user.email "action@github.com"
git config --local user.name "NanoMap Generation"
- git pull origin master
+ git add .
git commit -m "NanoMap Auto-Update (`date`)" -a || true
- - name: 'Push Maps'
- uses: ad-m/github-push-action@master
+ git push -f -u origin nanomaps_generation
+
+ - name: Create Pull Request
+ uses: repo-sync/pull-request@v2
with:
+ source_branch: "nanomaps_generation"
+ destination_branch: "master"
+ pr_title: "Automatic NanoMap Update"
+ pr_body: "This pull request updates the nanomap images to the latest version of the map."
+ pr_label: "Infrastructure"
+ pr_allow_empty: false
github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 7474eba31d..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-language: generic
-os: linux
-dist: bionic
-
-env:
- global:
- - BASENAME="vorestation" # $BASENAME.dmb, $BASENAME.dme, etc.
-
-cache:
- directories:
- - $HOME/BYOND
-
-addons:
- apt:
- packages:
- - libc6:i386
- - libgcc1:i386
- - libstdc++6:i386
- - libssl1.1:i386
- - g++-7
- - g++-7-multilib
- - gcc-multilib
- - zlib1g:i386
-
-before_install:
- - chmod -R +x ./tools/travis
-
-install:
- - ./tools/travis/install_byond.sh
-
-before_script:
- - shopt -s globstar
-
-script:
- - ldd librust_g.so
- - ./tools/travis/compile_and_run.sh
-
-# Build-specific settings
-jobs:
- include:
- - stage: "File Tests" #This is the odd man out, with specific installs and stuff.
- name: "Validate Files"
- addons:
- apt:
- packages:
- - python3
- - python3-pip
- - python3-setuptools
- install: #Need python for some of the tag matching stuff
- - tools/travis/install_build_deps.sh
- script:
- - tools/travis/validate_files.sh
- - tools/travis/build_tgui.sh
- - stage: "Unit Tests"
- env: TEST_DEFINE="UNIT_TEST" TEST_FILE="code/_unit_tests.dm" RUN="1"
- name: "Compile normally (unit tests)"
- - stage: "Isolation Tests"
- env: TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0"
- name: "Compile POIs (no run)"
- - env: TEST_DEFINE="AWAY_MISSION_TEST" TEST_FILE="code/_away_mission_tests.dm" RUN="0"
- name: "Compile away missions (no run)"
-
diff --git a/_build_dependencies.sh b/_build_dependencies.sh
index be33811c98..b89a8a2dd6 100644
--- a/_build_dependencies.sh
+++ b/_build_dependencies.sh
@@ -3,8 +3,6 @@
export SPACEMANDMM_TAG=suite-1.4
# For NanoUI + TGUI
export NODE_VERSION=12
-# For the scripts in tools
-export PHP_VERSION=7.2
# Byond Major
export BYOND_MAJOR=513
# Byond Minor
diff --git a/code/ATMOSPHERICS/pipes/tank_vr.dm b/code/ATMOSPHERICS/pipes/tank_vr.dm
new file mode 100644
index 0000000000..32341ad8f3
--- /dev/null
+++ b/code/ATMOSPHERICS/pipes/tank_vr.dm
@@ -0,0 +1,5 @@
+/obj/machinery/atmospherics/pipe/tank/phoron/full
+ start_pressure = 15000
+
+/obj/machinery/atmospherics/pipe/tank/air/full
+ start_pressure = 15000
\ No newline at end of file
diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm
index 4e9d7fd6ad..a2e15e6890 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 ccffcf4341..d497391d3f 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 3e86c13856..a7b3bd86f8 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/mobs.dm b/code/__defines/mobs.dm
index ca0e186ac9..d166b52fbe 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -26,7 +26,7 @@
#define BORGMESON 0x1
#define BORGTHERM 0x2
#define BORGXRAY 0x4
-#define BORGMATERIAL 8
+#define BORGMATERIAL 0x8
#define STANCE_ATTACK 11 // Backwards compatability
#define STANCE_ATTACKING 12 // Ditto
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index 34c68ebd08..9b9c83d256 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -24,6 +24,19 @@
#define EMP_TOX_DMG 0x80 // EMPs inflict toxin damage
#define EMP_OXY_DMG 0x100 // EMPs inflict oxy damage
+// Species allergens
+#define MEAT 0x1 // Skrell won't like this.
+#define FISH 0x2 // Seperate for completion's sake. Still bad for skrell.
+#define FRUIT 0x4 // An apple a day only keeps the doctor away if they're allergic.
+#define VEGETABLE 0x8 // Taters 'n' carrots. Potato allergy is a thing, apparently.
+#define GRAINS 0x10 // Wheat, oats, etc.
+#define BEANS 0x20 // The musical fruit! Includes soy.
+#define SEEDS 0x40 // Hope you don't have a nut allergy.
+#define DAIRY 0x80 // Lactose intolerance, ho! Also bad for skrell.
+#define FUNGI 0x100 // Delicious shrooms.
+#define COFFEE 0x200 // Mostly here for tajara.
+#define GENERIC 0x400 // Catchall for stuff that doesn't fall into the groups above. You shouldn't be allergic to this type, ever.
+
// Species spawn flags
#define SPECIES_IS_WHITELISTED 0x1 // Must be whitelisted to play.
#define SPECIES_IS_RESTRICTED 0x2 // Is not a core/normally playable species. (castes, mutantraces)
@@ -68,7 +81,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 8909238db2..78054e6ba8 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/_away_mission_tests.dm b/code/_away_mission_tests.dm
index 75286fb34e..4d9d4e91f9 100644
--- a/code/_away_mission_tests.dm
+++ b/code/_away_mission_tests.dm
@@ -1,7 +1,7 @@
/*
*
- * This file is used by Travis to indicate that additional maps need to be compiled to look for errors such as missing paths.
- * Do not add anything but the AWAY_MISSION_TEST definition here as it will be overwritten by Travis when running tests.
+ * This file is used by CI to indicate that additional maps need to be compiled to look for errors such as missing paths.
+ * Do not add anything but the AWAY_MISSION_TEST definition here as it will be overwritten by CI when running tests.
*
*
* Should you wish to edit set AWAY_MISSION_TEST to 1 like so:
diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm
index e02c99290c..742708face 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 da2b8a35d4..405d3c70c2 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -99,13 +99,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/////
@@ -237,7 +237,7 @@ var/global/list/string_slot_flags = list(
wing_styles_list[path] = instance
// 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 b2dfae0544..d45406225c 100644
--- a/code/_helpers/global_lists_vr.dm
+++ b/code/_helpers/global_lists_vr.dm
@@ -3,13 +3,16 @@
*/
var/global/list/ear_styles_list = list() // Stores /datum/sprite_accessory/ears indexed by type
+var/global/list/hair_accesories_list= list()// Stores /datum/sprite_accessory/hair_accessory indexed by type
var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail indexed by type
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
@@ -105,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,
@@ -179,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,
@@ -451,6 +499,12 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
var/datum/sprite_accessory/wing/instance = new path()
wing_styles_list[path] = instance
+ // Custom Hair Accessories
+ paths = typesof(/datum/sprite_accessory/hair_accessory) - /datum/sprite_accessory/hair_accessory
+ 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)
@@ -465,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
@@ -481,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/text.dm b/code/_helpers/text.dm
index a9aac1ffcf..2d59fa6b6a 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -55,7 +55,7 @@
input = replace_characters(input, list("\n"=" ","\t"=" "))
if(encode)
- // The below \ escapes have a space inserted to attempt to enable Travis auto-checking of span class usage. Please do not remove the space.
+ // The below \ escapes have a space inserted to attempt to enable CI auto-checking of span class usage. Please do not remove the space.
//In addition to processing html, html_encode removes byond formatting codes like "\ red", "\ i" and other.
//It is important to avoid double-encode text, it can "break" quotes and some other characters.
//Also, keep in mind that escaped characters don't work in the interface (window titles, lower left corner of the main window, etc.)
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index bc7dca1d74..10fcc662f1 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/_map_tests.dm b/code/_map_tests.dm
index 90a4004b79..372a4a7194 100644
--- a/code/_map_tests.dm
+++ b/code/_map_tests.dm
@@ -1,7 +1,7 @@
/*
*
- * This file is used by Travis to indicate that additional maps need to be compiled to look for errors such as missing paths.
- * Do not add anything but the MAP_TEST definition here as it will be overwritten by Travis when running tests.
+ * This file is used by CI to indicate that additional maps need to be compiled to look for errors such as missing paths.
+ * Do not add anything but the MAP_TEST definition here as it will be overwritten by CI when running tests.
*
*
* Should you wish to edit set MAP_TEST to 1 like so:
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 6a4579f191..b29a1192d9 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 d31a64dcda..247d1d3f8b 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 2b4f4fb85e..b419c6bd7f 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 6387f40d9e..22e8e459fc 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 b3388f7bf7..1d8df98a38 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 0000000000..555bcb8eba
--- /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/_unit_tests.dm b/code/_unit_tests.dm
index 88eebd5aec..7a1a4cbbf3 100644
--- a/code/_unit_tests.dm
+++ b/code/_unit_tests.dm
@@ -1,7 +1,7 @@
/*
*
- * This file is used by Travis to indicate that Unit Tests are to be ran.
- * Do not add anything but the UNIT_TEST definition here as it will be overwritten by Travis when running tests.
+ * This file is used by CI to indicate that Unit Tests are to be ran.
+ * Do not add anything but the UNIT_TEST definition here as it will be overwritten by CI when running tests.
*
*
* Should you wish to edit set UNIT_TEST to 1 like so:
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 2b7aa15bbc..67d14623cf 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -496,7 +496,7 @@ var/list/gamemode_cache = list()
config.respawn_time = raw_minutes MINUTES
if ("respawn_message")
- config.respawn_message = value
+ config.respawn_message = "[value]"
if ("servername")
config.server_name = value
diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm
index 40d2cc3133..8ef34e164f 100644
--- a/code/controllers/subsystems/air.dm
+++ b/code/controllers/subsystems/air.dm
@@ -27,7 +27,7 @@ SUBSYSTEM_DEF(air)
// Updating zone tiles requires temporary storage location of self-zone-blocked turfs across resumes. Used only by process_tiles_to_update.
var/list/selfblock_deferred = null
- // This is used to tell Travis WHERE the edges are.
+ // This is used to tell CI WHERE the edges are.
var/list/startup_active_edge_log = list()
/datum/controller/subsystem/air/PreInit()
diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm
index 60b08c71d2..77c9d3ab94 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 7f4fd9c42b..b4641ba7e0 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 0bce940385..40039edceb 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 cdb2adefde..750f6807cc 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 9c6ab5bb97..eed4839159 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 9e9a87ea71..9b88a496fa 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 bca9df5ae1..82e5f1f78b 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/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm
index 825902d483..9dcc601436 100644
--- a/code/datums/observation/~cleanup.dm
+++ b/code/datums/observation/~cleanup.dm
@@ -43,7 +43,7 @@ GLOBAL_LIST_EMPTY(event_listen_count)
for(var/entry in GLOB.all_observable_events.events)
var/decl/observ/event = entry
if(event.unregister_global(listener))
- log_debug("[event] - [listener] was deleted while still registered to global events.")
+ // log_debug("[event] - [listener] was deleted while still registered to global events.") // TODO: Apply axe, reimplement with datum component listeners
if(!(--listen_count))
return
@@ -55,7 +55,7 @@ GLOBAL_LIST_EMPTY(event_listen_count)
if(proc_owners)
for(var/proc_owner in proc_owners)
if(event.unregister(event_source, proc_owner))
- log_debug("[event] - [event_source] was deleted while still being listened to by [proc_owner].")
+ // log_debug("[event] - [event_source] was deleted while still being listened to by [proc_owner].") // TODO: Apply axe, reimplement with datum component listeners
if(!(--source_listener_count))
return
@@ -65,6 +65,6 @@ GLOBAL_LIST_EMPTY(event_listen_count)
var/decl/observ/event = entry
for(var/event_source in event.event_sources)
if(event.unregister(event_source, listener))
- log_debug("[event] - [listener] was deleted while still listening to [event_source].")
+ // log_debug("[event] - [listener] was deleted while still listening to [event_source].") // TODO: Apply axe, reimplement with datum component listeners
if(!(--listener_count))
return
\ No newline at end of file
diff --git a/code/datums/outfits/jobs/special_vr.dm b/code/datums/outfits/jobs/special_vr.dm
index dd8316358b..010010291d 100644
--- a/code/datums/outfits/jobs/special_vr.dm
+++ b/code/datums/outfits/jobs/special_vr.dm
@@ -9,6 +9,21 @@
id_type = /obj/item/weapon/card/id/centcom
pda_type = /obj/item/device/pda/centcom
+/decl/hierarchy/outfit/job/emergency_responder
+ name = OUTFIT_JOB_NAME("Emergency Responder")
+ uniform = /obj/item/clothing/under/ert
+ shoes = /obj/item/clothing/shoes/boots/swat
+ gloves = /obj/item/clothing/gloves/swat
+ l_ear = /obj/item/device/radio/headset/ert
+ 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")
uniform = /obj/item/clothing/under/rank/clown
diff --git a/code/datums/roundstats/_defines_local.dm b/code/datums/roundstats/_defines_local.dm
new file mode 100644
index 0000000000..951d7118ff
--- /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 0000000000..333e6c0396
--- /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/roundstats/roundstats.dm b/code/datums/roundstats/roundstats.dm
new file mode 100644
index 0000000000..c1453b18af
--- /dev/null
+++ b/code/datums/roundstats/roundstats.dm
@@ -0,0 +1,57 @@
+
+/*
+ * lbnesquik - Github
+ * Provided massive components of this. Polaris PR #5720.
+ */
+
+//This is for the round end stats system.
+
+//roundstat is used for easy finding of the variables, if you ever want to delete all of this,
+//just search roundstat and you'll find everywhere this thing reaches into.
+//It used to be bazinga but it only fly with microwaves.
+
+GLOBAL_VAR_INIT(cans_opened_roundstat, 0)
+GLOBAL_VAR_INIT(lights_switched_on_roundstat, 0)
+GLOBAL_VAR_INIT(turbo_lift_floors_moved_roundstat, 0)
+GLOBAL_VAR_INIT(lost_limbs_shift_roundstat, 0)
+GLOBAL_VAR_INIT(seed_planted_shift_roundstat, 0)
+GLOBAL_VAR_INIT(step_taken_shift_roundstat, 0)
+GLOBAL_VAR_INIT(destroyed_research_items_roundstat, 0)
+GLOBAL_VAR_INIT(items_sold_shift_roundstat, 0)
+GLOBAL_VAR_INIT(disposals_flush_shift_roundstat, 0)
+GLOBAL_VAR_INIT(rocks_drilled_roundstat, 0)
+GLOBAL_VAR_INIT(mech_destroyed_roundstat, 0)
+
+/hook/roundend/proc/RoundTrivia()//bazinga
+ var/list/valid_stats_list = list() //This is to be populated with the good shit
+
+ if(GLOB.lost_limbs_shift_roundstat > 1)
+ valid_stats_list.Add("[GLOB.lost_limbs_shift_roundstat] limbs left their owners bodies this shift, oh no!")
+ else if(GLOB.destroyed_research_items_roundstat > 13)
+ valid_stats_list.Add("[GLOB.destroyed_research_items_roundstat] objects were destroyed in the name of Science! Keep it up!")
+ else if(GLOB.mech_destroyed_roundstat > 1)
+ valid_stats_list.Add("[GLOB.mech_destroyed_roundstat] mechs were destroyed this shift. What did you do?")
+ else if(GLOB.seed_planted_shift_roundstat > 20)
+ valid_stats_list.Add("[GLOB.seed_planted_shift_roundstat] seeds were planted according to our sensors this shift.")
+
+ if(GLOB.rocks_drilled_roundstat > 80)
+ valid_stats_list.Add("Our strong miners pulverized a whole [GLOB.rocks_drilled_roundstat] piles of pathetic rubble.")
+ else if(GLOB.items_sold_shift_roundstat > 15)
+ valid_stats_list.Add("The vending machines sold [GLOB.items_sold_shift_roundstat] items today.")
+ else if(GLOB.step_taken_shift_roundstat > 900)
+ valid_stats_list.Add("The employees walked a total of [GLOB.step_taken_shift_roundstat] steps for this shift! It should put them on the road to fitness!")
+
+ if(GLOB.cans_opened_roundstat > 0)
+ valid_stats_list.Add("[GLOB.cans_opened_roundstat] cans were drank today!")
+ else if(GLOB.lights_switched_on_roundstat > 0)
+ valid_stats_list.Add("[GLOB.lights_switched_on_roundstat] light switches were flipped today!")
+ else if(GLOB.turbo_lift_floors_moved_roundstat > 20)
+ valid_stats_list.Add("The elevator moved up [GLOB.turbo_lift_floors_moved_roundstat] floors today!")
+ else if(GLOB.disposals_flush_shift_roundstat > 40)
+ valid_stats_list.Add("The disposal system flushed a whole [GLOB.disposals_flush_shift_roundstat] times for this shift. We should really invest in waste treatement.")
+
+ if(LAZYLEN(valid_stats_list))
+ to_world("Shift trivia!")
+
+ for(var/body in valid_stats_list)
+ to_world("[body]")
diff --git a/code/datums/supplypacks/costumes_vr.dm b/code/datums/supplypacks/costumes_vr.dm
index 995e935648..e31fb2415a 100644
--- a/code/datums/supplypacks/costumes_vr.dm
+++ b/code/datums/supplypacks/costumes_vr.dm
@@ -21,14 +21,20 @@
/datum/supply_pack/costumes/tesh_smocks_vr
name = "Teshari smocks"
+ num_contained = 4
contains = list(
/obj/item/clothing/under/seromi/smock,
- /obj/item/clothing/under/seromi/smock/rainbow,
- /obj/item/clothing/under/seromi/smock/red,
/obj/item/clothing/under/seromi/smock/white,
- /obj/item/clothing/under/seromi/smock/yellow
+ /obj/item/clothing/under/seromi/smock/red,
+ /obj/item/clothing/under/seromi/smock/yellow,
+ /obj/item/clothing/under/seromi/smock/rainbow,
+ /obj/item/clothing/under/seromi/smock/dress,
+ /obj/item/clothing/under/seromi/smock/blackutilitysmock,
+ /obj/item/clothing/under/seromi/smock/greydress,
+ /obj/item/clothing/under/seromi/smock/blackutility,
+ /obj/item/clothing/under/seromi/smock/bluegreydress
)
- cost = 25
+ cost = 20
containertype = /obj/structure/closet/crate
containername = "Teshari smocks crate"
@@ -36,18 +42,18 @@
name = "Teshari undercoats"
num_contained = 4
contains = list(
- /obj/item/clothing/under/seromi/undercoat/standard/blue_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/brown_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/green_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/lightgrey_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/orange,
/obj/item/clothing/under/seromi/undercoat/standard/orange_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/pink_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/purple_grey,
/obj/item/clothing/under/seromi/undercoat/standard/rainbow,
- /obj/item/clothing/under/seromi/undercoat/standard/red_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/lightgrey_grey,
/obj/item/clothing/under/seromi/undercoat/standard/white_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/yellow_grey
+ /obj/item/clothing/under/seromi/undercoat/standard/red_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/orange,
+ /obj/item/clothing/under/seromi/undercoat/standard/yellow_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/green_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/blue_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/purple_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/pink_grey,
+ /obj/item/clothing/under/seromi/undercoat/standard/brown_grey
)
cost = 20
containertype = /obj/structure/closet/crate
@@ -57,19 +63,18 @@
name = "Teshari undercoats (black)"
num_contained = 4
contains = list(
- /obj/item/clothing/under/seromi/undercoat/standard/black,
- /obj/item/clothing/under/seromi/undercoat/standard/black_blue,
- /obj/item/clothing/under/seromi/undercoat/standard/black_brown,
- /obj/item/clothing/under/seromi/undercoat/standard/black_green,
- /obj/item/clothing/under/seromi/undercoat/standard/black_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/black_lightgrey,
- /obj/item/clothing/under/seromi/undercoat/standard/black_midgrey,
+ /obj/item/clothing/under/seromi/undercoat,
/obj/item/clothing/under/seromi/undercoat/standard/black_orange,
- /obj/item/clothing/under/seromi/undercoat/standard/black_pink,
- /obj/item/clothing/under/seromi/undercoat/standard/black_purple,
- /obj/item/clothing/under/seromi/undercoat/standard/black_red,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_grey,
/obj/item/clothing/under/seromi/undercoat/standard/black_white,
- /obj/item/clothing/under/seromi/undercoat/standard/black_yellow
+ /obj/item/clothing/under/seromi/undercoat/standard/black_red,
+ /obj/item/clothing/under/seromi/undercoat/standard/black,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_yellow,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_green,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_blue,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_purple,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_pink,
+ /obj/item/clothing/under/seromi/undercoat/standard/black_brown
)
cost = 20
containertype = /obj/structure/closet/crate
@@ -79,18 +84,18 @@
name = "Teshari cloaks"
num_contained = 4
contains = list(
- /obj/item/clothing/suit/storage/seromi/cloak/standard/blue_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/brown_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/green_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/lightgrey_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/orange,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/orange_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/pink_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/purple_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/rainbow,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/red_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/white,
/obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/yellow_grey
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/red_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/orange_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/yellow_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/green_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/blue_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/purple_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/pink_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/brown_grey,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/rainbow,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/orange
)
cost = 40
containertype = /obj/structure/closet/crate
@@ -100,19 +105,125 @@
name = "Teshari cloaks (black)"
num_contained = 4
contains = list(
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_blue,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_brown,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_green,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_lightgrey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_midgrey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_orange,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_pink,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_purple,
+ /obj/item/clothing/suit/storage/seromi/cloak,
/obj/item/clothing/suit/storage/seromi/cloak/standard/black_red,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_orange,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_yellow,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_green,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_blue,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_purple,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_pink,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_brown,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_grey,
/obj/item/clothing/suit/storage/seromi/cloak/standard/black_white,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_yellow
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/black_glow,
+ /obj/item/clothing/suit/storage/seromi/cloak/standard/dark_retrowave
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate
+ containername = "Teshari cloaks crate"
+
+/datum/supply_pack/costumes/tesh_worksuits_vr
+ name = "Teshari worksuits"
+ num_contained = 4
+ contains = list(
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackpurple,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackorange,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackblue,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackgreen,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whitered,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whitepurple,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whiteorange,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whiteblue,
+ /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whitegreen
+ )
+ cost = 20
+ containertype = /obj/structure/closet/crate
+ containername = "Teshari worksuits crate"
+
+/datum/supply_pack/randomised/costumes/tesh_beltcloaks_vr
+ name = "Teshari cloaks (belted)"
+ num_contained = 4
+ contains = list(
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/orange_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/rainbow,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/lightgrey_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/white_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/red_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/orange,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/yellow_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/green_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/blue_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/purple_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/pink_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/brown_grey
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate
+ containername = "Teshari cloaks crate"
+
+/datum/supply_pack/randomised/costumes/tesh_beltcloaks_b_vr
+ name = "Teshari cloaks (belted, black)"
+ num_contained = 4
+ contains = list(
+ /obj/item/clothing/suit/storage/seromi/beltcloak,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_orange,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_grey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_midgrey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_lightgrey,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_white,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_red,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_yellow,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_green,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_blue,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_purple,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_pink,
+ /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_brown
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate
+ containername = "Teshari cloaks crate"
+
+/datum/supply_pack/randomised/costumes/tesh_hoodcloaks_vr
+ name = "Teshari cloaks (hooded)"
+ num_contained = 4
+ contains = list(
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/orange_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/lightgrey_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/white_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/red_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/orange,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/yellow_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/green_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/blue_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/purple_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/pink_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/brown_grey
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate
+ containername = "Teshari cloaks crate"
+
+/datum/supply_pack/randomised/costumes/tesh_hoodcloaks_b_vr
+ name = "Teshari cloaks (hooded, black)"
+ num_contained = 4
+ contains = list(
+ /obj/item/clothing/suit/storage/hooded/teshari,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_orange,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_grey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_midgrey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_lightgrey,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_white,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_red,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_yellow,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_green,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_blue,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_purple,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_pink,
+ /obj/item/clothing/suit/storage/hooded/teshari/standard/black_brown
)
cost = 40
containertype = /obj/structure/closet/crate
@@ -262,7 +373,7 @@
cost = 60
containertype = /obj/structure/closet/crate
containername = "Saddlebags crate"
-
+
/datum/supply_pack/costumes/knights_gear
name = "Knights Gear"
contains = list(
diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm
index 165c5fbfef..28a7431ec1 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 0aa29b7b9c..ed528d3bdd 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/munitions_vr.dm b/code/datums/supplypacks/munitions_vr.dm
index e8674dd390..75f2124c96 100644
--- a/code/datums/supplypacks/munitions_vr.dm
+++ b/code/datums/supplypacks/munitions_vr.dm
@@ -2,7 +2,7 @@
name = "Frontier phaser (station-locked) crate"
contains = list(
/obj/item/weapon/gun/energy/locked/frontier = 2,
- /obj/item/weapon/gun/energy/locked/frontier/holdout = 1,
+ /obj/item/weapon/gun/energy/locked/frontier/holdout = 2,
)
cost = 35
containertype = /obj/structure/closet/crate/secure
diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm
index 9bb6b1a442..eae37c5869 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 7da82fa580..6b2cc3d10f 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 3235bb7311..18235e5343 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 40f2a468f6..3e21676da3 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 65f71f2584..8addcc3f64 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 8f0264d3e9..5b4a0f31cc 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 f814b55232..66a099581e 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 51d7ec7cd2..eee41e9699 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 30b2cd725e..ad68f76922 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 d9e6d84db7..f7236ddbb0 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 8d9de8f732..e02e604984 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 d3ed1dcec3..b939e953de 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 209fcc4c30..5e757ad16c 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/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 8be56acbf3..ef15cfb26f 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -297,7 +297,7 @@
/obj/item/weapon/storage/part_replacer
name = "rapid part exchange device"
- desc = "Special mechanical module made to store, sort, and apply standard machine parts."
+ desc = "A special mechanical module made to store, sort, and apply standard machine parts."
icon_state = "RPED"
w_class = ITEMSIZE_HUGE
can_hold = list(/obj/item/weapon/stock_parts)
@@ -311,10 +311,11 @@
max_storage_space = 100
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
+ var/panel_req = TRUE
/obj/item/weapon/storage/part_replacer/adv
name = "advanced rapid part exchange device"
- desc = "Special mechanical module made to store, sort, and apply standard machine parts. This one has a greatly upgraded storage capacity"
+ desc = "A special mechanical module made to store, sort, and apply standard machine parts. This one has a greatly upgraded storage capacity."
icon_state = "RPED"
w_class = ITEMSIZE_HUGE
can_hold = list(/obj/item/weapon/stock_parts)
@@ -327,6 +328,31 @@
max_w_class = ITEMSIZE_NORMAL
max_storage_space = 400
+/obj/item/weapon/storage/part_replacer/adv/discount_bluespace
+ name = "discount bluespace rapid part exchange device"
+ desc = "A special mechanical module made to store, sort, and apply standard machine parts. This one has a further increased storage capacity, \
+ and the ability to work on machines with closed maintenance panels."
+ storage_slots = 400
+ max_storage_space = 800
+ panel_req = FALSE
+
+/obj/item/weapon/storage/part_replacer/drop_contents() // hacky-feeling tier-based drop system
+ hide_from(usr)
+ var/turf/T = get_turf(src)
+ var/lowest_rating = INFINITY // We want the lowest-part tier rating in the RPED so we only drop the lowest-tier parts.
+ /*
+ * Why not just use the stock part's rating variable?
+ * Future-proofing for a potential future where stock parts aren't the only thing that can fit in an RPED.
+ * see: /tg/ and /vg/'s RPEDs fitting power cells, beakers, etc.
+ */
+ for(var/obj/item/B in contents)
+ if(B.rped_rating() < lowest_rating)
+ lowest_rating = B.rped_rating()
+ for(var/obj/item/B in contents)
+ if(B.rped_rating() > lowest_rating)
+ continue
+ remove_from_storage(B, T)
+
/obj/item/weapon/stock_parts
name = "stock part"
desc = "What?"
@@ -342,6 +368,9 @@
src.pixel_y = rand(-5.0, 5)
..()
+/obj/item/weapon/stock_parts/get_rating()
+ return rating
+
//Rank 1
/obj/item/weapon/stock_parts/console_screen
diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm
index efcd5955f7..99216b9ef5 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/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm
index 4fcb678d34..2a46cfd0d9 100644
--- a/code/game/antagonist/station/rogue_ai.dm
+++ b/code/game/antagonist/station/rogue_ai.dm
@@ -68,7 +68,7 @@ var/datum/antagonist/rogue_ai/malf
sleep(50)
to_chat(malf, "MEMCHCK Corrupted sectors confirmed. Reccomended solution: Delete. Proceed? Y/N: Y")
sleep(10)
- // this is so Travis doesn't complain about the backslash-B. Fixed at compile time (or should be).
+ // this is so CI doesn't complain about the backslash-B. Fixed at compile time (or should be).
to_chat(malf, "Corrupted files deleted: sys\\core\\users.dat sys\\core\\laws.dat sys\\core\\" + "backups.dat")
sleep(20)
to_chat(malf, "CAUTION: Law database not found! User database not found! Unable to restore backups. Activating failsafe AI shutd3wn52&&$#!##")
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 04075fe825..9c8bbccc79 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 bf5fc0ab18..510b8bf762 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 b5825ab1e1..fccf178af9 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -42,20 +42,29 @@
#define DNA_UI_TAIL2_R 23
#define DNA_UI_TAIL2_G 24
#define DNA_UI_TAIL2_B 25
-#define DNA_UI_EARS_R 26
-#define DNA_UI_EARS_G 27
-#define DNA_UI_EARS_B 28
-#define DNA_UI_EARS2_R 29
-#define DNA_UI_EARS2_G 30
-#define DNA_UI_EARS2_B 31
-#define DNA_UI_WING_STYLE 32
-#define DNA_UI_WING_R 33
-#define DNA_UI_WING_G 34
-#define DNA_UI_WING_B 35
-#define DNA_UI_WING2_R 36
-#define DNA_UI_WING2_G 37
-#define DNA_UI_WING2_B 38 // VOREStation snippet end.
-#define DNA_UI_LENGTH 38 // VOREStation Edit - Needs to match the highest number above.
+#define DNA_UI_TAIL3_R 26
+#define DNA_UI_TAIL3_G 27
+#define DNA_UI_TAIL3_B 28
+#define DNA_UI_EARS_R 29
+#define DNA_UI_EARS_G 30
+#define DNA_UI_EARS_B 31
+#define DNA_UI_EARS2_R 32
+#define DNA_UI_EARS2_G 33
+#define DNA_UI_EARS2_B 34
+#define DNA_UI_EARS3_R 35
+#define DNA_UI_EARS3_G 36
+#define DNA_UI_EARS3_B 37
+#define DNA_UI_WING_STYLE 38
+#define DNA_UI_WING_R 39
+#define DNA_UI_WING_G 40
+#define DNA_UI_WING_B 41
+#define DNA_UI_WING2_R 42
+#define DNA_UI_WING2_G 43
+#define DNA_UI_WING2_B 44
+#define DNA_UI_WING3_R 45
+#define DNA_UI_WING3_G 46
+#define DNA_UI_WING3_B 47 // VOREStation snippet end.
+#define DNA_UI_LENGTH 47 // VOREStation Edit - Needs to match the highest number above.
#define DNA_SE_LENGTH 49 // VOREStation Edit (original was UI+11)
// For later:
@@ -193,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)
@@ -225,6 +220,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
SetUIValueRange(DNA_UI_TAIL2_G, character.g_tail2, 255, 1)
SetUIValueRange(DNA_UI_TAIL2_B, character.b_tail2, 255, 1)
+ SetUIValueRange(DNA_UI_TAIL3_R, character.r_tail3, 255, 1)
+ SetUIValueRange(DNA_UI_TAIL3_G, character.g_tail3, 255, 1)
+ SetUIValueRange(DNA_UI_TAIL3_B, character.b_tail3, 255, 1)
+
SetUIValueRange(DNA_UI_WING_R, character.r_wing, 255, 1)
SetUIValueRange(DNA_UI_WING_G, character.g_wing, 255, 1)
SetUIValueRange(DNA_UI_WING_B, character.b_wing, 255, 1)
@@ -233,6 +232,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
SetUIValueRange(DNA_UI_WING2_G, character.g_wing2, 255, 1)
SetUIValueRange(DNA_UI_WING2_B, character.b_wing2, 255, 1)
+ SetUIValueRange(DNA_UI_WING3_R, character.r_wing3, 255, 1)
+ SetUIValueRange(DNA_UI_WING3_G, character.g_wing3, 255, 1)
+ SetUIValueRange(DNA_UI_WING3_B, character.b_wing3, 255, 1)
+
SetUIValueRange(DNA_UI_EARS_R, character.r_ears, 255, 1)
SetUIValueRange(DNA_UI_EARS_G, character.g_ears, 255, 1)
SetUIValueRange(DNA_UI_EARS_B, character.b_ears, 255, 1)
@@ -241,6 +244,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
SetUIValueRange(DNA_UI_EARS2_G, character.g_ears2, 255, 1)
SetUIValueRange(DNA_UI_EARS2_B, character.b_ears2, 255, 1)
+ SetUIValueRange(DNA_UI_EARS3_R, character.r_ears3, 255, 1)
+ SetUIValueRange(DNA_UI_EARS3_G, character.g_ears3, 255, 1)
+ SetUIValueRange(DNA_UI_EARS3_B, character.b_ears3, 255, 1)
+
// VORE Station Edit End
SetUIValueRange(DNA_UI_HAIR_R, character.r_hair, 255, 1)
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index cd3ec6a44d..758f74d873 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -189,6 +189,10 @@
H.r_ears2 = dna.GetUIValueRange(DNA_UI_EARS2_R, 255)
H.g_ears2 = dna.GetUIValueRange(DNA_UI_EARS2_G, 255)
H.b_ears2 = dna.GetUIValueRange(DNA_UI_EARS2_B, 255)
+ H.r_ears3 = dna.GetUIValueRange(DNA_UI_EARS3_R, 255)
+ H.g_ears3 = dna.GetUIValueRange(DNA_UI_EARS3_G, 255)
+ H.b_ears3 = dna.GetUIValueRange(DNA_UI_EARS3_B, 255)
+
//Tail
var/tail = dna.GetUIValueRange(DNA_UI_TAIL_STYLE, tail_styles_list.len + 1) - 1
@@ -208,6 +212,12 @@
H.r_wing = dna.GetUIValueRange(DNA_UI_WING_R, 255)
H.g_wing = dna.GetUIValueRange(DNA_UI_WING_G, 255)
H.b_wing = dna.GetUIValueRange(DNA_UI_WING_B, 255)
+ H.r_wing2 = dna.GetUIValueRange(DNA_UI_WING2_R, 255)
+ H.g_wing2 = dna.GetUIValueRange(DNA_UI_WING2_G, 255)
+ H.b_wing2 = dna.GetUIValueRange(DNA_UI_WING2_B, 255)
+ H.r_wing3 = dna.GetUIValueRange(DNA_UI_WING3_R, 255)
+ H.g_wing3 = dna.GetUIValueRange(DNA_UI_WING3_G, 255)
+ H.b_wing3 = dna.GetUIValueRange(DNA_UI_WING3_B, 255)
// Playerscale
var/size = dna.GetUIValueRange(DNA_UI_PLAYERSCALE, player_sizes_list.len)
@@ -221,23 +231,15 @@
H.r_tail2 = dna.GetUIValueRange(DNA_UI_TAIL2_R, 255)
H.g_tail2 = dna.GetUIValueRange(DNA_UI_TAIL2_G, 255)
H.b_tail2 = dna.GetUIValueRange(DNA_UI_TAIL2_B, 255)
+ H.r_tail3 = dna.GetUIValueRange(DNA_UI_TAIL3_R, 255)
+ H.g_tail3 = dna.GetUIValueRange(DNA_UI_TAIL3_G, 255)
+ H.b_tail3 = dna.GetUIValueRange(DNA_UI_TAIL3_B, 255)
// 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 bbf4bfb343..241d613275 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 42e6a6ddd0..18d58a33ae 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 0b0b8d014c..a6ceb219c8 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 16038248d0..bd3906f16c 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 d2b830ad7b..4062775846 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 d2de3db85c..34cc2321ce 100644
--- a/code/game/jobs/job/special_vr.dm
+++ b/code/game/jobs/job/special_vr.dm
@@ -24,47 +24,31 @@
get_access()
return get_all_accesses().Copy()
-/*/datum/job/centcom_visitor //For Pleasure // You mean for admin abuse... -Ace
- title = "CentCom Visitor"
- department = "Civilian"
- head_position = 1
+/datum/job/emergency_responder //For staff managing/leading ERTs
+ title = "Emergency Responder"
+ departments = list("Central Command")
+ department_accounts = list(DEPARTMENT_COMMAND, DEPARTMENT_ENGINEERING, DEPARTMENT_MEDICAL, DEPARTMENT_RESEARCH, DEPARTMENT_SECURITY, DEPARTMENT_CARGO, DEPARTMENT_PLANET, DEPARTMENT_CIVILIAN)
faction = "Station"
total_positions = 2
spawn_positions = 1
supervisors = "company officials and Corporate Regulations"
selection_color = "#1D1D4F"
- idtype = /obj/item/weapon/card/id/centcom
access = list()
minimal_access = list()
minimal_player_age = 14
economic_modifier = 20
whitelist_only = 1
latejoin_only = 1
+ outfit_type = /decl/hierarchy/outfit/job/emergency_responder
+ job_description = "Emergency Responders are usually called in to deal with on-station emergencies that the crew require assistance to deal with."
- minimum_character_age = 25
- ideal_character_age = 40
+ minimum_character_age = 18
+ ideal_character_age = 30
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/centcom(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom, slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/device/pda/centcom(H), slot_belt)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(H), slot_gloves)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/officer(H), slot_head)
- H.equip_to_slot_or_del(new /obj/item/clothing/glasses/omnihud(H), slot_l_store)
-
- H.implant_loyalty()
-
- return 1
+ pto_type = PTO_CIVILIAN
get_access()
- var/access = get_all_accesses()
- return access*/
+ return get_all_accesses().Copy()
/datum/job/clown
title = "Clown"
@@ -72,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)
@@ -92,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"
@@ -102,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
@@ -119,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 a97fbf986f..e0ff3a6086 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/buttons.dm b/code/game/machinery/buttons.dm
index d15ea493ec..19716f5d74 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -16,9 +16,3 @@
/obj/machinery/button/attackby(obj/item/weapon/W, mob/user as mob)
return attack_hand(user)
-
-// VOREStation Edit Begin
-/obj/machinery/button/attack_hand(obj/item/weapon/W, mob/user as mob)
- if(..()) return 1
- playsound(src, 'sound/machines/button.ogg', 100, 1)
-// VOREStation Edit End
diff --git a/code/game/machinery/buttons_vr.dm b/code/game/machinery/buttons_vr.dm
new file mode 100644
index 0000000000..a8c9c4bed1
--- /dev/null
+++ b/code/game/machinery/buttons_vr.dm
@@ -0,0 +1,23 @@
+/obj/machinery/button/attack_hand(obj/item/weapon/W, mob/user as mob)
+ if(..()) return 1
+ playsound(src, 'sound/machines/button.ogg', 100, 1)
+
+/obj/machinery/button/windowtint/multitint
+ name = "tint control"
+ desc = "A remote control switch for polarized windows and doors."
+
+/obj/machinery/button/windowtint/multitint/toggle_tint()
+ use_power(5)
+ active = !active
+ update_icon()
+
+ var/in_range = range(src,range)
+ for(var/obj/structure/window/reinforced/polarized/W in in_range)
+ if(W.id == src.id || !W.id)
+ spawn(0)
+ W.toggle()
+ for(var/obj/machinery/door/D in in_range)
+ if(D.icon_tinted)
+ if(D.id_tint == src.id || !D.id_tint)
+ spawn(0)
+ D.toggle()
\ No newline at end of file
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 7ff97c83e8..25299dcda8 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/camera_vr.dm b/code/game/machinery/computer/camera_vr.dm
new file mode 100644
index 0000000000..1e006b0f4b
--- /dev/null
+++ b/code/game/machinery/computer/camera_vr.dm
@@ -0,0 +1,26 @@
+/obj/machinery/computer/security/abductor
+ name = "camera uplink"
+ desc = "Used for hacking into camera networks"
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "camera"
+ network = list( "Mercenary",
+ "Cargo",
+ "Circuits",
+ "Civilian",
+ "Command",
+ "Engine",
+ "Engineering",
+ "Exploration",
+ "Medical",
+ "Mining Outpost",
+ "Outside",
+ "Research",
+ "Research Outpost",
+ "Robots",
+ "Security",
+ "Telecommunications",
+ "Tether",
+ "TalonShip",
+ "Entertainment",
+ "Communicators"
+ )
\ No newline at end of file
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index cc05d63217..8d4202d421 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 5fc8c77bd0..20fd6991a0 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/id_restorer_vr.dm b/code/game/machinery/computer/id_restorer_vr.dm
index 7afabc5492..acd4caa14c 100644
--- a/code/game/machinery/computer/id_restorer_vr.dm
+++ b/code/game/machinery/computer/id_restorer_vr.dm
@@ -30,14 +30,15 @@
if(..()) return
if(stat & (NOPOWER|BROKEN)) return
+ if(!inserted) // No point in giving you an option what to do if there's no ID to do things with.
+ to_chat(user, "No ID is inserted.")
+ return
+
var/choice = alert(user,"What do you want to do?","[src]","Restore ID access","Eject ID","Cancel")
if(user.incapacitated() || (get_dist(src, user) > 1))
return
switch(choice)
if("Restore ID access")
- if(!inserted)
- to_chat(user, "No ID is inserted.")
- return
var/mob/living/carbon/human/H = user
if(!(istype(H)))
to_chat(user, "Invalid user detected. Access denied.")
@@ -66,9 +67,6 @@
flick(icon_fail, src)
return
if("Eject ID")
- if(!inserted)
- to_chat(user, "No ID is inserted.")
- return
if(ishuman(user))
inserted.forceMove(get_turf(src))
if(!user.get_active_hand())
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index adf53c80a8..680ce44345 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 1caa7b61a4..430b42591c 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 dbd5ba8383..5eae5e82d0 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 0b6ab77d7a..40a4d594cb 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 47b9e8ce25..e11f404b16 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 db27559796..64a3cc1fc7 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/airlock_vr.dm b/code/game/machinery/doors/airlock_vr.dm
index c26bb9187c..eb1594283b 100644
--- a/code/game/machinery/doors/airlock_vr.dm
+++ b/code/game/machinery/doors/airlock_vr.dm
@@ -20,3 +20,15 @@
req_one_access = list()
normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside.
hackProof = TRUE //VOREStation Edit - No borgos
+
+/obj/machinery/door/airlock/glass_security/polarized
+ name = "Electrochromic Security Airlock"
+ icon_tinted = 'icons/obj/doors/Doorsectinted_vr.dmi'
+
+/obj/machinery/door/airlock/glass_medical/polarized
+ name = "Electrochromic Medical Airlock"
+ icon_tinted = 'icons/obj/doors/doormedtinted_vr.dmi'
+
+/obj/machinery/door/airlock/glass_command/polarized
+ name = "Electrochormic Command Airlock"
+ icon_tinted = 'icons/obj/doors/Doorcomtinted_vr.dmi'
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index 08e0979ed5..8526820c33 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 f4d9c900ed..fdd526039b 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/doors/door_vr.dm b/code/game/machinery/doors/door_vr.dm
index 024162bc35..6c36a2514d 100644
--- a/code/game/machinery/doors/door_vr.dm
+++ b/code/game/machinery/doors/door_vr.dm
@@ -4,6 +4,9 @@
/obj/machinery/door
var/reinforcing = 0 //vorestation addition
+ var/tintable = 0
+ var/icon_tinted
+ var/id_tint
/obj/machinery/door/firedoor
heat_proof = 1
@@ -102,4 +105,29 @@
/obj/machinery/door/blast/regular/
heat_proof = 1 //just so repairing them doesn't try to fireproof something that never takes fire damage
+/obj/machinery/door/proc/toggle()
+ if(glass)
+ icon = icon_tinted
+ glass = 0
+ if(!operating && density)
+ set_opacity(1)
+ else
+ icon = initial(icon)
+ glass = 1
+ if(!operating)
+ set_opacity(0)
+/obj/machinery/button/windowtint/doortint
+ name = "door tint control"
+ desc = "A remote control switch for polarized glass doors."
+
+/obj/machinery/button/windowtint/doortint/toggle_tint()
+ use_power(5)
+ active = !active
+ update_icon()
+
+ for(var/obj/machinery/door/D in range(src,range))
+ if(D.icon_tinted && (D.id_tint == src.id || !D.id_tint))
+ spawn(0)
+ D.toggle()
+ return
\ No newline at end of file
diff --git a/code/game/machinery/doors/multi_tile_vr.dm b/code/game/machinery/doors/multi_tile_vr.dm
new file mode 100644
index 0000000000..f8a76c51ea
--- /dev/null
+++ b/code/game/machinery/doors/multi_tile_vr.dm
@@ -0,0 +1,22 @@
+/obj/machinery/door/airlock/multi_tile/glass/polarized
+ name = "Electrochromic Glass Airlock"
+ icon_tinted = 'icons/obj/doors/Door2x1tinted_vr.dmi'
+
+/obj/machinery/door/airlock/multi_tile/glass/polarized/New()
+ ..()
+ create_fillers()
+
+/obj/machinery/door/airlock/multi_tile/glass/polarized/toggle()
+ . = ..()
+ if(!operating)
+ if(filler1)
+ filler1.set_opacity(opacity)
+ if(filler2)
+ filler2.set_opacity(opacity)
+
+/obj/machinery/door/airlock/multi_tile/glass/polarized/close()
+ . = ..()
+ if(filler1)
+ filler1.set_opacity(!glass)
+ if(filler2)
+ filler2.set_opacity(!glass)
\ No newline at end of file
diff --git a/code/game/machinery/event/stage_vr.dm b/code/game/machinery/event/stage_vr.dm
new file mode 100644
index 0000000000..1190498a21
--- /dev/null
+++ b/code/game/machinery/event/stage_vr.dm
@@ -0,0 +1,10 @@
+/obj/structure/event/stage
+ name = "stage"
+ desc = "It's a stage!"
+ icon = 'icons/misc/event/stage.dmi'
+ icon_state = "stage1"
+ anchored = 1.0
+ density = 0
+ pixel_y = -224
+ pixel_x = -224
+ plane = -44
\ No newline at end of file
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index a208e6eefd..c078b854d0 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/machinery.dm b/code/game/machinery/machinery.dm
index 1afa9910f4..a96ef4ed0a 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -327,7 +327,10 @@ Class Procs:
return 0
if(!component_parts)
return 0
- if(panel_open)
+ to_chat(user, "Following parts detected in [src]:")
+ for(var/obj/item/C in component_parts)
+ to_chat(user, " [C.name]")
+ if(panel_open || !R.panel_req)
var/obj/item/weapon/circuitboard/CB = circuit
var/P
for(var/obj/item/weapon/stock_parts/A in component_parts)
@@ -347,10 +350,6 @@ Class Procs:
break
update_icon()
RefreshParts()
- else
- to_chat(user, "Following parts detected in the machine:")
- for(var/var/obj/item/C in component_parts) //var/var/obj/item/C?
- to_chat(user, " [C.name]")
return 1
// Default behavior for wrenching down machines. Supports both delay and instant modes.
@@ -426,6 +425,9 @@ Class Procs:
/obj/machinery/proc/dismantle()
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
+ for(var/obj/I in contents)
+ if(istype(I,/obj/item/weapon/card/id))
+ I.forceMove(src.loc)
//TFF 3/6/19 - port Cit RP fix of infinite frames. If it doesn't have a circuit board, don't create a frame. Return a smack instead. BONK!
if(!circuit)
return 0
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index c23d02f4d0..a1798ea5e4 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 5b10e398a3..51f48c416b 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 01a890bd79..8e9e6da8f7 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/portable_turret_vr.dm b/code/game/machinery/portable_turret_vr.dm
index 4af3a78142..90866e1d63 100644
--- a/code/game/machinery/portable_turret_vr.dm
+++ b/code/game/machinery/portable_turret_vr.dm
@@ -1,6 +1,28 @@
+/obj/machinery/porta_turret/stationary/CIWS
+ name = "CIWS turret"
+ desc = "A ship weapons turret designed for light defense."
+ req_one_access = list(access_cent_general)
+ health = 200
+ maxhealth = 200
+ enabled = TRUE
+ lethal = TRUE
+ check_weapons = TRUE
+ can_salvage = FALSE
+
+/obj/machinery/porta_turret/stationary/syndie/CIWS
+ name = "mercenary CIWS turret"
+ desc = "A ship weapons turret designed for light defense."
+ req_one_access = list(access_syndicate)
+ health = 200
+ maxhealth = 200
+ enabled = TRUE
+ lethal = TRUE
+ check_weapons = TRUE
+ can_salvage = FALSE
+
/obj/machinery/porta_turret/industrial/military
name = "military CIWS turret"
- desc = "A ship-grade weapons turret designed for anti-fighter defense."
+ desc = "A ship weapons turret designed for anti-fighter defense."
req_one_access = list(access_cent_general)
installation = /obj/item/weapon/gun/energy/lasercannon
health = 500
@@ -9,17 +31,4 @@
lethal = TRUE
check_weapons = TRUE
auto_repair = TRUE
- can_salvage = FALSE
-
-/obj/machinery/porta_turret/stationary/syndie/CIWS
- name = "mercenary CIWS turret"
- desc = "A ship-grade weapons turret designed for anti-fighter defense."
- req_one_access = list(access_syndicate)
- installation = /obj/item/weapon/gun/energy/lasercannon
- health = 500
- maxhealth = 500
- enabled = TRUE
- lethal = TRUE
- check_weapons = TRUE
- auto_repair = TRUE
can_salvage = FALSE
\ No newline at end of file
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index af7cdd5dfb..259c907bde 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -87,25 +87,44 @@
else if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
- // In case they somehow end up with positive values for otherwise unobtainable damage...
- if(H.getToxLoss() > 0)
- H.adjustToxLoss(-(rand(1,3)))
- if(H.getOxyLoss() > 0)
- H.adjustOxyLoss(-(rand(1,3)))
- if(H.getCloneLoss() > 0)
- H.adjustCloneLoss(-(rand(1,3)))
- if(H.getBrainLoss() > 0)
- H.adjustBrainLoss(-(rand(1,3)))
+ if(H.isSynthetic())
+ // In case they somehow end up with positive values for otherwise unobtainable damage...
+ if(H.getToxLoss() > 0)
+ H.adjustToxLoss(-(rand(1,3)))
+ if(H.getOxyLoss() > 0)
+ H.adjustOxyLoss(-(rand(1,3)))
+ if(H.getCloneLoss() > 0)
+ H.adjustCloneLoss(-(rand(1,3)))
+ if(H.getBrainLoss() > 0)
+ H.adjustBrainLoss(-(rand(1,3)))
- // Also recharge their internal battery.
- if(H.isSynthetic() && H.nutrition < 500) //VOREStation Edit
- H.nutrition = min(H.nutrition+10, 500) //VOREStation Edit
- cell.use(7000/450*10)
+ // Also recharge their internal battery.
+ if(H.isSynthetic() && H.nutrition < 500) //VOREStation Edit
+ H.nutrition = min(H.nutrition+10, 500) //VOREStation Edit
+ cell.use(7000/450*10)
- // And clear up radiation
- if(H.radiation > 0)
- H.radiation = max(H.radiation - rand(5, 15), 0)
+ // And clear up radiation
+ if(H.radiation > 0)
+ H.radiation = max(H.radiation - rand(5, 15), 0)
+ if(H.wearing_rig) // stepping into a borg charger to charge your rig and fix your shit
+ var/obj/item/weapon/rig/wornrig = H.get_rig()
+ if(wornrig) // just to make sure
+ for(var/obj/item/rig_module/storedmod in wornrig.installed_modules)
+ if(weld_rate && storedmod.damage && cell.checked_use(weld_power_use * weld_rate * CELLRATE))
+ to_chat(H, "[storedmod] is repaired!")
+ storedmod.damage = 0
+ if(wornrig.chest)
+ var/obj/item/clothing/suit/space/rig/rigchest = wornrig.chest
+ if(weld_rate && rigchest.damage && cell.checked_use(weld_power_use * weld_rate * CELLRATE))
+ rigchest.breaches = list()
+ rigchest.calc_breach_damage()
+ to_chat(H, "[rigchest] is repaired!")
+ if(wornrig.cell)
+ var/obj/item/weapon/cell/rigcell = wornrig.cell
+ var/diff = min(rigcell.maxcharge - rigcell.charge, charging_power * CELLRATE) // Capped by charging_power / tick
+ var/charge_used = cell.use(diff)
+ rigcell.give(charge_used)
/obj/machinery/recharge_station/examine(mob/user)
. = ..()
@@ -237,7 +256,7 @@
else if(istype(L, /mob/living/carbon/human))
var/mob/living/carbon/human/H = L
- if(H.isSynthetic())
+ if(H.isSynthetic() || H.wearing_rig)
add_fingerprint(H)
H.reset_view(src)
H.forceMove(src)
diff --git a/code/game/machinery/syndicatebeacon_vr.dm b/code/game/machinery/syndicatebeacon_vr.dm
index ef6b3da0bb..668b36dcb7 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/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 19bc030421..813c756ab4 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -233,17 +233,19 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if(is_freq_listening(signal)) // detect subspace signals
- signal.data["done"] = 1 // mark the signal as being broadcasted
+ //signal.data["done"] = 1 // mark the signal as being broadcasted since we're a broadcaster
signal.data["compression"] = 0
+ /*
// Search for the original signal and mark it as done as well
var/datum/signal/original = signal.data["original"]
if(original)
original.data["done"] = 1
+ */
// For some reason level is both used as a list and not a list, and now it needs to be a list.
// Because this is a 'all in one' machine, we're gonna just cheat.
- signal.data["level"] = using_map.contact_levels.Copy()
+ //signal.data["level"] = using_map.contact_levels.Copy()
if(signal.data["slow"] > 0)
sleep(signal.data["slow"]) // simulate the network lag if necessary
diff --git a/code/game/machinery/telecomms/broadcaster_vr.dm b/code/game/machinery/telecomms/broadcaster_vr.dm
new file mode 100644
index 0000000000..4bdccfbc80
--- /dev/null
+++ b/code/game/machinery/telecomms/broadcaster_vr.dm
@@ -0,0 +1,46 @@
+//ERT version with unlimited range (doesn't even check) and uses no power, to enable ert comms to work anywhere.
+/obj/machinery/telecomms/allinone/ert
+ use_power = USE_POWER_OFF
+ idle_power_usage = 0
+
+/obj/machinery/telecomms/allinone/ert/receive_signal(datum/signal/signal)
+ if(!on) // has to be on to receive messages
+ return
+
+ if(is_freq_listening(signal)) // detect subspace signals
+
+ //signal.data["done"] = 1 // mark the signal as being broadcasted since we're a broadcaster
+ signal.data["compression"] = 0
+
+ /*
+ // Search for the original signal and mark it as done as well
+ var/datum/signal/original = signal.data["original"]
+ if(original)
+ original.data["done"] = 1
+ */
+
+ // For some reason level is both used as a list and not a list, and now it needs to be a list.
+ // Because this is a 'all in one' machine, we're gonna just cheat.
+ //signal.data["level"] = using_map.contact_levels.Copy()
+
+ if(signal.data["slow"] > 0)
+ sleep(signal.data["slow"]) // simulate the network lag if necessary
+
+ /* ###### Broadcast a message using signal.data ###### */
+
+ var/datum/radio_frequency/connection = signal.data["connection"]
+
+ var/list/forced_radios
+ for(var/weakref/wr in linked_radios_weakrefs)
+ var/obj/item/device/radio/R = wr.resolve()
+ if(istype(R))
+ LAZYDISTINCTADD(forced_radios, R)
+
+ if(connection.frequency in CENT_FREQS) // if ert broadcast, just
+ Broadcast_Message(signal.data["connection"], signal.data["mob"],
+ signal.data["vmask"], signal.data["vmessage"],
+ signal.data["radio"], signal.data["message"],
+ signal.data["name"], signal.data["job"],
+ signal.data["realname"], signal.data["vname"], DATA_NORMAL,
+ signal.data["compression"], list(0), connection.frequency,
+ signal.data["verb"], forced_radios)
diff --git a/code/game/machinery/transportpod.dm b/code/game/machinery/transportpod.dm
index 0b499096fe..4a43cb1890 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 ad55fe14a1..7f5a1d8e56 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 c918fca5d2..58107d9d0b 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -458,13 +458,9 @@ GLOBAL_LIST_EMPTY(vending_products)
if(!can_buy(R, usr))
return
-
- vend_ready = FALSE // From this point onwards, vendor is locked to performing this transaction only, until it is resolved.
-
if(R.price <= 0)
vend(R, usr)
add_fingerprint(usr)
- vend_ready = TRUE
return TRUE
if(issilicon(usr)) //If the item is not free, provide feedback if a synth is trying to buy something.
@@ -473,6 +469,9 @@ GLOBAL_LIST_EMPTY(vending_products)
if(!ishuman(usr))
return
+
+ vend_ready = FALSE // From this point onwards, vendor is locked to performing this transaction only, until it is resolved.
+
var/mob/living/carbon/human/H = usr
var/obj/item/weapon/card/id/C = H.GetIdCard()
@@ -573,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 e04568c1d0..098d231ce7 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 a4ce500db2..c4c4e663d4 100644
--- a/code/game/machinery/vending_machines_vr.dm
+++ b/code/game/machinery/vending_machines_vr.dm
@@ -84,6 +84,158 @@
)
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/mysterysoup = 10)
vend_delay = 15
+
+//Specific food vending machines for events that want them!
+
+/obj/machinery/vending/fooditalian
+ name = "Italian Imports"
+ desc = "You wanted some italian food? Well here's some imported from the local pizza place!"
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/pastatomato = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/meatballspagetti = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/meatball = 15
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza = 1)
+ vend_delay = 10
+
+/obj/machinery/vending/foodfast
+ name = "United Grills"
+ desc = "Not sure how they're united but man is this grilled food delicious! Though it seems to just be a lot of fast food..."
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/monkeyburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/cheeseburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/fishburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/clownburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/mimeburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/superbiteburger = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/burger/bacon = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/hotdog = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/chickenfillet = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/fries = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/cheesyfries = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/chilicheesefries = 10
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/ghostburger = 3,
+ /obj/item/weapon/reagent_containers/food/snacks/tofuburger = 5)
+ vend_delay = 10
+
+/obj/machinery/vending/foodmeat
+ name = "Meaty Marvels"
+ desc = "What's a marvel is how you're not ordering from this machine yet!"
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/ribplate = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/meat_pocket = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/meatpie = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/roastbeef = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/stuffed_meatball = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/meatsteak = 20
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/monkeysdelight = 5)
+ vend_delay = 10
+
+/obj/machinery/vending/foodasian
+ name = "Authenticate Asian"
+ desc = "Some good ol' Sol food!"
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/sushi = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/chawanmushi = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/generalschicken = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/chickenkatsu = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sweet_and_sour = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/bibimbap = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/hotandsoursoup = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/kitsuneudon = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/milosoup = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/lomein = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/friedrice = 10
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/monkeyburger = 1)
+ vend_delay = 10
+
+/obj/machinery/vending/foodfish
+ name = "Fishy Food"
+ desc = "Don't mind the name, this is 100% fish!"
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/grilled_carp = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/kudzudonburi = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/zestfish = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/lobstercooked = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sashimi = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sharkmeatcooked = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sharkmeatdip = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sharkmeatcubes = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/cuttlefishcooked = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/monkfishcooked = 10
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/monkfish = 1)
+ vend_delay = 10
+
+/obj/machinery/vending/foodveggie
+ name = "Veggie Varieties"
+ desc = "Even vegitarians have their own vending machines! How thoughtful."
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/beetsoup = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/eggplantparm = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/eggbowl = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/flowerchildsalad = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/tossedsalad = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/fruitsalad = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/grilledcheese = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/tofurkey = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/stuffing = 10
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/meatsteak = 1)
+ vend_delay = 10
+
+/obj/machinery/vending/fooddessert
+ name = "Delightful Desserts"
+ desc = "Even if you've stuffed your face with a pizza or two, you ALWAYS have room for dessert!"
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/applepie = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/cherrypie = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/keylimepie = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/pie = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/funnelcake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/peanutcake = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/cookie = 15,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/brownies = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/chocolatebar = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece = 20
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/donut/chaos = 10)
+ vend_delay = 10
+
+/obj/machinery/vending/foodstuffing
+ name = "Stuffing Site"
+ desc = "Is... is it just full of stuffing? No wait, there's turkey in there too."
+ icon_state = "hotfood"
+ products = list(/obj/item/weapon/reagent_containers/food/snacks/stuffing = 50,
+ /obj/item/weapon/reagent_containers/food/snacks/sliceable/turkey= 20
+ )
+ contraband = list(/obj/item/weapon/reagent_containers/food/snacks/tofurkey = 10)
+ vend_delay = 10
+
+//End of food event machines
+
/* For later, then
/obj/machinery/vending/weapon_machine
name = "Frozen Star Guns&Ammo"
@@ -1294,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,
@@ -1456,6 +1608,30 @@
req_log_access = access_cmo
has_logs = 1
+/obj/machinery/vending/abductor
+ name = "Abduct-U"
+ desc = "A mysterious machine which can fabricate many tools for acquiring test subjects."
+ icon = 'icons/obj/abductor_vr.dmi'
+ icon_state = "dispenser_2way"
+ products = list(/obj/item/weapon/card/id/syndicate/station_access = 1,
+ /obj/item/weapon/storage/box/syndie_kit/chameleon = 1,
+ /obj/item/clothing/mask/bandana = 1,
+ /obj/item/clothing/glasses/sunglasses = 1,
+ /obj/item/device/radio/headset/syndicate/alt = 1,
+ /obj/item/device/pda = 1,
+ /obj/item/device/communicator = 1,
+ /obj/item/weapon/tape_roll = 2,
+ /obj/item/weapon/handcuffs = 4,
+ /obj/item/weapon/handcuffs/legcuffs = 4,
+ /obj/item/weapon/cell/device/weapon/recharge/alien = 2,
+ /obj/item/device/chameleon = 1,
+ /obj/item/weapon/storage/mre/menu11 = 2,
+ /obj/item/device/flash = 2,
+ /obj/item/weapon/pen/reagent/paralysis = 4,
+ /obj/item/device/perfect_tele/alien = 1
+ )
+ vend_delay = 15
+
/obj/machinery/vending/loadout
name = "Fingers and Toes"
desc = "A special vendor for gloves and shoes!"
@@ -3764,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,
@@ -4228,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,
@@ -4400,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 aa5a9e000c..19bd2b9c53 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 4052afe8e6..fecb361f1a 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 0323124c47..1f9d4a0b6e 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 = {"