Skip to content

Commit

Permalink
Poster Printer (#2557)
Browse files Browse the repository at this point in the history
## About The Pull Request

Adds poster printers. Currently unmapped, so there's no way to get them
at the moment, and I recommend one gets added to the outpost.
HOW TO USE:
get a sheet of paper and a printer

![image](https://github.com/shiptest-ss13/Shiptest/assets/64121399/44bf348e-3971-4bba-8f90-8166ca893ece)
put the paper in the printer

![image](https://github.com/shiptest-ss13/Shiptest/assets/64121399/7b157f7d-35f0-4d7b-a3aa-1a66c734c75b)
click on the printer and select the kind of poster you want to print

![image](https://github.com/shiptest-ss13/Shiptest/assets/64121399/ecab5df3-9536-464b-a0db-b3dc4ae49320)
print the poster, and then remove it

![image](https://github.com/shiptest-ss13/Shiptest/assets/64121399/b59950ab-a68a-4fd2-921b-f0baeeb0f0f0)
tada! free* poster!

![image](https://github.com/shiptest-ss13/Shiptest/assets/64121399/ba917741-2b3a-494a-923f-bee6aec7ea5a)

*actually uses some toner with each use, as well as a sheet of paper

## Why It's Good For The Game

A lot of people were complaining about how there's no easy way to get
posters at the moment, so I made a convenient printing device.

## Changelog

🆑
add: Added a poster printer. Please map this later, I didn't want to
mess with mapping for now so
/🆑

---------

Signed-off-by: Moon <[email protected]>
Signed-off-by: meem <[email protected]>
Co-authored-by: meem <[email protected]>
  • Loading branch information
MoonTheBird and meemofcourse authored Jan 29, 2024
1 parent 2ba9685 commit d41cb1f
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,15 @@
/obj/item/stock_parts/capacitor = 2
)

/obj/item/circuitboard/machine/printer
name = "Poster Printer (Machine Board)"
build_path = /obj/machinery/printer
req_components = list(
/obj/item/stock_parts/scanning_module = 2,
/obj/item/stock_parts/micro_laser = 1,
/obj/item/stock_parts/manipulator = 2,
)

/obj/item/circuitboard/machine/coffeemaker
name = "Modello 3 Coffeemaker"
build_path = /obj/machinery/coffeemaker
Expand Down
185 changes: 185 additions & 0 deletions code/game/objects/structures/printer.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/obj/machinery/printer
name = "poster printer"
desc = "Used to print out various posters using toner cartridges."
icon = 'icons/obj/printer.dmi'
icon_state = "printer"
density = TRUE
power_channel = AREA_USAGE_EQUIP
max_integrity = 100
pass_flags = PASSTABLE
circuit = /obj/item/circuitboard/machine/printer
var/busy = FALSE
var/datum/weakref/loaded_item_ref
var/datum/weakref/printed_poster
var/obj/item/toner/toner_cartridge
var/poster_type

/obj/machinery/printer/Initialize()
. = ..()
toner_cartridge = new(src)

/obj/machinery/printer/update_overlays()
. = ..()
if(panel_open)
. += mutable_appearance(icon, "printer_panel")
var/obj/item/loaded = loaded_item_ref?.resolve()
var/obj/item/poster = printed_poster?.resolve()
if(loaded)
. += mutable_appearance(icon, "contain_paper")
if(poster)
. += mutable_appearance(icon, "contain_poster")

/obj/machinery/printer/screwdriver_act(mob/living/user, obj/item/screwdriver)
. = ..()
default_deconstruction_screwdriver(user, icon_state, icon_state, screwdriver)
update_icon()
return TRUE

/obj/machinery/printer/Destroy()
QDEL_NULL(toner_cartridge)
QDEL_NULL(loaded_item_ref)
QDEL_NULL(printed_poster)
return ..()

/obj/machinery/printer/attackby(obj/item/item, mob/user, params)
if(panel_open)
if(is_wire_tool(item))
wires.interact(user)
return
if(can_load_item(item))
if(!loaded_item_ref?.resolve())
loaded_item_ref = WEAKREF(item)
item.forceMove(src)
update_icon()
return
else if(istype(item, /obj/item/toner))
if(toner_cartridge)
to_chat(user, "<span class='warning'>[src] already has a toner cartridge inserted. Remove that one first.</span>")
return
item.forceMove(src)
toner_cartridge = item
to_chat(user, "<span class='notice'>You insert [item] into [src].</span>")
else return ..()

/obj/machinery/printer/proc/can_load_item(obj/item/item)
if(busy)
return FALSE //no loading the printer if there's already a print job happening!
if(!istype(item, /obj/item/paper))
return FALSE
if(!istype(item, /obj/item/stack))
return TRUE
var/obj/item/stack/stack_item = item
return stack_item.amount == 1

/obj/machinery/printer/ui_data(mob/user)
var/list/data = list()
data["has_paper"] = !!loaded_item_ref?.resolve()
data["has_poster"] = !!printed_poster?.resolve()

if(toner_cartridge)
data["has_toner"] = TRUE
data["current_toner"] = toner_cartridge.charges
data["max_toner"] = toner_cartridge.max_charges
data["has_enough_toner"] = has_enough_toner()
else
data["has_toner"] = FALSE
data["has_enough_toner"] = FALSE

return data

/obj/machinery/printer/proc/has_enough_toner()
return toner_cartridge.charges >= 1

/obj/machinery/printer/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PosterPrinter")
ui.open()

/obj/machinery/printer/ui_act(action, list/params)
. = ..()
if(.)
return
var/obj/item/poster = printed_poster?.resolve()
var/obj/item/loaded = loaded_item_ref?.resolve()
switch(action)
if("remove")
if(!loaded)
return
loaded.forceMove(drop_location())
loaded_item_ref = null
update_icon()
return TRUE
if("remove_poster")
if(!poster)
to_chat(usr, span_warning("No poster! waddaheeeeell"))
return
if(busy)
to_chat(usr, span_warning("[src] is still printing your poster! Please wait until it is finished."))
return FALSE
poster.forceMove(drop_location())
printed_poster = null
update_icon()
return TRUE
if("choose_type")
poster_type = params["poster_type"]
return TRUE
if("print")
if(busy)
to_chat(usr, span_warning("[src] is currently busy printing a poster. Please wait until it is finished."))
return FALSE
if(toner_cartridge.charges - 1 < 0)
to_chat(usr, span_warning("There is not enough toner in [src] to print the poster, please replace the cartridge."))
return FALSE
if(!loaded)
to_chat(usr, span_warning("[src] has no paper in it! Please insert a sheet of paper."))
return FALSE
if(!poster_type)
to_chat(usr, span_warning("[src] has no poster type selected! Please select a type first!"))
return FALSE
if(poster)
to_chat(usr, span_warning("[src] ejects its current poster before printing a new one."))
poster.forceMove(drop_location())
printed_poster = null
update_icon()
print_poster()
return TRUE
if("remove_toner")
if(issilicon(usr) || (ishuman(usr) && !usr.put_in_hands(toner_cartridge)))
toner_cartridge.forceMove(drop_location())
toner_cartridge = null
return TRUE

/obj/machinery/printer/proc/print_poster()
busy = TRUE
loaded_item_ref = null
playsound(src, 'sound/items/poster_being_created.ogg', 20, FALSE)
toner_cartridge.charges -= 1
icon_state = "print"
var/mutable_appearance/overlay = mutable_appearance(icon, "print_poster")
overlays += overlay
update_icon()
addtimer(CALLBACK(src, PROC_REF(print_complete), overlay), 2.6 SECONDS)

/obj/machinery/printer/proc/print_complete(mutable_appearance/remove_overlay)
icon_state = "printer"
overlays -= remove_overlay
switch(poster_type)
if("Syndicate")
var/obj/item/poster/random_contraband/poster = new()
printed_poster = WEAKREF(poster)
if("SolGov")
var/obj/item/poster/random_solgov/poster = new()
printed_poster = WEAKREF(poster)
if("Nanotrasen")
var/obj/item/poster/random_official/poster = new()
printed_poster = WEAKREF(poster)
if("RILENA")
var/obj/item/poster/random_rilena/poster = new()
printed_poster = WEAKREF(poster)
if("Nanotrasen (Retro)")
var/obj/item/poster/random_retro/poster = new()
printed_poster = WEAKREF(poster)
update_icon()
busy = FALSE
poster_type = null
7 changes: 0 additions & 7 deletions code/modules/library/lib_machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
dat += "<h3>NTGanda(tm) Universal Printing Module</h3>"
dat += "What would you like to print?<BR>"
dat += "<A href='?src=[REF(src)];printbible=1'>\[Bible\]</A><BR>"
dat += "<A href='?src=[REF(src)];printposter=1'>\[Poster\]</A><BR>"
dat += "<A href='?src=[REF(src)];switchscreen=0'>(Return to main menu)</A><BR>"
if(8)
dat += "<h3>Accessing Forbidden Lore Vault v 1.3</h3>"
Expand Down Expand Up @@ -524,12 +523,6 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
cooldown = world.time + PRINTER_COOLDOWN
else
say("Printer currently unavailable, please wait a moment.")
if(href_list["printposter"])
if(cooldown < world.time)
new /obj/item/poster/random_official(src.loc)
cooldown = world.time + PRINTER_COOLDOWN
else
say("Printer currently unavailable, please wait a moment.")
add_fingerprint(usr)
updateUsrDialog()

Expand Down
Binary file added icons/obj/printer.dmi
Binary file not shown.
1 change: 1 addition & 0 deletions shiptest.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@
#include "code\game\objects\structures\petrified_statue.dm"
#include "code\game\objects\structures\plasticflaps.dm"
#include "code\game\objects\structures\poddoor_assembly.dm"
#include "code\game\objects\structures\printer.dm"
#include "code\game\objects\structures\radioactive.dm"
#include "code\game\objects\structures\railings.dm"
#include "code\game\objects\structures\reflector.dm"
Expand Down
126 changes: 126 additions & 0 deletions tgui/packages/tgui/interfaces/PosterPrinter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { useBackend } from '../backend';
import { Box, Button, Dropdown, ProgressBar, Section } from '../components';
import { Window } from '../layouts';

export const PosterPrinter = (props, context) => {
const { act, data } = useBackend(context);
const { has_paper, has_toner, has_poster } = data;

return (
<Window title="PosterPrinter" width={320} height={512}>
<Window.Content>
{has_toner ? (
<Toner />
) : (
<Section title="Toner">
<Box color="average">No inserted toner cartridge.</Box>
</Section>
)}
{has_paper ? (
<Options />
) : (
<Section title="Options">
<Box color="average">No inserted paper.</Box>
</Section>
)}
{has_poster ? (
<Section title="Remove Poster">
<Button
mt={0.5}
textAlign="center"
icon="reply"
onClick={() => act('remove_poster')}
>
Remove poster
</Button>
</Section>
) : (
<Section title="Remove Poster">
<Box color="average">No poster printed!</Box>
</Section>
)}
</Window.Content>
</Window>
);
};

const Toner = (props, context) => {
const { act, data } = useBackend(context);
const { has_toner, max_toner, current_toner } = data;

const average_toner = max_toner * 0.66;
const bad_toner = max_toner * 0.33;

return (
<Section
title="Toner"
buttons={
<Button
disabled={!has_toner}
onClick={() => act('remove_toner')}
icon="eject"
>
Eject
</Button>
}
>
<ProgressBar
ranges={{
good: [average_toner, max_toner],
average: [bad_toner, average_toner],
bad: [0, bad_toner],
}}
value={current_toner}
minValue={0}
maxValue={max_toner}
/>
</Section>
);
};

const Options = (props, context) => {
const { act, data } = useBackend(context);
const { has_toner, poster_type } = data;

const posterTypes = [
'Syndicate',
'Nanotrasen',
'Nanotrasen (Retro)',
'RILENA',
'SolGov',
];
const selectedType = poster_type ?? 'No Poster Selected';

return (
<Section title="Options">
<Dropdown
width="100%"
options={posterTypes}
selected={selectedType}
onSelected={(value) =>
act('choose_type', {
poster_type: value,
})
}
/>
<Button
disabled={!has_toner}
fluid
icon="images"
textAlign="center"
onClick={() => act('print')}
>
Print poster
</Button>
<Button
mt={0.5}
textAlign="center"
icon="reply"
fluid
onClick={() => act('remove')}
>
Remove paper
</Button>
</Section>
);
};

0 comments on commit d41cb1f

Please sign in to comment.