diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 50cb19a7e9..6e47391fc1 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -330,6 +330,7 @@ var/list/roundstart_mod_verbs = list( if(CLIENT_HAS_RIGHTS(src, R_BUILDMODE)) add_verb(src, /client/proc/togglebuildmodeself) add_verb(src, /client/proc/toggle_game_master) + add_verb(src, /client/proc/open_resin_panel) add_verb(src, /client/proc/open_sound_panel) add_verb(src, /client/proc/toggle_join_xeno) add_verb(src, /client/proc/game_master_rename_platoon) @@ -365,6 +366,7 @@ var/list/roundstart_mod_verbs = list( admin_verbs_default, /client/proc/togglebuildmodeself, /client/proc/toggle_game_master, + /client/proc/open_resin_panel, /client/proc/open_sound_panel, /client/proc/toggle_join_xeno, /client/proc/game_master_rename_platoon, diff --git a/code/modules/admin/game_master/resin_panel.dm b/code/modules/admin/game_master/resin_panel.dm new file mode 100644 index 0000000000..bab4097173 --- /dev/null +++ b/code/modules/admin/game_master/resin_panel.dm @@ -0,0 +1,177 @@ +#define RESIN_PANEL_STRUCTURES \ +list( \ + /datum/resin_construction/resin_turf/wall, \ + /datum/resin_construction/resin_turf/wall/thick, \ + /datum/resin_construction/resin_turf/wall/reflective, \ + /datum/resin_construction/resin_turf/membrane, \ + /datum/resin_construction/resin_turf/membrane/thick, \ + /datum/resin_construction/resin_obj/door, \ + /datum/resin_construction/resin_obj/door/thick, \ + /datum/resin_construction/resin_obj/resin_node, \ + /datum/resin_construction/resin_obj/sticky_resin, \ + /datum/resin_construction/resin_obj/fast_resin, \ + /datum/resin_construction/resin_obj/resin_spike, \ + /datum/resin_construction/resin_obj/acid_pillar, \ + /turf/closed/wall/mineral/bone_resin \ +) + +/client/proc/open_resin_panel() + set name = "Resin Panel" + set category = "Game Master" + + if(!check_rights(R_ADMIN)) + return + + new /datum/resin_panel(usr) + +/datum/resin_panel + var/static/list/structure_list + var/static/list/removal_allowlist + var/selected_structure + var/selected_hive = XENO_HIVE_NORMAL + var/client/holder + var/build_click_intercept = FALSE + +/datum/resin_panel/New(user) + if(isnull(structure_list)) //first run, init statics + structure_list = get_structures() + + removal_allowlist = list() + for(var/structure as anything in RESIN_PANEL_STRUCTURES) + if(structure in GLOB.resin_constructions_list) + var/datum/resin_construction/construct = structure + removal_allowlist += construct.build_path + else + removal_allowlist += structure + + if(isclient(user)) + holder = user + else + var/mob/mob = user + holder = mob.client + + holder.click_intercept = src + tgui_interact(holder.mob) + +/datum/resin_panel/proc/get_structures() + var/list/structures = list() + for(var/structure as anything in RESIN_PANEL_STRUCTURES) + var/list/entry = list() + + if(structure in GLOB.resin_constructions_list) + var/datum/resin_construction/construct = structure + entry["name"] = construct.name + entry["image"] = replacetext(construct.construction_name, " ", "-") + entry["id"] = "[construct]" + else if(structure in typesof(/turf)) + var/turf/turf = structure + entry["name"] = turf.name + switch(turf) + if(/turf/closed/wall/mineral/bone_resin) + entry["image"] = "reflective-resin-wall" //looks just like it, saves on making new spritesheet for one image + else + entry["image"] = turf.icon_state + entry["id"] = "[turf]" + + structures += list(entry) + + return structures + +/datum/resin_panel/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/choose_resin), + ) + +/datum/resin_panel/ui_static_data(mob/user) + var/list/data = list() + + data["structure_list"] = structure_list + data["hives_list"] = ALL_XENO_HIVES + + return data + +/datum/resin_panel/ui_data(mob/user) + var/list/data = list() + + data["selected_structure"] = selected_structure + data["selected_hive"] = selected_hive + data["build_click_intercept"] = build_click_intercept + + return data + +/datum/resin_panel/ui_close(mob/user) + holder = null + build_click_intercept = FALSE + qdel(src) + +/datum/resin_panel/ui_state(mob/user) + return GLOB.admin_state + +/datum/resin_panel/ui_status(mob/user, datum/ui_state/state) + return UI_INTERACTIVE + +/datum/resin_panel/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ResinPanel", "Resin Panel") + ui.set_autoupdate(FALSE) + ui.open() + +/datum/resin_panel/proc/InterceptClickOn(mob/user, params, atom/object) + if(!build_click_intercept) + return + + var/list/modifiers = params2list(params) + + if(LAZYACCESS(modifiers, MIDDLE_CLICK)) //remove + if(!(object.type in removal_allowlist)) + return + + if(isturf(object)) + var/turf/turf = object + turf.ScrapeAway() + else + qdel(object) + else //add + if(!selected_structure) + return + + var/turf/current_turf = get_turf(object) + + var/atom/new_structure + if(selected_structure in GLOB.resin_constructions_list) + var/datum/resin_construction/construct = GLOB.resin_constructions_list[selected_structure] + new_structure = construct.build(current_turf, selected_hive) + else if(selected_structure in typesof(/turf)) + var/turf/turf = selected_structure + new_structure = current_turf.PlaceOnTop(turf) + new_structure?.add_hiddenprint(user) //so admins know who placed it + + return TRUE + +/datum/resin_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + if(!check_rights(R_ADMIN)) + return + + switch(action) + if("set_selected_structure") + var/selected_type = text2path(params["type"]) + if(!(selected_type in RESIN_PANEL_STRUCTURES)) + return + selected_structure = selected_type + return TRUE + if("set_selected_hive") + var/hive = params["selected_hive"] + if(!(hive in ALL_XENO_HIVES)) + return + selected_hive = hive + return TRUE + if("toggle_build_click_intercept") + build_click_intercept = !build_click_intercept + return TRUE + +#undef RESIN_PANEL_STRUCTURES diff --git a/code/modules/cm_aliens/weeds.dm b/code/modules/cm_aliens/weeds.dm index 736d4f9474..9d15211f21 100644 --- a/code/modules/cm_aliens/weeds.dm +++ b/code/modules/cm_aliens/weeds.dm @@ -511,9 +511,9 @@ overlay_node = TRUE overlays += staticnode -/obj/effect/alien/weeds/node/Initialize(mapload, obj/effect/alien/weeds/node/node, mob/living/carbon/xenomorph/xeno, datum/hive_status/hive) - if (istype(hive)) - linked_hive = hive +/obj/effect/alien/weeds/node/Initialize(mapload, hive, mob/living/carbon/xenomorph/xeno) + if (hive) + linked_hive = GLOB.hive_datum[hive] else if (istype(xeno) && xeno.hive) linked_hive = xeno.hive else diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index 958e0f7a2f..aa8bf7eae6 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -67,7 +67,7 @@ xeno.visible_message(SPAN_XENONOTICE("\The [xeno] regurgitates a pulsating node and plants it on the ground!"), \ SPAN_XENONOTICE("You regurgitate a pulsating node and plant it on the ground!"), null, 5) - var/obj/effect/alien/weeds/node/new_node = new node_type(xeno.loc, src, xeno) + var/obj/effect/alien/weeds/node/new_node = new node_type(xeno.loc, xeno.hivenumber, xeno) if(to_convert) for(var/cur_weed in to_convert) diff --git a/colonialmarines.dme b/colonialmarines.dme index d75338ecfe..58cee33fcf 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1388,6 +1388,7 @@ #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\game_master\game_master.dm" #include "code\modules\admin\game_master\game_master_submenu.dm" +#include "code\modules\admin\game_master\resin_panel.dm" #include "code\modules\admin\game_master\sound_panel.dm" #include "code\modules\admin\game_master\extra_buttons\rappel_menu.dm" #include "code\modules\admin\game_master\extra_buttons\rename_platoon.dm" diff --git a/tgui/packages/tgui/interfaces/ResinPanel.tsx b/tgui/packages/tgui/interfaces/ResinPanel.tsx new file mode 100644 index 0000000000..e4587fe826 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ResinPanel.tsx @@ -0,0 +1,94 @@ +import { useBackend } from 'tgui/backend'; +import { Box, Button, Dropdown, Section, Stack, Tabs } from 'tgui/components'; +import { Window } from 'tgui/layouts'; +import { BooleanLike, classes } from 'common/react'; + +interface ResinPanelData { + structure_list: StructureEntry[]; + hives_list: string[]; + selected_structure: string; + selected_hive: string; + build_click_intercept: BooleanLike; +} + +interface StructureEntry { + name: string; + image: string; + id: string; +} + +export const ResinPanel = (props, context) => { + const { act, data } = useBackend(context); + const { + structure_list, + hives_list, + selected_structure, + selected_hive, + build_click_intercept, + } = data; + + let compact = false; + + return ( + + +
+ +
+
+
+ ); +};