Skip to content

Commit

Permalink
feat: Photocopier blanks and TGUI port (Rebased) (#148)
Browse files Browse the repository at this point in the history
<!-- Пишите **НИЖЕ** заголовков и **ВЫШЕ** комментариев, иначе что то
может пойти не так. -->
<!-- Вы можете прочитать Contributing.MD, если хотите узнать больше. -->

В принтер добавлены бюрократические формы с парашизы
Код полностью... практически полностью соответствует парашизовскому,
если не хуже, так что можно сказать я НАСРАЛ.
В будущем думаю переписать весь UI и добавить сканер как у оффовского,
поиск в бланки, и выпадающее меню, в общем, справа должны быть только
бланки
<!-- Вкратце опишите изменения, которые вносите. -->
<!-- Опишите **все** изменения, так как противное может сказаться на
рассмотрении этого PR'а! -->
<!-- Если вы исправляете Issue, добавьте "Fixes #1234" (где 1234 - номер
Issue) где-нибудь в описании PR'а. Это автоматически закроет Issue после
принятия PR'а. -->

Больше бланков богу бланков, не надо ручками писать
<!-- Опишите, почему, по вашему, следует добавить эти изменения в игру.
-->

![image](https://github.com/ss220club/Paradise-Remake/assets/69762909/1f8198ea-bbb8-4b84-a8d5-c6c10f5a6a5d)

<!-- Если вы не меняли карту или спрайты, можете опустить эту секцию.
Если хотите, можете вставить видео. -->

Тыкал кнопочки, в том числе за ИИ
Есть пара багов, если выставить 0 копий и пытаться распечатать фотку
жопы, звук будет стакаться и разрывать уши.
Не понимаю зачем кнопка с папкой, на офф тгуи она по всей видимости тоже
ничего не делает, кроме возможности хранить папку.
<!-- Как вы тестировали свой PR, если делали это вовсе? -->

:cl:
add: Добавлены бланки в ксерокс.
/:cl:

<!-- Оба :cl:'а должны быть на месте, что-бы чейнджлог работал! Вы
можете написать свой ник справа от первого :cl:, если хотите. Иначе
будет использован ваш ник на ГитХабе. -->
<!-- Вы можете использовать несколько записей с одинаковым префиксом
(Они используются только для иконки в игре) и удалить ненужные. Помните,
что чейнджлог должен быть понятен обычным игроком. -->
<!-- Если чейнджлог не влияет на игроков(например, это рефактор), вы
можете исключить всю секцию. -->

---------

Co-authored-by: Furior <[email protected]>
Co-authored-by: Furior <[email protected]>
Co-authored-by: Henri215 <[email protected]>
  • Loading branch information
4 people committed Oct 22, 2023
1 parent cde62cb commit 9d91610
Show file tree
Hide file tree
Showing 7 changed files with 925 additions and 0 deletions.
9 changes: 9 additions & 0 deletions modular_ss220/bureaucracy/_bureaucracy.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/datum/modpack/bureaucracy
name = "Бюрократия"
desc = "Добавляет бланки в ксерокс."
author = "Aylong220, Furior, RV666"

/datum/modpack/bureaucracy/initialize()
. = ..()
for(var/datum/bureaucratic_form/form as anything in subtypesof(/datum/bureaucratic_form))
GLOB.bureaucratic_forms["[form]"] = new form
5 changes: 5 additions & 0 deletions modular_ss220/bureaucracy/_bureaucracy.dme
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "_bureaucracy.dm"

#include "code/paper.dm"
#include "code/forms.dm"
#include "code/photocopier.dm"
539 changes: 539 additions & 0 deletions modular_ss220/bureaucracy/code/forms.dm

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions modular_ss220/bureaucracy/code/paper.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/obj/item/paper
var/paper_width_big = 600
var/paper_height_big = 700
var/small_paper_cap = 1024
var/force_big = FALSE

/obj/item/paper/updateinfolinks()
. = ..()
update_size()

/obj/item/paper/proc/update_size()
if(force_big || length(info) > small_paper_cap)
become_big()
else
reset_size()

/obj/item/paper/proc/become_big()
paper_width = paper_width_big
paper_height = paper_height_big

/obj/item/paper/proc/reset_size()
paper_width = initial(paper_width)
paper_height = initial(paper_height)
113 changes: 113 additions & 0 deletions modular_ss220/bureaucracy/code/photocopier.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/obj/machinery/photocopier
/// Selected form's category
var/category = ""
/// Selected form's id
var/form_id = ""
/// List of available forms
var/list/forms
/// Selected form's datum
var/datum/bureaucratic_form/form
/// Printing sound
var/print_sound = 'sound/goonstation/machines/printer_dotmatrix.ogg'

/obj/machinery/photocopier/Initialize(mapload)
. = ..()
forms = new

/obj/machinery/photocopier/attack_ai(mob/user)
add_hiddenprint(user)
parse_forms(user)
ui_interact(user)
return attack_hand(user)

/obj/machinery/photocopier/attack_ghost(mob/user)
ui_interact(user)
return attack_hand(user)

/obj/machinery/photocopier/attack_hand(mob/user)
if(..())
return TRUE

user.set_machine(src)
parse_forms(user)
ui_interact(user)

/obj/machinery/photocopier/ui_act(action, list/params)
if(..())
return

switch(action)
if("print_form")
for(var/i in 1 to copies)
if(toner <= 0)
break
print_form(form)
use_power(active_power_consumption)
sleep(15)
. = TRUE
if("choose_form")
form = GLOB.bureaucratic_forms[params["path"]]
form_id = params["id"]
. = TRUE
if("choose_category")
category = params["category"]
. = TRUE
if("aipic")
aipic()
. = TRUE

/obj/machinery/photocopier/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, "Photocopier220", name, 650, 635, master_ui, state)
ui.open()

/obj/machinery/photocopier/ui_data(mob/user)
if(!length(forms))
parse_forms(user)

var/list/data = list()

data["isAI"] = issilicon(user)
data["copynumber"] = copies
data["toner"] = toner
data["copyitem"] = (copyitem ? copyitem.name : null)
data["folder"] = (folder ? folder.name : null)
data["mob"] = (copymob ? copymob.name : null)
data["files"] = list()
data["form"] = form
data["category"] = category
data["form_id"] = form_id
data["forms"] = forms

if(LAZYLEN(saved_documents))
for(var/obj/item/O in saved_documents)
var/list/document_data = list(
name = O.name,
uid = O.UID()
)
data["files"] += list(document_data)
return data

/obj/machinery/photocopier/proc/parse_forms(mob/user)
var/list/access = user.get_access()
forms.Cut()
for(var/path in GLOB.bureaucratic_forms)
var/datum/bureaucratic_form/F = GLOB.bureaucratic_forms[path]
var/req_access = F.req_access
if(req_access && !(req_access in access))
continue
var/form[0]
form["path"] = F.type
form["id"] = F.id
form["altername"] = F.altername
form["category"] = F.category
forms.Add(list(form))

/obj/machinery/photocopier/proc/print_form(datum/bureaucratic_form/form)
playsound(loc, print_sound, 25, TRUE)
toner--
if(toner <= 0)
visible_message("<span class='notice'>На [src] мигает красная лампочка. Похоже, закончился тонер.</span>")
var/obj/item/paper/paper = new(loc)
form.apply_to_paper(paper, usr)
1 change: 1 addition & 0 deletions modular_ss220/modular_ss220.dme
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

// --- MISC --- //
#include "aesthetics_sounds/_aesthetics_sounds.dme"
#include "bureaucracy/_bureaucracy.dme"
#include "crawl_speed/_crawl_speed.dme"
#include "discord_link/_discord_link.dme"
#include "emotes/_emotes.dme"
Expand Down
235 changes: 235 additions & 0 deletions tgui/packages/tgui/interfaces/Photocopier220.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
import { useBackend, useLocalState } from '../backend';
import { Button, Section, Flex, Input } from "../components";
import { Window } from '../layouts';
import { filter, sortBy } from 'common/collections';
import { FlexItem } from '../components/Flex';
import { flow } from 'common/fp';
import { createSearch } from 'common/string';

String.prototype.trimLongStr = function (length) {
return this.length > length ? this.substring(0, length) + "..." : this;
};

const selectForms = (forms, searchText = '') => {
const testSearch = createSearch(searchText, (form) => form.altername);
return flow([
filter((form) => form?.altername),
searchText && filter(testSearch),
sortBy((form) => form.id),
])(forms);
};


export const Photocopier220 = (props, context) => {
const { act, data } = useBackend(context);

const [searchText, setSearchText] = useLocalState(context, 'searchText', '');

const forms = selectForms(sortBy(form => form.category)(data.forms || []), searchText);
const categories = [];
for (let form of forms) {
if (!categories.includes(form.category)) {
categories.push(form.category);
}
}

let category;
if (data.category === "") {
category = forms;
} else {
category = forms.filter(form => form.category === data.category);
}

return (
<Window theme={data.ui_theme}>
<Window.Content
scrollable
display="flex">
<Flex
direction="row"
spacing={1}>
<Flex.Item
width={24}
shrink={0}>
<Section
title="Статус">
<Flex>
<Flex.Item mr="20px" color="grey">
Заряд тонера:
</Flex.Item>
<Flex.Item mr="5px" color={data.toner > 0 ? "good" : "bad"} bold>
{data.toner}
</Flex.Item>
</Flex>
<Flex>
<Flex.Item width="100%" mt="8px">
<Button
fluid
textAlign="center"
disabled={!data.copyitem && !data.mob}
content={
data.copyitem
? data.copyitem
: data.mob
? "Жопа " + data.mob + "!"
: 'Слот для документа'
}
onClick={() => act('removedocument')}
/>
</Flex.Item>
</Flex>
<Flex>
<Flex.Item width="100%" mt="3px">
<Button
fluid
textAlign="center"
disabled={!data.folder}
content={data.folder ? data.folder : 'Слот для папки'}
onClick={() => act('removefolder')}
/>
</Flex.Item>
</Flex>
</Section>
<Section
title="Управление">
<Flex>
<Flex.Item width="60%" mr="3px">
<Button
fluid
textAlign="center"
icon="clone"
content="Копия"
disabled={data.toner === 0 || !data.copyitem && !data.mob}
onClick={() => act("copy")}
/>
</Flex.Item>
<Flex.Item width="40%" mr="3px">
<Button
fluid
textAlign="center"
icon="file"
disabled={data.toner === 0 || data.form === null}
content="Печать"
onClick={() => act("print_form")}
/>
</Flex.Item>
</Flex>
<Flex>
<Flex.Item width="100%" mr="5px">
{!!data.isAI && (
<Button
fluid
textAlign="center"
icon="terminal"
disabled={data.toner < 5}
content="Фото из БД"
onClick={() => act("aipic")}
/>
)}
</Flex.Item>
</Flex>
<Flex>
<Flex.Item mr="10px" mt="10px" color="grey">
Количество:
</Flex.Item>
<Flex.Item mr="15px" mt="10px">
{data.copynumber}
</Flex.Item>
<Flex.Item mr="3px" mt="8px">
<Button
fluid
icon="minus"
textAlign="center"
disabled={data.copynumber === 1}
content=""
onClick={() => act('minus')}
/>
</Flex.Item>
<Flex.Item mr="3px" mt="8px">
<Button
fluid
icon="plus"
textAlign="center"
disabled={data.copynumber >= data.toner}
content=""
onClick={() => act('add')}
/>
</Flex.Item>
</Flex>
</Section>
<Section
title="Бюрократия">
<Flex>
<Flex.Item mr="20px" color="grey">
Форма:
</Flex.Item>
<FlexItem bold>
{data.form_id === "" ? "Не выбрана" : data.form_id}
</FlexItem>
</Flex>
<Flex
direction="column"
mt={2}>
<Flex.Item>
<Button
fluid
icon="chevron-right"
content="Все формы"
selected={data.category === "" ? "selected" : null}
onClick={() => act("choose_category", {
category: null,
})}
mb={1}
/>
</Flex.Item>
{categories.map(category => (
<Flex.Item key={category}>
<Button fluid key={category}
icon="chevron-right"
content={category}
selected={data.category === category ? "selected" : null}
onClick={() => act("choose_category", {
category: category,
})}
mb={1}
/>
</Flex.Item>
))}
</Flex>
</Section>
</Flex.Item>
<Flex.Item
width={35}>
<Section
title={data.category === "" ? "Все формы" : data.category}>
<Input
fluid
mb={1}
placeholder="Поиск формы"
onInput={(e, value) => setSearchText(value)}
/>
<Flex
direction="column"
mt={2}>
{category.map(form => (
<Flex.Item key={form.path}>
<Button fluid key={form.path}
content={form.id + ": " + form.altername.trimLongStr(27)}
tooltip={form.id + ": " + form.altername}
selected={data.form_id === form.id ? "selected" : null}
onClick={() => act("choose_form", {
path: form.path,
id: form.id,
})}
mb={1}
/>
</Flex.Item>
))}
</Flex>
</Section>
</Flex.Item>
</Flex>
</Window.Content>
</Window>
);
};

0 comments on commit 9d91610

Please sign in to comment.