diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 07a0bdb0df3..834ecbe88b7 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -31,7 +31,7 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/caps, GLOB.caps_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings, GLOB.moth_wings_list) - + init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, GLOB.moth_markings_list) //Species for(var/spath in subtypesof(/datum/species)) @@ -52,7 +52,7 @@ // Keybindings init_keybindings() - + GLOB.emote_list = init_emote_list() init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm index 881e0ebd90c..eae7522511d 100644 --- a/code/datums/mutations/actions.dm +++ b/code/datums/mutations/actions.dm @@ -187,7 +187,7 @@ if(!isturf(user.loc)) return FALSE -/obj/effect/proc_holder/spell/self/void/cast(mob/user = usr) +/obj/effect/proc_holder/spell/self/void/cast(list/targets, mob/user = usr) . = ..() new /obj/effect/immortality_talisman/void(get_turf(user), user) @@ -210,7 +210,7 @@ charge_max = 100 action_icon_state = "autotomy" -/obj/effect/proc_holder/spell/self/self_amputation/cast(mob/user = usr) +/obj/effect/proc_holder/spell/self/self_amputation/cast(list/targets, mob/user = usr) if(!iscarbon(user)) return @@ -252,7 +252,7 @@ action_icon_state = "spike" var/spike_path = /obj/item/hardened_spike -/obj/effect/proc_holder/spell/self/tongue_spike/cast(mob/user = usr) +/obj/effect/proc_holder/spell/self/tongue_spike/cast(list/targets, mob/user = usr) if(!iscarbon(user)) return @@ -408,7 +408,7 @@ to_chat(user, "There's already a web here!") return FALSE -/obj/effect/proc_holder/spell/self/lay_genetic_web/cast(mob/user = usr) +/obj/effect/proc_holder/spell/self/lay_genetic_web/cast(list/targets, mob/user = usr) var/turf/T = get_turf(user) user.visible_message("[user] begins to secrete a sticky substance.","You begin to lay a web.") diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index a245750cec0..062e5f909a3 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -57,14 +57,14 @@ /obj/item/storage/bag/trash/update_icon_state() switch(contents.len) - if(0) - icon_state = "[initial(icon_state)]" - if(0 to 11) - icon_state = "[initial(icon_state)]1" + if(20 to INFINITY) + icon_state = "[initial(icon_state)]3" if(11 to 20) icon_state = "[initial(icon_state)]2" + if(1 to 11) + icon_state = "[initial(icon_state)]1" else - icon_state = "[initial(icon_state)]3" + icon_state = "[initial(icon_state)]" /obj/item/storage/bag/trash/cyborg insertable = FALSE diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index a8e479f4875..b6a761b4b34 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -4,14 +4,15 @@ icon_state = "timer" custom_materials = list(/datum/material/iron=500, /datum/material/glass=50) attachable = TRUE - + drop_sound = 'sound/items/handling/component_drop.ogg' + pickup_sound = 'sound/items/handling/component_pickup.ogg' + var/ui_x = 275 + var/ui_y = 115 var/timing = FALSE var/time = 5 var/saved_time = 5 var/loop = FALSE var/hearing_range = 3 - drop_sound = 'sound/items/handling/component_drop.ogg' - pickup_sound = 'sound/items/handling/component_pickup.ogg' /obj/item/assembly/timer/suicide_act(mob/living/user) user.visible_message("[user] looks at the timer and decides [user.p_their()] fate! It looks like [user.p_theyre()] going to commit suicide!") @@ -43,7 +44,6 @@ update_icon() return TRUE - /obj/item/assembly/timer/toggle_secure() secured = !secured if(secured) @@ -54,7 +54,6 @@ update_icon() return secured - /obj/item/assembly/timer/proc/timer_end() if(!secured || next_activate > world.time) return FALSE @@ -68,7 +67,6 @@ timing = TRUE update_icon() - /obj/item/assembly/timer/process() if(!timing) return @@ -78,7 +76,6 @@ timer_end() time = saved_time - /obj/item/assembly/timer/update_icon() cut_overlays() attached_overlays = list() @@ -88,48 +85,44 @@ if(holder) holder.update_icon() - -/obj/item/assembly/timer/ui_interact(mob/user)//TODO: Have this use the wires - . = ..() +/obj/item/assembly/timer/ui_status(mob/user) if(is_secured(user)) - var/second = time % 60 - var/minute = (time - second) / 60 - var/dat = "Timing Unit" - dat += "
[(timing ? "Timing" : "Not Timing")] [minute]:[second]" - dat += "
- - + +" - dat += "

Stop repeating" : "1'>Set to repeat")]" - dat += "

Refresh" - dat += "

Close" - var/datum/browser/popup = new(user, "timer", name) - popup.set_content(dat) - popup.open() + return ..() + return UI_CLOSE +/obj/item/assembly/timer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "timer", name, ui_x, ui_y, master_ui, state) + ui.open() -/obj/item/assembly/timer/Topic(href, href_list) - ..() - if(!usr.canUseTopic(src, BE_CLOSE)) - usr << browse(null, "window=timer") - onclose(usr, "timer") +/obj/item/assembly/timer/ui_data(mob/user) + var/list/data = list() + var/time_left = time + data["seconds"] = round(time_left % 60) + data["minutes"] = round((time_left - data["seconds"]) / 60) + data["timing"] = timing + data["loop"] = loop + return data + +/obj/item/assembly/timer/ui_act(action, params) + if(..()) return - if(href_list["time"]) - timing = text2num(href_list["time"]) - if(timing && istype(holder, /obj/item/transfer_valve)) - log_bomber(usr, "activated a", src, "attachment on [holder]") - - update_icon() - if(href_list["repeat"]) - loop = text2num(href_list["repeat"]) - - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 1), 600) - saved_time = time - - if(href_list["close"]) - usr << browse(null, "window=timer") - return - - if(usr) - attack_self(usr) + switch(action) + if("time") + timing = !timing + if(timing && istype(holder, /obj/item/transfer_valve)) + log_bomber(usr, "activated a", src, "attachment on [holder]") + update_icon() + . = TRUE + if("repeat") + loop = !loop + . = TRUE + if("input") + var/value = text2num(params["adjust"]) + if(value) + time = min(max(round(time+value), 1), 600) + saved_time = time + . = TRUE diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 3b8237dde68..6231006c5bb 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -46,7 +46,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key) parent.update_movement_keys(src) to_chat(parent, "Empty keybindings, setting default to [hotkeys ? "Hotkey" : "Classic"] mode") - + if(current_version < 30) if(clientfps == 0) clientfps = 60 @@ -329,6 +329,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["backpack"] >> backpack S["jumpsuit_style"] >> jumpsuit_style S["uplink_loc"] >> uplink_spawn_loc + S["phobia"] >> phobia S["randomise"] >> randomise S["feature_mcolor"] >> features["mcolor"] S["feature_ethcolor"] >> features["ethcolor"] @@ -468,6 +469,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc) WRITE_FILE(S["randomise"] , randomise) WRITE_FILE(S["species"] , pref_species.id) + WRITE_FILE(S["phobia"], phobia) WRITE_FILE(S["feature_mcolor"] , features["mcolor"]) WRITE_FILE(S["feature_ethcolor"] , features["ethcolor"]) WRITE_FILE(S["feature_lizard_tail"] , features["tail_lizard"]) diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm index 94912dfc554..92aadd3ca04 100644 --- a/code/modules/mining/machine_silo.dm +++ b/code/modules/mining/machine_silo.dm @@ -232,8 +232,9 @@ GLOBAL_LIST_EMPTY(silo_access_logs) var/list/msg = list("([timestamp]) [machine_name] in [area_name]
[action] [abs(amount)]x [noun]
") var/sep = "" for(var/key in materials) + var/datum/material/M = key var/val = round(materials[key]) / MINERAL_MATERIAL_AMOUNT msg += sep sep = ", " - msg += "[amount < 0 ? "-" : "+"][val] [copytext(key, length(key[1]) + 1)]" + msg += "[amount < 0 ? "-" : "+"][val] [M.name]" formatted = msg.Join() diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm index ddd0ccd74cb..0329fe1e321 100644 --- a/code/modules/research/bepis.dm +++ b/code/modules/research/bepis.dm @@ -111,11 +111,19 @@ return /obj/machinery/rnd/bepis/proc/calcsuccess() - var/turf/dropturf = get_turf(pick(view(1,src))) + var/turf/dropturf = null var/gauss_major = 0 var/gauss_minor = 0 var/gauss_real = 0 - if(!dropturf) //Check to verify the turf exists and the reward isn't lost somehow. + var/list/turfs = block(locate(x-1,y-1,z),locate(x+1,y+1,z)) //NO MORE DISCS IN WINDOWS + while(length(turfs)) + var/turf/T = pick_n_take(turfs) + if(is_blocked_turf(T, exclude_mobs=TRUE)) + continue + else + dropturf = T + break + if (!dropturf) dropturf = drop_location() gauss_major = (gaussian(major_threshold, std) - negative_cash_offset) //This is the randomized profit value that this experiment has to surpass to unlock a tech. gauss_minor = (gaussian(minor_threshold, std) - negative_cash_offset) //And this is the threshold to instead get a minor prize. diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index d6e908a8131..75c613f70f2 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1082,6 +1082,10 @@ description = "A bored scientist was thinking to himself for very long...and then realized his coffee got cold! He made this invention to solve this extreme problem." prereq_ids = list("base") design_ids = list("mauna_mug") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 2500 + hidden = TRUE + experimental = TRUE /datum/techweb_node/spec_eng id = "spec_eng" diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index d27728018e8..ff88b3cca1e 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -552,7 +552,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th school = "restoration" sound = 'sound/magic/staff_healing.ogg' -/obj/effect/proc_holder/spell/self/basic_heal/cast(mob/living/carbon/human/user) //Note the lack of "list/targets" here. Instead, use a "user" var depending on mob requirements. +/obj/effect/proc_holder/spell/self/basic_heal/cast(list/targets, mob/living/carbon/human/user) //Note the lack of "list/targets" here. Instead, use a "user" var depending on mob requirements. //Also, notice the lack of a "for()" statement that looks through the targets. This is, again, because the spell can only have a single target. user.visible_message("A wreath of gentle light passes over [user]!", "You wreath yourself in healing light!") user.adjustBruteLoss(-10) diff --git a/code/modules/spells/spell_types/soultap.dm b/code/modules/spells/spell_types/soultap.dm index eb4fa112d29..c152c89f8c0 100644 --- a/code/modules/spells/spell_types/soultap.dm +++ b/code/modules/spells/spell_types/soultap.dm @@ -17,7 +17,7 @@ action_icon = 'icons/mob/actions/actions_spells.dmi' action_icon_state = "soultap" -/obj/effect/proc_holder/spell/self/tap/cast(mob/living/user = usr) +/obj/effect/proc_holder/spell/self/tap/cast(list/targets, mob/living/user = usr) if(!user.mind.hasSoul) to_chat(user, "You do not possess a soul to tap into!") return diff --git a/html/changelogs/AutoChangeLog-pr-48902.yml b/html/changelogs/AutoChangeLog-pr-48902.yml new file mode 100644 index 00000000000..51b068e14e6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-48902.yml @@ -0,0 +1,4 @@ +author: "ArcaneMusic" +delete-after: True +changes: + - bugfix: "The B.E.P.I.S. no longer shunts rewards into the walls and windows of the station." diff --git a/html/changelogs/AutoChangeLog-pr-48979.yml b/html/changelogs/AutoChangeLog-pr-48979.yml new file mode 100644 index 00000000000..3844770d806 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-48979.yml @@ -0,0 +1,4 @@ +author: "TheVekter" +delete-after: True +changes: + - bugfix: "Fixes the Mauna Mug research being available from roundstart." diff --git a/html/changelogs/AutoChangeLog-pr-48980.yml b/html/changelogs/AutoChangeLog-pr-48980.yml new file mode 100644 index 00000000000..fa1ea2e0079 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-48980.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - bugfix: "Removed rogue pixel on salbutamol pen inhand sprite." diff --git a/html/changelogs/AutoChangeLog-pr-48981.yml b/html/changelogs/AutoChangeLog-pr-48981.yml new file mode 100644 index 00000000000..3731d13caaf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-48981.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - rscadd: "Timer assembly now uses tgui-next." diff --git a/html/changelogs/AutoChangeLog-pr-49001.yml b/html/changelogs/AutoChangeLog-pr-49001.yml new file mode 100644 index 00000000000..459be4301e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-49001.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - bugfix: "Trashbag will now properly update its icon." diff --git a/html/changelogs/AutoChangeLog-pr-49005.yml b/html/changelogs/AutoChangeLog-pr-49005.yml new file mode 100644 index 00000000000..39878742cd3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-49005.yml @@ -0,0 +1,4 @@ +author: "Names-Are-Hard" +delete-after: True +changes: + - bugfix: "phobia quirk properly saves now" diff --git a/html/changelogs/AutoChangeLog-pr-49006.yml b/html/changelogs/AutoChangeLog-pr-49006.yml new file mode 100644 index 00000000000..7cc59f3720d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-49006.yml @@ -0,0 +1,4 @@ +author: "Names-Are-Hard" +delete-after: True +changes: + - bugfix: "Fixed moth markings not saving properly" diff --git a/icons/mob/inhands/equipment/medical_lefthand.dmi b/icons/mob/inhands/equipment/medical_lefthand.dmi index e26eb4e04da..a1e711eee38 100644 Binary files a/icons/mob/inhands/equipment/medical_lefthand.dmi and b/icons/mob/inhands/equipment/medical_lefthand.dmi differ diff --git a/tgui-next/packages/tgui/interfaces/Timer.js b/tgui-next/packages/tgui/interfaces/Timer.js new file mode 100644 index 00000000000..0b7328cb81f --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Timer.js @@ -0,0 +1,48 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, Section } from '../components'; + +export const Timer = props => { + const { act, data } = useBackend(props); + const { + minutes, + seconds, + timing, + loop, + } = data; + return ( +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/routes.js b/tgui-next/packages/tgui/routes.js index 5002ea19054..a741f5c6644 100644 --- a/tgui-next/packages/tgui/routes.js +++ b/tgui-next/packages/tgui/routes.js @@ -99,6 +99,7 @@ import { Tank } from './interfaces/Tank'; import { TankDispenser } from './interfaces/TankDispenser'; import { Teleporter } from './interfaces/Teleporter'; import { ThermoMachine } from './interfaces/ThermoMachine'; +import { Timer } from './interfaces/Timer'; import { TurbineComputer } from './interfaces/TurbineComputer'; import { Uplink } from './interfaces/Uplink'; import { VaultController } from './interfaces/VaultController'; @@ -553,6 +554,10 @@ const ROUTES = { component: () => ThermoMachine, scrollable: false, }, + timer: { + component: () => Timer, + scrollable: false, + }, turbine_computer: { component: () => TurbineComputer, scrollable: false,