Files
Bubberstation/code/game/machinery/constructable_frame.dm
SkyratBot 8d7b5ddc55 [MIRROR] Stops machine frames and circuitboards referring to manipulators as micro-manipulators [MDB IGNORE] (#12422)
* Stops machine frames and circuitboards referring to manipulators as micro-manipulators (#64878)

About The Pull Request

    Gives stock parts a base_name variable and sets it to manipulator for micro-manipulators
    Reorders sprites of stock parts in stock_parts.dmi to be together and in order of tier. Image
    Makes component part lists on machine frames and circuitboards nicer and makes them identical between the two
    Improves code for generating these lists
    Adds numtotext() proc which these lists use

Why It's Good For The Game

    Solves the issue where examining machines says they require a micro-manipulator when any manipulator will do
    Makes sprites easier to find
    Wows players by using actual words for numbers in generated parts lists
    Cleans up ancient code
    This proc can be used for other things, e.g. station names (which I have now incorporated it into)

Changelog

cl
fix: Machine frames and circuit boards no longer call manipulators micro-manipulators when examined
code: Improves code in constructable_frame.dm and circuitboard.dm
/cl

* Stops machine frames and circuitboards referring to manipulators as micro-manipulators

Co-authored-by: cacogen <25089914+cacogen@users.noreply.github.com>
2022-04-01 00:12:13 +01:00

315 lines
10 KiB
Plaintext

/obj/structure/frame
name = "frame"
icon = 'icons/obj/stock_parts.dmi'
icon_state = "box_0"
density = TRUE
max_integrity = 250
var/obj/item/circuitboard/machine/circuit = null
var/state = 1
/obj/structure/frame/examine(user)
. = ..()
if(circuit)
. += "It has \a [circuit] installed."
/obj/structure/frame/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/sheet/iron(loc, 5)
if(circuit)
circuit.forceMove(loc)
circuit = null
qdel(src)
/obj/structure/frame/machine
name = "machine frame"
var/list/components = null
var/list/req_components = null
var/list/req_component_names = null // user-friendly names of components
/obj/structure/frame/machine/examine(user)
. = ..()
if(state != 3)
return
if(!length(req_components))
. += span_info("It requires no components.")
return .
if(!req_component_names)
stack_trace("[src]'s req_components list has items but its req_component_names list is null!")
return
var/list/nice_list = list()
for(var/atom/component as anything in req_components)
if(!ispath(component))
stack_trace("An item in [src]'s req_components list is not a path!")
continue
if(!req_components[component])
continue
nice_list += list("[req_components[component]] [req_component_names[component]]\s")
. += span_info("It requires [english_list(nice_list, "no more components")].")
/obj/structure/frame/machine/proc/update_namelist()
if(!req_components)
return
req_component_names = list()
for(var/atom/component_path as anything in req_components)
if(!ispath(component_path))
continue
req_component_names[component_path] = initial(component_path.name)
if(ispath(component_path, /obj/item/stack))
var/obj/item/stack/stack_path = component_path
if(initial(stack_path.singular_name))
req_component_names[component_path] = initial(stack_path.singular_name)
continue
if(ispath(component_path, /obj/item/stock_parts))
var/obj/item/stock_parts/stock_part = component_path
if(initial(stock_part.base_name))
req_component_names[component_path] = initial(stock_part.base_name)
/obj/structure/frame/machine/proc/get_req_components_amt()
var/amt = 0
for(var/path in req_components)
amt += req_components[path]
return amt
/obj/structure/frame/machine/attackby(obj/item/P, mob/living/user, params)
switch(state)
if(1)
if(istype(P, /obj/item/circuitboard/machine))
to_chat(user, span_warning("The frame needs wiring first!"))
return
else if(istype(P, /obj/item/circuitboard))
to_chat(user, span_warning("This frame does not accept circuit boards of this type!"))
return
if(istype(P, /obj/item/stack/cable_coil))
if(!P.tool_start_check(user, amount=5))
return
to_chat(user, span_notice("You start to add cables to the frame..."))
if(P.use_tool(src, user, 20, volume=50, amount=5))
to_chat(user, span_notice("You add cables to the frame."))
state = 2
icon_state = "box_1"
return
if(P.tool_behaviour == TOOL_SCREWDRIVER && !anchored)
user.visible_message(span_warning("[user] disassembles the frame."), \
span_notice("You start to disassemble the frame..."), span_hear("You hear banging and clanking."))
if(P.use_tool(src, user, 40, volume=50))
if(state == 1)
to_chat(user, span_notice("You disassemble the frame."))
var/obj/item/stack/sheet/iron/M = new (loc, 5)
if (!QDELETED(M))
M.add_fingerprint(user)
qdel(src)
return
if(P.tool_behaviour == TOOL_WRENCH)
var/turf/ground = get_turf(src)
if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
to_chat(user, span_notice("You fail to secure [src]."))
return
to_chat(user, span_notice("You start [anchored ? "un" : ""]securing [src]..."))
if(P.use_tool(src, user, 40, volume=75))
if(state == 1)
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
set_anchored(!anchored)
return
if(2)
if(P.tool_behaviour == TOOL_WRENCH)
to_chat(user, span_notice("You start [anchored ? "un" : ""]securing [src]..."))
if(P.use_tool(src, user, 40, volume=75))
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
set_anchored(!anchored)
return
if(istype(P, /obj/item/circuitboard/machine))
var/obj/item/circuitboard/machine/B = P
if(!B.build_path)
to_chat(user, span_warning("This circuitboard seems to be broken."))
return
if(!anchored && B.needs_anchored)
to_chat(user, span_warning("The frame needs to be secured first!"))
return
if(!user.transferItemToLoc(B, src))
return
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
to_chat(user, span_notice("You add the circuit board to the frame."))
circuit = B
icon_state = "box_2"
state = 3
components = list()
req_components = B.req_components.Copy()
update_namelist()
return
else if(istype(P, /obj/item/circuitboard))
to_chat(user, span_warning("This frame does not accept circuit boards of this type!"))
return
if(P.tool_behaviour == TOOL_WIRECUTTER)
P.play_tool_sound(src)
to_chat(user, span_notice("You remove the cables."))
state = 1
icon_state = "box_0"
new /obj/item/stack/cable_coil(drop_location(), 5)
return
if(3)
if(P.tool_behaviour == TOOL_CROWBAR)
P.play_tool_sound(src)
state = 2
circuit.forceMove(drop_location())
components.Remove(circuit)
circuit = null
if(components.len == 0)
to_chat(user, span_notice("You remove the circuit board."))
else
to_chat(user, span_notice("You remove the circuit board and other components."))
for(var/atom/movable/AM in components)
AM.forceMove(drop_location())
desc = initial(desc)
req_components = null
components = null
icon_state = "box_1"
return
if(P.tool_behaviour == TOOL_WRENCH && !circuit.needs_anchored)
to_chat(user, span_notice("You start [anchored ? "un" : ""]securing [src]..."))
if(P.use_tool(src, user, 40, volume=75))
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
set_anchored(!anchored)
return
if(P.tool_behaviour == TOOL_SCREWDRIVER)
var/component_check = TRUE
for(var/R in req_components)
if(req_components[R] > 0)
component_check = FALSE
break
if(component_check)
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc)
if(istype(new_machine))
// Machines will init with a set of default components. Move to nullspace so we don't trigger handle_atom_del, then qdel.
// Finally, replace with this frame's parts.
if(new_machine.circuit)
// Move to nullspace and delete.
new_machine.circuit.moveToNullspace()
QDEL_NULL(new_machine.circuit)
for(var/obj/old_part in new_machine.component_parts)
// Move to nullspace and delete.
old_part.moveToNullspace()
qdel(old_part)
// Set anchor state and move the frame's parts over to the new machine.
// Then refresh parts and call on_construction().
new_machine.set_anchored(anchored)
new_machine.component_parts = list()
circuit.forceMove(new_machine)
new_machine.component_parts += circuit
new_machine.circuit = circuit
for(var/obj/new_part in src)
new_part.forceMove(new_machine)
new_machine.component_parts += new_part
new_machine.RefreshParts()
new_machine.on_construction()
qdel(src)
return
if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt())
var/obj/item/storage/part_replacer/replacer = P
var/list/added_components = list()
var/list/part_list = list()
//Assemble a list of current parts, then sort them by their rating!
for(var/obj/item/co in replacer)
part_list += co
//Sort the parts. This ensures that higher tier items are applied first.
part_list = sortTim(part_list, /proc/cmp_rped_sort)
for(var/path in req_components)
while(req_components[path] > 0 && (locate(path) in part_list))
var/obj/item/part = (locate(path) in part_list)
part_list -= part
if(istype(part,/obj/item/stack))
var/obj/item/stack/S = part
var/used_amt = min(round(S.get_amount()), req_components[path])
if(!used_amt || !S.use(used_amt))
continue
var/NS = new S.merge_type(src, used_amt)
added_components[NS] = path
req_components[path] -= used_amt
else
added_components[part] = path
if(SEND_SIGNAL(replacer, COMSIG_TRY_STORAGE_TAKE, part, src))
req_components[path]--
for(var/obj/item/part in added_components)
if(istype(part,/obj/item/stack))
var/obj/item/stack/incoming_stack = part
for(var/obj/item/stack/merge_stack in components)
if(incoming_stack.can_merge(merge_stack))
incoming_stack.merge(merge_stack)
if(QDELETED(incoming_stack))
break
if(!QDELETED(part)) //If we're a stack and we merged we might not exist anymore
components += part
part.forceMove(src)
to_chat(user, span_notice("You add [part] to [src]."))
if(added_components.len)
replacer.play_rped_sound()
return
if(isitem(P) && get_req_components_amt())
for(var/I in req_components)
if(istype(P, I) && (req_components[I] > 0))
if(istype(P, /obj/item/stack))
var/obj/item/stack/S = P
var/used_amt = min(round(S.get_amount()), req_components[I])
if(used_amt && S.use(used_amt))
var/obj/item/stack/NS = locate(S.merge_type) in components
if(!NS)
NS = new S.merge_type(src, used_amt)
components += NS
else
NS.add(used_amt)
req_components[I] -= used_amt
to_chat(user, span_notice("You add [P] to [src]."))
return
if(!user.transferItemToLoc(P, src))
break
to_chat(user, span_notice("You add [P] to [src]."))
components += P
req_components[I]--
return TRUE
to_chat(user, span_warning("You cannot add that to the machine!"))
return FALSE
if(user.combat_mode)
return ..()
/obj/structure/frame/machine/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(state >= 2)
new /obj/item/stack/cable_coil(loc , 5)
for(var/X in components)
var/obj/item/I = X
I.forceMove(loc)
..()