Skip to content

Commit

Permalink
TGUI Misc 1 (sojourn-13#5520)
Browse files Browse the repository at this point in the history
* TGUI Guild: Bullet Fabricator

* Make RPED work to insert/upgrade components in an unfinished frame

* Allow hotswapping chem dispenser cell when panel is open

* Fix a bunch of spurious runtimes in my logs

* TGUI NTOS: Computer Vendor

* TGUI NTOS: DoS antag program

* TGUI Service: Janicart
  • Loading branch information
ShadowLarkens authored Jul 9, 2024
1 parent 9828e59 commit cf20cb5
Show file tree
Hide file tree
Showing 22 changed files with 1,075 additions and 550 deletions.
161 changes: 61 additions & 100 deletions code/game/machinery/autolathe/fabricators.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// TODO: Remove the back end beakers
// Note - For some reason the code shits itself if you try to remove the beakers and there isn't any real harm with it being there. Probably fix it later. Maybe. If I can be arsed. - Kazkin
/obj/machinery/bulletfabricator
name = "Bullet Fabricator"
desc = "A machine for producing ammo magazines, speed loaders, ammo boxes, and exotic munitions using any type of materials converted into an unknown state, \
Expand All @@ -14,13 +12,11 @@
idle_power_usage = 40
circuit = /obj/item/circuitboard/bullet_fab
var/processing = FALSE
var/obj/item/reagent_containers/glass/beaker = null
var/points = 0
var/menustat = "menu"
var/build_eff = 1
var/eat_eff = 1


var/list/recipes = list(
"9mm Speed Loader",
list(name="Speed Loader (9mm Special)", cost=30, path=/obj/item/ammo_magazine/speed_loader_pistol_35),
Expand Down Expand Up @@ -294,14 +290,6 @@
list(name="50mm HEAD ammunition box", cost=1250, path=/obj/item/mech_ammo_box/scattershot),
)

/obj/machinery/bulletfabricator/New()
..()
create_reagents(1000)
beaker = new /obj/item/reagent_containers/glass/beaker/large(src) //???

/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well.
update_icon()

/obj/machinery/bulletfabricator/update_icon()
if(!processing)
icon_state = "ammolathe"
Expand All @@ -310,82 +298,74 @@
return

/obj/machinery/bulletfabricator/attackby(var/obj/item/I, var/mob/user)

if(!check_user(user))
return

if(istype(I, /obj/item/stack/material/cyborg))
return //Prevents borgs throwing their stuff into it

if(default_deconstruction(I, user))
return

if(default_part_replacement(I, user))
return

if(processing)
to_chat(user, SPAN_NOTICE("\The [src] is currently processing."))
to_chat(user, SPAN_NOTICE("[src] is currently processing."))
else if(!istype(I, /obj/item/stack/material) && !istype(I, /obj/item/stack/material/refined_scrap))
to_chat(user, SPAN_NOTICE("You cannot put this in \the [src]."))
to_chat(user, SPAN_NOTICE("You cannot put this in [src]."))
else
var/i = 0
for(var/obj/item/stack/material/G in contents)
i++
if(i >= 120)
to_chat(user, SPAN_NOTICE("\The [src] is full! Activate it."))
to_chat(user, SPAN_NOTICE("[src] is full! Activate it."))
else
user.remove_from_mob(I)
I.loc = src
to_chat(user, SPAN_NOTICE("You put \the [I] in \the [src]"))
I.forceMove(src)
to_chat(user, SPAN_NOTICE("You put [I] in [src]"))

update_icon()
return

/obj/machinery/bulletfabricator/nano_ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = NANOUI_FOCUS, var/datum/nano_topic_state/state =GLOB.outside_state)
user.set_machine(src)
/obj/machinery/bulletfabricator/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "BulletFabricator", name)
ui.open()

/obj/machinery/bulletfabricator/ui_static_data(mob/user)
var/list/data = list()
data["points"] = points
if(menustat == "menu")
data["beaker"] = beaker
if(beaker)

var/list/tmp_recipes = list()
for(var/smth in recipes)
if(istext(smth))
tmp_recipes += list(list(
"is_category" = TRUE,
"name" = smth,
))
else
var/list/L = smth
tmp_recipes += list(list(
"is_category" = FALSE,
"name" = L["name"],
"cost" = round(L["cost"]/build_eff),
"allow_multiple" = L["allow_multiple"],
))
var/list/recipes_data = list()

for(var/id in recipes)
if(istext(id))
recipes_data += list(list(
"is_category" = TRUE,
"name" = id,
))
else
recipes_data += list(list(
"is_category" = FALSE,
"name" = id["name"],
"cost" = round(id["cost"] / build_eff)
))

data["recipes"] = recipes_data

data["recipes"] = tmp_recipes
return data

/obj/machinery/bulletfabricator/ui_data(mob/user)
var/list/data = list()

data["points"] = points
data["menustate"] = menustat
data["processing"] = processing
data["menustat"] = menustat
if(menustat == "menu")
data["beaker"] = beaker

ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "bulletfabricator.tmpl", "Munitions Fabricator", 550, 655)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
return data

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

user.set_machine(src)
nano_ui_interact(user)
ui_interact(user)

/obj/machinery/bulletfabricator/proc/activate()
if (usr.stat)
Expand All @@ -399,24 +379,21 @@
for(var/obj/item/stack/I in contents)
S += 5
points += I.amount * I.price_tag * 5
//if(I.reagents.get_reagent_amount("nutriment") < 0.1)
// points += 1
//else points += I.reagents.get_reagent_amount("nutriment") * 8 * eat_eff
qdel(I)
if(S)
processing = TRUE
update_icon()
updateUsrDialog()
playsound(src.loc, 'sound/sanity/hydraulic.ogg', 50, 1)
playsound(loc, 'sound/sanity/hydraulic.ogg', 50, 1)
use_power(S * 30)
spawn((1 + S * 0.5) / eat_eff) //Max stack with t1 is 61 / 1 so long time
processing = FALSE
update_icon()
addtimer(CALLBACK(src, PROC_REF(finish_processing)), (1 + S * 0.5) / eat_eff)
else
menustat = "void"
return

/obj/machinery/bulletfabricator/proc/create_product(var/item, var/amount)
/obj/machinery/bulletfabricator/proc/finish_processing()
processing = FALSE
update_icon()

/obj/machinery/bulletfabricator/proc/create_product(item)
var/list/recipe = null
if(processing)
return
Expand All @@ -428,12 +405,7 @@
if(!recipe)
return

if(!("allow_multiple" in recipe))
amount = 1
else
amount = max(amount, 1)

var/cost = recipe["cost"] * amount / build_eff
var/cost = recipe["cost"] / build_eff

if(cost > points)
menustat = "nopoints"
Expand All @@ -443,39 +415,28 @@
update_icon()
updateUsrDialog() //maybe we can remove it
points -= cost
spawn(cost / eat_eff * 0.1) //Insainly quick do to being made to mass create ammo
addtimer(CALLBACK(src, PROC_REF(finish_creating_product), recipe["path"]), cost / eat_eff * 0.1)

var/creating = recipe["path"]
var/reagent = recipe["reagent"]
if(reagent) //For reagents like milk
beaker.reagents.add_reagent(reagent, 30)
else
for(var/i in 1 to amount)
new creating(loc)
processing = FALSE
menustat = "menu" //complete adds an extra step thats annoying to deal with
update_icon()
return
/obj/machinery/bulletfabricator/proc/finish_creating_product(path)
new path(loc)
menustat = "menu" //complete adds an extra step thats annoying to deal with
finish_processing()

/obj/machinery/bulletfabricator/Topic(href, href_list)
if(stat & BROKEN) return
if(usr.stat || usr.restrained()) return
if(!in_range(src, usr)) return
usr.set_machine(src)
/obj/machinery/bulletfabricator/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return

switch(href_list["action"])
switch(action)
if("activate")
activate()
if("detach")
if(beaker)
beaker.loc = src.loc
beaker = null
update_icon()
. = TRUE
if("create")
create_product(href_list["item"], text2num(href_list["amount"]))
if("menu")
create_product(params["item"])
. = TRUE
if("reset_menu")
menustat = "menu"
updateUsrDialog()
. = TRUE

/obj/machinery/bulletfabricator/RefreshParts()
..()
Expand Down
47 changes: 46 additions & 1 deletion code/game/machinery/constructable_frame.dm
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,10 @@
to_chat(user, SPAN_WARNING("This frame does not accept circuit boards of this type!"))

if(STATE_CIRCUIT)
if(istype(I, /obj/item/storage/part_replacer))
handle_part_replacer(I, user)

if(istype(I, /obj/item))
else if(istype(I, /obj/item))
for(var/CM in req_components)
if(istype(I, CM) && (req_components[CM] > 0))
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
Expand Down Expand Up @@ -212,6 +214,49 @@
examine(user)
update_icon()

/obj/machinery/constructable_frame/machine_frame/proc/handle_part_replacer(obj/item/storage/part_replacer/R, mob/user)
// Ahead of time prepping for bluespace RPED calling into this directly
if(state != STATE_CIRCUIT || !req_components)
return

var/took_something = FALSE

for(var/obj/item/stock_parts/replacement in R.contents)
// This is a cursed double loop but we have to do it this way because we have to use the CM path key
// and also check if the replacement passes istype
for(var/CM in req_components)
if(!istype(replacement, CM))
continue

// Found something
// Get some new parts from the part replacer
if(req_components[CM] > 0)
took_something = TRUE
R.remove_from_storage(replacement, src)
components += replacement
req_components[CM]--
to_chat(usr, SPAN_NOTICE("[replacement] installed in [src]."))
continue // no-op but we'll be explicit
else
// Try to replace existing parts
for(var/obj/item/stock_parts/installed in components)
if(istype(installed, CM))
if(replacement.rating > installed.rating)
took_something = TRUE
// Replacing worse components
R.remove_from_storage(replacement, src)
R.handle_item_insertion(installed, 1)
components -= installed
components += replacement
to_chat(usr, SPAN_NOTICE("[installed] replaced with [replacement]."))
break // We took replacement, break out of our component loop

if(took_something)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
examine(user)
else
to_chat(usr, SPAN_WARNING("No items in [R] could be loaded into [src]."))

/obj/machinery/constructable_frame/machine_frame/MouseDrop_T(obj/A, mob/user, src_location, over_location, src_control, over_control, params)
if(istype(A, /obj/item))
attackby(A, user)
Expand Down
4 changes: 2 additions & 2 deletions code/game/machinery/doors/door.dm
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,8 @@

set_opacity(0)
if(istype(src, /obj/machinery/door/airlock/multi_tile/metal))
f5.set_opacity(0)
f6.set_opacity(0)
f5?.set_opacity(0)
f6?.set_opacity(0)

do_animate("opening")
icon_state = "door0"
Expand Down
Loading

0 comments on commit cf20cb5

Please sign in to comment.