diff --git a/aurorastation.dme b/aurorastation.dme
index a407ac3bfbb..874e6fbd8c2 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -2208,8 +2208,8 @@
#include "code\modules\modular_computers\file_system\data.dm"
#include "code\modules\modular_computers\file_system\news_article.dm"
#include "code\modules\modular_computers\file_system\program.dm"
-#include "code\modules\modular_computers\file_system\script.dm"
#include "code\modules\modular_computers\file_system\program_events.dm"
+#include "code\modules\modular_computers\file_system\script.dm"
#include "code\modules\modular_computers\file_system\programs\_program.dm"
#include "code\modules\modular_computers\file_system\programs\app_presets.dm"
#include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm"
diff --git a/code/__defines/tgs.dm b/code/__defines/tgs.dm
index 4015d24808d..7665982f8e6 100644
--- a/code/__defines/tgs.dm
+++ b/code/__defines/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "5.2.2"
+#define TGS_DMAPI_VERSION "6.0.2"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -67,7 +67,7 @@
#define TGS_EVENT_REPO_CHECKOUT 1
/// When the repository performs a fetch operation. No parameters
#define TGS_EVENT_REPO_FETCH 2
-/// When the repository merges a pull request. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user
+/// When the repository test merges. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user
#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3
/// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path
#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4
@@ -95,8 +95,13 @@
#define TGS_EVENT_WATCHDOG_SHUTDOWN 15
/// Before the watchdog detaches for a TGS update/restart. No parameters.
#define TGS_EVENT_WATCHDOG_DETACH 16
-// We don't actually implement this value as the DMAPI can never receive it
+// We don't actually implement these 4 events as the DMAPI can never receive them.
// #define TGS_EVENT_WATCHDOG_LAUNCH 17
+// #define TGS_EVENT_WATCHDOG_CRASH 18
+// #define TGS_EVENT_WORLD_END_PROCESS 19
+// #define TGS_EVENT_WORLD_REBOOT 20
+/// Watchdog event when TgsInitializationComplete() is called. No parameters.
+#define TGS_EVENT_WORLD_PRIME 21
// OTHER ENUMS
@@ -145,6 +150,7 @@
/world/proc/TgsReboot()
return
+
// DATUM DEFINITIONS
// All datums defined here should be considered read-only
@@ -152,6 +158,8 @@
/datum/tgs_revision_information
/// Full SHA of the commit.
var/commit
+ /// ISO 8601 timestamp of when the commit was created
+ var/timestamp
/// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch.
var/origin_commit
@@ -174,37 +182,36 @@
/// String value minus prefix
var/deprefixed_parameter
+
/**
- * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
- */
+ * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
+ */
/datum/tgs_version/proc/Wildcard()
return
/**
- * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version.
- *
- * other_version - The [/datum/tgs_version] to compare against.
- */
+ * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version.
+ *
+ * other_version - The [/datum/tgs_version] to compare against.
+ */
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
return
/// Represents a merge of a GitHub pull request.
/datum/tgs_revision_information/test_merge
- /// The pull request number.
+ /// The test merge number.
var/number
- /// The pull request title when it was merged.
+ /// The test merge source's title when it was merged.
var/title
- /// The pull request body when it was merged.
+ /// The test merge source's body when it was merged.
var/body
- /// The GitHub username of the pull request's author.
+ /// The Username of the test merge source's author.
var/author
- /// An http URL to the pull request.
+ /// An http URL to the test merge source.
var/url
- /// The SHA of the pull request when that was merged.
- var/pull_request_commit
- /// ISO 8601 timestamp of when the pull request was merged.
- var/time_merged
- /// (Nullable) Comment left by the TGS user who initiated the merge..
+ /// The SHA of the test merge when that was merged.
+ var/head_commit
+ /// Optional comment left by the TGS user who initiated the merge.
var/comment
/// Represents a connected chat channel.
@@ -234,10 +241,10 @@
var/datum/tgs_chat_channel/channel
/**
- * User definable callback for handling TGS events.
- *
- * event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each
- */
+ * User definable callback for handling TGS events.
+ *
+ * event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each
+ */
/datum/tgs_event_handler/proc/HandleEvent(event_code, ...)
set waitfor = FALSE
return
@@ -252,67 +259,67 @@
var/admin_only = FALSE
/**
- * Process command activation. Should return a string to respond to the issuer with.
- *
- * sender - The [/datum/tgs_chat_user] who issued the command.
- * params - The trimmed string following the command `/datum/tgs_chat_command/var/name].
- */
+ * Process command activation. Should return a string to respond to the issuer with.
+ *
+ * sender - The [/datum/tgs_chat_user] who issued the command.
+ * params - The trimmed string following the command `/datum/tgs_chat_command/var/name].
+ */
/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params)
CRASH("[type] has no implementation for Run()")
// API FUNCTIONS
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
-/world/proc/TgsMaximumAPIVersion()
+/world/proc/TgsMaximumApiVersion()
return
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
-/world/proc/TgsMinimumAPIVersion()
+/world/proc/TgsMinimumApiVersion()
return
/**
- * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
- */
+ * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
+ */
/world/proc/TgsAvailable()
return
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
/**
- * Forces a hard reboot of DreamDaemon by ending the process.
- *
- * Unlike del(world) clients will try to reconnect.
- * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again
- */
+ * Forces a hard reboot of DreamDaemon by ending the process.
+ *
+ * Unlike del(world) clients will try to reconnect.
+ * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again
+ */
/world/proc/TgsEndProcess()
return
/**
- * Send a message to connected chats.
- *
- * message - The string to send.
- * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
- */
+ * Send a message to connected chats.
+ *
+ * message - The string to send.
+ * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
+ */
/world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE)
return
/**
- * Send a private message to a specific user.
- *
- * message - The string to send.
- * user: The [/datum/tgs_chat_user] to PM.
- */
+ * Send a private message to a specific user.
+ *
+ * message - The string to send.
+ * user: The [/datum/tgs_chat_user] to PM.
+ */
/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user)
return
// The following functions will sleep if a call to TgsNew() is sleeping
/**
- * Send a message to connected chats that are flagged as game-related in TGS.
- *
- * message - The string to send.
- * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
- */
+ * Send a message to connected chats that are flagged as game-related in TGS.
+ *
+ * message - The string to send.
+ * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
+ */
/world/proc/TgsChatBroadcast(message, list/channels = null)
return
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 32eb4c33b40..e27e5354658 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -120,10 +120,11 @@ client/verb/showrevinfo()
. += {"
"}
. += {" "}
. += {"| Author: | [html_encode(tm.author)] | "}
- . += {"| Merged: | [tm.time_merged] | "}
if (config.githuburl)
. += {"| Link to Github | "}
. += {"| Description: | [html_encode(tm.body)] | "}
+ if(tm.comment)
+ . += {"| Comment: | [html_encode(tm.comment)] | "}
. += {" |
"}
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 0a60fea5778..7686c0d5bb5 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -31,7 +31,7 @@
update_clothing_icon()
/obj/item/storage/belt/Initialize()
- ..()
+ . = ..()
update_flip_verb()
/obj/item/storage/belt/proc/update_flip_verb()
@@ -52,7 +52,7 @@
flipped = !flipped
icon_state = "[initial(icon_state)][flipped ? "_flip" : ""]"
- item_state = icon_state
+ item_state = "[initial(item_state)][flipped ? "_flip" : ""]"
to_chat(usr, SPAN_NOTICE("You change \the [src] to be [src.flipped ? "behind" : "in front of"] you."))
update_clothing_icon()
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 993a706a40a..295f71fd6ca 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -213,6 +213,9 @@ var/list/forum_groupids_to_ranks = list()
if(isnull(user.ckey))
log_debug("AdminRanks: [user.forum_name] does not have a ckey linked - Ignoring")
return
+ if(user.psync_game_disabled)
+ log_debug("AdminRanks: [user.forum_name] has permsync-game disabled - Ignoring")
+ return
var/rights = 0
for (var/group_id in (user.forum_secondary_groups + user.forum_primary_group))
diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
index 593db51462b..0939c399d2d 100644
--- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
@@ -199,7 +199,7 @@
/datum/gear/uniform/colorpants/New()
..()
- var/colorpants = list()
+ var/list/colorpants = list()
colorpants["dress pants"] = /obj/item/clothing/under/pants/dress
colorpants["striped pants"] = /obj/item/clothing/under/pants/striped
gear_tweaks += new/datum/gear_tweak/path(colorpants)
@@ -209,14 +209,14 @@
path = /obj/item/clothing/under/syndicate/tacticool
/datum/gear/uniform/dominia
- display_name = "dominia clothing selection"
- description = "A selection of dominian clothing."
+ display_name = "dominian clothing selection"
+ description = "A selection of Dominian clothing."
path = /obj/item/clothing/under/dominia
flags = GEAR_HAS_DESC_SELECTION
/datum/gear/uniform/dominia/New()
..()
- var/suit = list()
+ var/list/suit = list()
suit["dominia suit, red"] = /obj/item/clothing/under/dominia
suit["dominia suit, black"] = /obj/item/clothing/under/dominia/black
suit["dominia sweater"] = /obj/item/clothing/under/dominia/sweater
@@ -226,6 +226,19 @@
suit["dominia summer dress"] = /obj/item/clothing/under/dominia/dress/summer
gear_tweaks += new/datum/gear_tweak/path(suit)
+/datum/gear/uniform/dominia_dress
+ display_name = "dominian dress selection"
+ description = "A selection of fancy Dominian dresses."
+ path = /obj/item/clothing/under/dominia/dress
+
+/datum/gear/uniform/dominia_dress/New()
+ ..()
+ var/list/suit = list()
+ for(var/dress in subtypesof(/obj/item/clothing/under/dominia/dress/fancy))
+ var/obj/item/clothing/under/dominia/dress/D = new dress //I'm not typing all this shit manually. Jesus christ.
+ suit["[D.name]"] = D.type
+ gear_tweaks += new/datum/gear_tweak/path(suit)
+
/datum/gear/uniform/elyra_holo
display_name = "elyran holographic suit selection"
description = "A marvel of Elyran technology, uses hardlight fabric and masks to transform a skin-tight, cozy suit into cultural apparel of your choosing. Has a dial for Midenean, Aemaqii and Perispolisean clothes respectively."
@@ -234,7 +247,7 @@
/datum/gear/uniform/elyra_holo/New()
..()
- var/suit = list()
+ var/list/suit = list()
suit["elyran holographic suit, feminine"] = /obj/item/clothing/under/elyra_holo
suit["elyran holographic suit, masculine"] = /obj/item/clothing/under/elyra_holo/masc
gear_tweaks += new/datum/gear_tweak/path(suit)
@@ -252,7 +265,7 @@
/datum/gear/uniform/officer/New()
..()
- var/uniform = list()
+ var/list/uniform = list()
uniform["officer uniform, standard"] = /obj/item/clothing/under/rank/security
uniform["officer uniform, corporate"] = /obj/item/clothing/under/rank/security/corp
uniform["officer uniform, blue"] = /obj/item/clothing/under/rank/security/blue
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index cace2eebb53..14425365548 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -936,7 +936,6 @@
var/mob/M = src.loc
M.update_inv_w_uniform()
-
/obj/item/clothing/under/examine(mob/user)
..(user)
switch(src.sensor_mode)
diff --git a/code/modules/clothing/factions/dominia.dm b/code/modules/clothing/factions/dominia.dm
index efe79644a14..9802762074c 100644
--- a/code/modules/clothing/factions/dominia.dm
+++ b/code/modules/clothing/factions/dominia.dm
@@ -325,6 +325,37 @@
overlay_state = "dominian_cape_red"
contained_sprite = TRUE
icon_override = null
+ var/rolled = FALSE
+
+/obj/item/clothing/accessory/poncho/dominia/red/update_clothing_icon()
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_wear_suit()
+ get_mob_overlay(TRUE)
+ get_inv_overlay(TRUE)
+
+/obj/item/clothing/accessory/poncho/dominia/red/verb/roll_up_mantle()
+ set name = "Roll Up Cape Mantle"
+ set desc = "Roll up your cape's mantle. Doesn't work with some capes."
+ set src in usr
+
+ if(use_check_and_message(usr))
+ return FALSE
+
+ var/list/icon_states = icon_states(icon)
+ var/initial_state = initial(icon_state)
+ var/new_state = "[initial_state]_h"
+ if(!(new_state in icon_states))
+ to_chat(usr, SPAN_WARNING("Your cape doesn't allow this!"))
+ return
+
+ rolled = !rolled
+ to_chat(usr, SPAN_NOTICE("You roll your cape's mantle [rolled ? "up" : "down"]."))
+ icon_state = rolled ? new_state : initial_state
+ item_state = rolled ? new_state : initial_state
+ overlay_state = rolled ? new_state : initial_state
+ update_icon()
+ update_clothing_icon()
/obj/item/clothing/under/dominia/initiate
name = "tribunal initiate's robe"
@@ -383,3 +414,84 @@
desc = "A warm fur hat with ear flaps that can be raised and tied to be out of the way. This one has a large Fisanduhian flag on the front."
icon_state = "fishushanka"
item_state = "fishushanka"
+
+/obj/item/clothing/under/dominia/dress/fancy
+ name = "Morozi dress"
+ desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has sleeves."
+ desc_fluff = "Dresses such as this one are a common sight in the more developed colonies of the Empire of Dominia, and their origins can be traced back to \
+ the fashion houses of Nova Luxembourg. While both sleeved and sleeveless variants exist, the sleeved one is far more common \
+ due to the often frigid temperatures of Moroz."
+ icon = 'icons/clothing/under/uniforms/dominia_dresses.dmi'
+ icon_state = "morozi_dress"
+ item_state = "morozi_dress"
+ contained_sprite = TRUE
+ var/house
+
+/obj/item/clothing/under/dominia/dress/fancy/Initialize()
+ . = ..()
+ if(house)
+ desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has sleeves, and a colored sash marking its wearer as \
+ an affiliate of House [capitalize(house)]."
+ icon_state = "[house]"
+ item_state = "[house]"
+ update_clothing_icon()
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless
+ name = "sleeveless Morozi dress"
+ desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has no sleeves."
+ desc_fluff = "Dresses such as this one are a common sight in the more developed colonies of the Empire of Dominia, and their origins can be traced back to \
+ the fashion houses of Nova Luxembourg. While both sleeved and sleeveless variants exist, the sleeved one is far more common \
+ due to the often frigid temperatures of Moroz."
+ icon_state = "morozi_dress_rs"
+ item_state = "morozi_dress_rs"
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless/Initialize()
+ . = ..()
+ if(house)
+ desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has no sleeves, and a colored sash marking its wearer as \
+ an affiliate of House [house]."
+ icon_state += "_rs"
+ item_state += "_rs"
+ update_clothing_icon()
+
+/obj/item/clothing/under/dominia/dress/fancy/zhao
+ name = "house zhao Morozi dress"
+ house = "zhao"
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless/zhao
+ name = "sleeveless house zhao Morozi dress"
+ house = "zhao"
+
+/obj/item/clothing/under/dominia/dress/fancy/volvalaad
+ name = "house volvalaad Morozi dress"
+ house = "volvalaad"
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless/volvalaad
+ name = "sleeveless house volvalaad Morozi dress"
+ house = "volvalaad"
+
+/obj/item/clothing/under/dominia/dress/fancy/strelitz
+ name = "house strelitz Morozi dress"
+ house = "strelitz"
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless/strelitz
+ name = "sleeveless house strelitz Morozi dress"
+ house = "strelitz"
+
+/obj/item/clothing/under/dominia/dress/fancy/caladius
+ name = "house caladius Morozi dress"
+ house = "caladius"
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless/caladius
+ name = "sleeveless house caladius Morozi dress"
+ house = "caladius"
+
+/obj/item/clothing/under/dominia/dress/fancy/kazhkz
+ name = "house kazhkz Morozi dress"
+ house = "kazhkz"
+
+/obj/item/clothing/under/dominia/dress/fancy/sleeveless/kazhkz
+ name = "sleeveless house kazhkz Morozi dress"
+ house = "kazhkz"
+
+
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index bad23d7a30c..7042602aaee 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -28,11 +28,11 @@
cut_overlays()
add_overlay(overlay_image(icon, worn_overlay, flags=RESET_COLOR)) //add the overlay w/o coloration of the original sprite
-/obj/item/clothing/accessory/proc/get_inv_overlay()
+/obj/item/clothing/accessory/proc/get_inv_overlay(var/force = FALSE)
if(!mob_overlay)
get_mob_overlay()
var/I = mob_overlay.icon
- if(!inv_overlay)
+ if(!inv_overlay || force)
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
if(icon_override)
if("[tmp_icon_state]_tie" in icon_states(icon_override))
@@ -47,9 +47,9 @@
inv_overlay.add_overlay(overlay_image(I, worn_overlay, flags=RESET_COLOR)) //add the overlay w/o coloration of the original sprite
return inv_overlay
-/obj/item/clothing/accessory/proc/get_mob_overlay()
+/obj/item/clothing/accessory/proc/get_mob_overlay(var/force = FALSE)
var/I = icon_override ? icon_override : contained_sprite ? icon : INV_ACCESSORIES_DEF_ICON
- if(!mob_overlay)
+ if(!mob_overlay || force)
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
if(icon_override)
if("[tmp_icon_state]_mob" in icon_states(I))
diff --git a/code/modules/http/forumuser_api.dm b/code/modules/http/forumuser_api.dm
index 20da806c8b3..d3611f354f2 100644
--- a/code/modules/http/forumuser_api.dm
+++ b/code/modules/http/forumuser_api.dm
@@ -7,6 +7,7 @@ var/global/forumuser_api_key = null
var/list/forum_secondary_groups = list()
var/discord_id
var/ckey
+ var/psync_game_disabled = FALSE
/datum/forum_user/New(data)
forum_member_id = data["forum_member_id"]
@@ -18,6 +19,8 @@ var/global/forumuser_api_key = null
discord_id = data["discord_id"]
ckey = data["ckey"]
+ if(data["psync_game_disalbed"] == 1) //This here is needed because the data can be null, 1 or 0
+ psync_game_disabled = TRUE
/datum/http_request/forumuser_api
@@ -62,4 +65,3 @@ var/global/forumuser_api_key = null
R.body = users
return R
-
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 5dfc9664abd..5fb5ecedc3d 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -969,7 +969,6 @@ There are several things that need to be remembered:
if(belt.contained_sprite)
belt.auto_adapt_species(src)
var/t_state = "[UNDERSCORE_OR_NULL(belt.icon_species_tag)][belt.item_state][WORN_BELT]"
-
result_layer = image(belt.icon_override || belt.icon, t_state)
else if(belt.icon_override)
t_icon = belt.icon_override
@@ -977,11 +976,9 @@ There are several things that need to be remembered:
t_icon = belt.sprite_sheets[GET_BODY_TYPE]
else if(belt.item_icons && (slot_belt_str in belt.item_icons))
t_icon = belt.item_icons[slot_belt_str]
- else
- t_icon = INV_BELT_DEF_ICON
if(!result_layer) //Create the image
- result_layer = image(t_icon, belt.icon_state)
+ result_layer = image(t_icon, belt.item_state)
if(belt.color)
result_layer.color = belt.color
@@ -989,11 +986,11 @@ There are several things that need to be remembered:
result_layer.appearance_flags = RESET_ALPHA
var/image/worn_overlays = belt.worn_overlays(t_icon)
if(worn_overlays)
- result_layer.overlays.Add(worn_overlays)
+ result_layer.add_overlay(worn_overlays)
var/list/ovr
- if(belt.contents.len && istype(belt, /obj/item/storage/belt))
+ if(length(belt.contents) && istype(belt, /obj/item/storage/belt))
ovr = list(result_layer)
for(var/obj/item/i in belt.contents)
var/c_state
@@ -1005,10 +1002,9 @@ There are several things that need to be remembered:
c_icon = INV_BELT_DEF_ICON
c_state = i.item_state || i.icon_state
var/image/belt_item_image = image(c_icon, c_state)
- if(i.color)
- belt_item_image.color = i.color
+ belt_item_image.color = i.color
belt_item_image.appearance_flags = RESET_ALPHA
- ovr += image(c_icon, c_state)
+ ovr += belt_item_image
var/belt_layer = BELT_LAYER
if(istype(belt, /obj/item/storage/belt))
@@ -1024,9 +1020,6 @@ There are several things that need to be remembered:
if(update_icons)
update_icon()
- if (QDELING(src))
- return
-
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
if (QDELING(src))
return
diff --git a/code/modules/tgs/core/core.dm b/code/modules/tgs/core/core.dm
index f75e7837af0..41a04733945 100644
--- a/code/modules/tgs/core/core.dm
+++ b/code/modules/tgs/core/core.dm
@@ -40,7 +40,7 @@
if(5)
api_datum = /datum/tgs_api/v5
- var/datum/tgs_version/max_api_version = TgsMaximumAPIVersion();
+ var/datum/tgs_version/max_api_version = TgsMaximumApiVersion();
if(version.suite != null && version.minor != null && version.patch != null && version.deprecated_patch != null && version.deprefixed_parameter > max_api_version.deprefixed_parameter)
TGS_ERROR_LOG("Detected unknown API version! Defaulting to latest. Update the DMAPI to fix this problem.")
api_datum = /datum/tgs_api/latest
@@ -64,10 +64,10 @@
TGS_WRITE_GLOBAL(tgs, null)
TGS_ERROR_LOG("Failed to activate API!")
-/world/TgsMaximumAPIVersion()
+/world/TgsMaximumApiVersion()
return new /datum/tgs_version("5.x.x")
-/world/TgsMinimumAPIVersion()
+/world/TgsMinimumApiVersion()
return new /datum/tgs_version("3.2.x")
/world/TgsInitializationComplete()
diff --git a/code/modules/tgs/includes.dm b/code/modules/tgs/includes.dm
index c803cf7ac26..4018074f4e3 100644
--- a/code/modules/tgs/includes.dm
+++ b/code/modules/tgs/includes.dm
@@ -14,4 +14,4 @@
#include "v5\_defines.dm"
#include "v5\api.dm"
#include "v5\commands.dm"
-#include "v5\undef.dm"
+#include "v5\undefs.dm"
diff --git a/code/modules/tgs/v3210/api.dm b/code/modules/tgs/v3210/api.dm
index e0d00ad15d1..245381b93ea 100644
--- a/code/modules/tgs/v3210/api.dm
+++ b/code/modules/tgs/v3210/api.dm
@@ -39,7 +39,7 @@
var/warned_custom_commands = FALSE
/datum/tgs_api/v3210/ApiVersion()
- return new /datum/tgs_version("3.2.1.0")
+ return new /datum/tgs_version("3.2.1.3")
/datum/tgs_api/v3210/proc/trim_left(text)
for (var/i = 1 to length(text))
@@ -160,7 +160,7 @@
var/datum/tgs_revision_information/test_merge/tm = new
tm.number = text2num(I)
var/list/entry = json[I]
- tm.pull_request_commit = entry["commit"]
+ tm.head_commit = entry["commit"]
tm.author = entry["author"]
tm.title = entry["title"]
. += tm
@@ -180,7 +180,7 @@
ExportService(SERVICE_REQUEST_KILL_PROCESS)
/datum/tgs_api/v3210/ChatChannelInfo()
- return list()
+ return list() // :omegalul:
/datum/tgs_api/v3210/ChatBroadcast(message, list/channels)
if(channels)
diff --git a/code/modules/tgs/v3210/commands.dm b/code/modules/tgs/v3210/commands.dm
index a1949da444d..4ccfc1a8a60 100644
--- a/code/modules/tgs/v3210/commands.dm
+++ b/code/modules/tgs/v3210/commands.dm
@@ -42,5 +42,11 @@
var/datum/tgs_chat_command/stc = new command_type
var/datum/tgs_chat_user/user = new
user.friendly_name = sender
+
+ // Discord hack, fix the mention if it's only numbers (fuck you IRC trolls)
+ var/regex/discord_id_regex = regex(@"^[0-9]+$")
+ if(findtext(sender, discord_id_regex))
+ sender = "<@[sender]>"
+
user.mention = sender
return stc.Run(user, params) || TRUE
diff --git a/code/modules/tgs/v4/api.dm b/code/modules/tgs/v4/api.dm
index 5e7f3c60bed..4eb8e67d928 100644
--- a/code/modules/tgs/v4/api.dm
+++ b/code/modules/tgs/v4/api.dm
@@ -92,7 +92,7 @@
var/list/json = cached_json["testMerges"]
for(var/entry in json)
var/datum/tgs_revision_information/test_merge/tm = new
- tm.time_merged = text2num(entry["timeMerged"])
+ tm.timestamp = text2num(entry["timeMerged"])
var/list/revInfo = entry["revision"]
if(revInfo)
@@ -104,7 +104,7 @@
tm.url = entry["url"]
tm.author = entry["author"]
tm.number = entry["number"]
- tm.pull_request_commit = entry["pullRequestRevision"]
+ tm.head_commit = entry["pullRequestRevision"]
tm.comment = entry["comment"]
cached_test_merges += tm
@@ -114,15 +114,6 @@
/datum/tgs_api/v4/OnInitializationComplete()
Export(TGS4_COMM_SERVER_PRIMED)
- var/tgs4_secret_sleep_offline_sauce = 29051994
- var/old_sleep_offline = world.sleep_offline
- world.sleep_offline = tgs4_secret_sleep_offline_sauce
- sleep(1)
- if(world.sleep_offline == tgs4_secret_sleep_offline_sauce) //if not someone changed it
- world.sleep_offline = old_sleep_offline
- else
- TGS_WARNING_LOG("world.sleep_offline unexpectedly changed!")
-
/datum/tgs_api/v4/OnTopic(T)
var/list/params = params2list(T)
var/their_sCK = params[TGS4_INTEROP_ACCESS_IDENTIFIER]
@@ -257,7 +248,7 @@
return instance_name
/datum/tgs_api/v4/TestMerges()
- return cached_test_merges
+ return cached_test_merges.Copy()
/datum/tgs_api/v4/EndProcess()
Export(TGS4_COMM_END_PROCESS)
diff --git a/code/modules/tgs/v5/README.md b/code/modules/tgs/v5/README.md
new file mode 100644
index 00000000000..5b48d57a1f0
--- /dev/null
+++ b/code/modules/tgs/v5/README.md
@@ -0,0 +1,8 @@
+# DMAPI V5
+
+This DMAPI implements bridge requests using HTTP GET requests to TGS. It has no security restrictions.
+
+- [_defines.dm](./_defines.dm) contains constant definitions.
+- [api.dm](./api.dm) contains the bulk of the API code.
+- [commands.dm](./commands.dm) contains functions relating to `/datum/tgs_chat_command`s.
+- [undefs.dm](./undefs.dm) Undoes the work of `_defines.dm`.
diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm
index 8fd84e19fa3..10bc4cbe406 100644
--- a/code/modules/tgs/v5/_defines.dm
+++ b/code/modules/tgs/v5/_defines.dm
@@ -79,6 +79,7 @@
#define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses"
#define DMAPI5_REVISION_INFORMATION_COMMIT_SHA "commitSha"
+#define DMAPI5_REVISION_INFORMATION_TIMESTAMP "timestamp"
#define DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA "originCommitSha"
#define DMAPI5_CHAT_USER_ID "id"
diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm
index 3791cbde843..6735ed5dec5 100644
--- a/code/modules/tgs/v5/api.dm
+++ b/code/modules/tgs/v5/api.dm
@@ -15,8 +15,12 @@
var/datum/tgs_revision_information/revision
var/list/chat_channels
+ var/initialized = FALSE
+
/datum/tgs_api/v5/ApiVersion()
- return new /datum/tgs_version("5.2.2")
+ return new /datum/tgs_version(
+ #include "interop_version.dm"
+ )
/datum/tgs_api/v5/OnWorldNew(minimum_required_security_level)
server_port = world.params[DMAPI5_PARAM_SERVER_PORT]
@@ -46,6 +50,7 @@
if(istype(revisionData))
revision = new
revision.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA]
+ revision.timestamp = revisionData[DMAPI5_REVISION_INFORMATION_TIMESTAMP]
revision.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA]
else
TGS_ERROR_LOG("Failed to decode [DMAPI5_RUNTIME_INFORMATION_REVISION] from runtime information!")
@@ -61,15 +66,18 @@
if(revInfo)
tm.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA]
tm.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA]
+ tm.timestamp = entry[DMAPI5_REVISION_INFORMATION_TIMESTAMP]
else
TGS_WARNING_LOG("Failed to decode [DMAPI5_TEST_MERGE_REVISION] from test merge #[tm.number]!")
- tm.time_merged = text2num(entry[DMAPI5_TEST_MERGE_TIME_MERGED])
+ if(!tm.timestamp)
+ tm.timestamp = entry[DMAPI5_TEST_MERGE_TIME_MERGED]
+
tm.title = entry[DMAPI5_TEST_MERGE_TITLE_AT_MERGE]
tm.body = entry[DMAPI5_TEST_MERGE_BODY_AT_MERGE]
tm.url = entry[DMAPI5_TEST_MERGE_URL]
tm.author = entry[DMAPI5_TEST_MERGE_AUTHOR]
- tm.pull_request_commit = entry[DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION]
+ tm.head_commit = entry[DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION]
tm.comment = entry[DMAPI5_TEST_MERGE_COMMENT]
test_merges += tm
@@ -79,6 +87,7 @@
chat_channels = list()
DecodeChannels(runtime_information)
+ initialized = TRUE
return TRUE
/datum/tgs_api/v5/proc/RequireInitialBridgeResponse()
@@ -88,15 +97,6 @@
/datum/tgs_api/v5/OnInitializationComplete()
Bridge(DMAPI5_BRIDGE_COMMAND_PRIME)
- var/tgs4_secret_sleep_offline_sauce = 29051994
- var/old_sleep_offline = world.sleep_offline
- world.sleep_offline = tgs4_secret_sleep_offline_sauce
- sleep(1)
- if(world.sleep_offline == tgs4_secret_sleep_offline_sauce) //if not someone changed it
- world.sleep_offline = old_sleep_offline
- else
- TGS_WARNING_LOG("world.sleep_offline unexpectedly changed!")
-
/datum/tgs_api/v5/proc/TopicResponse(error_message = null)
var/list/response = list()
response[DMAPI5_RESPONSE_ERROR_MESSAGE] = error_message
@@ -107,12 +107,16 @@
var/list/params = params2list(T)
var/json = params[DMAPI5_TOPIC_DATA]
if(!json)
- return FALSE //continue world/Topic
+ return FALSE // continue to /world/Topic
var/list/topic_parameters = json_decode(json)
if(!topic_parameters)
return TopicResponse("Invalid topic parameters json!");
+ if(!initialized)
+ TGS_WARNING_LOG("Missed topic due to not being initialized: [T]")
+ return TRUE // too early to handle, but it's still our responsibility
+
var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER]
if(their_sCK != access_identifier)
return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] from: [json]!");
@@ -284,7 +288,7 @@
/datum/tgs_api/v5/TestMerges()
RequireInitialBridgeResponse()
- return test_merges
+ return test_merges.Copy()
/datum/tgs_api/v5/EndProcess()
Bridge(DMAPI5_BRIDGE_COMMAND_KILL)
@@ -329,7 +333,7 @@
/datum/tgs_api/v5/ChatChannelInfo()
RequireInitialBridgeResponse()
- return chat_channels
+ return chat_channels.Copy()
/datum/tgs_api/v5/proc/DecodeChannels(chat_update_json)
var/list/chat_channels_json = chat_update_json[DMAPI5_CHAT_UPDATE_CHANNELS]
diff --git a/code/modules/tgs/v5/interop_version.dm b/code/modules/tgs/v5/interop_version.dm
new file mode 100644
index 00000000000..c7bf62ecae3
--- /dev/null
+++ b/code/modules/tgs/v5/interop_version.dm
@@ -0,0 +1 @@
+"5.3.0"
diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm
new file mode 100644
index 00000000000..5885a60e75c
--- /dev/null
+++ b/code/modules/tgs/v5/undefs.dm
@@ -0,0 +1,99 @@
+#undef DMAPI5_PARAM_SERVER_PORT
+#undef DMAPI5_PARAM_ACCESS_IDENTIFIER
+
+#undef DMAPI5_BRIDGE_DATA
+#undef DMAPI5_TOPIC_DATA
+
+#undef DMAPI5_BRIDGE_COMMAND_PORT_UPDATE
+#undef DMAPI5_BRIDGE_COMMAND_STARTUP
+#undef DMAPI5_BRIDGE_COMMAND_PRIME
+#undef DMAPI5_BRIDGE_COMMAND_REBOOT
+#undef DMAPI5_BRIDGE_COMMAND_KILL
+#undef DMAPI5_BRIDGE_COMMAND_CHAT_SEND
+
+#undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER
+#undef DMAPI5_PARAMETER_CUSTOM_COMMANDS
+
+#undef DMAPI5_RESPONSE_ERROR_MESSAGE
+
+#undef DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE
+#undef DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT
+#undef DMAPI5_BRIDGE_PARAMETER_VERSION
+#undef DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE
+#undef DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL
+
+#undef DMAPI5_BRIDGE_RESPONSE_NEW_PORT
+#undef DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION
+
+#undef DMAPI5_CHAT_MESSAGE_TEXT
+#undef DMAPI5_CHAT_MESSAGE_CHANNEL_IDS
+
+#undef DMAPI5_RUNTIME_INFORMATION_ACCESS_IDENTIFIER
+#undef DMAPI5_RUNTIME_INFORMATION_SERVER_VERSION
+#undef DMAPI5_RUNTIME_INFORMATION_SERVER_PORT
+#undef DMAPI5_RUNTIME_INFORMATION_API_VALIDATE_ONLY
+#undef DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME
+#undef DMAPI5_RUNTIME_INFORMATION_REVISION
+#undef DMAPI5_RUNTIME_INFORMATION_TEST_MERGES
+#undef DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL
+
+#undef DMAPI5_CHAT_UPDATE_CHANNELS
+
+#undef DMAPI5_TEST_MERGE_TIME_MERGED
+#undef DMAPI5_TEST_MERGE_REVISION
+#undef DMAPI5_TEST_MERGE_TITLE_AT_MERGE
+#undef DMAPI5_TEST_MERGE_BODY_AT_MERGE
+#undef DMAPI5_TEST_MERGE_URL
+#undef DMAPI5_TEST_MERGE_AUTHOR
+#undef DMAPI5_TEST_MERGE_NUMBER
+#undef DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION
+#undef DMAPI5_TEST_MERGE_COMMENT
+
+#undef DMAPI5_CHAT_COMMAND_NAME
+#undef DMAPI5_CHAT_COMMAND_PARAMS
+#undef DMAPI5_CHAT_COMMAND_USER
+
+#undef DMAPI5_EVENT_NOTIFICATION_TYPE
+#undef DMAPI5_EVENT_NOTIFICATION_PARAMETERS
+
+#undef DMAPI5_TOPIC_COMMAND_CHAT_COMMAND
+#undef DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION
+#undef DMAPI5_TOPIC_COMMAND_CHANGE_PORT
+#undef DMAPI5_TOPIC_COMMAND_CHANGE_REBOOT_STATE
+#undef DMAPI5_TOPIC_COMMAND_INSTANCE_RENAMED
+#undef DMAPI5_TOPIC_COMMAND_CHAT_CHANNELS_UPDATE
+#undef DMAPI5_TOPIC_COMMAND_SERVER_PORT_UPDATE
+#undef DMAPI5_TOPIC_COMMAND_HEARTBEAT
+#undef DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH
+
+#undef DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE
+#undef DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND
+#undef DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION
+#undef DMAPI5_TOPIC_PARAMETER_NEW_PORT
+#undef DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE
+#undef DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME
+#undef DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE
+#undef DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION
+
+#undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE
+#undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES
+
+#undef DMAPI5_REVISION_INFORMATION_COMMIT_SHA
+#undef DMAPI5_REVISION_INFORMATION_TIMESTAMP
+#undef DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA
+
+#undef DMAPI5_CHAT_USER_ID
+#undef DMAPI5_CHAT_USER_FRIENDLY_NAME
+#undef DMAPI5_CHAT_USER_MENTION
+#undef DMAPI5_CHAT_USER_CHANNEL
+
+#undef DMAPI5_CHAT_CHANNEL_ID
+#undef DMAPI5_CHAT_CHANNEL_FRIENDLY_NAME
+#undef DMAPI5_CHAT_CHANNEL_CONNECTION_NAME
+#undef DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL
+#undef DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL
+#undef DMAPI5_CHAT_CHANNEL_TAG
+
+#undef DMAPI5_CUSTOM_CHAT_COMMAND_NAME
+#undef DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT
+#undef DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY
diff --git a/code/world.dm b/code/world.dm
index cba467bd0b5..058e0a08da9 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -430,7 +430,7 @@ var/list/world_api_rate_limit = list()
/proc/establish_db_connection(var/DBConnection/con)
if (!config.sql_enabled)
return FALSE
-
+
if (!con)
error("No DBConnection object passed to establish_db_connection() proc.")
return FALSE
diff --git a/html/changelog.html b/html/changelog.html
index 5e43f69928a..87dfb8eda9f 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -35,6 +35,20 @@
-->
+
09 February 2021
+
Geeves updated:
+
+ - Fixes belts missing their sprites and having uncoloured overlays.
+
+
+
08 February 2021
+
MattAtlas, DasFox updated:
+
+ - Added new fancy Dominian dresses under a new loadout selection.
+ - Updated the tribunal cape.
+ - Added a verb to the red tribunalist cape that allows you to hide part of it.
+
+
07 February 2021
Doxxmedearly updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 18fe598b8ff..1b5bd866ec7 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -18214,3 +18214,12 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- rscadd: Adds colorable belts.
- tweak: Fannypacks are now recolorable.
- rscadd: Belts now have a dedicated loadout section.
+2021-02-08:
+ MattAtlas, DasFox:
+ - rscadd: Added new fancy Dominian dresses under a new loadout selection.
+ - imageadd: Updated the tribunal cape.
+ - rscadd: Added a verb to the red tribunalist cape that allows you to hide part
+ of it.
+2021-02-09:
+ Geeves:
+ - bugfix: Fixes belts missing their sprites and having uncoloured overlays.
diff --git a/icons/clothing/suits/capes/dominia_doublecape.dmi b/icons/clothing/suits/capes/dominia_doublecape.dmi
index d4f7d78e30f..62aeff321ff 100644
Binary files a/icons/clothing/suits/capes/dominia_doublecape.dmi and b/icons/clothing/suits/capes/dominia_doublecape.dmi differ
diff --git a/icons/clothing/suits/capes/dominia_red.dmi b/icons/clothing/suits/capes/dominia_red.dmi
index 5a3a535348e..16ed401fe0e 100644
Binary files a/icons/clothing/suits/capes/dominia_red.dmi and b/icons/clothing/suits/capes/dominia_red.dmi differ
diff --git a/icons/clothing/under/uniforms/dominia_dresses.dmi b/icons/clothing/under/uniforms/dominia_dresses.dmi
new file mode 100644
index 00000000000..9a65e02ddc2
Binary files /dev/null and b/icons/clothing/under/uniforms/dominia_dresses.dmi differ