Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into changelogs-tgui
This commit is contained in:
@@ -778,6 +778,24 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
target_amount = count
|
||||
update_explanation_text()
|
||||
*/
|
||||
/datum/objective/protect_object
|
||||
name = "protect object"
|
||||
var/obj/protect_target
|
||||
|
||||
/datum/objective/protect_object/proc/set_target(obj/O)
|
||||
protect_target = O
|
||||
update_explanation_text()
|
||||
|
||||
/datum/objective/protect_object/update_explanation_text()
|
||||
. = ..()
|
||||
if(protect_target)
|
||||
explanation_text = "Protect \the [protect_target] at all costs."
|
||||
else
|
||||
explanation_text = "Free objective."
|
||||
|
||||
/datum/objective/protect_object/check_completion()
|
||||
return !QDELETED(protect_target)
|
||||
|
||||
//Changeling Objectives
|
||||
|
||||
/datum/objective/absorb
|
||||
|
||||
+208
-217
@@ -1,7 +1,3 @@
|
||||
#define AUTOLATHE_MAIN_MENU 1
|
||||
#define AUTOLATHE_CATEGORY_MENU 2
|
||||
#define AUTOLATHE_SEARCH_MENU 3
|
||||
|
||||
/obj/machinery/autolathe
|
||||
name = "autolathe"
|
||||
desc = "It produces items using metal and glass."
|
||||
@@ -24,13 +20,14 @@
|
||||
var/shock_wire
|
||||
|
||||
var/busy = FALSE
|
||||
var/prod_coeff = 1
|
||||
|
||||
///the multiplier for how much materials the created object takes from this machines stored materials
|
||||
var/creation_efficiency = 1.6
|
||||
|
||||
var/datum/design/being_built
|
||||
var/datum/techweb/stored_research
|
||||
var/list/datum/design/matching_designs
|
||||
var/selected_category
|
||||
var/screen = 1
|
||||
var/selected_category = "None"
|
||||
var/base_price = 25
|
||||
var/hacked_price = 50
|
||||
|
||||
@@ -60,7 +57,7 @@
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/ui_interact(mob/user)
|
||||
/obj/machinery/autolathe/ui_interact(mob/user, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(!is_operational())
|
||||
return
|
||||
@@ -68,101 +65,129 @@
|
||||
if(shocked && !(stat & NOPOWER))
|
||||
shock(user,50)
|
||||
|
||||
var/dat
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Autolathe", capitalize(src.name))
|
||||
ui.open()
|
||||
|
||||
switch(screen)
|
||||
if(AUTOLATHE_MAIN_MENU)
|
||||
dat = main_win(user)
|
||||
if(AUTOLATHE_CATEGORY_MENU)
|
||||
dat = category_win(user,selected_category)
|
||||
if(AUTOLATHE_SEARCH_MENU)
|
||||
dat = search_win(user)
|
||||
|
||||
var/datum/browser/popup = new(user, "autolathe", name, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/autolathe/on_deconstruction()
|
||||
/obj/machinery/autolathe/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["materials"] = list()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.retrieve_all()
|
||||
data["materialtotal"] = materials.total_amount
|
||||
data["materialsmax"] = materials.max_amount
|
||||
data["categories"] = categories
|
||||
data["designs"] = list()
|
||||
data["active"] = busy
|
||||
|
||||
/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params)
|
||||
if (busy)
|
||||
to_chat(user, "<span class=\"alert\">The autolathe is busy. Please wait for completion of previous operation.</span>")
|
||||
return TRUE
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O))
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return TRUE
|
||||
|
||||
if(panel_open && is_wire_tool(O))
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
|
||||
if(user.a_intent == INTENT_HARM) //so we can hit the machine
|
||||
return ..()
|
||||
|
||||
if(stat)
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message("<span class='notice'>[user] begins to load \the [O] in \the [src]...</span>",
|
||||
"<span class='notice'>You begin to load a design from \the [O]...</span>",
|
||||
"<span class='hear'>You hear the chatter of a floppy drive.</span>")
|
||||
busy = TRUE
|
||||
var/obj/item/disk/design_disk/D = O
|
||||
if(do_after(user, 14.4, target = src))
|
||||
for(var/B in D.blueprints)
|
||||
if(B)
|
||||
stored_research.add_design(B)
|
||||
busy = FALSE
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
|
||||
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
use_power(MINERAL_MATERIAL_AMOUNT / 10)
|
||||
else if(custom_materials && custom_materials.len && custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)])
|
||||
flick("autolathe_r",src)//plays glass insertion animation by default otherwise
|
||||
for(var/mat_id in materials.materials)
|
||||
var/datum/material/M = mat_id
|
||||
var/mineral_count = materials.materials[mat_id]
|
||||
var/list/material_data = list(
|
||||
name = M.name,
|
||||
mineral_amount = mineral_count,
|
||||
matcolour = M.color,
|
||||
)
|
||||
data["materials"] += list(material_data)
|
||||
if(selected_category != "None" && !length(matching_designs))
|
||||
data["designs"] = handle_designs(stored_research.researched_designs, TRUE)
|
||||
else
|
||||
flick("autolathe_o",src)//plays metal insertion animation
|
||||
data["designs"] = handle_designs(matching_designs, FALSE)
|
||||
return data
|
||||
|
||||
/obj/machinery/autolathe/proc/handle_designs(list/designs, categorycheck)
|
||||
var/list/output = list()
|
||||
for(var/v in designs)
|
||||
var/datum/design/D = categorycheck ? SSresearch.techweb_design_by_id(v) : v
|
||||
if(categorycheck)
|
||||
if(!(selected_category in D.category))
|
||||
continue
|
||||
var/unbuildable = FALSE // we can't build the design currently
|
||||
var/m10 = FALSE // 10x mult
|
||||
var/m25 = FALSE // 25x mult
|
||||
var/m50 = FALSE // 50x mult
|
||||
var/m5 = FALSE // 5x mult
|
||||
var/sheets = FALSE // sheets or no?
|
||||
if(disabled || !can_build(D))
|
||||
unbuildable = TRUE
|
||||
var/max_multiplier = unbuildable ? 0 : 1
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
sheets = TRUE
|
||||
if(!unbuildable)
|
||||
var/datum/component/material_container/mats = GetComponent(/datum/component/material_container)
|
||||
for(var/datum/material/mat in D.materials)
|
||||
max_multiplier = min(D.maxstack, round(mats.get_material_amount(mat)/D.materials[mat]))
|
||||
if (max_multiplier>10 && !disabled)
|
||||
m10 = TRUE
|
||||
if (max_multiplier>25 && !disabled)
|
||||
m25 = TRUE
|
||||
else
|
||||
if(!unbuildable)
|
||||
if(!disabled && can_build(D, 5))
|
||||
m5 = TRUE
|
||||
if(!disabled && can_build(D, 10))
|
||||
m10 = TRUE
|
||||
var/datum/component/material_container/mats = GetComponent(/datum/component/material_container)
|
||||
for(var/datum/material/mat in D.materials)
|
||||
max_multiplier = min(50, round(mats.get_material_amount(mat)/(D.materials[mat] * creation_efficiency)))
|
||||
|
||||
use_power(min(1000, amount_inserted / 100))
|
||||
updateUsrDialog()
|
||||
var/list/design = list(
|
||||
name = D.name,
|
||||
id = D.id,
|
||||
ref = REF(src),
|
||||
cost = get_design_cost(D),
|
||||
buildable = unbuildable,
|
||||
mult5 = m5,
|
||||
mult10 = m10,
|
||||
mult25 = m25,
|
||||
mult50 = m50,
|
||||
sheet = sheets,
|
||||
maxmult = max_multiplier,
|
||||
)
|
||||
output += list(design)
|
||||
return output
|
||||
|
||||
/obj/machinery/autolathe/Topic(href, href_list)
|
||||
if(..())
|
||||
/obj/machinery/autolathe/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if (!busy)
|
||||
if(href_list["menu"])
|
||||
screen = text2num(href_list["menu"])
|
||||
updateUsrDialog()
|
||||
if(action == "menu")
|
||||
selected_category = null
|
||||
matching_designs.Cut()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["category"])
|
||||
selected_category = href_list["category"]
|
||||
updateUsrDialog()
|
||||
if(action == "category")
|
||||
selected_category = params["selectedCategory"]
|
||||
matching_designs.Cut()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["make"])
|
||||
if(action == "search")
|
||||
matching_designs.Cut()
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(findtext(D.name,params["to_search"]))
|
||||
matching_designs.Add(D)
|
||||
. = TRUE
|
||||
|
||||
if(action == "make")
|
||||
if (!busy)
|
||||
/////////////////
|
||||
//href protection
|
||||
being_built = stored_research.isDesignResearchedID(href_list["make"])
|
||||
being_built = stored_research.isDesignResearchedID(params["id"])
|
||||
if(!being_built)
|
||||
return
|
||||
|
||||
var/multiplier = text2num(href_list["multiplier"])
|
||||
var/multiplier = text2num(params["multiplier"])
|
||||
if(!multiplier)
|
||||
to_chat(usr, span_alert("[src] only accepts a numerical multiplier!"))
|
||||
return
|
||||
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
|
||||
multiplier = clamp(multiplier,1,50)
|
||||
multiplier = clamp(round(multiplier),1,50)
|
||||
|
||||
/////////////////
|
||||
|
||||
var/coeff = (is_stack ? 1 : prod_coeff) //stacks are unaffected by production coefficient
|
||||
var/coeff = (is_stack ? 1 : creation_efficiency) //stacks are unaffected by production coefficient
|
||||
var/total_amount = 0
|
||||
|
||||
for(var/MAT in being_built.materials)
|
||||
@@ -184,8 +209,8 @@
|
||||
if(materials.materials[i] > 0)
|
||||
list_to_show += i
|
||||
|
||||
used_material = input("Choose [used_material]", "Custom Material") as null|anything in sortList(list_to_show, /proc/cmp_typepaths_asc)
|
||||
if(!used_material)
|
||||
used_material = tgui_input_list(usr, "Choose [used_material]", "Custom Material", sortList(list_to_show, /proc/cmp_typepaths_asc))
|
||||
if(isnull(used_material))
|
||||
return //Didn't pick any material, so you can't build shit either.
|
||||
custom_materials[used_material] += amount_needed
|
||||
|
||||
@@ -193,27 +218,95 @@
|
||||
|
||||
if(materials.has_materials(materials_used))
|
||||
busy = TRUE
|
||||
to_chat(usr, span_notice("You print [multiplier] item(s) from the [src]"))
|
||||
use_power(power)
|
||||
icon_state = "autolathe_n"
|
||||
var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
|
||||
addtimer(CALLBACK(src, .proc/make_item, power, materials_used, custom_materials, multiplier, coeff, is_stack, usr), time)
|
||||
. = TRUE
|
||||
else
|
||||
to_chat(usr, "<span class=\"alert\">Not enough materials for this operation.</span>")
|
||||
to_chat(usr, span_alert("Not enough materials for this operation."))
|
||||
else
|
||||
to_chat(usr, span_alert("The autolathe is busy. Please wait for completion of previous operation."))
|
||||
|
||||
if(href_list["search"])
|
||||
matching_designs.Cut()
|
||||
/obj/machinery/autolathe/on_deconstruction()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.retrieve_all()
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(findtext(D.name,href_list["to_search"]))
|
||||
matching_designs.Add(D)
|
||||
updateUsrDialog()
|
||||
/obj/machinery/autolathe/attackby(obj/item/O, mob/living/user, params)
|
||||
if(busy)
|
||||
balloon_alert(user, "it's busy!")
|
||||
return TRUE
|
||||
|
||||
if(user.a_intent == INTENT_HARM) //so we can hit the machine
|
||||
return ..()
|
||||
|
||||
if(stat)
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message(span_notice("[user] begins to load \the [O] in \the [src]..."),
|
||||
balloon_alert(user, "uploading design..."),
|
||||
span_hear("You hear the chatter of a floppy drive."))
|
||||
busy = TRUE
|
||||
if(do_after(user, 14.4, target = src))
|
||||
var/obj/item/disk/design_disk/disky = O
|
||||
var/list/not_imported
|
||||
for(var/datum/design/blueprint as anything in disky.blueprints)
|
||||
if(!blueprint)
|
||||
continue
|
||||
if(blueprint.build_type & AUTOLATHE)
|
||||
stored_research.add_design(blueprint)
|
||||
else
|
||||
LAZYADD(not_imported, blueprint.name)
|
||||
if(not_imported)
|
||||
to_chat(user, span_warning("The following design[length(not_imported) > 1 ? "s" : ""] couldn't be imported: [english_list(not_imported)]"))
|
||||
busy = FALSE
|
||||
return TRUE
|
||||
|
||||
if(panel_open)
|
||||
balloon_alert(user, "close the panel first!")
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/screwdriver_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(busy)
|
||||
balloon_alert(user, "it's busy!")
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", I))
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
/obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(busy)
|
||||
balloon_alert(user, "it's busy!")
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
/obj/machinery/autolathe/multitool_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(busy)
|
||||
balloon_alert(user, "it's busy!")
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
if(panel_open)
|
||||
wires.interact(user)
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
|
||||
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
use_power(MINERAL_MATERIAL_AMOUNT / 10)
|
||||
else if(custom_materials && custom_materials.len && custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)])
|
||||
flick("autolathe_r", src)//plays glass insertion animation by default otherwise
|
||||
else
|
||||
to_chat(usr, "<span class=\"alert\">The autolathe is busy. Please wait for completion of previous operation.</span>")
|
||||
flick("autolathe_o", src)//plays metal insertion animation
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
return
|
||||
use_power(min(1000, amount_inserted / 100))
|
||||
|
||||
/obj/machinery/autolathe/proc/make_item(power, list/materials_used, list/picked_materials, multiplier, coeff, is_stack, mob/user)
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
@@ -223,11 +316,11 @@
|
||||
materials.use_materials(materials_used)
|
||||
|
||||
if(is_stack)
|
||||
var/obj/item/stack/N = new being_built.build_path(A, multiplier)
|
||||
N.update_icon()
|
||||
var/obj/item/stack/N = new being_built.build_path(A, multiplier, FALSE)
|
||||
N.update_appearance()
|
||||
N.autolathe_crafted(src)
|
||||
else
|
||||
for(var/i=1, i<=multiplier, i++)
|
||||
for(var/i in 1 to multiplier)
|
||||
var/obj/item/new_item = new being_built.build_path(A)
|
||||
new_item.autolathe_crafted(src)
|
||||
|
||||
@@ -241,132 +334,30 @@
|
||||
|
||||
icon_state = "autolathe"
|
||||
busy = FALSE
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/autolathe/RefreshParts()
|
||||
var/T = 0
|
||||
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
|
||||
T += MB.rating*75000
|
||||
var/mat_capacity = 0
|
||||
for(var/obj/item/stock_parts/matter_bin/new_matter_bin in component_parts)
|
||||
mat_capacity += new_matter_bin.rating*75000
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.max_amount = T
|
||||
T=1.2
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
T -= M.rating*0.2
|
||||
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
|
||||
materials.max_amount = mat_capacity
|
||||
|
||||
var/efficiency=1.2
|
||||
for(var/obj/item/stock_parts/manipulator/new_manipulator in component_parts)
|
||||
efficiency -= new_manipulator.rating*0.2
|
||||
creation_efficiency = max(1,efficiency) // creation_efficiency goes 1 -> 0,8 -> 0,6 -> 0,4 per level of manipulator efficiency
|
||||
|
||||
/obj/machinery/autolathe/examine(mob/user)
|
||||
. += ..()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[prod_coeff*100]%</b>.</span>"
|
||||
|
||||
/obj/machinery/autolathe/proc/main_win(mob/user)
|
||||
var/dat = "<div class='statusDisplay'><h3>Autolathe Menu:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
dat += "<form name='search' action='?src=[REF(src)]'>\
|
||||
<input type='hidden' name='src' value='[REF(src)]'>\
|
||||
<input type='hidden' name='search' value='to_search'>\
|
||||
<input type='hidden' name='menu' value='[AUTOLATHE_SEARCH_MENU]'>\
|
||||
<input type='text' name='to_search'>\
|
||||
<input type='submit' value='Search'>\
|
||||
</form><hr>"
|
||||
|
||||
var/line_length = 1
|
||||
dat += "<table style='width:100%' align='center'><tr>"
|
||||
|
||||
for(var/C in categories)
|
||||
if(line_length > 2)
|
||||
dat += "</tr><tr>"
|
||||
line_length = 1
|
||||
|
||||
dat += "<td><A href='?src=[REF(src)];category=[C];menu=[AUTOLATHE_CATEGORY_MENU]'>[C]</A></td>"
|
||||
line_length++
|
||||
|
||||
dat += "</tr></table></div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autolathe/proc/category_win(mob/user,selected_category)
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(!(selected_category in D.category))
|
||||
continue
|
||||
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/max_multiplier
|
||||
for(var/datum/material/mat in D.materials)
|
||||
max_multiplier = min(D.maxstack, round(materials.get_material_amount(mat)/D.materials[mat]))
|
||||
if (max_multiplier>10 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
if (max_multiplier>25 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=25'>x25</a>"
|
||||
if(max_multiplier > 0 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
else
|
||||
if(!disabled && can_build(D, 5))
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=5'>x5</a>"
|
||||
if(!disabled && can_build(D, 10))
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autolathe/proc/search_win(mob/user)
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Search results:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
for(var/v in matching_designs)
|
||||
var/datum/design/D = v
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/max_multiplier
|
||||
for(var/datum/material/mat in D.materials)
|
||||
max_multiplier = min(D.maxstack, round(materials.get_material_amount(mat)/D.materials[mat]))
|
||||
if (max_multiplier>10 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
if (max_multiplier>25 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=25'>x25</a>"
|
||||
if(max_multiplier > 0 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autolathe/proc/materials_printout()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/dat = "<b>Total amount:</b> [materials.total_amount] / [materials.max_amount] cm<sup>3</sup><br>"
|
||||
for(var/mat_id in materials.materials)
|
||||
var/datum/material/M = mat_id
|
||||
var/mineral_amount = materials.materials[mat_id]
|
||||
if(mineral_amount > 0)
|
||||
dat += "<b>[M.name] amount:</b> [mineral_amount] cm<sup>3</sup><br>"
|
||||
return dat
|
||||
. += span_notice("The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[creation_efficiency*100]%</b>.")
|
||||
|
||||
/obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1)
|
||||
if(D.make_reagents.len)
|
||||
if(length(D.make_reagents))
|
||||
return FALSE
|
||||
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : creation_efficiency)
|
||||
|
||||
var/list/required_materials = list()
|
||||
|
||||
@@ -379,7 +370,7 @@
|
||||
|
||||
|
||||
/obj/machinery/autolathe/proc/get_design_cost(datum/design/D)
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : creation_efficiency)
|
||||
var/dat
|
||||
for(var/i in D.materials)
|
||||
if(istext(i)) //Category handling
|
||||
@@ -402,7 +393,7 @@
|
||||
disabled = FALSE
|
||||
|
||||
/obj/machinery/autolathe/proc/shock(mob/user, prb)
|
||||
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
return FALSE
|
||||
if(!prob(prb))
|
||||
return FALSE
|
||||
@@ -424,7 +415,7 @@
|
||||
else
|
||||
stored_research.remove_design(D)
|
||||
|
||||
/obj/machinery/autolathe/hacked/Initialize()
|
||||
/obj/machinery/autolathe/hacked/Initialize(mapload)
|
||||
. = ..()
|
||||
adjust_hacked(TRUE)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//Objects that spawn ghosts in as a certain role when they click on it, i.e. away mission bartenders.
|
||||
|
||||
#define spawnOverride TRUE
|
||||
//Preserved terrarium/seed vault: Spawns in seed vault structures in lavaland. Ghosts become plantpeople and are advised to begin growing plants in the room near them.
|
||||
/obj/effect/mob_spawn/human/seed_vault
|
||||
name = "preserved terrarium"
|
||||
@@ -36,6 +36,44 @@
|
||||
|
||||
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
|
||||
|
||||
/obj/structure/ash_walker_eggshell
|
||||
name = "ash walker egg"
|
||||
desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within. The egg shell looks resistant to temperature but otherwise rather brittle."
|
||||
icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
|
||||
icon_state = "large_egg"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | FREEZE_PROOF
|
||||
max_integrity = 80
|
||||
var/obj/effect/mob_spawn/human/ash_walker/egg
|
||||
|
||||
/obj/structure/ash_walker_eggshell/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) //lifted from xeno eggs
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(damage_amount)
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 100, TRUE)
|
||||
else
|
||||
playsound(src, 'sound/weapons/tap.ogg', 50, TRUE)
|
||||
if(BURN)
|
||||
if(damage_amount)
|
||||
playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/ash_walker_eggshell/attack_ghost(mob/user) //Pass on ghost clicks to the mob spawner
|
||||
if(egg)
|
||||
egg.attack_ghost(user)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/ash_walker_eggshell/Destroy()
|
||||
if(!egg)
|
||||
return ..()
|
||||
var/mob/living/carbon/human/yolk = new /mob/living/carbon/human/(get_turf(src))
|
||||
yolk.fully_replace_character_name(null,random_unique_lizard_name(gender))
|
||||
yolk.set_species(/datum/species/lizard/ashwalker)
|
||||
yolk.underwear = "Nude"
|
||||
yolk.equipOutfit(/datum/outfit/ashwalker)//this is an authentic mess we're making
|
||||
yolk.update_body()
|
||||
yolk.gib()
|
||||
QDEL_NULL(egg)
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker
|
||||
name = "ash walker egg"
|
||||
desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within."
|
||||
@@ -55,12 +93,25 @@
|
||||
You have seen lights in the distance... they foreshadow the arrival of outsiders to your domain. \
|
||||
Ensure your nest remains protected at all costs."
|
||||
assignedrole = "Ash Walker"
|
||||
var/datum/team/ashwalkers/team
|
||||
var/obj/structure/ash_walker_eggshell/eggshell
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker/Destroy()
|
||||
eggshell = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker/allow_spawn(mob/user, silent = FALSE)
|
||||
if(!(user.key in team.players_spawned) || spawnOverride)//one per person unless you get a bonus spawn
|
||||
return TRUE
|
||||
to_chat(user, span_warning("<b>You have exhausted your usefulness to the Necropolis</b>."))
|
||||
return FALSE
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn)
|
||||
new_spawn.real_name = random_unique_lizard_name(gender)
|
||||
if(is_mining_level(z))
|
||||
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>")
|
||||
to_chat(new_spawn, "<b>You can expand the weather proof area provided by your shelters by using the 'New Area' key near the bottom right of your HUD.</b>")
|
||||
to_chat(new_spawn, "<b>Dragging injured ashwalkers to the tentacle or using the sleep verb next to it youself causes the body to remade whole after a short delay!</b>")
|
||||
else
|
||||
to_chat(new_spawn, "<span class='userdanger'>You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.</span>")
|
||||
|
||||
@@ -72,10 +123,18 @@
|
||||
H.undershirt = "Nude"
|
||||
H.socks = "Nude"
|
||||
H.update_body()
|
||||
new_spawn.mind.add_antag_datum(/datum/antagonist/ashwalker, team)
|
||||
team.players_spawned += (new_spawn.key)
|
||||
eggshell.egg = null
|
||||
QDEL_NULL(eggshell)
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload)
|
||||
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload, datum/team/ashwalkers/ashteam)
|
||||
. = ..()
|
||||
var/area/A = get_area(src)
|
||||
team = ashteam
|
||||
eggshell = new /obj/structure/ash_walker_eggshell(get_turf(loc))
|
||||
eggshell.egg = src
|
||||
src.forceMove(eggshell)
|
||||
if(A)
|
||||
notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER, ignore_dnr_observers = TRUE)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user