Skip to content

Commit

Permalink
[TGUI] Stack Craft (#1401)
Browse files Browse the repository at this point in the history
## Что этот PR делает
Оживление TGUI для Stack Craft -
ParadiseSS13#25263
Используя наработки знаменитой крысы - @Gaxeer 
Убивая ассеты так как они сука лагают
Залезая в кор код потому что на конфликты ТГУИ и так похуй
Родилось это...

## Почему это хорошо для игры
Наконец-то можно крафтить хуйню удобно

## Изображения изменений


![image](https://github.com/user-attachments/assets/4b74d4d4-aeb0-4143-8595-556e77194e80)

![image](https://github.com/user-attachments/assets/a63c120b-3da9-4c47-9394-7152a2f5a92d)

![image](https://github.com/user-attachments/assets/f96b62ef-92d3-4770-9d7f-2857d6bc8235)

## Тестирование
Ну типа

## Changelog

:cl:
add: Меню крафта из материалов теперь использует TGUI. Картинки того что
вы крафтите и поиск входит в комплект
fix: При создании нескольких предметов из материала, например сразу 20
плиток пола, больше не должна крафтиться бита или т.п.
/:cl:

---------

Co-authored-by: Gaxeer <[email protected]>
  • Loading branch information
AyIong and Gaxeer authored Jul 31, 2024
1 parent 4d93987 commit f013298
Show file tree
Hide file tree
Showing 15 changed files with 552 additions and 85 deletions.
2 changes: 2 additions & 0 deletions code/game/objects/items/stacks/stack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@
merge(AM)
. = ..()

/* SS220 REMOVAL
/obj/item/stack/Destroy()
if(usr && usr.machine == src)
usr << browse(null, "window=stack")
return ..()
*/

/obj/item/stack/examine(mob/user)
. = ..()
Expand Down
32 changes: 16 additions & 16 deletions modular_ss220/aesthetics/_aesthetics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,28 @@
GLOB.wood_recipes += list(
null,
new /datum/stack_recipe_list("Деревянный пол", list(
new /datum/stack_recipe("Обычный деревянный пол", /obj/item/stack/tile/wood, 1, 4),
new /datum/stack_recipe("Дубовый деревянный пол", /obj/item/stack/tile/wood/oak, 1, 4),
new /datum/stack_recipe("Берёзовый деревянный пол", /obj/item/stack/tile/wood/birch, 1, 4),
new /datum/stack_recipe("Вишнёвый деревянный пол", /obj/item/stack/tile/wood/cherry, 1, 4),
new /datum/stack_recipe("Обычный деревянный пол", /obj/item/stack/tile/wood, 1, 4, 20),
new /datum/stack_recipe("Дубовый деревянный пол", /obj/item/stack/tile/wood/oak, 1, 4, 20),
new /datum/stack_recipe("Берёзовый деревянный пол", /obj/item/stack/tile/wood/birch, 1, 4, 20),
new /datum/stack_recipe("Вишнёвый деревянный пол", /obj/item/stack/tile/wood/cherry, 1, 4, 20),
)),
new /datum/stack_recipe_list("Деревянный пол (Цельный)", list(
new /datum/stack_recipe("Обычный цельный деревянный пол", /obj/item/stack/tile/wood/fancy, 1, 4),
new /datum/stack_recipe("Дубовый цельный деревянный пол", /obj/item/stack/tile/wood/fancy/oak, 1, 4),
new /datum/stack_recipe("Берёзовый цельный деревянный пол", /obj/item/stack/tile/wood/fancy/birch, 1, 4),
new /datum/stack_recipe("Вишнёвый цельный деревянный пол", /obj/item/stack/tile/wood/fancy/cherry, 1, 4),
new /datum/stack_recipe("Обычный цельный деревянный пол", /obj/item/stack/tile/wood/fancy, 1, 4, 20),
new /datum/stack_recipe("Дубовый цельный деревянный пол", /obj/item/stack/tile/wood/fancy/oak, 1, 4, 20),
new /datum/stack_recipe("Берёзовый цельный деревянный пол", /obj/item/stack/tile/wood/fancy/birch, 1, 4, 20),
new /datum/stack_recipe("Вишнёвый цельный деревянный пол", /obj/item/stack/tile/wood/fancy/cherry, 1, 4, 20),
)),
new /datum/stack_recipe_list("Паркет", list(
new /datum/stack_recipe("Обычный паркет", /obj/item/stack/tile/wood/parquet, 1, 4),
new /datum/stack_recipe("Дубовый паркет", /obj/item/stack/tile/wood/parquet/oak, 1, 4),
new /datum/stack_recipe("Берёзовый паркет", /obj/item/stack/tile/wood/parquet/birch, 1, 4),
new /datum/stack_recipe("Вишнёвый паркет", /obj/item/stack/tile/wood/parquet/cherry, 1, 4),
new /datum/stack_recipe("Обычный паркет", /obj/item/stack/tile/wood/parquet, 1, 4, 20),
new /datum/stack_recipe("Дубовый паркет", /obj/item/stack/tile/wood/parquet/oak, 1, 4, 20),
new /datum/stack_recipe("Берёзовый паркет", /obj/item/stack/tile/wood/parquet/birch, 1, 4, 20),
new /datum/stack_recipe("Вишнёвый паркет", /obj/item/stack/tile/wood/parquet/cherry, 1, 4, 20),
)),
new /datum/stack_recipe_list("Паркет (Классический)", list(
new /datum/stack_recipe("Классический обычный паркет", /obj/item/stack/tile/wood/parquet/tile, 1, 4),
new /datum/stack_recipe("Классический дубовый паркет", /obj/item/stack/tile/wood/parquet/tile/oak, 1, 4),
new /datum/stack_recipe("Классический берёзовый паркет", /obj/item/stack/tile/wood/parquet/tile/birch, 1, 4),
new /datum/stack_recipe("Классический вишнёвый паркет", /obj/item/stack/tile/wood/parquet/tile/cherry, 1, 4),
new /datum/stack_recipe("Классический обычный паркет", /obj/item/stack/tile/wood/parquet/tile, 1, 4, 20),
new /datum/stack_recipe("Классический дубовый паркет", /obj/item/stack/tile/wood/parquet/tile/oak, 1, 4, 20),
new /datum/stack_recipe("Классический берёзовый паркет", /obj/item/stack/tile/wood/parquet/tile/birch, 1, 4, 20),
new /datum/stack_recipe("Классический вишнёвый паркет", /obj/item/stack/tile/wood/parquet/tile/cherry, 1, 4, 20),
)),
null)

1 change: 1 addition & 0 deletions modular_ss220/modular_ss220.dme
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
#include "phrases/_phrases.dme"
#include "species/_species.dme"
#include "species_whitelist/_species_whitelist.dme"
#include "stack_craft_tgui/_stack_craft_tgui.dme"
#include "antagonists/_antagonists.dme"
#include "uplink_items/_uplink_items.dme"
#include "shuttles/_shuttles.dme"
Expand Down
5 changes: 5 additions & 0 deletions modular_ss220/stack_craft_tgui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Изменения в изначальном коде

`code/game/objects/items/stacks/stack.dm` - `del`:`proc "Destroy"`
`tgui/packages/tgui/components/Collapsible.js` - `add`:`prop "contentStyle"`
`tgui/packages/tgui/styles/components/ImageButton.scss` - `add`:`style "user-select"`
4 changes: 4 additions & 0 deletions modular_ss220/stack_craft_tgui/_stack_craft_tgui.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/datum/modpack/stack_craft_tgui
name = "Stack Craft TGUI"
desc = "Красивый, удобный интерфейс для меню крафта материалов."
author = "Aylong, Gaxeer"
5 changes: 5 additions & 0 deletions modular_ss220/stack_craft_tgui/_stack_craft_tgui.dme
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "_stack_craft_tgui.dm"

#include "code/stack.dm"
#include "code/stack_ui.dm"
#include "code/stack_recipe.dm"
122 changes: 122 additions & 0 deletions modular_ss220/stack_craft_tgui/code/stack.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/obj/item/stack/Topic(href, href_list)
return

/obj/item/stack/list_recipes(mob/user, recipes_sublist)
return

/obj/item/stack/attack_self(mob/user)
ui_interact(user)

/obj/item/stack/attack_self_tk(mob/user)
ui_interact(user)

/obj/item/stack/attack_tk(mob/user)
if(user.stat || !isturf(loc))
return
// Allow remote stack splitting, because telekinetic inventory managing
// is really cool
if(!(src in user.tkgrabbed_objects))
..()
return

var/obj/item/stack/material = split(user, 1)
material.attack_tk(user)
if(src && user.machine == src)
ui_interact(user)

/obj/item/stack/attack_hand(mob/user)
if(!user.is_in_inactive_hand(src) && get_amount() > 1)
..()
return

change_stack(user, 1)
if(src && user.machine == src)
ui_interact(user)


/obj/item/stack/change_stack(mob/user,amount)
. = ..()
SStgui.update_uis(src)

/obj/item/stack/attackby(obj/item/W, mob/user, params)
. = ..()
SStgui.update_uis(src)

/obj/item/stack/proc/make(mob/user, datum/stack_recipe/recipe_to_make, multiplier)
if(get_amount() < 1 && !is_cyborg)
qdel(src)
return FALSE

if(!validate_build(user, recipe_to_make, multiplier))
return FALSE

if(recipe_to_make.time)
to_chat(user, span_notice("Изготовление [recipe_to_make.title]..."))
if(!do_after(user, recipe_to_make.time, target = user))
return FALSE

if(!validate_build(user, recipe_to_make, multiplier))
return FALSE

var/atom/created
var/atom/drop_location = user.drop_location()
if(recipe_to_make.max_res_amount > 1) //Is it a stack?
created = new recipe_to_make.result_type(drop_location, recipe_to_make.res_amount * multiplier)
else
created = new recipe_to_make.result_type(drop_location)
created.setDir(user.dir)

use(recipe_to_make.req_amount * multiplier)

recipe_to_make.post_build(user, src, created)
if(isitem(created))
user.put_in_hands(created)

created.add_fingerprint(user)

//BubbleWrap - so newly formed boxes are empty
if(isstorage(created))
for(var/obj/item/thing in created)
qdel(thing)
//BubbleWrap END

return TRUE

/obj/item/stack/proc/validate_build(mob/builder, datum/stack_recipe/recipe_to_build, multiplier)
if(!multiplier || multiplier <= 0 || multiplier > 50 || !IS_INT(multiplier)) // Href exploit checks
message_admins("[key_name_admin(builder)] just attempted to href exploit sheet crafting with an invalid multiplier. Ban highly advised.")
return FALSE

if(get_amount() < recipe_to_build.req_amount * multiplier)
if(recipe_to_build.req_amount * multiplier > 1)
to_chat(builder, span_warning("У тебя недостаточно [src] для создания [recipe_to_build.req_amount * multiplier] [recipe_to_build.title]!"))
else
to_chat(builder, span_warning("У тебя недостаточно [src] для создания [recipe_to_build.title]!"))
return FALSE

var/turf/target_turf = get_turf(src)
if(recipe_to_build.window_checks && !valid_window_location(target_turf, builder.dir))
to_chat(builder, span_warning("[recipe_to_build.title] не помещается здесь!"))
return FALSE

if(recipe_to_build.one_per_turf && (locate(recipe_to_build.result_type) in target_turf))
to_chat(builder, span_warning("Тут уже есть [recipe_to_build.title]!"))
return FALSE

if(recipe_to_build.on_floor && !issimulatedturf(target_turf))
to_chat(builder, span_warning("[recipe_to_build.title] должно быть собрано на полу!"))
return FALSE

if(recipe_to_build.on_floor_or_lattice && !(issimulatedturf(target_turf) || locate(/obj/structure/lattice) in target_turf))
to_chat(builder, span_warning("[recipe_to_build.title] должно быть собрано на полу или решётке!"))
return FALSE

if(recipe_to_build.cult_structure)
if(builder.holy_check())
return FALSE

if(!is_level_reachable(builder.z))
to_chat(builder, span_warning("Энергия этого места вмешивается в процесс сборки!"))
return FALSE

return TRUE
29 changes: 29 additions & 0 deletions modular_ss220/stack_craft_tgui/code/stack_recipe.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/datum/stack_recipe
var/image

/datum/stack_recipe/post_build(mob/user, obj/item/stack/S, obj/item/stack/created)
return

/datum/stack_recipe/New(
title,
result_type,
req_amount = 1,
res_amount = 1,
max_res_amount = 1,
time = 0,
one_per_turf = FALSE,
on_floor = FALSE,
on_floor_or_lattice = FALSE,
window_checks = FALSE,
cult_structure = FALSE
)
. = ..()
var/obj/item/result = result_type
var/icon/result_icon = icon(result::icon, result::icon_state, SOUTH, 1)
var/paint = result::color

result_icon.Scale(32, 32)
if(!isnull(paint) && paint != COLOR_WHITE)
result_icon.Blend(paint, ICON_MULTIPLY)

image = "[icon2base64(result_icon)]"
53 changes: 53 additions & 0 deletions modular_ss220/stack_craft_tgui/code/stack_ui.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/obj/item/stack/ui_state(mob/user)
return GLOB.hands_state

/obj/item/stack/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "StackCraft220", name)
ui.set_autoupdate(FALSE)
ui.open()

/obj/item/stack/ui_data(mob/user)
var/list/data = list()
data["amount"] = get_amount()
return data

/obj/item/stack/ui_static_data(mob/user)
var/list/data = list()
data["recipes"] = recursively_build_recipes(recipes)
return data

/obj/item/stack/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
if(..())
return FALSE

switch(action)
if("make")
var/datum/stack_recipe/recipe = locateUID(params["recipe_uid"])
var/multiplier = text2num(params["multiplier"])
return make(usr, recipe, multiplier)

/obj/item/stack/proc/recursively_build_recipes(list/recipes_to_iterate)
var/list/recipes_data = list()
for(var/recipe in recipes_to_iterate)
if(istype(recipe, /datum/stack_recipe))
var/datum/stack_recipe/single_recipe = recipe
recipes_data["[single_recipe.title]"] = build_recipe_data(single_recipe)

else if(istype(recipe, /datum/stack_recipe_list))
var/datum/stack_recipe_list/recipe_list = recipe
recipes_data["[recipe_list.title]"] = recursively_build_recipes(recipe_list.recipes)

return recipes_data

/obj/item/stack/proc/build_recipe_data(datum/stack_recipe/recipe)
var/list/data = list()

data["uid"] = recipe.UID()
data["required_amount"] = recipe.req_amount
data["result_amount"] = recipe.res_amount
data["max_result_amount"] = recipe.max_res_amount
data["image"] = recipe.image

return data
8 changes: 6 additions & 2 deletions tgui/packages/tgui/components/Collapsible.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Collapsible extends Component {
render() {
const { props } = this;
const { open } = this.state;
const { children, color = 'default', title, buttons, ...rest } = props;
const { children, color = 'default', title, buttons, contentStyle, ...rest } = props;
return (
<Box className="Collapsible">
<div className="Table">
Expand All @@ -37,7 +37,11 @@ export class Collapsible extends Component {
</div>
{buttons && <div className="Table__cell Table__cell--collapsing">{buttons}</div>}
</div>
{open && <Box mt={1}>{children}</Box>}
{open && (
<Box mt={1} style={contentStyle}>
{children}
</Box>
)}
</Box>
);
}
Expand Down
Loading

0 comments on commit f013298

Please sign in to comment.