Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into changelogs-tgui
This commit is contained in:
@@ -81,6 +81,7 @@
|
||||
#define SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT 5 //What is the minimum amount of temp you move towards the target point, even if it would be less with default calculations?
|
||||
#define SYNTH_INTEGRATION_COOLANT_PENALTY 0.4 //Integrating coolant is multiplied with this for calculation of impact on passive cooling.
|
||||
#define SYNTH_INTEGRATION_COOLANT_CAP 0.25 //Integrating coolant is capped at counting as current_blood * this number. This is so you can't just run on salglu or whatever.
|
||||
#define SYNTH_COLD_OFFSET -125 //How much colder temps Synths can tolerate. Used in their species.
|
||||
|
||||
#define BODYTEMP_NORMAL 310.15 //The natural temperature for a body
|
||||
#define BODYTEMP_AUTORECOVERY_DIVISOR 11 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive.
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
#define TRAIT_RESISTCOLD "resist_cold"
|
||||
#define TRAIT_RESISTHIGHPRESSURE "resist_high_pressure"
|
||||
#define TRAIT_RESISTLOWPRESSURE "resist_low_pressure"
|
||||
#define TRAIT_LOWPRESSURECOOLING "low_pressure_cooling"
|
||||
#define TRAIT_BOMBIMMUNE "bomb_immunity"
|
||||
#define TRAIT_RADIMMUNE "rad_immunity"
|
||||
#define TRAIT_GENELESS "geneless"
|
||||
|
||||
@@ -38,6 +38,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD,
|
||||
"TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE,
|
||||
"TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE,
|
||||
"TRAIT_LOWPRESSURECOOLING" = TRAIT_LOWPRESSURECOOLING,
|
||||
"TRAIT_BOMBIMMUNE" = TRAIT_BOMBIMMUNE,
|
||||
"TRAIT_RADIMMUNE" = TRAIT_RADIMMUNE,
|
||||
"TRAIT_GENELESS" = TRAIT_GENELESS,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
/atom/movable/screen
|
||||
name = ""
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
layer = HUD_LAYER
|
||||
plane = HUD_PLANE
|
||||
animate_movement = SLIDE_STEPS
|
||||
speech_span = SPAN_ROBOT
|
||||
|
||||
@@ -294,3 +294,8 @@
|
||||
description = "<span class='boldwarning'>I hate when my shoes come untied!</span>\n"
|
||||
mood_change = -3
|
||||
timeout = 1 MINUTES
|
||||
|
||||
/datum/mood_event/sacrifice_bad
|
||||
description = "<span class='warning'>Those darn savages!</span>\n"
|
||||
mood_change = -5
|
||||
timeout = 2 MINUTES
|
||||
|
||||
@@ -205,3 +205,8 @@
|
||||
/datum/mood_event/cleared_stomach
|
||||
description = "<span class='nicegreen'>Feels nice to get that out of the way!</span>\n"
|
||||
mood_change = 3
|
||||
|
||||
/datum/mood_event/sacrifice_good
|
||||
description = "<span class='nicegreen'>The gods are pleased with this offering!</span>\n"
|
||||
mood_change = 5
|
||||
timeout = 3 MINUTES
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
return
|
||||
ADD_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance")
|
||||
ADD_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance")
|
||||
ADD_TRAIT(owner, TRAIT_LOWPRESSURECOOLING, "cold_resistance")
|
||||
owner.add_filter("space_glow", 2, list("type" = "outline", "color" = "#ffe46bd8", "size" = 1))
|
||||
addtimer(CALLBACK(src, .proc/glow_loop, owner), rand(1,19))
|
||||
|
||||
@@ -27,5 +28,6 @@
|
||||
return
|
||||
REMOVE_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance")
|
||||
REMOVE_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance")
|
||||
REMOVE_TRAIT(owner, TRAIT_LOWPRESSURECOOLING, "cold_resistance")
|
||||
owner.remove_filter("space_glow")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
remove_innate_effects(old_body)
|
||||
if(!soft_antag && old_body.stat != DEAD && !LAZYLEN(old_body.mind?.antag_datums))
|
||||
if(!soft_antag && old_body && old_body.stat != DEAD && !length(old_body.mind?.antag_datums))
|
||||
old_body.remove_from_current_living_antags()
|
||||
apply_innate_effects(new_body)
|
||||
if(!soft_antag && new_body.stat != DEAD)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/datum/team/ashwalkers
|
||||
name = "Ashwalkers"
|
||||
show_roundend_report = FALSE
|
||||
var/list/players_spawned = new
|
||||
|
||||
/datum/antagonist/ashwalker
|
||||
name = "\improper Ash Walker"
|
||||
job_rank = ROLE_LAVALAND
|
||||
show_in_antagpanel = FALSE
|
||||
show_to_ghosts = TRUE
|
||||
antagpanel_category = "Ash Walkers"
|
||||
var/datum/team/ashwalkers/ashie_team
|
||||
|
||||
/datum/antagonist/ashwalker/create_team(datum/team/team)
|
||||
if(team)
|
||||
ashie_team = team
|
||||
objectives |= ashie_team.objectives
|
||||
else
|
||||
ashie_team = new
|
||||
|
||||
/datum/antagonist/ashwalker/get_team()
|
||||
return ashie_team
|
||||
|
||||
/datum/antagonist/ashwalker/on_body_transfer(mob/living/old_body, mob/living/new_body)
|
||||
. = ..()
|
||||
RegisterSignal(new_body, COMSIG_MOB_EXAMINATE, .proc/on_examinate)
|
||||
|
||||
/datum/antagonist/ashwalker/on_gain()
|
||||
. = ..()
|
||||
RegisterSignal(owner.current, COMSIG_MOB_EXAMINATE, .proc/on_examinate)
|
||||
|
||||
/datum/antagonist/ashwalker/on_removal()
|
||||
. = ..()
|
||||
UnregisterSignal(owner.current, COMSIG_MOB_EXAMINATE)
|
||||
|
||||
/datum/antagonist/ashwalker/proc/on_examinate(datum/source, atom/A)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(istype(A, /obj/structure/headpike))
|
||||
SEND_SIGNAL(owner.current, COMSIG_ADD_MOOD_EVENT, "headspear", /datum/mood_event/sacrifice_good)
|
||||
@@ -33,6 +33,10 @@
|
||||
var/ghost_usable = TRUE
|
||||
var/skip_reentry_check = FALSE //Skips the ghost role blacklist time for people who ghost/suicide/cryo
|
||||
|
||||
///override this to add special spawn conditions to a ghost role
|
||||
/obj/effect/mob_spawn/proc/allow_spawn(mob/user, silent = FALSE)
|
||||
return TRUE
|
||||
|
||||
//ATTACK GHOST IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/mob_spawn/attack_ghost(mob/user, latejoinercalling)
|
||||
if(!SSticker.HasRoundStarted() || !loc || !ghost_usable)
|
||||
@@ -43,6 +47,8 @@
|
||||
if(jobban_isbanned(user, banType))
|
||||
to_chat(user, "<span class='warning'>You are jobanned!</span>")
|
||||
return
|
||||
if(!allow_spawn(user, silent = FALSE))
|
||||
return
|
||||
if(QDELETED(src) || QDELETED(user))
|
||||
return
|
||||
if(isobserver(user))
|
||||
|
||||
@@ -36,3 +36,25 @@
|
||||
/datum/keybinding/living/toggle_resting/down(client/user)
|
||||
var/mob/living/L = user.mob
|
||||
L.lay_down()
|
||||
|
||||
/datum/keybinding/living/cancel_action
|
||||
hotkey_keys = list("Unbound")
|
||||
name = "cancel_action"
|
||||
full_name = "Cancel Action"
|
||||
description = "Cancel the current action."
|
||||
|
||||
/// Technically you shouldn't be doing any actions if you were sleeping either but...
|
||||
/datum/keybinding/living/can_use(client/user)
|
||||
. = ..()
|
||||
var/mob/living/mob = user.mob
|
||||
return . && (mob.stat == CONSCIOUS)
|
||||
|
||||
/datum/keybinding/living/cancel_action/down(client/user)
|
||||
var/mob/M = user.mob
|
||||
if(length(M.do_afters))
|
||||
var/atom/target = M.do_afters[M.do_afters.len]
|
||||
to_chat(M, "<span class='notice'>You stop interacting with \the [target].</span>")
|
||||
LAZYREMOVE(M.do_afters, target)
|
||||
else
|
||||
to_chat(M, "<span class='notice'>There's nothing that you can cancel right now.</span>")
|
||||
return TRUE
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING,HAS_FLESH,HAS_BONE,HAIR,ROBOTIC_LIMBS)
|
||||
hair_alpha = 210
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
mutant_bodyparts = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
|
||||
mutant_bodyparts = list("ipc_screen" = "Blank", "deco_wings" = "None", "ipc_antenna" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,HAS_FLESH)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "legs" = "Plantigrade")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade")
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 160 //a notch brighter so it blends better.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
|
||||
@@ -699,6 +699,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
var/heat_efficiency = clamp(1 + ((bodytemperature - heat) * SYNTH_HEAT_EFFICIENCY_COEFF), 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP)
|
||||
var/pressure_efficiency = clamp(pressure / ONE_ATMOSPHERE, 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_LOWPRESSURECOOLING))
|
||||
pressure_efficiency = max(pressure_efficiency, 1) //Space adaptation nulls drawbacks of low-pressure cooling.
|
||||
|
||||
var/total_environment_efficiency = min(heat_efficiency * pressure_efficiency, SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP) //At best, you can get 200% total
|
||||
return total_environment_efficiency
|
||||
|
||||
|
||||
@@ -292,18 +292,21 @@
|
||||
|
||||
/mob/living/simple_animal/bot/on_attack_hand(mob/living/carbon/human/H)
|
||||
if(H.a_intent == INTENT_HELP)
|
||||
interact(H)
|
||||
ui_interact(H)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/attack_ai(mob/user)
|
||||
if(!topic_denied(user))
|
||||
interact(user)
|
||||
ui_interact(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src]'s interface is not responding!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/interact(mob/user)
|
||||
show_controls(user)
|
||||
/mob/living/simple_animal/bot/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SimpleBot", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/simple_animal/bot/attackby(obj/item/W, mob/user, params)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
@@ -795,56 +798,48 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
else // no path, so calculate new one
|
||||
calc_summon_path()
|
||||
|
||||
/mob/living/simple_animal/bot/Bump(M as mob|obj) //Leave no door unopened!
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["can_hack"] = (issilicon(user) || IsAdminGhost(user))
|
||||
data["custom_controls"] = list()
|
||||
data["emagged"] = emagged
|
||||
data["locked"] = locked
|
||||
data["pai"] = list()
|
||||
data["settings"] = list()
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
data["pai"]["allow_pai"] = allow_pai
|
||||
data["pai"]["card_inserted"] = paicard
|
||||
data["settings"]["airplane_mode"] = remote_disabled
|
||||
data["settings"]["maintenance_lock"] = !open
|
||||
data["settings"]["power"] = on
|
||||
data["settings"]["patrol_station"] = auto_patrol
|
||||
return data
|
||||
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/ui_act(action, params)
|
||||
. = ..()
|
||||
if((istype(M, /obj/machinery/door/airlock) || istype(M, /obj/machinery/door/window)) && (!isnull(access_card)))
|
||||
var/obj/machinery/door/D = M
|
||||
if(D.check_access(access_card))
|
||||
D.open()
|
||||
frustration = 0
|
||||
|
||||
/mob/living/simple_animal/bot/proc/show_controls(mob/M)
|
||||
users |= M
|
||||
var/dat = ""
|
||||
dat = get_controls(M)
|
||||
var/datum/browser/popup = new(M,window_id,window_name,350,600)
|
||||
popup.set_content(dat)
|
||||
popup.open(use_onclose = 0)
|
||||
onclose(M,window_id,ref=src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/proc/update_controls()
|
||||
for(var/mob/M in users)
|
||||
show_controls(M)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/get_controls(mob/M)
|
||||
return "PROTOBOT - NOT FOR USE"
|
||||
|
||||
/mob/living/simple_animal/bot/Topic(href, href_list)
|
||||
//No ..() to prevent strip panel showing up - Todo: make that saner
|
||||
if(href_list["close"])// HUE HUE
|
||||
if(usr in users)
|
||||
users.Remove(usr)
|
||||
return TRUE
|
||||
|
||||
if(topic_denied(usr))
|
||||
to_chat(usr, "<span class='warning'>[src]'s interface is not responding!</span>")
|
||||
return TRUE
|
||||
add_fingerprint(usr)
|
||||
|
||||
if((href_list["power"]) && (bot_core.allowed(usr) || !locked))
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
|
||||
switch(href_list["operation"])
|
||||
if(.)
|
||||
return
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
to_chat(usr, span_warning("Access denied."))
|
||||
return
|
||||
if(action == "lock")
|
||||
locked = !locked
|
||||
if(locked && !(issilicon(usr) || IsAdminGhost(usr)))
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
update_appearance()
|
||||
if("maintenance")
|
||||
open = !open
|
||||
if("patrol")
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
auto_patrol = !auto_patrol
|
||||
bot_reset()
|
||||
if("remote")
|
||||
if("airplane")
|
||||
remote_disabled = !remote_disabled
|
||||
if("hack")
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr))
|
||||
@@ -865,11 +860,11 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
hacked = FALSE
|
||||
to_chat(usr, "<span class='notice'>[text_dehack]</span>")
|
||||
bot_reset()
|
||||
if("ejectpai")
|
||||
if("eject_pai")
|
||||
if(paicard && (!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr)))
|
||||
to_chat(usr, "<span class='notice'>You eject [paicard] from [bot_name]</span>")
|
||||
ejectpai(usr)
|
||||
update_controls()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/update_icon_state()
|
||||
icon_state = "[initial(icon_state)][on]"
|
||||
@@ -897,33 +892,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/proc/hack(mob/user)
|
||||
var/hack
|
||||
if(hasSiliconAccessInArea(user) || IsAdminGhost(user)) //Allows silicons or admins to toggle the emag status of a bot.
|
||||
hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]<BR>"
|
||||
hack += "Harm Prevention Safety System: <A href='?src=[REF(src)];operation=hack'>[emagged ? "<span class='bad'>DANGER</span>" : "Engaged"]</A><BR>"
|
||||
else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
|
||||
hack += "Remote network control radio: <A href='?src=[REF(src)];operation=remote'>[remote_disabled ? "Disconnected" : "Connected"]</A><BR>"
|
||||
return hack
|
||||
|
||||
/mob/living/simple_animal/bot/proc/showpai(mob/user)
|
||||
var/eject = ""
|
||||
if((!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr)))
|
||||
if(paicard || allow_pai)
|
||||
eject += "Personality card status: "
|
||||
if(paicard)
|
||||
if(client)
|
||||
eject += "<A href='?src=[REF(src)];operation=ejectpai'>Active</A>"
|
||||
else
|
||||
eject += "<A href='?src=[REF(src)];operation=ejectpai'>Inactive</A>"
|
||||
else if(!allow_pai || key)
|
||||
eject += "Unavailable"
|
||||
else
|
||||
eject += "Not inserted"
|
||||
eject += "<BR>"
|
||||
eject += "<BR>"
|
||||
return eject
|
||||
|
||||
/mob/living/simple_animal/bot/proc/insertpai(mob/user, obj/item/paicard/card)
|
||||
if(paicard)
|
||||
to_chat(user, "<span class='warning'>A [paicard] is already inserted!</span>")
|
||||
|
||||
@@ -443,37 +443,33 @@
|
||||
/obj/machinery/bot_core/cleanbot
|
||||
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS)
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"})
|
||||
if(!locked || issilicon(user)|| IsAdminGhost(user))
|
||||
dat += "<BR>Clean Blood: <A href='?src=[REF(src)];operation=blood'>[blood ? "Yes" : "No"]</A>"
|
||||
dat += "<BR>Clean Trash: <A href='?src=[REF(src)];operation=trash'>[trash ? "Yes" : "No"]</A>"
|
||||
dat += "<BR>Clean Graffiti: <A href='?src=[REF(src)];operation=drawn'>[drawn ? "Yes" : "No"]</A>"
|
||||
dat += "<BR>Exterminate Pests: <A href='?src=[REF(src)];operation=pests'>[pests ? "Yes" : "No"]</A>"
|
||||
dat += "<BR><BR>Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"
|
||||
return dat
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/cleanbot/ui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["operation"])
|
||||
switch(href_list["operation"])
|
||||
if("blood")
|
||||
blood = !blood
|
||||
if("pests")
|
||||
pests = !pests
|
||||
if("trash")
|
||||
trash = !trash
|
||||
if("drawn")
|
||||
drawn = !drawn
|
||||
get_targets()
|
||||
update_controls()
|
||||
if(!locked || issilicon(user)|| IsAdminGhost(user))
|
||||
data["custom_controls"]["clean_blood"] = blood
|
||||
data["custom_controls"]["clean_trash"] = trash
|
||||
data["custom_controls"]["clean_graffiti"] = drawn
|
||||
data["custom_controls"]["pest_control"] = pests
|
||||
return data
|
||||
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/cleanbot/ui_act(action, params)
|
||||
. = ..()
|
||||
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("clean_blood")
|
||||
blood = !blood
|
||||
if("pest_control")
|
||||
pests = !pests
|
||||
if("clean_trash")
|
||||
trash = !trash
|
||||
if("clean_graffiti")
|
||||
drawn = !drawn
|
||||
get_targets()
|
||||
return
|
||||
|
||||
/obj/machinery/bot_core/cleanbot/medbay
|
||||
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS, ACCESS_MEDICAL)
|
||||
|
||||
@@ -96,64 +96,45 @@
|
||||
text_dehack = "You restore [name]'s combat inhibitor."
|
||||
text_dehack_fail = "[name] ignores your attempts to restrict him!"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Security Unit v2.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/ed209/ui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
if(!locked || hasSiliconAccessInArea(user)|| IsAdminGhost(user))
|
||||
if(!lasercolor)
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol[]"},
|
||||
data["custom_controls"]["check_id"] = idcheck
|
||||
data["custom_controls"]["check_weapons"] = weaponscheck
|
||||
data["custom_controls"]["check_warrants"] = check_records
|
||||
data["custom_controls"]["handcuff_targets"] = !arrest_type
|
||||
data["custom_controls"]["arrest_alert"] = declare_arrests
|
||||
return data
|
||||
|
||||
"<A href='?src=[REF(src)];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/Topic(href, href_list)
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/ed209/ui_act(action, params)
|
||||
if(lasercolor && ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it
|
||||
return
|
||||
else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag)))
|
||||
return
|
||||
if(..())
|
||||
return 1
|
||||
switch(lasercolor) //Opposing team cannot operate it
|
||||
if("b")
|
||||
if(istype(H.wear_suit, /obj/item/clothing/suit/redtag))
|
||||
return TRUE
|
||||
if("r")
|
||||
if(istype(H.wear_suit, /obj/item/clothing/suit/bluetag))
|
||||
return TRUE
|
||||
. = ..()
|
||||
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
switch(action)
|
||||
if("check_id")
|
||||
idcheck = !idcheck
|
||||
update_controls()
|
||||
if("weaponscheck")
|
||||
if("check_weapons")
|
||||
weaponscheck = !weaponscheck
|
||||
update_controls()
|
||||
if("ignorerec")
|
||||
if("check_warrants")
|
||||
check_records = !check_records
|
||||
update_controls()
|
||||
if("switchmode")
|
||||
if("handcuff_targets")
|
||||
arrest_type = !arrest_type
|
||||
update_controls()
|
||||
if("declarearrests")
|
||||
if("arrest_alert")
|
||||
declare_arrests = !declare_arrests
|
||||
update_controls()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/judgement_criteria()
|
||||
var/final = FALSE
|
||||
|
||||
@@ -102,23 +102,6 @@
|
||||
text_dehack = "You detect errors in [name] and reset his programming."
|
||||
text_dehack_fail = "[name] is not responding to reset commands!"
|
||||
|
||||
/mob/living/simple_animal/bot/firebot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<TT><B>Mobile Fire Extinguisher v1.0</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += "Extinguish Fires: <A href='?src=[REF(src)];operation=extinguish_fires'>[extinguish_fires ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Extinguish People: <A href='?src=[REF(src)];operation=extinguish_people'>[extinguish_people ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Stationary Mode: <a href='?src=[REF(src)];operation=stationary_mode'>[stationary_mode ? "Yes" : "No"]</a><br>"
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/firebot/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(emagged == 1)
|
||||
@@ -138,20 +121,29 @@
|
||||
internal_ext.max_water = INFINITY
|
||||
internal_ext.refill()
|
||||
|
||||
/mob/living/simple_animal/bot/firebot/Topic(href, href_list)
|
||||
if(..())
|
||||
return TRUE
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/firebot/ui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
data["custom_controls"]["extinguish_fires"] = extinguish_fires
|
||||
data["custom_controls"]["extinguish_people"] = extinguish_people
|
||||
data["custom_controls"]["stationary_mode"] = stationary_mode
|
||||
return data
|
||||
|
||||
switch(href_list["operation"])
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/firebot/ui_act(action, params)
|
||||
. = ..()
|
||||
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("extinguish_fires")
|
||||
extinguish_fires = !extinguish_fires
|
||||
if("extinguish_people")
|
||||
extinguish_people = !extinguish_people
|
||||
if("stationary_mode")
|
||||
stationary_mode = !stationary_mode
|
||||
|
||||
update_controls()
|
||||
update_icon()
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target)
|
||||
if(ismob(target))
|
||||
|
||||
@@ -71,36 +71,6 @@
|
||||
text_dehack = "You detect errors in [name] and reset his programming."
|
||||
text_dehack_fail = "[name] is not responding to reset commands!"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<TT><B>Floor Repairer Controls v1.1</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Special tiles: "
|
||||
if(specialtiles)
|
||||
dat += "<A href='?src=[REF(src)];operation=eject'>Loaded \[[specialtiles]/[maxtiles]\]</a><BR>"
|
||||
else
|
||||
dat += "None Loaded<BR>"
|
||||
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += "Add tiles to new hull plating: <A href='?src=[REF(src)];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Place floor tiles: <A href='?src=[REF(src)];operation=place'>[placetiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Replace existing floor tiles with custom tiles: <A href='?src=[REF(src)];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Repair damaged tiles and platings: <A href='?src=[REF(src)];operation=fix'>[fixfloors ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Traction Magnets: <A href='?src=[REF(src)];operation=anchor'>[anchored ? "Engaged" : "Disengaged"]</A><BR>"
|
||||
dat += "Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
|
||||
var/bmode
|
||||
if(targetdirection)
|
||||
bmode = dir2text(targetdirection)
|
||||
else
|
||||
bmode = "disabled"
|
||||
dat += "Line Mode : <A href='?src=[REF(src)];operation=linemode'>[bmode]</A><BR>"
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params)
|
||||
if(istype(W, /obj/item/stack/tile/plasteel))
|
||||
to_chat(user, "<span class='notice'>The floorbot can produce normal tiles itself.</span>")
|
||||
@@ -161,26 +131,44 @@
|
||||
if(user)
|
||||
to_chat(user, "<span class='danger'>[src] buzzes and beeps.</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/floorbot/ui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
data["custom_controls"]["tile_hull"] = autotile
|
||||
data["custom_controls"]["place_tiles"] = placetiles
|
||||
data["custom_controls"]["place_custom"] = replacetiles
|
||||
data["custom_controls"]["repair_damage"] = fixfloors
|
||||
data["custom_controls"]["traction_magnets"] = anchored
|
||||
data["custom_controls"]["tile_stack"] = 0
|
||||
data["custom_controls"]["line_mode"] = FALSE
|
||||
if(specialtiles)
|
||||
data["custom_controls"]["tile_stack"] = specialtiles
|
||||
if(targetdirection)
|
||||
data["custom_controls"]["line_mode"] = dir2text(targetdirection)
|
||||
return data
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("replace")
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/floorbot/ui_act(action, params)
|
||||
. = ..()
|
||||
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("place_custom")
|
||||
replacetiles = !replacetiles
|
||||
if("place")
|
||||
if("place_tiles")
|
||||
placetiles = !placetiles
|
||||
if("fix")
|
||||
if("repair_damage")
|
||||
fixfloors = !fixfloors
|
||||
if("autotile")
|
||||
if("tile_hull")
|
||||
autotile = !autotile
|
||||
if("anchor")
|
||||
if("traction_magnets")
|
||||
anchored = !anchored
|
||||
if("eject")
|
||||
if("eject_tiles")
|
||||
if(specialtiles && tiletype != null)
|
||||
empty_tiles()
|
||||
|
||||
if("linemode")
|
||||
if("line_mode")
|
||||
var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable")
|
||||
switch(setdir)
|
||||
if("north")
|
||||
@@ -193,7 +181,7 @@
|
||||
targetdirection = 8
|
||||
if("disable")
|
||||
targetdirection = null
|
||||
update_controls()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/empty_tiles()
|
||||
new tiletype(drop_location(), specialtiles)
|
||||
|
||||
@@ -78,24 +78,6 @@
|
||||
text_dehack = "You reboot [name] and restore the sound control system."
|
||||
text_dehack_fail = "[name] refuses to accept your authority!"
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Honkomatic Bike Horn Unit v1.0.7 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=[TRUE]'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += text({"<BR> Auto Patrol: []"},
|
||||
|
||||
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/judgement_criteria()
|
||||
var/final = NONE
|
||||
if(check_records)
|
||||
|
||||
@@ -155,87 +155,63 @@
|
||||
/mob/living/simple_animal/bot/medbot/attack_paw(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<TT><B>Medical Unit Controls v1.1</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Beaker: "
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/medbot/ui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
if(reagent_glass)
|
||||
dat += "<A href='?src=[REF(src)];eject=1'>Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]</a>"
|
||||
else
|
||||
dat += "None Loaded"
|
||||
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
|
||||
data["custom_controls"]["beaker"] = reagent_glass
|
||||
data["custom_contrlos"]["reagents"] = "[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]"
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += "<TT>Healing Threshold: "
|
||||
dat += "<a href='?src=[REF(src)];adj_threshold=-10'>--</a> "
|
||||
dat += "<a href='?src=[REF(src)];adj_threshold=-5'>-</a> "
|
||||
dat += "[heal_threshold] "
|
||||
dat += "<a href='?src=[REF(src)];adj_threshold=5'>+</a> "
|
||||
dat += "<a href='?src=[REF(src)];adj_threshold=10'>++</a>"
|
||||
dat += "</TT><br>"
|
||||
data["custom_controls"]["injection_amount"] = injection_amount
|
||||
data["custom_controls"]["use_beaker"] = use_beaker
|
||||
data["custom_controls"]["treat_virus"] = treat_virus
|
||||
data["custom_controls"]["heal_threshold"] = heal_threshold
|
||||
data["custom_controls"]["speaker"] = !shut_up
|
||||
data["custom_controls"]["crit_alerts"] = declare_crit
|
||||
data["custom_controls"]["stationary_mode"] = stationary_mode
|
||||
return data
|
||||
|
||||
dat += "<TT>Injection Level: "
|
||||
dat += "<a href='?src=[REF(src)];adj_inject=-5'>-</a> "
|
||||
dat += "[injection_amount] "
|
||||
dat += "<a href='?src=[REF(src)];adj_inject=5'>+</a> "
|
||||
dat += "</TT><br>"
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/medbot/ui_act(action, params)
|
||||
. = ..()
|
||||
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("heal_threshold")
|
||||
var/adjust_num = round(text2num(params["threshold"]))
|
||||
heal_threshold = adjust_num
|
||||
if(heal_threshold < 5)
|
||||
heal_threshold = 5
|
||||
if(heal_threshold > 75)
|
||||
heal_threshold = 75
|
||||
|
||||
dat += "Reagent Source: "
|
||||
dat += "<a href='?src=[REF(src)];use_beaker=1'>[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]</a><br>"
|
||||
if("injection_amount")
|
||||
var/adjust_num = round(text2num(params["amount"]))
|
||||
injection_amount = adjust_num
|
||||
if(injection_amount < 1)
|
||||
injection_amount = 1
|
||||
if(injection_amount > 15)
|
||||
injection_amount = 15
|
||||
|
||||
dat += "Treat Viral Infections: <a href='?src=[REF(src)];virus=1'>[treat_virus ? "Yes" : "No"]</a><br>"
|
||||
dat += "The speaker switch is [shut_up ? "off" : "on"]. <a href='?src=[REF(src)];togglevoice=[1]'>Toggle</a><br>"
|
||||
dat += "Critical Patient Alerts: <a href='?src=[REF(src)];critalerts=1'>[declare_crit ? "Yes" : "No"]</a><br>"
|
||||
dat += "Patrol Station: <a href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</a><br>"
|
||||
dat += "Stationary Mode: <a href='?src=[REF(src)];stationary=1'>[stationary_mode ? "Yes" : "No"]</a><br>"
|
||||
if("use_beaker")
|
||||
use_beaker = !use_beaker
|
||||
|
||||
return dat
|
||||
if("eject")
|
||||
if(!isnull(reagent_glass))
|
||||
reagent_glass.forceMove(drop_location())
|
||||
reagent_glass = null
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if("speaker")
|
||||
shut_up = !shut_up
|
||||
if("crit_alerts")
|
||||
declare_crit = !declare_crit
|
||||
if("stationary_mode")
|
||||
stationary_mode = !stationary_mode
|
||||
path = list()
|
||||
update_appearance()
|
||||
|
||||
if(href_list["adj_threshold"])
|
||||
var/adjust_num = text2num(href_list["adj_threshold"])
|
||||
heal_threshold += adjust_num
|
||||
if(heal_threshold < 5)
|
||||
heal_threshold = 5
|
||||
if(heal_threshold > 75)
|
||||
heal_threshold = 75
|
||||
|
||||
else if(href_list["adj_inject"])
|
||||
var/adjust_num = text2num(href_list["adj_inject"])
|
||||
injection_amount += adjust_num
|
||||
if(injection_amount < 5)
|
||||
injection_amount = 5
|
||||
if(injection_amount > 15)
|
||||
injection_amount = 15
|
||||
|
||||
else if(href_list["use_beaker"])
|
||||
use_beaker = !use_beaker
|
||||
|
||||
else if(href_list["eject"] && (!isnull(reagent_glass)))
|
||||
reagent_glass.forceMove(drop_location())
|
||||
reagent_glass = null
|
||||
|
||||
else if(href_list["togglevoice"])
|
||||
shut_up = !shut_up
|
||||
|
||||
else if(href_list["critalerts"])
|
||||
declare_crit = !declare_crit
|
||||
|
||||
else if(href_list["stationary"])
|
||||
stationary_mode = !stationary_mode
|
||||
path = list()
|
||||
update_icon()
|
||||
|
||||
else if(href_list["virus"])
|
||||
treat_virus = !treat_virus
|
||||
|
||||
update_controls()
|
||||
if("virus")
|
||||
treat_virus = !treat_virus
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
@@ -251,7 +227,6 @@
|
||||
|
||||
reagent_glass = W
|
||||
to_chat(user, "<span class='notice'>You insert [W].</span>")
|
||||
show_controls(user)
|
||||
|
||||
else if(istype(W, /obj/item/reagent_containers/syringe/piercing))
|
||||
if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_PIERERCING))
|
||||
|
||||
@@ -276,56 +276,6 @@
|
||||
if("ejectpai")
|
||||
ejectpairemote(user)
|
||||
|
||||
// TODO: remove this; PDAs currently depend on it
|
||||
/mob/living/simple_animal/bot/mulebot/get_controls(mob/user)
|
||||
var/ai = hasSiliconAccessInArea(user)
|
||||
var/dat
|
||||
dat += "<h3>Multiple Utility Load Effector Mk. V</h3>"
|
||||
dat += "<b>ID:</b> [id]<BR>"
|
||||
dat += "<b>Power:</b> [on ? "On" : "Off"]<BR>"
|
||||
dat += "<h3>Status</h3>"
|
||||
dat += "<div class='statusDisplay'>"
|
||||
switch(mode)
|
||||
if(BOT_IDLE)
|
||||
dat += "<span class='good'>Ready</span>"
|
||||
if(BOT_DELIVER)
|
||||
dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>"
|
||||
if(BOT_GO_HOME)
|
||||
dat += "<span class='good'>[mode_name[BOT_GO_HOME]]</span>"
|
||||
if(BOT_BLOCKED)
|
||||
dat += "<span class='average'>[mode_name[BOT_BLOCKED]]</span>"
|
||||
if(BOT_NAV,BOT_WAIT_FOR_NAV)
|
||||
dat += "<span class='average'>[mode_name[BOT_NAV]]</span>"
|
||||
if(BOT_NO_ROUTE)
|
||||
dat += "<span class='bad'>[mode_name[BOT_NO_ROUTE]]</span>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<b>Current Load:</b> [load ? load.name : "<i>none</i>"]<BR>"
|
||||
dat += "<b>Destination:</b> [!destination ? "<i>none</i>" : destination]<BR>"
|
||||
dat += "<b>Power level:</b> [cell ? cell.percent() : 0]%"
|
||||
|
||||
if(locked && !ai && !IsAdminGhost(user))
|
||||
dat += " <br /><div class='notice'>Controls are locked</div><A href='byond://?src=[REF(src)];op=unlock'>Unlock Controls</A>"
|
||||
else
|
||||
dat += " <br /><div class='notice'>Controls are unlocked</div><A href='byond://?src=[REF(src)];op=lock'>Lock Controls</A><BR><BR>"
|
||||
|
||||
dat += "<A href='byond://?src=[REF(src)];op=power'>Toggle Power</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=stop'>Stop</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=go'>Proceed</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=home'>Return to Home</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=destination'>Set Destination</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=setid'>Set Bot ID</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=sethome'>Set Home</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];op=report'>Toggle Delivery Reporting</A> ([report_delivery ? "On" : "Off"])<BR>"
|
||||
if(load)
|
||||
dat += "<A href='byond://?src=[REF(src)];op=unload'>Unload Now</A><BR>"
|
||||
dat += "<div class='notice'>The maintenance hatch is closed.</div>"
|
||||
|
||||
return dat
|
||||
|
||||
|
||||
// returns true if the bot has power
|
||||
/mob/living/simple_animal/bot/mulebot/proc/has_power()
|
||||
return !open && cell && cell.charge > 0 && (!wires.is_cut(WIRE_POWER1) && !wires.is_cut(WIRE_POWER2))
|
||||
|
||||
@@ -209,57 +209,34 @@
|
||||
text_dehack = "You reboot [name] and restore the target identification."
|
||||
text_dehack_fail = "[name] refuses to accept your authority!"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
// Variables sent to TGUI
|
||||
/mob/living/simple_animal/bot/secbot/ui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol: []"},
|
||||
data["custom_controls"]["check_id"] = idcheck
|
||||
data["custom_controls"]["check_weapons"] = weaponscheck
|
||||
data["custom_controls"]["check_warrants"] = check_records
|
||||
data["custom_controls"]["handcuff_targets"] = !arrest_type
|
||||
data["custom_controls"]["arrest_alert"] = declare_arrests
|
||||
return data
|
||||
|
||||
"<A href='?src=[REF(src)];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
// Actions received from TGUI
|
||||
/mob/living/simple_animal/bot/secbot/ui_act(action, params)
|
||||
. = ..()
|
||||
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
switch(action)
|
||||
if("check_id")
|
||||
idcheck = !idcheck
|
||||
update_controls()
|
||||
if("weaponscheck")
|
||||
if("check_weapons")
|
||||
weaponscheck = !weaponscheck
|
||||
update_controls()
|
||||
if("ignorerec")
|
||||
if("check_warrants")
|
||||
check_records = !check_records
|
||||
update_controls()
|
||||
if("switchmode")
|
||||
if("handcuff_targets")
|
||||
arrest_type = !arrest_type
|
||||
update_controls()
|
||||
if("declarearrests")
|
||||
if("arrest_alert")
|
||||
declare_arrests = !declare_arrests
|
||||
update_controls()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
|
||||
@@ -308,10 +308,15 @@
|
||||
adjustHealth(unsuitable_atmos_damage)
|
||||
|
||||
/mob/living/simple_animal/gib(no_brain, no_organs, no_bodyparts, datum/explosion/was_explosion)
|
||||
if(butcher_results)
|
||||
if(butcher_results || guaranteed_butcher_results)
|
||||
var/list/butcher = list()
|
||||
if(butcher_results)
|
||||
butcher += butcher_results
|
||||
if(guaranteed_butcher_results)
|
||||
butcher += guaranteed_butcher_results
|
||||
var/atom/Tsec = drop_location()
|
||||
for(var/path in butcher_results)
|
||||
for(var/i in 1 to butcher_results[path])
|
||||
for(var/path in butcher)
|
||||
for(var/i in 1 to butcher[path])
|
||||
new path(Tsec)
|
||||
..()
|
||||
|
||||
|
||||
@@ -495,7 +495,11 @@
|
||||
|
||||
/datum/status_effect/stabilized/orange/tick()
|
||||
var/body_temperature_difference = BODYTEMP_NORMAL - owner.bodytemperature
|
||||
owner.adjust_bodytemperature(min(5,body_temperature_difference))
|
||||
var/cooling_cap = -5
|
||||
if(HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM))
|
||||
cooling_cap *= 0.5 //Only cools by half as much (which is 5 per life tick since this ticks twice as much as life) so it isn't true spaceproofness..
|
||||
body_temperature_difference += SYNTH_COLD_OFFSET //.. But also cools towards a cold temp, provided there is nothing that counters it.
|
||||
owner.adjust_bodytemperature(clamp(body_temperature_difference, cooling_cap, 5))
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/purple
|
||||
|
||||
@@ -12,14 +12,29 @@
|
||||
max_integrity = 200
|
||||
var/faction = list("ashwalker")
|
||||
var/meat_counter = 6
|
||||
var/datum/team/ashwalkers/ashies
|
||||
var/datum/linked_objective
|
||||
|
||||
/obj/structure/lavaland/ash_walker/Initialize()
|
||||
/obj/structure/lavaland/ash_walker/Initialize(mapload)
|
||||
.=..()
|
||||
ashies = new /datum/team/ashwalkers()
|
||||
var/datum/objective/protect_object/objective = new
|
||||
objective.set_target(src)
|
||||
linked_objective = objective
|
||||
ashies.objectives += objective
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/structure/lavaland/ash_walker/Destroy()
|
||||
ashies.objectives -= linked_objective
|
||||
ashies = null
|
||||
QDEL_NULL(linked_objective)
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/lavaland/ash_walker/deconstruct(disassembled)
|
||||
new /obj/item/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs)))
|
||||
new /obj/effect/collapse(loc)
|
||||
return ..()
|
||||
|
||||
/obj/structure/lavaland/ash_walker/process()
|
||||
consume()
|
||||
@@ -28,20 +43,64 @@
|
||||
/obj/structure/lavaland/ash_walker/proc/consume()
|
||||
for(var/mob/living/H in view(src, 1)) //Only for corpse right next to/on same tile
|
||||
if(H.stat)
|
||||
visible_message("<span class='warning'>Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.</span>")
|
||||
playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, 1)
|
||||
for(var/obj/item/W in H)
|
||||
if(!H.dropItemToGround(W))
|
||||
qdel(W)
|
||||
if(issilicon(H)) //no advantage to sacrificing borgs...
|
||||
H.gib()
|
||||
visible_message(span_notice("Serrated tendrils eagerly pull [H] apart, but find nothing of interest."))
|
||||
return
|
||||
|
||||
if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.key || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached
|
||||
visible_message(span_warning("Serrated tendrils carefully pull [H] to [src], absorbing the body and creating it anew."))
|
||||
var/datum/mind/deadmind
|
||||
if(H.key)
|
||||
deadmind = H
|
||||
else
|
||||
deadmind = H.get_ghost(FALSE, TRUE)
|
||||
to_chat(deadmind, "Your body has been returned to the nest. You are being remade anew, and will awaken shortly. </br><b>Your memories will remain intact in your new body, as your soul is being salvaged</b>")
|
||||
SEND_SOUND(deadmind, sound('sound/magic/enter_blood.ogg',volume=100))
|
||||
addtimer(CALLBACK(src, .proc/remake_walker, H.mind, H.real_name), 20 SECONDS)
|
||||
new /obj/effect/gibspawner/generic(get_turf(H))
|
||||
qdel(H)
|
||||
return
|
||||
|
||||
if(ismegafauna(H))
|
||||
meat_counter += 20
|
||||
else
|
||||
meat_counter++
|
||||
visible_message(span_warning("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs."))
|
||||
playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE)
|
||||
var/deliverykey = H.fingerprintslast //key of whoever brought the body
|
||||
var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said key
|
||||
//there is a 40% chance that the Lava Lizard unlocks their respawn with each sacrifice
|
||||
if(deliverymob && (deliverymob.mind?.has_antag_datum(/datum/antagonist/ashwalker)) && (deliverykey in ashies.players_spawned) && (prob(40)))
|
||||
to_chat(deliverymob, span_warning("<b>The Necropolis is pleased with your sacrifice. You feel confident your existence after death is secure.</b>"))
|
||||
ashies.players_spawned -= deliverykey
|
||||
H.gib()
|
||||
obj_integrity = min(obj_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril
|
||||
for(var/mob/living/L in view(src, 5))
|
||||
if(L.mind?.has_antag_datum(/datum/antagonist/ashwalker))
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "headspear", /datum/mood_event/sacrifice_good)
|
||||
else
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "headspear", /datum/mood_event/sacrifice_bad)
|
||||
|
||||
/obj/structure/lavaland/ash_walker/proc/remake_walker(datum/mind/oldmind, oldname)
|
||||
var/mob/living/carbon/human/M = new /mob/living/carbon/human(get_step(loc, pick(GLOB.alldirs)))
|
||||
M.set_species(/datum/species/lizard/ashwalker)
|
||||
M.real_name = oldname
|
||||
M.underwear = "Nude"
|
||||
M.undershirt = "Nude"
|
||||
M.socks = "Nude"
|
||||
M.update_body()
|
||||
M.remove_language(/datum/language/common)
|
||||
oldmind.transfer_to(M)
|
||||
M.mind.grab_ghost()
|
||||
to_chat(M, "<b>You have been pulled back from beyond the grave, with a new body and renewed purpose. Glory to the Necropolis!</b>")
|
||||
playsound(get_turf(M),'sound/magic/exit_blood.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/lavaland/ash_walker/proc/spawn_mob()
|
||||
if(meat_counter >= ASH_WALKER_SPAWN_THRESHOLD)
|
||||
new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs)))
|
||||
new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs)), ashies)
|
||||
visible_message("<span class='danger'>One of the eggs swells to an unnatural size and tumbles free. It's ready to hatch!</span>")
|
||||
meat_counter -= ASH_WALKER_SPAWN_THRESHOLD
|
||||
|
||||
@@ -35,67 +35,63 @@
|
||||
. = ..()
|
||||
. += distance_multiplier < 1 ? "Bluespace shortcut module installed. Route is [distance_multiplier]x the original length." : ""
|
||||
|
||||
/obj/machinery/computer/custom_shuttle/ui_interact(mob/user)
|
||||
/obj/machinery/computer/custom_shuttle/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "CustomShuttleConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/custom_shuttle/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/options = params2list(possible_destinations)
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
var/dat = "[M ? "Current Location : [M.getStatusText()]" : "Shuttle link required."]<br><br>"
|
||||
data["docked_location"] = M ? M.get_status_text_tgui() : null
|
||||
if(M)
|
||||
dat += "<A href='?src=[REF(src)];calculate=1'>Run Flight Calculations</A><br>"
|
||||
dat += "<b>Shuttle Data</b><hr>"
|
||||
dat += "Shuttle Mass: [calculated_mass/10]tons<br>"
|
||||
dat += "Engine Force: [calculated_dforce]kN ([calculated_engine_count] engines)<br>"
|
||||
dat += "Sublight Speed: [calculated_speed]ms<sup>-1</sup><br>"
|
||||
dat += calculated_speed < 1 ? "<b>INSUFFICIENT ENGINE POWER</b><br>" : ""
|
||||
dat += calculated_non_operational_thrusters > 0 ? "<b>Warning: [calculated_non_operational_thrusters] thrusters offline.</b><br>" : ""
|
||||
dat += "Fuel Consumption: [calculated_consumption]units per distance<br>"
|
||||
dat += "Engine Cooldown: [calculated_cooldown]s<hr>"
|
||||
var/destination_found
|
||||
calculateStats(FALSE, 0, TRUE)
|
||||
data["ship_name"] = M.area_type ? M.area_type:name : "ERROR"
|
||||
data["shuttle_mass"] = calculated_mass/10
|
||||
data["engine_force"] = calculated_dforce
|
||||
data["engines"] = calculated_engine_count
|
||||
data["calculated_speed"] = calculated_speed
|
||||
data["damaged_engines"] = calculated_non_operational_thrusters
|
||||
data["calculated_consumption"] = calculated_consumption
|
||||
data["calculated_cooldown"] = calculated_cooldown
|
||||
data["locations"] = list()
|
||||
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
|
||||
if(!options.Find(S.id))
|
||||
continue
|
||||
if(!M.check_dock(S, silent=TRUE))
|
||||
if(!M.check_dock(S, silent = TRUE))
|
||||
continue
|
||||
if(calculated_speed == 0)
|
||||
break
|
||||
destination_found = TRUE
|
||||
var/dist = round(calculateDistance(S))
|
||||
dat += "<A href='?src=[REF(src)];setloc=[S.id]'>Target [S.name] (Dist: [dist] | Fuel Cost: [round(dist * calculated_consumption)] | Time: [round(dist / calculated_speed)])</A><br>"
|
||||
if(!destination_found)
|
||||
dat += "<B>No valid destinations</B><br>"
|
||||
dat += "<hr>[targetLocation ? "Target Location : [targetLocation]" : "No Target Location"]"
|
||||
dat += "<hr><A href='?src=[REF(src)];fly=1'>Initate Flight</A><br>"
|
||||
dat += "<A href='?src=[REF(user)];mach_close=computer'>Close</a>"
|
||||
var/list/location_data = list(
|
||||
id = S.id,
|
||||
name = S.name,
|
||||
dist = round(calculateDistance(S))
|
||||
)
|
||||
data["locations"] += list(location_data)
|
||||
data["destination"] = targetLocation
|
||||
return data
|
||||
|
||||
popup = new(user, "computer", M ? M.name : "shuttle", 350, 450)
|
||||
popup.set_content("<center>[dat]</center>")
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/custom_shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
/obj/machinery/computer/custom_shuttle/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(!allowed(usr))
|
||||
to_chat(usr, "<span class='danger'>Access denied.</span>")
|
||||
return
|
||||
|
||||
if(href_list["calculate"])
|
||||
calculateStats()
|
||||
ui_interact(usr)
|
||||
return
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
if(!M)
|
||||
to_chat(usr, "<span class='danger'>Shuttle Link Required.</span>")
|
||||
return
|
||||
if(M.launch_status == ENDGAME_LAUNCHED)
|
||||
return
|
||||
if(href_list["setloc"])
|
||||
SetTargetLocation(href_list["setloc"])
|
||||
ui_interact(usr)
|
||||
return
|
||||
else if(href_list["fly"])
|
||||
Fly()
|
||||
ui_interact(usr)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("setloc")
|
||||
SetTargetLocation(params["setloc"])
|
||||
if("fly")
|
||||
Fly()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/custom_shuttle/proc/calculateDistance(var/obj/docking_port/stationary/port)
|
||||
var/deltaX = port.x - x
|
||||
|
||||
Reference in New Issue
Block a user