Smith Expansion - Smith + Xenobiology = Energy Guns (#29040)

* Initial Commit

* Small adjustment

* Vendor stock update

* Icon states

* Finished merge, fixed runtimes, coded properly now

* Mapped in assemblers

* Swapped bluespace slime and sepia slime guns

* Replaced scatter laser with eshotgun

---------

Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
This commit is contained in:
PollardTheDragon
2025-05-10 20:25:04 +00:00
committed by GitHub
parent 6c405f0d5e
commit a7b5c28f77
17 changed files with 285 additions and 8 deletions
+11
View File
@@ -1097,6 +1097,17 @@ to destroy them and players will be able to make replacements.
/obj/item/stock_parts/manipulator = 3,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/scientific_assembler
board_name = "Scientific Assembler"
icon_state = "supply"
build_path = /obj/machinery/smithing/scientific_assembler
board_type = "machine"
origin_tech = "programming=1;engineering=4"
req_components = list(
/obj/item/stock_parts/micro_laser = 1,
/obj/item/stock_parts/manipulator = 3,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/ore_redemption
board_name = "Ore Redemption"
icon_state = "supply"
+1
View File
@@ -367,6 +367,7 @@
/obj/item/smithing_cast/component/lens_focus = 3,
/obj/item/smithing_cast/component/lens_frame = 3,
/obj/item/smithing_cast/component/trim = 3,
/obj/item/smithing_cast/misc/egun_parts = 3,
/obj/item/storage/bag/smith = 2,
/obj/item/storage/box/crewvend = 1)
@@ -582,6 +582,16 @@
build_path = /obj/item/circuitboard/kinetic_assembler
category = list ("Misc. Machinery")
/datum/design/scientific_assembler
name = "Machine Design (Kinetic Assembler)"
desc = "The circuit board for a Kinetic Assembler."
id = "scientific_assembler"
req_tech = list("programming" = 2, "engineering" = 4, "plasmatech" = 3)
build_type = IMPRINTER
materials = list(MAT_GLASS = 1000)
build_path = /obj/item/circuitboard/scientific_assembler
category = list ("Misc. Machinery")
/datum/design/mining_equipment_vendor
name = "Machine Design (Mining Rewards Vendor Board)"
desc = "The circuit board for a Mining Rewards Vendor."
@@ -17,6 +17,8 @@
var/Uses = 1
/// The mob who last injected the extract with plasma, water or blood. Used for logging.
var/mob/living/injector_mob
/// The gun type associated with the extract
var/obj/item/gun/energy/associated_gun_type
/obj/item/slime_extract/attackby__legacy__attackchain(obj/item/O, mob/user)
if(istype(O, /obj/item/slimepotion/enhancer))
@@ -41,86 +43,107 @@
/obj/item/slime_extract/gold
name = "gold slime extract"
icon_state = "gold slime extract"
associated_gun_type = /obj/item/gun/energy/gun/shotgun
/obj/item/slime_extract/silver
name = "silver slime extract"
icon_state = "silver slime extract"
associated_gun_type = /obj/item/gun/energy/disabler/smg
/obj/item/slime_extract/metal
name = "metal slime extract"
icon_state = "metal slime extract"
associated_gun_type = /obj/item/gun/energy/gun/mini
/obj/item/slime_extract/purple
name = "purple slime extract"
icon_state = "purple slime extract"
associated_gun_type = /obj/item/gun/energy/disabler
/obj/item/slime_extract/darkpurple
name = "dark purple slime extract"
icon_state = "dark purple slime extract"
associated_gun_type = /obj/item/gun/energy/laser
/obj/item/slime_extract/orange
name = "orange slime extract"
icon_state = "orange slime extract"
associated_gun_type = /obj/item/gun/energy/gun/mini
/obj/item/slime_extract/yellow
name = "yellow slime extract"
icon_state = "yellow slime extract"
associated_gun_type = /obj/item/gun/energy/ionrifle/carbine
/obj/item/slime_extract/red
name = "red slime extract"
icon_state = "red slime extract"
associated_gun_type = /obj/item/gun/energy/plasma_pistol
/obj/item/slime_extract/blue
name = "blue slime extract"
icon_state = "blue slime extract"
associated_gun_type = /obj/item/gun/energy/disabler
/obj/item/slime_extract/darkblue
name = "dark blue slime extract"
icon_state = "dark blue slime extract"
associated_gun_type = /obj/item/gun/energy/gun
/obj/item/slime_extract/pink
name = "pink slime extract"
icon_state = "pink slime extract"
associated_gun_type = /obj/item/gun/energy/gun/blueshield
/obj/item/slime_extract/green
name = "green slime extract"
icon_state = "green slime extract"
associated_gun_type = /obj/item/gun/projectile/automatic/laserrifle
/obj/item/slime_extract/lightpink
name = "light pink slime extract"
icon_state = "light pink slime extract"
associated_gun_type = /obj/item/gun/energy/arc_revolver
/obj/item/slime_extract/black
name = "black slime extract"
icon_state = "black slime extract"
associated_gun_type = /obj/item/gun/energy/lasercannon
/obj/item/slime_extract/oil
name = "oil slime extract"
icon_state = "oil slime extract"
associated_gun_type = /obj/item/gun/energy/immolator
/obj/item/slime_extract/adamantine
name = "adamantine slime extract"
icon_state = "adamantine slime extract"
associated_gun_type = /obj/item/gun/energy/gun/nuclear
/obj/item/slime_extract/bluespace
name = "bluespace slime extract"
icon_state = "bluespace slime extract"
associated_gun_type = /obj/item/gun/energy/sparker
/obj/item/slime_extract/pyrite
name = "pyrite slime extract"
icon_state = "pyrite slime extract"
associated_gun_type = /obj/item/gun/energy/gun/mini
/obj/item/slime_extract/cerulean
name = "cerulean slime extract"
icon_state = "cerulean slime extract"
associated_gun_type = /obj/item/gun/energy/gun/shotgun
/obj/item/slime_extract/sepia
name = "sepia slime extract"
icon_state = "sepia slime extract"
associated_gun_type = /obj/item/gun/energy/laser/retro
/obj/item/slime_extract/rainbow
name = "rainbow slime extract"
icon_state = "rainbow slime extract"
associated_gun_type = /obj/item/gun/energy/lwap
////Slime-derived potions///
@@ -50,6 +50,16 @@
. += "<span class='notice'> - [MAT]: [ROUND_UP(((temp_product.materials[MAT] * quality.material_mult) * efficiency) / MINERAL_MATERIAL_AMOUNT)] sheets.</span>"
// Get rid of the temp product
qdel(temp_product)
else if(istype(cast, /obj/item/smithing_cast/misc) && !produced_item)
var/obj/item/temp_product = new cast.selected_product(src) // This is necessary due to selected_product being a type
var/obj/item/smithing_cast/component/comp_cast = cast
. += "<span class='notice'>Required Resources:</span>"
var/MAT
// Get the materials the item needs and display
for(MAT in temp_product.materials)
. += "<span class='notice'> - [MAT]: [ROUND_UP((temp_product.materials[MAT] * efficiency) / MINERAL_MATERIAL_AMOUNT)] sheets.</span>"
// Get rid of the temp product
qdel(temp_product)
if(produced_item)
. += "<span class='notice'>There is a [produced_item] in the machine. You can pick it up with your hand.</span>"
@@ -86,6 +96,8 @@
. += "cast_lens"
else if(istype(cast, /obj/item/smithing_cast/component/trim))
. += "cast_trim"
else if(istype(cast, /obj/item/smithing_cast/misc/egun_parts))
. += "cast_egun_parts"
. += "casting_lip"
if(panel_open)
. += "casting_wires"
@@ -233,6 +245,32 @@
qdel(temp_product)
return FINISH_ATTACK
if(istype(cast, /obj/item/smithing_cast/misc))
var/list/used_mats = list()
// Check if there is enough materials to craft the item
for(MAT in temp_product.materials)
used_mats[MAT] = temp_product.materials[MAT] * efficiency
if(!materials.has_materials(used_mats, 1))
to_chat(user, "<span class='warning'>Not enough materials in the crucible to smelt [temp_product.name]!</span>")
qdel(temp_product)
return FINISH_ATTACK
to_chat(user, "<span class='notice'>You begin to pour the liquid minerals into the [src]...</span>")
// Use the materials and create the item.
materials.use_amount(used_mats)
linked_crucible.animate_pour(operation_time SECONDS)
operate(operation_time, user)
produced_item = new cast.selected_product(src)
produced_item.set_worktime()
produced_item.update_appearance(UPDATE_NAME)
produced_item.update_icon(UPDATE_ICON_STATE)
update_icon(UPDATE_OVERLAYS)
// Clean up temps
qdel(temp_product)
return FINISH_ATTACK
/obj/machinery/smithing/casting_basin/Destroy()
if(linked_crucible)
linked_crucible.linked_machines -= src
@@ -231,3 +231,148 @@
extra_product.update_appearance(UPDATE_NAME)
extra_product.scatter_atom()
finished_product = null
// MARK: Scientific Assembler
/obj/machinery/smithing/scientific_assembler
name = "scientific assembler"
desc = "A smart assembler that takes slime cores, energy cells, and energy gun parts to produce energy guns."
icon = 'icons/obj/machines/smithing_machines.dmi'
icon_state = "assembler"
max_integrity = 100
pixel_x = 0 // 1x1
pixel_y = 0
bound_height = 32
bound_width = 32
bound_y = 0
operation_sound = 'sound/items/welder.ogg'
/// Slime extract for the egun
var/obj/item/slime_extract/slime_core
/// The gun frame
var/obj/item/smithed_item/component/egun_parts/parts
/// The battery
var/obj/item/stock_parts/cell/cell
/obj/machinery/smithing/scientific_assembler/Initialize(mapload)
. = ..()
// Stock parts
component_parts = list()
component_parts += new /obj/item/circuitboard/kinetic_assembler(null)
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/stock_parts/micro_laser(null)
component_parts += new /obj/item/stack/sheet/glass(null)
RefreshParts()
/obj/machinery/smithing/scientific_assembler/examine(mob/user)
. = ..()
if(slime_core || parts || cell)
. += "<span class='notice'>You can activate the machine with your hand, or remove a component by alt-clicking.</span>"
if(slime_core)
. += "<span class='notice'>There is a [slime_core] in the core slot.</span>"
if(parts)
. += "<span class='notice'>There is a [parts] in the gun frame slot.</span>"
if(cell)
. += "<span class='notice'>There is a [cell] in the power cell slot.</span>"
/obj/machinery/smithing/scientific_assembler/RefreshParts()
var/operation_mult = 0
for(var/obj/item/stock_parts/component in component_parts)
operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating
// Update our values
operation_time = operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2)
/obj/machinery/smithing/scientific_assembler/update_icon_state()
. = ..()
if(panel_open)
icon_state = "assembler_wires"
/obj/machinery/smithing/kinetic_assembler/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I)
. = ..()
update_icon(UPDATE_ICON_STATE)
/obj/machinery/smithing/scientific_assembler/update_overlays()
. = ..()
overlays.Cut()
if(panel_open)
icon_state = "assembler_wires"
/obj/machinery/smithing/scientific_assembler/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(operating)
to_chat(user, "<span class='warning'>[src] is still operating!</span>")
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/slime_extract))
var/obj/item/slime_extract/core = used
if(!core.associated_gun_type)
to_chat(user, "<span class='notice'>[core] is not capable of producing an energy gun!</span>")
return ITEM_INTERACT_COMPLETE
if(slime_core)
to_chat(user, "<span class='notice'>You remove [slime_core] from the core component slot of [src].</span>")
slime_core.forceMove(src.loc)
slime_core = null
if(used.flags & NODROP || !user.transfer_item_to(used, src))
to_chat(user, "<span class='warning'>[used] is stuck to your hand!</span>")
return ITEM_INTERACT_COMPLETE
to_chat(user, "<span class='notice'>You insert [used] into the core component slot of [src].</span>")
slime_core = used
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/smithed_item/component/egun_parts))
if(parts)
to_chat(user, "<span class='notice'>You remove [parts] from the gun parts component slot of [src].</span>")
parts.forceMove(src.loc)
parts = null
if(used.flags & NODROP || !user.transfer_item_to(used, src))
to_chat(user, "<span class='warning'>[used] is stuck to your hand!</span>")
return ITEM_INTERACT_COMPLETE
var/obj/item/smithed_item/component/egun_parts/new_parts = used
if(new_parts.hammer_time)
to_chat(user, "<span class='warning'>[new_parts] is not complete yet!</span>")
return ITEM_INTERACT_COMPLETE
to_chat(user, "<span class='notice'>You insert [used] into the gun parts component slot of [src].</span>")
parts = used
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/stock_parts/cell))
if(cell)
to_chat(user, "<span class='notice'>You remove [cell] from the power cell component slot of [src].</span>")
cell.forceMove(src.loc)
cell = null
if(used.flags & NODROP || !user.transfer_item_to(used, src))
to_chat(user, "<span class='warning'>[used] is stuck to your hand!</span>")
return ITEM_INTERACT_COMPLETE
to_chat(user, "<span class='notice'>You insert [used] into the power cell component slot of [src].</span>")
cell = used
return ITEM_INTERACT_COMPLETE
to_chat(user, "<span class='warning'>You feel like there's no reason to process [used].</span>")
return ITEM_INTERACT_COMPLETE
/obj/machinery/smithing/scientific_assembler/attack_hand(mob/user)
if(!slime_core)
to_chat(user, "<span class='warning'>[src] lacks a slime core!</span>")
return FINISH_ATTACK
if(!parts)
to_chat(user, "<span class='warning'>[src] lacks an energy gun frame!</span>")
return FINISH_ATTACK
if(!cell)
to_chat(user, "<span class='warning'>[src] lacks a power cell!</span>")
return FINISH_ATTACK
operate(operation_time, user)
return FINISH_ATTACK
/obj/machinery/smithing/scientific_assembler/operate(loops, mob/living/user)
..()
var/obj/item/gun/energy/finished_product = new slime_core.associated_gun_type(src)
finished_product.forceMove(src.loc)
qdel(slime_core)
qdel(parts)
qdel(cell)
slime_core = null
parts = null
cell = null
@@ -48,7 +48,7 @@
/obj/machinery/smithing/power_hammer/operate(loops, mob/living/user)
if(!working_component)
to_chat(user, "<span class='notice'>There is no component in the machine.</span>")
to_chat(user, "<span class='notice'>There is no component to hammer!</span>")
return
if(!working_component.heat)
to_chat(user, "<span class='notice'>[working_component] is too cold to properly shape.</span>")
@@ -0,0 +1,7 @@
// MARK: Energy Gun Frame
/obj/item/smithed_item/component/egun_parts
name = "energy gun parts"
desc = "Smithed component of an energy gun."
icon_state = "egun_parts"
materials = list(MAT_TITANIUM = 10000, MAT_PLASMA = 10000)
hammer_time = 6
+21
View File
@@ -26,11 +26,15 @@
. = ..()
if(!possible_products)
return
if(!length(possible_products))
return
var/list/product_names = list()
var/product
for(product in possible_products)
var/obj/item/possible_product = product
product_names[possible_product.name] = possible_product
if(!length(product_names))
return
var/new_product = tgui_input_list(user, "Select a product", src, product_names)
if(!new_product)
selected_product = possible_products[1]
@@ -158,3 +162,20 @@
icon_state = "trim_cast"
desc = "A cast for creating trims."
product_type = /obj/item/smithed_item/component/trim
/obj/item/smithing_cast/misc
name = "misc cast"
icon_state = "insert_frame_cast"
desc = "Debug cast. If you see this, notify the development team."
/obj/item/smithing_cast/misc/AltClick(mob/user, modifiers)
return
/obj/item/smithing_cast/misc/examine(mob/user)
. = desc
/obj/item/smithing_cast/misc/egun_parts
name = "energy gun parts cast"
icon_state = "egun_parts_cast"
desc = "A cast for creating energy gun frames."
selected_product = /obj/item/smithed_item/component/egun_parts