From 800d1b3e263040998e3452059a9278286c32b0fe Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 18 Oct 2024 01:47:05 +0000 Subject: [PATCH 1/5] Update TGS DMAPI --- code/__DEFINES/tgs.dm | 100 ++++++++++++++------ code/modules/tgs/README.md | 2 +- code/modules/tgs/core/README.md | 2 +- code/modules/tgs/core/byond_world_export.dm | 22 +++++ code/modules/tgs/core/core.dm | 7 +- code/modules/tgs/core/datum.dm | 2 +- code/modules/tgs/includes.dm | 1 + code/modules/tgs/v5/__interop_version.dm | 2 +- code/modules/tgs/v5/_defines.dm | 1 + code/modules/tgs/v5/api.dm | 7 +- code/modules/tgs/v5/bridge.dm | 21 ++-- code/modules/tgs/v5/topic.dm | 4 +- code/modules/tgs/v5/undefs.dm | 2 +- 13 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 code/modules/tgs/core/byond_world_export.dm diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index e2c89df90e9b..42f2d5fc31fe 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,18 +1,19 @@ // tgstation-server DMAPI +// The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119. -#define TGS_DMAPI_VERSION "7.1.2" +#define TGS_DMAPI_VERSION "7.3.0" // All functions and datums outside this document are subject to change with any version and should not be relied on. // CONFIGURATION -/// Create this define if you want to do TGS configuration outside of this file. +/// Consumers SHOULD create this define if you want to do TGS configuration outside of this file. #ifndef TGS_EXTERNAL_CONFIGURATION -// Comment this out once you've filled in the below. +// Consumers MUST comment this out once you've filled in the below and are not using [TGS_EXTERNAL_CONFIGURATION]. #error TGS API unconfigured -// Uncomment this if you wish to allow the game to interact with TGS 3.. +// Consumers MUST uncomment this if you wish to allow the game to interact with TGS version 3. // This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()(). //#define TGS_V3_API @@ -52,7 +53,7 @@ #ifndef TGS_FILE2TEXT_NATIVE #ifdef file2text -#error Your codebase is re-defining the BYOND proc file2text. The DMAPI requires the native version to read the result of world.Export(). You can fix this by adding "#define TGS_FILE2TEXT_NATIVE file2text" before your override of file2text to allow the DMAPI to use the native version. This will only be used for world.Export(), not regular file accesses +#error Your codebase is re-defining the BYOND proc file2text. The DMAPI requires the native version to read the result of world.Export(). You SHOULD fix this by adding "#define TGS_FILE2TEXT_NATIVE file2text" before your override of file2text to allow the DMAPI to use the native version. This will only be used for world.Export(), not regular file accesses #endif #define TGS_FILE2TEXT_NATIVE file2text #endif @@ -152,16 +153,17 @@ //REQUIRED HOOKS /** - * Call this somewhere in [/world/proc/New] that is always run. This function may sleep! + * Consumers MUST call this somewhere in [/world/proc/New] that is always run. This function may sleep! * * * event_handler - Optional user defined [/datum/tgs_event_handler]. * * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED]. + * * http_handler - Optional user defined [/datum/tgs_http_handler]. */ -/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) +/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler) return /** - * Call this when your initializations are complete and your game is ready to play before any player interactions happen. + * Consumers MUST call this when world initializations are complete and the game is ready to play before any player interactions happen. * * This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running. * Afterwards, consider explicitly setting it to what you want to avoid this BYOND bug: http://www.byond.com/forum/post/2575184 @@ -170,12 +172,10 @@ /world/proc/TgsInitializationComplete() return -/// Put this at the start of [/world/proc/Topic]. +/// Consumers MUST run this macro at the start of [/world/proc/Topic]. #define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return -/** - * Call this as late as possible in [world/proc/Reboot] (BEFORE ..()). - */ +/// Consumers MUST call this as late as possible in [world/proc/Reboot] (BEFORE ..()). /world/proc/TgsReboot() return @@ -269,7 +269,7 @@ /// The [/datum/tgs_chat_channel] the user was from. var/datum/tgs_chat_channel/channel -/// User definable handler for TGS events. +/// User definable handler for TGS events This abstract version SHOULD be overridden to be used. /datum/tgs_event_handler /// If the handler receieves [TGS_EVENT_HEALTH_CHECK] events. var/receive_health_checks = FALSE @@ -283,7 +283,41 @@ set waitfor = FALSE return -/// User definable chat command. +/// User definable handler for HTTP calls. This abstract version MUST be overridden to be used. +/datum/tgs_http_handler + +/** + * User definable callback for executing HTTP GET requests. + * MUST perform BYOND sleeps while the request is in flight. + * MUST return a [/datum/tgs_http_result]. + * SHOULD log its own errors + * + * url - The full URL to execute the GET request for including query parameters. + */ +/datum/tgs_http_handler/proc/PerformGet(url) + CRASH("[type]/PerformGet not implemented!") + +/// Result of a [/datum/tgs_http_handler] call. MUST NOT be overridden. +/datum/tgs_http_result + /// HTTP response as text + var/response_text + /// Boolean request success flag. Set for any 2XX response code. + var/success + +/** + * Create a [/datum/tgs_http_result]. + * + * * response_text - HTTP response as text. Must be provided in New(). + * * success - Boolean request success flag. Set for any 2XX response code. Must be provided in New(). + */ +/datum/tgs_http_result/New(response_text, success) + if(response_text && !istext(response_text)) + CRASH("response_text was not text!") + + src.response_text = response_text + src.success = success + +/// User definable chat command. This abstract version MUST be overridden to be used. /datum/tgs_chat_command /// The string to trigger this command on a chat bot. e.g `@bot name ...` or `!tgs name ...`. var/name = "" @@ -296,21 +330,27 @@ /** * Process command activation. Should return a [/datum/tgs_message_content] to respond to the issuer with. + * MUST be implemented * - * sender - The [/datum/tgs_chat_user] who issued the command. - * params - The trimmed string following the command `/datum/tgs_chat_command/var/name]. + * * 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()") -/// User definable chat message. +/// User definable chat message. MUST NOT be overridden. /datum/tgs_message_content - /// The tring content of the message. Must be provided in New(). + /// The string content of the message. Must be provided in New(). var/text /// The [/datum/tgs_chat_embed] to embed in the message. Not supported on all chat providers. var/datum/tgs_chat_embed/structure/embed +/** + * Create a [/datum/tgs_message_content]. + * + * * text - The string content of the message. + */ /datum/tgs_message_content/New(text) ..() if(!istext(text)) @@ -319,7 +359,7 @@ src.text = text -/// User definable chat embed. Currently mirrors Discord chat embeds. See https://discord.com/developers/docs/resources/channel#embed-object-embed-structure for details. +/// User definable chat embed. Currently mirrors Discord chat embeds. See https://discord.com/developers/docs/resources/message#embed-object for details. /datum/tgs_chat_embed/structure var/title var/description @@ -331,13 +371,13 @@ /// Colour must be #AARRGGBB or #RRGGBB hex string. var/colour - /// See https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure for details. + /// See https://discord.com/developers/docs/resources/message#embed-object-embed-image-structure for details. var/datum/tgs_chat_embed/media/image - /// See https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure for details. + /// See https://discord.com/developers/docs/resources/message#embed-object-embed-thumbnail-structure for details. var/datum/tgs_chat_embed/media/thumbnail - /// See https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure for details. + /// See https://discord.com/developers/docs/resources/message#embed-object-embed-video-structure for details. var/datum/tgs_chat_embed/media/video var/datum/tgs_chat_embed/footer/footer @@ -346,7 +386,7 @@ var/list/datum/tgs_chat_embed/field/fields -/// Common datum for similar discord embed medias. +/// Common datum for similar Discord embed medias. /datum/tgs_chat_embed/media /// Must be set in New(). var/url @@ -354,6 +394,7 @@ var/height var/proxy_url +/// Create a [/datum/tgs_chat_embed]. /datum/tgs_chat_embed/media/New(url) ..() if(!istext(url)) @@ -361,13 +402,14 @@ src.url = url -/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure for details. +/// See https://discord.com/developers/docs/resources/message#embed-object-embed-footer-structure for details. /datum/tgs_chat_embed/footer /// Must be set in New(). var/text var/icon_url var/proxy_icon_url +/// Create a [/datum/tgs_chat_embed/footer]. /datum/tgs_chat_embed/footer/New(text) ..() if(!istext(text)) @@ -375,16 +417,17 @@ src.text = text -/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure for details. +/// See https://discord.com/developers/docs/resources/message#embed-object-embed-provider-structure for details. /datum/tgs_chat_embed/provider var/name var/url -/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure for details. Must have name set in New(). +/// See https://discord.com/developers/docs/resources/message#embed-object-embed-author-structure for details. Must have name set in New(). /datum/tgs_chat_embed/provider/author var/icon_url var/proxy_icon_url +/// Create a [/datum/tgs_chat_embed/footer]. /datum/tgs_chat_embed/provider/author/New(name) ..() if(!istext(name)) @@ -392,12 +435,15 @@ src.name = name -/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure for details. Must have name and value set in New(). +/// See https://discord.com/developers/docs/resources/message#embed-object-embed-field-structure for details. /datum/tgs_chat_embed/field + /// Must be set in New(). var/name + /// Must be set in New(). var/value var/is_inline +/// Create a [/datum/tgs_chat_embed/field]. /datum/tgs_chat_embed/field/New(name, value) ..() if(!istext(name)) diff --git a/code/modules/tgs/README.md b/code/modules/tgs/README.md index 6319028d8106..35ca73d7e9a8 100644 --- a/code/modules/tgs/README.md +++ b/code/modules/tgs/README.md @@ -1,6 +1,6 @@ # DMAPI Internals -This folder should be placed on it's own inside a codebase that wishes to use the TGS DMAPI. Warranty void if modified. +This folder should be placed on its own inside a codebase that wishes to use the TGS DMAPI. Warranty void if modified. - [includes.dm](./includes.dm) is the file that should be included by DM code, it handles including the rest. - The [core](./core) folder includes all code not directly part of any API version. diff --git a/code/modules/tgs/core/README.md b/code/modules/tgs/core/README.md index b82d8f49e297..965e21b549a3 100644 --- a/code/modules/tgs/core/README.md +++ b/code/modules/tgs/core/README.md @@ -3,7 +3,7 @@ This folder contains all DMAPI code not directly involved in an API. - [_definitions.dm](./definitions.dm) contains defines needed across DMAPI internals. +- [byond_world_export.dm](./byond_world_export.dm) contains the default `/datum/tgs_http_handler` implementation which uses `world.Export()`. - [core.dm](./core.dm) contains the implementations of the `/world/proc/TgsXXX()` procs. Many map directly to the `/datum/tgs_api` functions. It also contains the /datum selection and setup code. - [datum.dm](./datum.dm) contains the `/datum/tgs_api` declarations that all APIs must implement. - [tgs_version.dm](./tgs_version.dm) contains the `/datum/tgs_version` definition -- diff --git a/code/modules/tgs/core/byond_world_export.dm b/code/modules/tgs/core/byond_world_export.dm new file mode 100644 index 000000000000..6ef8d841b8f7 --- /dev/null +++ b/code/modules/tgs/core/byond_world_export.dm @@ -0,0 +1,22 @@ +/datum/tgs_http_handler/byond_world_export + +/datum/tgs_http_handler/byond_world_export/PerformGet(url) + // This is an infinite sleep until we get a response + var/export_response = world.Export(url) + TGS_DEBUG_LOG("byond_world_export: Export complete") + + if(!export_response) + TGS_ERROR_LOG("byond_world_export: Failed request: [url]") + return new /datum/tgs_http_result(null, FALSE) + + var/content = export_response["CONTENT"] + if(!content) + TGS_ERROR_LOG("byond_world_export: Failed request, missing content!") + return new /datum/tgs_http_result(null, FALSE) + + var/response_json = TGS_FILE2TEXT_NATIVE(content) + if(!response_json) + TGS_ERROR_LOG("byond_world_export: Failed request, failed to load content!") + return new /datum/tgs_http_result(null, FALSE) + + return new /datum/tgs_http_result(response_json, TRUE) diff --git a/code/modules/tgs/core/core.dm b/code/modules/tgs/core/core.dm index 15622228e91f..63cb5a2c3514 100644 --- a/code/modules/tgs/core/core.dm +++ b/code/modules/tgs/core/core.dm @@ -1,4 +1,4 @@ -/world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) +/world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler = null) var/current_api = TGS_READ_GLOBAL(tgs) if(current_api) TGS_ERROR_LOG("API datum already set (\ref[current_api] ([current_api]))! Was TgsNew() called more than once?") @@ -55,7 +55,10 @@ TGS_ERROR_LOG("Invalid parameter for event_handler: [event_handler]") event_handler = null - var/datum/tgs_api/new_api = new api_datum(event_handler, version) + if(!http_handler) + http_handler = new /datum/tgs_http_handler/byond_world_export + + var/datum/tgs_api/new_api = new api_datum(event_handler, version, http_handler) TGS_WRITE_GLOBAL(tgs, new_api) diff --git a/code/modules/tgs/core/datum.dm b/code/modules/tgs/core/datum.dm index f734fd0527f0..3ca53e9bf7c6 100644 --- a/code/modules/tgs/core/datum.dm +++ b/code/modules/tgs/core/datum.dm @@ -6,7 +6,7 @@ TGS_DEFINE_AND_SET_GLOBAL(tgs, null) var/list/warned_deprecated_command_runs -/datum/tgs_api/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version) +/datum/tgs_api/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version, datum/tgs_http_handler/http_handler) ..() src.event_handler = event_handler src.version = version diff --git a/code/modules/tgs/includes.dm b/code/modules/tgs/includes.dm index 23b714f9d064..f5118ed55a3c 100644 --- a/code/modules/tgs/includes.dm +++ b/code/modules/tgs/includes.dm @@ -1,4 +1,5 @@ #include "core\_definitions.dm" +#include "core\byond_world_export.dm" #include "core\core.dm" #include "core\datum.dm" #include "core\tgs_version.dm" diff --git a/code/modules/tgs/v5/__interop_version.dm b/code/modules/tgs/v5/__interop_version.dm index f4806f7adb97..29ea239ad84d 100644 --- a/code/modules/tgs/v5/__interop_version.dm +++ b/code/modules/tgs/v5/__interop_version.dm @@ -1 +1 @@ -"5.9.0" +"5.10.0" diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm index 92c7a8388a71..a47bfd78000b 100644 --- a/code/modules/tgs/v5/_defines.dm +++ b/code/modules/tgs/v5/_defines.dm @@ -95,6 +95,7 @@ #define DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION "newServerVersion" #define DMAPI5_TOPIC_PARAMETER_BROADCAST_MESSAGE "broadcastMessage" +#define DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT "clientCount" #define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE "commandResponse" #define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE "commandResponseMessage" #define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses" diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm index 95b8edd3ee5c..3e328fc7c27d 100644 --- a/code/modules/tgs/v5/api.dm +++ b/code/modules/tgs/v5/api.dm @@ -31,9 +31,12 @@ var/detached = FALSE -/datum/tgs_api/v5/New() + var/datum/tgs_http_handler/http_handler + +/datum/tgs_api/v5/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version, datum/tgs_http_handler/http_handler) . = ..() interop_version = version + src.http_handler = http_handler TGS_DEBUG_LOG("V5 API created: [json_encode(args)]") /datum/tgs_api/v5/ApiVersion() @@ -50,7 +53,9 @@ version = null // we want this to be the TGS version, not the interop version // sleep once to prevent an issue where world.Export on the first tick can hang indefinitely + TGS_DEBUG_LOG("Starting Export bug prevention sleep tick. time:[world.time] sleep_offline:[world.sleep_offline]") sleep(world.tick_lag) + TGS_DEBUG_LOG("Export bug prevention sleep complete") var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands(), DMAPI5_PARAMETER_TOPIC_PORT = GetTopicPort())) if(!istype(bridge_response)) diff --git a/code/modules/tgs/v5/bridge.dm b/code/modules/tgs/v5/bridge.dm index 0c5e701a32b6..62201fcc9e58 100644 --- a/code/modules/tgs/v5/bridge.dm +++ b/code/modules/tgs/v5/bridge.dm @@ -78,27 +78,24 @@ WaitForReattach(FALSE) TGS_DEBUG_LOG("Bridge request start") - // This is an infinite sleep until we get a response - var/export_response = world.Export(bridge_request) + var/datum/tgs_http_result/result = http_handler.PerformGet(bridge_request) TGS_DEBUG_LOG("Bridge request complete") - if(!export_response) - TGS_ERROR_LOG("Failed bridge request: [bridge_request]") + if(isnull(result)) + TGS_ERROR_LOG("Failed bridge request, handler returned null!") return - var/content = export_response["CONTENT"] - if(!content) - TGS_ERROR_LOG("Failed bridge request, missing content!") + if(!istype(result) || result.type != /datum/tgs_http_result) + TGS_ERROR_LOG("Failed bridge request, handler returned non-[/datum/tgs_http_result]!") return - var/response_json = TGS_FILE2TEXT_NATIVE(content) - if(!response_json) - TGS_ERROR_LOG("Failed bridge request, failed to load content!") + if(!result.success) + TGS_DEBUG_LOG("Failed bridge request, HTTP request failed!") return - var/list/bridge_response = json_decode(response_json) + var/list/bridge_response = json_decode(result.response_text) if(!bridge_response) - TGS_ERROR_LOG("Failed bridge request, bad json: [response_json]") + TGS_ERROR_LOG("Failed bridge request, bad json: [result.response_text]") return var/error = bridge_response[DMAPI5_RESPONSE_ERROR_MESSAGE] diff --git a/code/modules/tgs/v5/topic.dm b/code/modules/tgs/v5/topic.dm index e1f2cb638578..59e5e63e5cd4 100644 --- a/code/modules/tgs/v5/topic.dm +++ b/code/modules/tgs/v5/topic.dm @@ -149,7 +149,9 @@ if(DMAPI5_TOPIC_COMMAND_HEALTHCHECK) if(event_handler && event_handler.receive_health_checks) event_handler.HandleEvent(TGS_EVENT_HEALTH_CHECK) - return TopicResponse() + var/list/health_check_response = TopicResponse() + health_check_response[DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT] = TGS_CLIENT_COUNT + return health_check_response; if(DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH) detached = FALSE diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm index 237207fdfd05..acd19dfa6411 100644 --- a/code/modules/tgs/v5/undefs.dm +++ b/code/modules/tgs/v5/undefs.dm @@ -18,7 +18,6 @@ #undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER #undef DMAPI5_PARAMETER_CUSTOM_COMMANDS -#undef DMAPI5_PARAMETER_TOPIC_PORT #undef DMAPI5_CHUNK #undef DMAPI5_CHUNK_PAYLOAD @@ -95,6 +94,7 @@ #undef DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION #undef DMAPI5_TOPIC_PARAMETER_BROADCAST_MESSAGE +#undef DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT #undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE #undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE #undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES From 68f88741558d35cb0e1a347c1bf6ea2c0c030586 Mon Sep 17 00:00:00 2001 From: generalthrax <139387950+generalthrax@users.noreply.github.com> Date: Sat, 9 Nov 2024 13:06:52 -0600 Subject: [PATCH 2/5] Revert "Automatic TGS DMAPI Update" From d0e236d297db0a619b7bdac3391d8fc32128e600 Mon Sep 17 00:00:00 2001 From: generalthrax <5nthr5x@gmail.com> Date: Tue, 10 Dec 2024 14:59:41 -0600 Subject: [PATCH 3/5] whoops --- .../components/crafting/recipes/weapon.dm | 2 +- code/game/objects/items/storage/belt.dm | 2 +- .../food_and_drinks/drinks/drinks/bottle.dm | 25 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/code/datums/components/crafting/recipes/weapon.dm b/code/datums/components/crafting/recipes/weapon.dm index 6783c60c6c6b..039ff4fa486b 100644 --- a/code/datums/components/crafting/recipes/weapon.dm +++ b/code/datums/components/crafting/recipes/weapon.dm @@ -26,7 +26,7 @@ /datum/crafting_recipe/molotov name = "Molotov" - result = /obj/item/reagent_containers/food/drinks/bottle/molotov + result = /obj/item/reagent_containers/food/drinks/molotov reqs = list(/obj/item/reagent_containers/glass/rag = 1, /obj/item/reagent_containers/food/drinks/bottle = 1) parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 7bb42ef321b4..7a102a4527b3 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -605,7 +605,7 @@ /obj/item/screwdriver, /obj/item/lighter, /obj/item/multitool, - /obj/item/reagent_containers/food/drinks/bottle/molotov, + /obj/item/reagent_containers/food/drinks/molotov, /obj/item/grenade/c4, /obj/item/reagent_containers/food/snacks/grown/cherry_bomb, /obj/item/reagent_containers/food/snacks/grown/firelemon diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 454d5a44bc3e..bead24002f6b 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -453,14 +453,27 @@ isGlass = TRUE ////////////////////////// MOLOTOV /////////////////////// -/obj/item/reagent_containers/food/drinks/bottle/molotov +/obj/item/reagent_containers/food/drinks/molotov name = "molotov cocktail" desc = "A throwing weapon used to ignite things, typically filled with an accelerant. Recommended highly by desperate militias and revolutionaries. Light and toss." icon_state = "vodkabottle" + fill_icon_thresholds = list(0, 10, 20, 30, 40, 50, 60, 70, 80, 90) + amount_per_transfer_from_this = 10 + volume = 100 + force = 15 //Smashing bottles over someone's head hurts. + throwforce = 15 + item_state = "broken_beer" //Generic held-item sprite until unique ones are made. + lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' + pickup_sound = 'sound/items/handling/bottle_pickup.ogg' + drop_sound = 'sound/items/handling/bottle_drop.ogg' + var/const/duration = 13 //Directly relates to the 'knockdown' duration. Lowered by armor (i.e. helmets) + isGlass = TRUE + foodtype = ALCOHOL list_reagents = list() var/active = 0 -/obj/item/reagent_containers/food/drinks/bottle/molotov/CheckParts(list/parts_list) +/obj/item/reagent_containers/food/drinks/molotov/CheckParts(list/parts_list) ..() var/obj/item/reagent_containers/food/drinks/bottle/B = locate() in contents if(B) @@ -471,7 +484,7 @@ isGlass = FALSE return -/obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) +/obj/item/reagent_containers/food/drinks/molotov/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) var/firestarter = FALSE for(var/datum/reagent/reagent as anything in reagents.reagent_list) if(reagent.accelerant_quality) @@ -488,7 +501,7 @@ new /obj/effect/hotspot(otherT) ..() -/obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params) +/obj/item/reagent_containers/food/drinks/molotov/attackby(obj/item/I, mob/user, params) if(I.get_temperature() && !active) active = TRUE log_bomber(user, "has primed a", src, "for detonation") @@ -498,7 +511,7 @@ if(!isGlass) addtimer(CALLBACK(src, PROC_REF(explode)), 5 SECONDS) -/obj/item/reagent_containers/food/drinks/bottle/molotov/proc/explode() +/obj/item/reagent_containers/food/drinks/molotov/proc/explode() if(!active) return if(get_turf(src)) @@ -510,7 +523,7 @@ target.fire_act() qdel(src) -/obj/item/reagent_containers/food/drinks/bottle/molotov/attack_self(mob/user) +/obj/item/reagent_containers/food/drinks/molotov/attack_self(mob/user) if(active) if(!isGlass) to_chat(user, "The flame's spread too far on it!") From dfc9c640121b13df62dbef55bf1945b1bc9241f7 Mon Sep 17 00:00:00 2001 From: generalthrax <5nthr5x@gmail.com> Date: Tue, 10 Dec 2024 15:06:05 -0600 Subject: [PATCH 4/5] molotov mapping --- .../RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm | 2 +- code/modules/food_and_drinks/drinks/drinks/bottle.dm | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm index 64588e8452f5..579d58a4c09f 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm @@ -3533,7 +3533,7 @@ /obj/structure/flippedtable{ dir = 4 }, -/obj/item/reagent_containers/food/drinks/bottle/molotov, +/obj/item/reagent_containers/food/drinks/molotov/full, /obj/item/lighter/greyscale{ pixel_x = -8; pixel_y = -7 diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index bead24002f6b..4d389cc2bde2 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -532,6 +532,9 @@ cut_overlay(custom_fire_overlay ? custom_fire_overlay : GLOB.fire_overlay) active = 0 +/ob/item/reagent_containers/food/drinks/molotov/full + list_reagents = list(/datum/reagent/consumable/ethanol/vodka = 100) + /obj/item/reagent_containers/food/drinks/bottle/pruno name = "pruno mix" desc = "A trash bag filled with fruit, sugar, yeast, and water, pulped together into a pungent slurry to be fermented in an enclosed space, traditionally the toilet." From 29e17a7cea5a7042025df7fadc8bcbe47bc5ceb1 Mon Sep 17 00:00:00 2001 From: generalthrax <5nthr5x@gmail.com> Date: Tue, 10 Dec 2024 15:21:57 -0600 Subject: [PATCH 5/5] whoops --- code/modules/food_and_drinks/drinks/drinks/bottle.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 4d389cc2bde2..ece2f0dfbcfb 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -532,7 +532,7 @@ cut_overlay(custom_fire_overlay ? custom_fire_overlay : GLOB.fire_overlay) active = 0 -/ob/item/reagent_containers/food/drinks/molotov/full +/obj/item/reagent_containers/food/drinks/molotov/full list_reagents = list(/datum/reagent/consumable/ethanol/vodka = 100) /obj/item/reagent_containers/food/drinks/bottle/pruno