mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-01-05 23:12:26 +00:00
Merge branch 'master' into aro-poismes
This commit is contained in:
@@ -142,6 +142,7 @@
|
||||
hostile = FALSE
|
||||
retaliate = FALSE
|
||||
cooperative = FALSE
|
||||
holder.a_intent = I_HELP
|
||||
|
||||
// The holder's attack changes based on intent. This lets the AI choose what effect is desired.
|
||||
/datum/ai_holder/simple_mob/xenobio_slime/pre_melee_attack(atom/A)
|
||||
@@ -178,6 +179,7 @@
|
||||
if(!(H in grudges)) // Unless they're an ass.
|
||||
return FALSE
|
||||
if(discipline && !rabid)
|
||||
holder.a_intent = I_HELP
|
||||
return FALSE // We're a good slime.
|
||||
|
||||
/datum/ai_holder/simple_mob/xenobio_slime/react_to_attack(atom/movable/attacker)
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
STANCE_REPOSITION,
|
||||
STANCE_MOVE,
|
||||
STANCE_FOLLOW,
|
||||
STANCE_FLEE
|
||||
STANCE_FLEE,
|
||||
STANCE_DISABLED
|
||||
)
|
||||
var/list/static/noprocess_stances = list(
|
||||
STANCE_SLEEP
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
var/chatOutputLoadedAt
|
||||
|
||||
var/adminhelped = 0
|
||||
var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel.
|
||||
|
||||
|
||||
///////////////
|
||||
//SOUND STUFF//
|
||||
|
||||
@@ -5,17 +5,18 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
|
||||
"operative" = 1, // 1
|
||||
"changeling" = 1, // 2
|
||||
"wizard" = 1, // 3
|
||||
"malf AI" = 1, // 4
|
||||
"malf AI" = 1, // 4
|
||||
"revolutionary" = 1, // 5
|
||||
"alien candidate" = 1, // 6
|
||||
"positronic brain" = 1, // 7
|
||||
"cultist" = 1, // 8
|
||||
"renegade" = 1, // 9
|
||||
"ninja" = 1, // 10
|
||||
"renegade" = 1, // 9
|
||||
"ninja" = 1, // 10
|
||||
"raider" = 1, // 11
|
||||
"diona" = 1, // 12
|
||||
"loyalist" = 1, // 13
|
||||
"pAI candidate" = 1, // -- TLE // 14
|
||||
"diona" = 1, // 12
|
||||
"mutineer" = 1, // 13
|
||||
"loyalist" = 1, // 14
|
||||
"pAI candidate" = 1, // 15
|
||||
)
|
||||
|
||||
/datum/category_item/player_setup_item/antagonism/candidacy
|
||||
|
||||
@@ -75,16 +75,16 @@
|
||||
path = /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen/sleeveless
|
||||
|
||||
/datum/gear/suit/mil
|
||||
display_name = "military jacket"
|
||||
display_name = "military jacket selection"
|
||||
path = /obj/item/clothing/suit/storage/miljacket
|
||||
|
||||
/datum/gear/suit/mil/alt
|
||||
display_name = "military jacket, alt"
|
||||
path = /obj/item/clothing/suit/storage/miljacket/alt
|
||||
|
||||
/datum/gear/suit/mil/green
|
||||
display_name = "military jacket, green"
|
||||
path = /obj/item/clothing/suit/storage/miljacket/green
|
||||
|
||||
/datum/gear/suit/mil/New()
|
||||
..()
|
||||
var/list/mil_jackets = list()
|
||||
for(var/military_style in typesof(/obj/item/clothing/suit/storage/miljacket))
|
||||
var/obj/item/clothing/suit/storage/miljacket/miljacket = military_style
|
||||
mil_jackets[initial(miljacket.name)] = miljacket
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(mil_jackets))
|
||||
|
||||
/datum/gear/suit/greyjacket
|
||||
display_name = "grey jacket"
|
||||
|
||||
@@ -131,6 +131,10 @@ datum/preferences
|
||||
|
||||
var/lastnews // Hash of last seen lobby news content.
|
||||
|
||||
var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel.
|
||||
var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off
|
||||
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
player_setup = new(src)
|
||||
set_biological_gender(pick(MALE, FEMALE))
|
||||
|
||||
@@ -81,6 +81,8 @@
|
||||
else
|
||||
player_setup.load_character(S)
|
||||
S.cd = "/character[default_slot]"
|
||||
player_setup.save_character(S)
|
||||
sanitize_preferences()
|
||||
|
||||
player_setup.load_character(S)
|
||||
return 1
|
||||
|
||||
@@ -13,6 +13,7 @@ var/list/spawntypes = list()
|
||||
var/list/restrict_job = null
|
||||
var/list/disallow_job = null
|
||||
var/announce_channel = "Common"
|
||||
var/allowed_mob_types = JOB_SILICON|JOB_CARBON
|
||||
|
||||
proc/check_job_spawning(job)
|
||||
if(restrict_job && !(job in restrict_job))
|
||||
@@ -22,9 +23,15 @@ var/list/spawntypes = list()
|
||||
return 0
|
||||
|
||||
var/datum/job/J = SSjob.get_job(job)
|
||||
if(J?.offmap_spawn && !(job in restrict_job))
|
||||
if(!J) // Couldn't find, admin shenanigans? Allow it
|
||||
return 1
|
||||
|
||||
if(J.offmap_spawn && !(job in restrict_job))
|
||||
return 0
|
||||
|
||||
if(!(J.mob_type & allowed_mob_types))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/datum/spawnpoint/proc/get_spawn_position()
|
||||
@@ -57,7 +64,7 @@ var/list/spawntypes = list()
|
||||
/datum/spawnpoint/cryo
|
||||
display_name = "Cryogenic Storage"
|
||||
msg = "has completed cryogenic revival"
|
||||
disallow_job = list("Cyborg")
|
||||
allowed_mob_types = JOB_CARBON
|
||||
|
||||
/datum/spawnpoint/cryo/New()
|
||||
..()
|
||||
@@ -66,7 +73,7 @@ var/list/spawntypes = list()
|
||||
/datum/spawnpoint/cyborg
|
||||
display_name = "Cyborg Storage"
|
||||
msg = "has been activated from storage"
|
||||
restrict_job = list("Cyborg")
|
||||
allowed_mob_types = JOB_SILICON
|
||||
|
||||
/datum/spawnpoint/cyborg/New()
|
||||
..()
|
||||
|
||||
@@ -313,17 +313,34 @@
|
||||
set category = "Preferences"
|
||||
set desc = "Control the additional behaviour of examining things"
|
||||
|
||||
examine_text_mode++
|
||||
examine_text_mode %= EXAMINE_MODE_MAX // This cycles through them because if you're already specifically being routed to the examine panel, you probably don't need to have the extra text printed to chat
|
||||
switch(examine_text_mode) // ... And I only wanted to add one verb
|
||||
prefs.examine_text_mode++
|
||||
prefs.examine_text_mode %= EXAMINE_MODE_MAX // This cycles through them because if you're already specifically being routed to the examine panel, you probably don't need to have the extra text printed to chat
|
||||
switch(prefs.examine_text_mode) // ... And I only wanted to add one verb
|
||||
if(EXAMINE_MODE_DEFAULT)
|
||||
to_chat(src, "Examining things will only output the base examine text, and you will not be redirected to the examine panel automatically.")
|
||||
to_chat(src, "<span class='filter_system'>Examining things will only output the base examine text, and you will not be redirected to the examine panel automatically.</span>")
|
||||
|
||||
if(EXAMINE_MODE_INCLUDE_USAGE)
|
||||
to_chat(src, "Examining things will also print any extra usage information normally included in the examine panel to the chat.")
|
||||
to_chat(src, "<span class='filter_system'>Examining things will also print any extra usage information normally included in the examine panel to the chat.</span>")
|
||||
|
||||
if(EXAMINE_MODE_SWITCH_TO_PANEL)
|
||||
to_chat(src, "Examining things will direct you to the examine panel, where you can view extended information about the thing.")
|
||||
to_chat(src, "<span class='filter_system'>Examining things will direct you to the examine panel, where you can view extended information about the thing.</span>")
|
||||
|
||||
/client/verb/toggle_multilingual_mode()
|
||||
set name = "Toggle Multilingual Mode"
|
||||
set category = "Preferences"
|
||||
set desc = "Control the behaviour of multilingual speech parsing"
|
||||
|
||||
prefs.multilingual_mode++
|
||||
prefs.multilingual_mode %= MULTILINGUAL_MODE_MAX // Cycles through the various options
|
||||
switch(prefs.multilingual_mode)
|
||||
if(MULTILINGUAL_DEFAULT)
|
||||
to_chat(src, "<span class='filter_system'>Multilingual parsing will only check for the delimiter-key combination (,0galcom-2tradeband).</span>")
|
||||
if(MULTILINGUAL_SPACE)
|
||||
to_chat(src, "<span class='filter_system'>Multilingual parsing will enforce a space after the delimiter-key combination (,0 galcom -2still galcom). The extra space will be consumed by the pattern-matching.</span>")
|
||||
if(MULTILINGUAL_DOUBLE_DELIMITER)
|
||||
to_chat(src, "<span class='filter_system'>Multilingual parsing will enforce the a language delimiter after the delimiter-key combination (,0,galcom -2 still galcom). The extra delimiter will be consumed by the pattern-matching.</span>")
|
||||
if(MULTILINGUAL_OFF)
|
||||
to_chat(src, "<span class='filter_system'>Multilingual parsing is now disabled. Entire messages will be in the language specified at the start of the message.</span>")
|
||||
|
||||
|
||||
//Toggles for Staff
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
user.recalculate_vis()
|
||||
|
||||
//BS12: Species-restricted clothing check.
|
||||
/obj/item/clothing/mob_can_equip(M as mob, slot)
|
||||
/obj/item/clothing/mob_can_equip(M as mob, slot, disable_warning = 0)
|
||||
|
||||
//if we can't equip the item anyway, don't bother with species_restricted (cuts down on spam)
|
||||
if (!..())
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
drop_sound = 'sound/items/drop/metalshield.ogg'
|
||||
|
||||
/obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot)
|
||||
/obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
if(..()) //This will only run if no other problems occured when equiping.
|
||||
if(H.wear_suit)
|
||||
if(H.wear_suit.body_parts_covered & ARMS)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
punch_force = 5
|
||||
var/obj/item/clothing/gloves/gloves = null //Undergloves
|
||||
|
||||
/obj/item/clothing/gloves/gauntlets/mob_can_equip(mob/user)
|
||||
/obj/item/clothing/gloves/gauntlets/mob_can_equip(mob/user, slot, disable_warning = 0)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.gloves)
|
||||
gloves = H.gloves
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
canremove = 1
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/mask/monitor/mob_can_equip(var/mob/living/carbon/human/user, var/slot)
|
||||
/obj/item/clothing/mask/monitor/mob_can_equip(var/mob/living/carbon/human/user, var/slot, disable_warning = FALSE)
|
||||
if (!..())
|
||||
return 0
|
||||
if(istype(user))
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
user.update_inv_shoes() //so our mob-overlays update
|
||||
user.update_action_buttons()
|
||||
|
||||
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user, slot)
|
||||
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user, slot, disable_warning = FALSE)
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
if(H.shoes)
|
||||
|
||||
@@ -520,7 +520,7 @@
|
||||
|ACCESSORY_SLOT_ARMOR_M)
|
||||
blood_overlay_type = "armor"
|
||||
|
||||
/obj/item/clothing/suit/armor/pcarrier/mob_can_equip(var/mob/living/carbon/human/H, slot)
|
||||
/obj/item/clothing/suit/armor/pcarrier/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE)
|
||||
if(..()) //This will only run if no other problems occured when equiping.
|
||||
if(H.gloves)
|
||||
if(H.gloves.body_parts_covered & ARMS)
|
||||
|
||||
@@ -398,19 +398,59 @@ obj/item/clothing/suit/kamishimo
|
||||
flags_inv = HIDEHOLSTER
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/alt
|
||||
name = "military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable."
|
||||
name = "military jacket, alternate"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one has some extra badges on it."
|
||||
icon_state = "militaryjacket_badge"
|
||||
item_state_slots = list(slot_r_hand_str = "suit_olive", slot_l_hand_str = "suit_olive")
|
||||
flags_inv = HIDEHOLSTER
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/green
|
||||
name = "military jacket"
|
||||
desc = "A dark green canvas jacket. Feels sturdy, yet comfortable."
|
||||
name = "green military jacket"
|
||||
desc = "A dark but rather high-saturation green canvas jacket. Feels sturdy, yet comfortable."
|
||||
icon_state = "militaryjacket_green"
|
||||
item_state_slots = list(slot_r_hand_str = "suit_olive", slot_l_hand_str = "suit_olive")
|
||||
flags_inv = HIDEHOLSTER
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/tan
|
||||
name = "tan military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. Now in sandy tans for desert fans."
|
||||
icon_state = "militaryjacket_tan"
|
||||
item_state_slots = list(slot_r_hand_str = "suit_orange", slot_l_hand_str = "suit_orange")
|
||||
flags_inv = HIDEHOLSTER
|
||||
index = 1
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/grey
|
||||
name = "grey military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one's in urban grey."
|
||||
icon_state = "militaryjacket_grey"
|
||||
item_state_slots = list(slot_r_hand_str = "suit_grey", slot_l_hand_str = "suit_grey")
|
||||
flags_inv = HIDEHOLSTER
|
||||
index = 1
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/navy
|
||||
name = "navy military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. Dark navy, this one is."
|
||||
icon_state = "militaryjacket_navy"
|
||||
item_state_slots = list(slot_r_hand_str = "suit_navy", slot_l_hand_str = "suit_navy")
|
||||
flags_inv = HIDEHOLSTER
|
||||
index = 1
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/black
|
||||
name = "black military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. Now in tactical black."
|
||||
icon_state = "militaryjacket_black"
|
||||
item_state_slots = list(slot_r_hand_str = "suit_black", slot_l_hand_str = "suit_black")
|
||||
flags_inv = HIDEHOLSTER
|
||||
index = 1
|
||||
|
||||
/obj/item/clothing/suit/storage/miljacket/white
|
||||
name = "white military jacket"
|
||||
desc = "A white canvas jacket. Don't wear this for walks in the snow, it won't keep you warm - it'll just make it harder to find your frozen corpse."
|
||||
icon_state = "militaryjacket_white"
|
||||
item_state_slots = list(slot_r_hand_str = "med_dep_jacket", slot_l_hand_str = "med_dep_jacket")
|
||||
flags_inv = HIDEHOLSTER
|
||||
index = 1
|
||||
|
||||
/obj/item/clothing/suit/storage/toggle/bomber
|
||||
name = "bomber jacket"
|
||||
desc = "A thick, well-worn WW2 leather bomber jacket."
|
||||
|
||||
@@ -16,14 +16,9 @@
|
||||
var/last_process_worldtime = 0
|
||||
var/report_num = 0
|
||||
|
||||
/obj/machinery/dnaforensics/New()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
RefreshParts()
|
||||
..()
|
||||
/obj/machinery/dnaforensics/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/dnaforensics/attackby(var/obj/item/W, mob/user as mob)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
var/last_world_time = 0
|
||||
|
||||
/datum/event_container/process()
|
||||
if(!round_start_time)
|
||||
if(!GLOB.round_start_time)
|
||||
return //don't do events if the round hasn't even started yet
|
||||
|
||||
if(!next_event_time)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/lid_color = "black"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
lid_color = pick("black", "red", "blue")
|
||||
update_icon()
|
||||
|
||||
@@ -24,8 +24,14 @@
|
||||
name = "protein shake"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
reagents.add_reagent("nutriment", 30)
|
||||
reagents.add_reagent("iron", 10)
|
||||
reagents.add_reagent("protein", 35)
|
||||
reagents.add_reagent("water", 25)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake/update_icon()
|
||||
..()
|
||||
// And now set half the stuff back because our name shouldn't change
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
@@ -26,6 +26,8 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/afterattack(var/obj/target, var/mob/user, var/flag)
|
||||
if(!user.Adjacent(target))
|
||||
return
|
||||
if(standard_dispenser_refill(user, target))
|
||||
return
|
||||
if(standard_pour_into(user, target))
|
||||
|
||||
@@ -31,13 +31,11 @@
|
||||
********************/
|
||||
|
||||
/obj/machinery/microwave/Initialize()
|
||||
. = ..()
|
||||
reagents = new/datum/reagents(100)
|
||||
reagents.my_atom = src
|
||||
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/motor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
default_apply_parts()
|
||||
|
||||
if (!available_recipes)
|
||||
available_recipes = new
|
||||
@@ -60,9 +58,7 @@
|
||||
acceptable_items |= /obj/item/device/soulstone
|
||||
acceptable_items |= /obj/item/weapon/fuel_assembly/supermatter
|
||||
|
||||
RefreshParts()
|
||||
soundloop = new(list(src), FALSE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/microwave/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
|
||||
@@ -126,9 +126,11 @@
|
||||
"mutagen" = 15
|
||||
)
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/AltClick()
|
||||
if(mechanical && !usr.incapacitated() && Adjacent(usr))
|
||||
close_lid(usr)
|
||||
/obj/machinery/portable_atmospherics/hydroponics/AltClick(var/mob/living/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
if(mechanical && !user.incapacitated() && Adjacent(user))
|
||||
close_lid(user)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/clock/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, time2text(station_time_in_ticks, "hh:mm:ss") )
|
||||
set_pin_data(IC_OUTPUT, 2, text2num(time2text(station_time_in_ticks, "hh") ) )
|
||||
set_pin_data(IC_OUTPUT, 3, text2num(time2text(station_time_in_ticks, "mm") ) )
|
||||
set_pin_data(IC_OUTPUT, 4, text2num(time2text(station_time_in_ticks, "ss") ) )
|
||||
set_pin_data(IC_OUTPUT, 1, time2text(station_time_in_ds, "hh:mm:ss") )
|
||||
set_pin_data(IC_OUTPUT, 2, text2num(time2text(station_time_in_ds, "hh") ) )
|
||||
set_pin_data(IC_OUTPUT, 3, text2num(time2text(station_time_in_ds, "mm") ) )
|
||||
set_pin_data(IC_OUTPUT, 4, text2num(time2text(station_time_in_ds, "ss") ) )
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
@@ -52,16 +52,9 @@
|
||||
var/need_update_field = 0
|
||||
var/need_player_check = 0
|
||||
|
||||
/obj/machinery/mining/drill/New()
|
||||
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/weapon/cell/high(src)
|
||||
|
||||
RefreshParts()
|
||||
/obj/machinery/mining/drill/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/mining/drill/process()
|
||||
|
||||
|
||||
93
code/modules/mob/_modifiers/changeling.dm
Normal file
93
code/modules/mob/_modifiers/changeling.dm
Normal file
@@ -0,0 +1,93 @@
|
||||
/datum/modifier/changeling
|
||||
name = "changeling"
|
||||
desc = "Changeling modifier."
|
||||
|
||||
var/required_chems = 1 // Default is to require at least 1 chem unit. This does not consume it.
|
||||
|
||||
var/chem_maintenance = 1 // How many chems are expended per cycle, if we are consuming chems.
|
||||
|
||||
var/max_genetic_damage = 100
|
||||
|
||||
var/max_stat = 0
|
||||
|
||||
var/use_chems = FALSE // Do we have an upkeep cost on chems?
|
||||
|
||||
var/exterior_modifier = FALSE // Should we be checking the origin mob for chems?
|
||||
|
||||
/datum/modifier/changeling/check_if_valid()
|
||||
var/mob/living/L = null
|
||||
if(exterior_modifier)
|
||||
if(origin)
|
||||
L = origin.resolve()
|
||||
else
|
||||
expire()
|
||||
return
|
||||
|
||||
if((!exterior_modifier && !holder.changeling_power(required_chems, 0, max_genetic_damage, max_stat)) || (exterior_modifier && L && !L.changeling_power(required_chems, 0, max_genetic_damage, max_stat)))
|
||||
expire()
|
||||
else
|
||||
..()
|
||||
|
||||
/datum/modifier/changeling/tick()
|
||||
..()
|
||||
|
||||
if(use_chems)
|
||||
var/mob/living/L = null
|
||||
|
||||
if(exterior_modifier)
|
||||
L = origin.resolve()
|
||||
|
||||
else
|
||||
L = holder
|
||||
|
||||
L.mind.changeling.chem_charges = between(0, L.mind.changeling.chem_charges - chem_maintenance, L.mind.changeling.chem_storage)
|
||||
|
||||
/datum/modifier/changeling/thermal_sight
|
||||
name = "Thermal Adaptation"
|
||||
desc = "Our eyes are capable of seeing into the infrared spectrum to accurately identify prey through walls."
|
||||
vision_flags = SEE_MOBS
|
||||
|
||||
on_expired_text = "<span class='alien'>Your sight returns to what it once was.</span>"
|
||||
stacks = MODIFIER_STACK_EXTEND
|
||||
|
||||
/datum/modifier/changeling/thermal_sight/check_if_valid()
|
||||
var/mob/living/L = null
|
||||
|
||||
if(exterior_modifier)
|
||||
L = origin.resolve()
|
||||
|
||||
else
|
||||
L = holder
|
||||
|
||||
if(!L)
|
||||
expire()
|
||||
return
|
||||
|
||||
var/datum/changeling/changeling = L.changeling_power(0,0,100,CONSCIOUS)
|
||||
|
||||
if(!changeling)
|
||||
expire()
|
||||
return
|
||||
|
||||
if(!changeling.thermal_sight)
|
||||
expire()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/datum/modifier/changeling/thermal_sight/expire()
|
||||
var/mob/living/L = null
|
||||
|
||||
if(exterior_modifier)
|
||||
L = origin.resolve()
|
||||
|
||||
else
|
||||
L = holder
|
||||
|
||||
if(L)
|
||||
var/datum/changeling/changeling = L.changeling_power(0,0,100,CONSCIOUS)
|
||||
|
||||
if(changeling)
|
||||
changeling.thermal_sight = FALSE
|
||||
|
||||
..()
|
||||
@@ -51,6 +51,8 @@
|
||||
var/emp_modifier // Added to the EMP strength, which is an inverse scale from 1 to 4, with 1 being the strongest EMP. 5 is a nullification.
|
||||
var/explosion_modifier // Added to the bomb strength, which is an inverse scale from 1 to 3, with 1 being gibstrength. 4 is a nullification.
|
||||
|
||||
var/vision_flags // Vision flags to add to the mob. SEE_MOB, SEE_OBJ, etc.
|
||||
|
||||
/datum/modifier/New(var/new_holder, var/new_origin)
|
||||
holder = new_holder
|
||||
if(new_origin)
|
||||
|
||||
@@ -1363,6 +1363,10 @@
|
||||
see_in_dark = 8
|
||||
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.vision_flags))
|
||||
sight |= M.vision_flags
|
||||
|
||||
if(!glasses_processed && (species.get_vision_flags(src) > 0))
|
||||
sight |= species.get_vision_flags(src)
|
||||
if(!seer && !glasses_processed && seedarkness)
|
||||
|
||||
@@ -37,13 +37,27 @@
|
||||
winset(client, "input", "text=[null]")
|
||||
|
||||
/mob/living/carbon/human/speech_bubble_appearance()
|
||||
if(isSynthetic())
|
||||
var/datum/robolimb/robo = isSynthetic()
|
||||
return robo.speech_bubble_appearance
|
||||
else
|
||||
if(species)
|
||||
return species.speech_bubble_appearance
|
||||
return "normal"
|
||||
var/sounds_synth = FALSE
|
||||
var/datum/robolimb/robo = isSynthetic() //Will get torso manufacturer
|
||||
if(robo)
|
||||
sounds_synth = looksSynthetic() //Based on lifelike robolimb vars
|
||||
|
||||
// Not lifelike and got manufacturer
|
||||
if(sounds_synth)
|
||||
return robo.speech_bubble_appearance || "synthetic"
|
||||
|
||||
// Not lifelike synth, might have synth voice box
|
||||
if(!robo)
|
||||
var/obj/item/organ/internal/V = internal_organs_by_name[O_VOICE]
|
||||
if(V?.robotic >= ORGAN_ROBOT)
|
||||
return "synthetic"
|
||||
|
||||
// Species might have custom one
|
||||
if(species.speech_bubble_appearance)
|
||||
return species.speech_bubble_appearance
|
||||
|
||||
// NORMIE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/say_understands(var/mob/other, var/datum/language/speaking = null)
|
||||
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
|
||||
|
||||
@@ -731,7 +731,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
|
||||
var/obj/item/clothing/suit/suit = wear_suit
|
||||
var/suit_sprite
|
||||
|
||||
if(suit.index)
|
||||
if(istype(suit) && suit.index)
|
||||
suit_sprite = "[INV_SUIT_DEF_ICON]_[suit.index].dmi"
|
||||
else if(istype(suit, /obj/item/clothing) && !isnull(suit.update_icon_define))
|
||||
suit_sprite = suit.update_icon_define
|
||||
|
||||
@@ -189,6 +189,13 @@
|
||||
see_invisible = SEE_INVISIBLE_NOLIGHTING
|
||||
else
|
||||
see_invisible = initial(see_invisible)
|
||||
|
||||
sight = initial(sight)
|
||||
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.vision_flags))
|
||||
sight |= M.vision_flags
|
||||
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_hud_icons()
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
|
||||
return (!mover.density || !density || lying)
|
||||
|
||||
/mob/CanZASPass(turf/T, is_zone)
|
||||
return ATMOS_PASS_YES
|
||||
|
||||
/mob/living/SelfMove(turf/n, direct)
|
||||
// If on walk intent, don't willingly step into hazardous tiles.
|
||||
// Unless the walker is confused.
|
||||
|
||||
@@ -336,6 +336,8 @@
|
||||
next_alarm_notice = world.time + SecondsToTicks(10)
|
||||
if(alarm.hidden)
|
||||
return
|
||||
if(alarm.origin && !(get_z(alarm.origin) in using_map.get_map_levels(get_z(src), TRUE)))
|
||||
return
|
||||
|
||||
var/list/alarms = queued_alarms[alarm_handler]
|
||||
if(was_raised)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
movement_cooldown = 1
|
||||
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 25
|
||||
melee_damage_upper = 20
|
||||
attack_armor_pen = 40
|
||||
base_attack_cooldown = 2 SECONDS
|
||||
attacktext = list("gouged", "bit", "cut", "clawed", "whipped")
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
special_attack_min_range = 0
|
||||
special_attack_max_range = 4
|
||||
special_attack_cooldown = 30 SECONDS
|
||||
special_attack_cooldown = 1 MINUTE
|
||||
|
||||
// Players have 2 seperate cooldowns for these, while the AI must choose one. Both respect special_attack_cooldown
|
||||
var/last_strike_time = 0
|
||||
@@ -108,11 +108,11 @@
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.get_active_hand())
|
||||
var/obj/item/I = H.get_active_hand()
|
||||
if(I.force >= 1.20 * melee_damage_upper)
|
||||
if(I.force <= 1.25 * melee_damage_upper)
|
||||
return TRUE
|
||||
else if(istype(L, /mob/living/simple_mob))
|
||||
var/mob/living/simple_mob/S = L
|
||||
if(S.melee_damage_upper > 1.20 * melee_damage_upper)
|
||||
if(S.melee_damage_upper > 1.5 * melee_damage_upper)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_mob/animal/sif/kururak/handle_special()
|
||||
@@ -188,11 +188,8 @@
|
||||
flash_strength *= H.species.flash_mod
|
||||
if(flash_strength > 0)
|
||||
to_chat(H, span("alien","You are disoriented by \the [src]!"))
|
||||
H.Confuse(flash_strength + 5)
|
||||
H.Blind(flash_strength)
|
||||
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
|
||||
H.flash_eyes()
|
||||
H.adjustHalLoss(flash_strength / 5)
|
||||
H.apply_damage(flash_strength * H.species.flash_burn/5, BURN, BP_HEAD, 0, 0, "Photon burns")
|
||||
|
||||
else if(issilicon(L))
|
||||
@@ -282,9 +279,11 @@
|
||||
visible_message(span("danger","\The [src] rakes its claws against \the [A]."))
|
||||
var/obj/mecha/M = A
|
||||
M.take_damage(damage_to_apply)
|
||||
if(prob(3) && do_after(src, 5))
|
||||
visible_message(span("critical","\The [src]'s strike ripped \the [M]'s access hatch open, allowing it to drag [M.occupant] out!"))
|
||||
M.go_out()
|
||||
if(prob(3))
|
||||
visible_message(span("critical","\The [src] begins digging its claws into \the [M]'s hatch!"))
|
||||
if(do_after(src, 1 SECOND))
|
||||
visible_message(span("critical","\The [src] rips \the [M]'s access hatch open, dragging [M.occupant] out!"))
|
||||
M.go_out()
|
||||
|
||||
else
|
||||
A.attack_generic(src, damage_to_apply, "rakes its claws against") // Well it's not a mob, and it's not a mech.
|
||||
@@ -393,6 +392,10 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/ai_holder/simple_mob/intentional/kururak/post_special_attack(atom/A)
|
||||
holder.a_intent = I_HURT
|
||||
return ..()
|
||||
|
||||
/datum/ai_holder/simple_mob/intentional/kururak/post_melee_attack()
|
||||
if(holder.has_modifier_of_type(/datum/modifier/ace))
|
||||
request_help()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
if(matches) matches += " and "
|
||||
matches += "ID ([client.computer_id])"
|
||||
if(!config.disable_cid_warn_popup)
|
||||
spawn() alert("You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
|
||||
spawn() alert("You appear to have logged in with another key this round, which is not permitted. Please contact an administrator if you believe this message to be in error.")
|
||||
if(matches)
|
||||
if(M.client)
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] has the same [matches] as [key_name_admin(M)].</font>", 1)
|
||||
|
||||
@@ -378,10 +378,10 @@
|
||||
character = job_master.EquipRank(character, rank, 1) //equips the human
|
||||
UpdateFactionList(character)
|
||||
|
||||
// AIs don't need a spawnpoint, they must spawn at an empty core
|
||||
if(character.mind.assigned_role == "AI")
|
||||
var/datum/job/J = SSjob.get_job(rank)
|
||||
|
||||
character = character.AIize(move=0) // AIize the character, but don't move them yet
|
||||
// AIs don't need a spawnpoint, they must spawn at an empty core
|
||||
if(J.mob_type & JOB_SILICON_AI)
|
||||
|
||||
// IsJobAvailable for AI checks that there is an empty core available in this list
|
||||
var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
|
||||
@@ -389,11 +389,14 @@
|
||||
|
||||
character.loc = C.loc
|
||||
|
||||
// AIize the character, but don't move them yet
|
||||
character = character.AIize(move = FALSE) // Dupe of code in /datum/controller/subsystem/ticker/proc/create_characters() for non-latespawn, unify?
|
||||
|
||||
AnnounceCyborg(character, rank, "has been transferred to the empty core in \the [character.loc.loc]")
|
||||
ticker.mode.latespawn(character)
|
||||
|
||||
qdel(C)
|
||||
qdel(src)
|
||||
qdel(C) //Deletes empty core (really?)
|
||||
qdel(src) //Deletes new_player
|
||||
return
|
||||
|
||||
// Equip our custom items only AFTER deploying to spawn points eh?
|
||||
@@ -407,18 +410,15 @@
|
||||
character.buckled.set_dir(character.dir)
|
||||
|
||||
ticker.mode.latespawn(character)
|
||||
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
|
||||
if(J.mob_type & JOB_SILICON)
|
||||
AnnounceCyborg(character, rank, join_message, announce_channel, character.z)
|
||||
else
|
||||
AnnounceArrival(character, rank, join_message, announce_channel, character.z)
|
||||
data_core.manifest_inject(character)
|
||||
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
|
||||
|
||||
//Grab some data from the character prefs for use in random news procs.
|
||||
|
||||
AnnounceArrival(character, rank, join_message, announce_channel, character.z)
|
||||
else
|
||||
AnnounceCyborg(character, rank, join_message, announce_channel, character.z)
|
||||
|
||||
qdel(src)
|
||||
|
||||
qdel(src) // Delete new_player mob
|
||||
|
||||
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message, var/channel, var/zlevel)
|
||||
if (ticker.current_state == GAME_STATE_PLAYING)
|
||||
@@ -588,6 +588,9 @@
|
||||
/mob/new_player/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null)
|
||||
return
|
||||
|
||||
/mob/new_player/hear_holopad_talk(list/message_pieces, var/verb = "says", var/mob/speaker = null)
|
||||
return
|
||||
|
||||
// Prevents lobby players from seeing emotes, even with ghosteyes
|
||||
/mob/new_player/show_message(msg, type, alt, alt_type)
|
||||
return
|
||||
|
||||
@@ -148,8 +148,8 @@
|
||||
/mob/proc/find_valid_prefixes(message)
|
||||
var/list/prefixes = list() // [["Common", start, end], ["Gutter", start, end]]
|
||||
for(var/i in 1 to length(message))
|
||||
// This grabs trimmed 3 character substrings, to allow for up to 1 prefix and 1 letter language keys
|
||||
var/selection = trim_right(lowertext(copytext(message, i, i + 2)))
|
||||
// This grabs 3 character substrings, to allow for up to 1 prefix, 1 letter language key, and one post-key character to more strictly control where the language breaks happen
|
||||
var/selection = lowertext(copytext(message, i, i + 3))
|
||||
// The first character in the selection will always be the prefix (if this is a valid language invocation)
|
||||
var/prefix = copytext(selection, 1, 2)
|
||||
var/language_key = copytext(selection, 2, 3)
|
||||
@@ -157,6 +157,18 @@
|
||||
// Okay, we're definitely now trying to invoke a language (probably)
|
||||
// This "[]" is probably unnecessary but BYOND will runtime if a number is used
|
||||
var/datum/language/L = GLOB.language_keys["[language_key]"]
|
||||
|
||||
// MULTILINGUAL_SPACE enforces a space after the language key
|
||||
if(client && (client.prefs.multilingual_mode == MULTILINGUAL_SPACE) && (text2ascii(copytext(selection, 3, 4)) != 32)) // If we're looking for a space and we don't find one
|
||||
continue
|
||||
|
||||
// MULTILINGUAL_DOUBLE_DELIMITER enforces a delimiter (valid prefix) after the language key
|
||||
if(client && (client.prefs.multilingual_mode == MULTILINGUAL_DOUBLE_DELIMITER) && !is_language_prefix(copytext(selection, 3, 4)))
|
||||
continue
|
||||
|
||||
if(client && (client.prefs.multilingual_mode in list(MULTILINGUAL_DEFAULT)))
|
||||
selection = copytext(selection, 1, 3) // These modes only use two characters, not three
|
||||
|
||||
// It's kinda silly that we have to check L != null and this isn't done for us by can_speak (it runtimes instead), but w/e
|
||||
if(L && can_speak(L))
|
||||
// So we have a valid language invocation, and we can speak that language, let's make a piece for it
|
||||
@@ -170,6 +182,10 @@
|
||||
// This covers the case of "no prefixes in use."
|
||||
prefixes[++prefixes.len] = list(get_default_language(), i, i)
|
||||
|
||||
// If multilingualism is disabled, then after the first pass we're guaranteed to have either found a language key at the start, or else there isn't one and we're using the default for the whole message
|
||||
if(client && (client.prefs.multilingual_mode == MULTILINGUAL_OFF))
|
||||
break
|
||||
|
||||
return prefixes
|
||||
|
||||
/mob/proc/strip_prefixes(message, mob/prefixer = null)
|
||||
|
||||
@@ -64,10 +64,34 @@
|
||||
invisibility = 101
|
||||
return ..()
|
||||
|
||||
/mob/proc/AIize(move=1)
|
||||
/mob/proc/AIize(var/move = TRUE)
|
||||
if(client)
|
||||
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs
|
||||
var/mob/living/silicon/ai/O = new (loc, using_map.default_law_type,,1)//No MMI but safety is in effect.
|
||||
|
||||
var/newloc = loc
|
||||
if(move)
|
||||
var/obj/loc_landmark
|
||||
for(var/obj/effect/landmark/start/sloc in landmarks_list)
|
||||
if (sloc.name != "AI")
|
||||
continue
|
||||
if ((locate(/mob/living) in sloc.loc) || (locate(/obj/structure/AIcore) in sloc.loc))
|
||||
continue
|
||||
loc_landmark = sloc
|
||||
if (!loc_landmark)
|
||||
for(var/obj/effect/landmark/tripai in landmarks_list)
|
||||
if (tripai.name == "tripai")
|
||||
if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/AIcore) in tripai.loc))
|
||||
continue
|
||||
loc_landmark = tripai
|
||||
if (!loc_landmark)
|
||||
to_chat(src, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.")
|
||||
for(var/obj/effect/landmark/start/sloc in landmarks_list)
|
||||
if (sloc.name == "AI")
|
||||
loc_landmark = sloc
|
||||
|
||||
newloc = loc_landmark.loc
|
||||
|
||||
var/mob/living/silicon/ai/O = new (newloc, using_map.default_law_type,,1)//No MMI but safety is in effect.
|
||||
O.invisibility = 0
|
||||
O.aiRestorePowerRoutine = 0
|
||||
|
||||
@@ -101,28 +125,6 @@
|
||||
if(LANGUAGE_ROOTLOCAL in B.alternate_languages)
|
||||
O.add_language(LANGUAGE_ROOTLOCAL, 1)
|
||||
|
||||
if(move)
|
||||
var/obj/loc_landmark
|
||||
for(var/obj/effect/landmark/start/sloc in landmarks_list)
|
||||
if (sloc.name != "AI")
|
||||
continue
|
||||
if ((locate(/mob/living) in sloc.loc) || (locate(/obj/structure/AIcore) in sloc.loc))
|
||||
continue
|
||||
loc_landmark = sloc
|
||||
if (!loc_landmark)
|
||||
for(var/obj/effect/landmark/tripai in landmarks_list)
|
||||
if (tripai.name == "tripai")
|
||||
if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/AIcore) in tripai.loc))
|
||||
continue
|
||||
loc_landmark = tripai
|
||||
if (!loc_landmark)
|
||||
to_chat(O, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.")
|
||||
for(var/obj/effect/landmark/start/sloc in landmarks_list)
|
||||
if (sloc.name == "AI")
|
||||
loc_landmark = sloc
|
||||
|
||||
O.loc = loc_landmark.loc
|
||||
|
||||
O.on_mob_init()
|
||||
|
||||
O.add_ai_verbs()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use_power = USE_POWER_ACTIVE
|
||||
active_power_usage = 20000 //20kW, apropriate for machine that keeps massive cross-Zlevel wireless network operational.
|
||||
idle_power_usage = 100
|
||||
icon_state = "bus"
|
||||
icon_state = "ntnet"
|
||||
anchored = 1
|
||||
density = 1
|
||||
circuit = /obj/item/weapon/circuitboard/ntnet_relay
|
||||
@@ -32,9 +32,9 @@
|
||||
|
||||
/obj/machinery/ntnet_relay/update_icon()
|
||||
if(operable())
|
||||
icon_state = "bus"
|
||||
icon_state = initial(icon_state)
|
||||
else
|
||||
icon_state = "bus_off"
|
||||
icon_state = "[initial(icon_state)]_off"
|
||||
|
||||
/obj/machinery/ntnet_relay/process()
|
||||
if(operable())
|
||||
|
||||
@@ -25,14 +25,9 @@
|
||||
/obj/item/weapon/paper_bundle = 3,
|
||||
)
|
||||
|
||||
/obj/machinery/papershredder/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/motor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/gear(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/gear(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
RefreshParts()
|
||||
/obj/machinery/papershredder/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/papershredder/attackby(var/obj/item/W, var/mob/user)
|
||||
|
||||
@@ -16,14 +16,9 @@
|
||||
var/toner = 30 //how much toner is left! woooooo~
|
||||
var/maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier!
|
||||
|
||||
/obj/machinery/photocopier/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/motor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
RefreshParts()
|
||||
/obj/machinery/photocopier/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/photocopier/examine(mob/user as mob)
|
||||
. = ..()
|
||||
|
||||
@@ -11,27 +11,29 @@
|
||||
|
||||
/datum/time/New(new_time)
|
||||
if(new_time)
|
||||
if(new_time >= seconds_in_day)
|
||||
new_time = rollover(new_time)
|
||||
seconds_stored = new_time
|
||||
..()
|
||||
|
||||
/datum/time/proc/add_seconds(amount)
|
||||
var/answer = seconds_stored + amount * 10
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
answer = rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/add_minutes(amount)
|
||||
var/real_amount = amount * seconds_in_minute
|
||||
var/answer = real_amount + seconds_stored
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
answer = rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/add_hours(amount)
|
||||
var/real_amount = amount * seconds_in_hour
|
||||
var/answer = real_amount + seconds_stored
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
answer = rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/rollover(time)
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
#define POWERCHAN_ON 2
|
||||
#define POWERCHAN_ON_AUTO 3
|
||||
|
||||
#define NIGHTSHIFT_AUTO 1
|
||||
#define NIGHTSHIFT_NEVER 2
|
||||
#define NIGHTSHIFT_ALWAYS 3
|
||||
|
||||
//NOTE: STUFF STOLEN FROM AIRLOCK.DM thx
|
||||
|
||||
/obj/machinery/power/apc/critical
|
||||
@@ -119,6 +123,10 @@
|
||||
var/global/list/status_overlays_lighting
|
||||
var/global/list/status_overlays_environ
|
||||
var/alarms_hidden = FALSE //If power alarms from this APC are visible on consoles
|
||||
|
||||
var/nightshift_lights = FALSE
|
||||
var/nightshift_setting = NIGHTSHIFT_AUTO
|
||||
var/last_nightshift_switch = 0
|
||||
|
||||
/obj/machinery/power/apc/updateDialog()
|
||||
if (stat & (BROKEN|MAINT))
|
||||
@@ -798,6 +806,8 @@
|
||||
"coverLocked" = coverlocked,
|
||||
"siliconUser" = issilicon(user) || isobserver(user), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate.
|
||||
"emergencyLights" = !emergency_lights,
|
||||
"nightshiftLights" = nightshift_lights,
|
||||
"nightshiftSetting" = nightshift_setting,
|
||||
|
||||
"powerChannels" = list(
|
||||
list(
|
||||
@@ -917,6 +927,15 @@
|
||||
if(!can_use(usr, 1))
|
||||
return 1
|
||||
|
||||
if(href_list["nightshift"])
|
||||
if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam...
|
||||
to_chat(usr, "<span class='warning'>[src]'s night lighting circuit breaker is still cycling!</span>")
|
||||
return 0
|
||||
last_nightshift_switch = world.time
|
||||
nightshift_setting = text2num(href_list["nightshift"])
|
||||
update_nightshift()
|
||||
return 1
|
||||
|
||||
if(locked && !issilicon(usr) )
|
||||
if(isobserver(usr) )
|
||||
var/mob/observer/dead/O = usr //Added to allow admin nanoUI interactions.
|
||||
@@ -1367,4 +1386,24 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
if(src && grid_check == TRUE)
|
||||
grid_check = FALSE
|
||||
|
||||
/obj/machinery/power/apc/proc/set_nightshift(on, var/automated)
|
||||
set waitfor = FALSE
|
||||
if(automated && istype(area, /area/shuttle))
|
||||
return
|
||||
nightshift_lights = on
|
||||
update_nightshift()
|
||||
|
||||
/obj/machinery/power/apc/proc/update_nightshift()
|
||||
var/new_state = nightshift_lights
|
||||
|
||||
switch(nightshift_setting)
|
||||
if(NIGHTSHIFT_NEVER)
|
||||
new_state = FALSE
|
||||
if(NIGHTSHIFT_ALWAYS)
|
||||
new_state = TRUE
|
||||
|
||||
for(var/obj/machinery/light/L in area)
|
||||
L.nightshift_mode(new_state)
|
||||
CHECK_TICK
|
||||
|
||||
#undef APC_UPDATE_ICON_COOLDOWN
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor/
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin/ // Matter Bin: Max. amount of cells.
|
||||
|
||||
|
||||
/obj/machinery/power/smes/batteryrack/RefreshParts()
|
||||
var/capacitor_efficiency = 0
|
||||
var/maxcells = 0
|
||||
|
||||
@@ -8,20 +8,22 @@
|
||||
/obj/machinery/power/debug_items/examine(mob/user)
|
||||
. = ..()
|
||||
if(show_extended_information)
|
||||
show_info(user)
|
||||
. += show_info(user)
|
||||
|
||||
/obj/machinery/power/debug_items/proc/show_info(var/mob/user)
|
||||
var/list/extra_info = list()
|
||||
if(!powernet)
|
||||
to_chat(user, "<span class='filter_notice'>This device is not connected to a powernet</span>")
|
||||
extra_info += "<span class='filter_notice'>This device is not connected to a powernet</span>"
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='filter_notice'>Connected to powernet: [powernet]</span>")
|
||||
to_chat(user, "<span class='filter_notice'>Available power: [num2text(powernet.avail, 20)] W</span>")
|
||||
to_chat(user, "<span class='filter_notice'>Load: [num2text(powernet.viewload, 20)] W</span>")
|
||||
to_chat(user, "<span class='filter_notice'>Has alert: [powernet.problem ? "YES" : "NO"]</span>")
|
||||
to_chat(user, "<span class='filter_notice'>Cables: [powernet.cables.len]</span>")
|
||||
to_chat(user, "<span class='filter_notice'>Nodes: [powernet.nodes.len]</span>")
|
||||
extra_info += "<span class='filter_notice'>Connected to powernet: [powernet]</span>"
|
||||
extra_info += "<span class='filter_notice'>Available power: [num2text(powernet.avail, 20)] W</span>"
|
||||
extra_info += "<span class='filter_notice'>Load: [num2text(powernet.viewload, 20)] W</span>"
|
||||
extra_info += "<span class='filter_notice'>Has alert: [powernet.problem ? "YES" : "NO"]</span>"
|
||||
extra_info += "<span class='filter_notice'>Cables: [powernet.cables.len]</span>"
|
||||
extra_info += "<span class='filter_notice'>Nodes: [powernet.nodes.len]</span>"
|
||||
|
||||
return extra_info
|
||||
|
||||
// An infinite power generator. Adds energy to connected cable.
|
||||
/obj/machinery/power/debug_items/infinite_generator
|
||||
@@ -33,8 +35,8 @@
|
||||
add_avail(power_generation_rate)
|
||||
|
||||
/obj/machinery/power/debug_items/infinite_generator/show_info(var/mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='filter_notice'>Generator is providing [num2text(power_generation_rate, 20)] W</span>")
|
||||
. = ..()
|
||||
. += "<span class='filter_notice'>Generator is providing [num2text(power_generation_rate, 20)] W</span>"
|
||||
|
||||
|
||||
// A cable powersink, without the explosion/network alarms normal powersink causes.
|
||||
@@ -48,9 +50,9 @@
|
||||
last_used = draw_power(power_usage_rate)
|
||||
|
||||
/obj/machinery/power/debug_items/infinite_cable_powersink/show_info(var/mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='filter_notice'>Power sink is demanding [num2text(power_usage_rate, 20)] W</span>")
|
||||
to_chat(user, "<span class='filter_notice'>[num2text(last_used, 20)] W was actually used last tick</span>")
|
||||
. = ..()
|
||||
. += "<span class='filter_notice'>Power sink is demanding [num2text(power_usage_rate, 20)] W</span>"
|
||||
. += "<span class='filter_notice'>[num2text(last_used, 20)] W was actually used last tick</span>"
|
||||
|
||||
|
||||
/obj/machinery/power/debug_items/infinite_apc_powersink
|
||||
@@ -60,6 +62,6 @@
|
||||
active_power_usage = 0
|
||||
|
||||
/obj/machinery/power/debug_items/infinite_apc_powersink/show_info(var/mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='filter_notice'>Dummy load is using [num2text(active_power_usage, 20)] W</span>")
|
||||
to_chat(user, "<span class='filter_notice'>Powered: [powered() ? "YES" : "NO"]</span>")
|
||||
. = ..()
|
||||
. += "<span class='filter_notice'>Dummy load is using [num2text(active_power_usage, 20)] W</span>"
|
||||
. += "<span class='filter_notice'>Powered: [powered() ? "YES" : "NO"]</span>"
|
||||
|
||||
@@ -15,17 +15,12 @@
|
||||
var/wire_allow_manual_3 = FALSE
|
||||
var/opened = FALSE
|
||||
|
||||
/obj/machinery/power/grid_checker/New()
|
||||
..()
|
||||
/obj/machinery/power/grid_checker/Initialize()
|
||||
. = ..()
|
||||
connect_to_network()
|
||||
update_icon()
|
||||
wires = new(src)
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src, 10)
|
||||
RefreshParts()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/power/grid_checker/Destroy()
|
||||
qdel(wires)
|
||||
|
||||
@@ -240,9 +240,18 @@ var/global/list/light_type_cache = list()
|
||||
var/bulb_emergency_pow_mul = 0.75 // the multiplier for determining the light's power in emergency mode
|
||||
var/bulb_emergency_pow_min = 0.5 // the minimum value for the light's power in emergency mode
|
||||
|
||||
var/nightshift_enabled = FALSE
|
||||
var/nightshift_allowed = TRUE
|
||||
var/brightness_range_ns
|
||||
var/brightness_power_ns
|
||||
var/brightness_color_ns
|
||||
|
||||
/obj/machinery/light/flicker
|
||||
auto_flicker = TRUE
|
||||
|
||||
/obj/machinery/light/no_nightshift
|
||||
nightshift_allowed = FALSE
|
||||
|
||||
// the smaller bulb light fixture
|
||||
|
||||
/obj/machinery/light/small
|
||||
@@ -370,7 +379,10 @@ var/global/list/light_type_cache = list()
|
||||
/obj/machinery/light/proc/update(var/trigger = 1)
|
||||
update_icon()
|
||||
if(on)
|
||||
if(light_range != brightness_range || light_power != brightness_power || light_color != brightness_color)
|
||||
var/correct_range = nightshift_enabled ? brightness_range_ns : brightness_range
|
||||
var/correct_power = nightshift_enabled ? brightness_power_ns : brightness_power
|
||||
var/correct_color = nightshift_enabled ? brightness_color_ns : brightness_color
|
||||
if(light_range != correct_range || light_power != correct_power || light_color != correct_color)
|
||||
if(!auto_flicker)
|
||||
switchcount++
|
||||
if(rigged)
|
||||
@@ -388,7 +400,7 @@ var/global/list/light_type_cache = list()
|
||||
set_light(0)
|
||||
else
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
set_light(brightness_range, brightness_power, brightness_color)
|
||||
set_light(correct_range, correct_power, correct_color)
|
||||
else if(has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !turned_off())
|
||||
update_use_power(USE_POWER_IDLE)
|
||||
emergency_mode = TRUE
|
||||
@@ -399,6 +411,13 @@ var/global/list/light_type_cache = list()
|
||||
|
||||
update_active_power_usage((light_range * light_power) * LIGHTING_POWER_FACTOR)
|
||||
|
||||
/obj/machinery/light/proc/nightshift_mode(var/state)
|
||||
if(!nightshift_allowed)
|
||||
return
|
||||
|
||||
if(state != nightshift_enabled)
|
||||
nightshift_enabled = state
|
||||
update(FALSE)
|
||||
|
||||
/obj/machinery/light/attack_generic(var/mob/user, var/damage)
|
||||
if(!damage)
|
||||
@@ -459,10 +478,15 @@ var/global/list/light_type_cache = list()
|
||||
status = L.status
|
||||
switchcount = L.switchcount
|
||||
rigged = L.rigged
|
||||
|
||||
brightness_range = L.brightness_range
|
||||
brightness_power = L.brightness_power
|
||||
brightness_color = L.brightness_color
|
||||
|
||||
brightness_range_ns = L.nightshift_range
|
||||
brightness_power_ns = L.nightshift_power
|
||||
brightness_color_ns = L.nightshift_color
|
||||
|
||||
// attack with item - insert light (if right type), otherwise try to break the light
|
||||
|
||||
/obj/machinery/light/proc/insert_bulb(obj/item/weapon/light/L)
|
||||
@@ -825,6 +849,10 @@ var/global/list/light_type_cache = list()
|
||||
var/brightness_power = 1
|
||||
var/brightness_color = LIGHT_COLOR_INCANDESCENT_TUBE
|
||||
|
||||
var/nightshift_range = 8
|
||||
var/nightshift_power = 0.7
|
||||
var/nightshift_color = LIGHT_COLOR_NIGHTSHIFT
|
||||
|
||||
/obj/item/weapon/light/tube
|
||||
name = "light tube"
|
||||
desc = "A replacement light tube."
|
||||
@@ -841,6 +869,9 @@ var/global/list/light_type_cache = list()
|
||||
brightness_range = 15
|
||||
brightness_power = 9
|
||||
|
||||
nightshift_range = 10
|
||||
nightshift_power = 0.9
|
||||
|
||||
/obj/item/weapon/light/bulb
|
||||
name = "light bulb"
|
||||
desc = "A replacement light bulb."
|
||||
@@ -852,6 +883,9 @@ var/global/list/light_type_cache = list()
|
||||
brightness_power = 4
|
||||
brightness_color = LIGHT_COLOR_INCANDESCENT_BULB
|
||||
|
||||
nightshift_range = 3
|
||||
nightshift_power = 0.35
|
||||
|
||||
/obj/item/weapon/light/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
shatter()
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
name = "Pacman II"
|
||||
desc = "P.A.C.M.A.N. type II portable generator. Uses liquid phoron as a fuel source."
|
||||
power_gen = 4500
|
||||
circuit = /obj/item/weapon/circuitboard/pacman2
|
||||
var/obj/item/weapon/tank/phoron/P = null
|
||||
var/board_path = "/obj/item/weapon/circuitboard/pacman2"
|
||||
var/emagged = 0
|
||||
var/heat = 0
|
||||
/*
|
||||
@@ -30,16 +30,9 @@
|
||||
P.air_contents.phoron -= 0.01
|
||||
return
|
||||
|
||||
New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new board_path(src)
|
||||
RefreshParts()
|
||||
Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
RefreshParts()
|
||||
var/temp_rating = 0
|
||||
|
||||
@@ -112,18 +112,10 @@
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src, 2)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
RefreshParts()
|
||||
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Destroy()
|
||||
DropFuel()
|
||||
return ..()
|
||||
|
||||
@@ -47,12 +47,19 @@
|
||||
return 2
|
||||
|
||||
/obj/singularity_pull(S, current_size)
|
||||
if(simulated)
|
||||
if(anchored)
|
||||
if(current_size >= STAGE_FIVE)
|
||||
step_towards(src, S)
|
||||
else
|
||||
step_towards(src, S)
|
||||
set waitfor = 0
|
||||
|
||||
if(anchored)
|
||||
return
|
||||
|
||||
sleep(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
|
||||
if(current_size >= STAGE_FOUR)
|
||||
step_towards(src,S)
|
||||
sleep(1)
|
||||
step_towards(src,S)
|
||||
else if(current_size > STAGE_ONE)
|
||||
step_towards(src,S)
|
||||
else ..()
|
||||
|
||||
/obj/effect/beam/singularity_pull()
|
||||
return
|
||||
@@ -60,20 +67,6 @@
|
||||
/obj/effect/overlay/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/item/singularity_pull(S, current_size)
|
||||
spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
|
||||
if(current_size >= STAGE_FOUR)
|
||||
//throw_at(S, 14, 3)
|
||||
step_towards(src,S)
|
||||
sleep(1)
|
||||
step_towards(src,S)
|
||||
else if(current_size > STAGE_ONE)
|
||||
step_towards(src,S)
|
||||
else ..()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/machinery/power/supermatter/shard/singularity_act()
|
||||
qdel(src)
|
||||
return 5000
|
||||
@@ -113,30 +106,6 @@
|
||||
ChangeTurf(get_base_turf_by_area(src))
|
||||
return 2
|
||||
|
||||
/turf/simulated/floor/singularity_pull(S, current_size)
|
||||
if(flooring && current_size >= STAGE_THREE)
|
||||
if(prob(current_size / 2))
|
||||
var/leave_tile = TRUE
|
||||
if(broken || burnt || flooring.flags & TURF_IS_FRAGILE)
|
||||
leave_tile = FALSE
|
||||
playsound(src, 'sound/items/crowbar.ogg', 50, 1)
|
||||
make_plating(leave_tile)
|
||||
|
||||
/turf/simulated/wall/singularity_pull(S, current_size)
|
||||
|
||||
if(!reinf_material)
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(75))
|
||||
dismantle_wall()
|
||||
return
|
||||
if(current_size == STAGE_FOUR)
|
||||
if(prob(30))
|
||||
dismantle_wall()
|
||||
else
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(30))
|
||||
dismantle_wall()
|
||||
|
||||
/turf/space/singularity_act()
|
||||
return
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
|
||||
//inputting
|
||||
if(input_attempt && (!input_pulsed && !input_cut) && !grid_check)
|
||||
target_load = min((capacity-charge)/SMESRATE, input_level) // Amount we will request from the powernet.
|
||||
target_load = clamp((capacity-charge)/SMESRATE, 0, input_level) // Amount we will request from the powernet.
|
||||
var/input_available = FALSE
|
||||
for(var/obj/machinery/power/terminal/term in terminals)
|
||||
if(!term.powernet)
|
||||
@@ -459,17 +459,17 @@
|
||||
take_damage(250 / severity)
|
||||
|
||||
/obj/machinery/power/smes/examine(var/mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='filter_notice'>The service hatch is [panel_open ? "open" : "closed"].</span>")
|
||||
. = ..()
|
||||
. += "<span class='filter_notice'>The service hatch is [panel_open ? "open" : "closed"].</span>"
|
||||
if(!damage)
|
||||
return
|
||||
var/damage_percentage = round((damage / maxdamage) * 100)
|
||||
switch(damage_percentage)
|
||||
if(75 to INFINITY)
|
||||
to_chat(user, "<span class='filter_notice'><span class='danger'>It's casing is severely damaged, and sparking circuitry may be seen through the holes!</span></span>")
|
||||
. += "<span class='filter_notice'><span class='danger'>It's casing is severely damaged, and sparking circuitry may be seen through the holes!</span></span>"
|
||||
if(50 to 74)
|
||||
to_chat(user, "<span class='filter_notice'><span class='notice'>It's casing is considerably damaged, and some of the internal circuits appear to be exposed!</span></span>")
|
||||
. += "<span class='filter_notice'><span class='notice'>It's casing is considerably damaged, and some of the internal circuits appear to be exposed!</span></span>"
|
||||
if(25 to 49)
|
||||
to_chat(user, "<span class='filter_notice'><span class='notice'>It's casing is quite seriously damaged.</span></span>")
|
||||
. += "<span class='filter_notice'><span class='notice'>It's casing is quite seriously damaged.</span></span>"
|
||||
if(0 to 24)
|
||||
to_chat(user, "<span class='filter_notice'>It's casing has some minor damage.</span>")
|
||||
. += "<span class='filter_notice'>It's casing has some minor damage.</span>"
|
||||
@@ -41,23 +41,23 @@
|
||||
|
||||
// These are used on individual outposts as backup should power line be cut, or engineering outpost lost power.
|
||||
// 1M Charge, 150K I/O
|
||||
/obj/machinery/power/smes/buildable/outpost_substation/New()
|
||||
..(0)
|
||||
/obj/machinery/power/smes/buildable/outpost_substation/Initialize()
|
||||
. = ..()
|
||||
component_parts += new /obj/item/weapon/smes_coil/weak(src)
|
||||
recalc_coils()
|
||||
|
||||
// This one is pre-installed on engineering shuttle. Allows rapid charging/discharging for easier transport of power to outpost
|
||||
// 11M Charge, 2.5M I/O
|
||||
/obj/machinery/power/smes/buildable/power_shuttle/New()
|
||||
..(0)
|
||||
/obj/machinery/power/smes/buildable/power_shuttle/Initialize()
|
||||
. = ..()
|
||||
component_parts += new /obj/item/weapon/smes_coil/super_io(src)
|
||||
component_parts += new /obj/item/weapon/smes_coil/super_io(src)
|
||||
component_parts += new /obj/item/weapon/smes_coil(src)
|
||||
recalc_coils()
|
||||
|
||||
// Pre-installed and pre-charged SMES hidden from the station, for use in submaps.
|
||||
/obj/machinery/power/smes/buildable/point_of_interest/New()
|
||||
..(1)
|
||||
/obj/machinery/power/smes/buildable/point_of_interest/Initialize()
|
||||
. = ..()
|
||||
charge = capacity // Should be enough for an individual POI.
|
||||
RCon = FALSE
|
||||
input_level = input_level_max
|
||||
@@ -119,7 +119,8 @@
|
||||
// Proc: New()
|
||||
// Parameters: None
|
||||
// Description: Adds standard components for this SMES, and forces recalculation of properties.
|
||||
/obj/machinery/power/smes/buildable/New(var/install_coils = 1)
|
||||
/obj/machinery/power/smes/buildable/Initialize(var/install_coils = 1)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/stack/cable_coil(src,30)
|
||||
wires = new /datum/wires/smes(src)
|
||||
@@ -129,7 +130,6 @@
|
||||
for(var/i = 1, i <= cur_coils, i++)
|
||||
component_parts += new /obj/item/weapon/smes_coil(src)
|
||||
recalc_coils()
|
||||
..()
|
||||
|
||||
// Proc: attack_hand()
|
||||
// Parameters: None
|
||||
|
||||
@@ -25,11 +25,21 @@
|
||||
|
||||
// Base variants are applied to everyone on the same Z level
|
||||
// Range variants are applied on per-range basis: numbers here are on point blank, it scales with the map size (assumes square shaped Z levels)
|
||||
#define DETONATION_RADS 20
|
||||
#define DETONATION_HALLUCINATION_BASE 300
|
||||
#define DETONATION_HALLUCINATION_RANGE 300
|
||||
#define DETONATION_HALLUCINATION 600
|
||||
#define DETONATION_RADS 40
|
||||
#define DETONATION_MOB_CONCUSSION 4 // Value that will be used for Weaken() for mobs.
|
||||
|
||||
// Base amount of ticks for which a specific type of machine will be offline for. +- 20% added by RNG.
|
||||
// This does pretty much the same thing as an electrical storm, it just affects the whole Z level instantly.
|
||||
#define DETONATION_APC_OVERLOAD_PROB 10 // prob() of overloading an APC's lights.
|
||||
#define DETONATION_SHUTDOWN_APC 120 // Regular APC.
|
||||
#define DETONATION_SHUTDOWN_CRITAPC 10 // Critical APC. AI core and such. Considerably shorter as we don't want to kill the AI with a single blast. Still a nuisance.
|
||||
#define DETONATION_SHUTDOWN_SMES 60 // SMES
|
||||
#define DETONATION_SHUTDOWN_RNG_FACTOR 20 // RNG factor. Above shutdown times can be +- X%, where this setting is the percent. Do not set to 100 or more.
|
||||
#define DETONATION_SOLAR_BREAK_CHANCE 60 // prob() of breaking solar arrays (this is per-panel, and only affects the Z level SM is on)
|
||||
|
||||
// If power level is between these two, explosion strength will be scaled accordingly between min_explosion_power and max_explosion_power
|
||||
#define DETONATION_EXPLODE_MIN_POWER 200 // If power level is this or lower, minimal detonation strength will be used
|
||||
#define DETONATION_EXPLODE_MAX_POWER 2000 // If power level is this or higher maximal detonation strength will be used
|
||||
|
||||
#define WARNING_DELAY 20 //seconds between warnings.
|
||||
|
||||
@@ -65,7 +75,8 @@
|
||||
var/pull_radius = 14
|
||||
// Time in ticks between delamination ('exploding') and exploding (as in the actual boom)
|
||||
var/pull_time = 100
|
||||
var/explosion_power = 8
|
||||
var/min_explosion_power = 8
|
||||
var/max_explosion_power = 16
|
||||
|
||||
var/emergency_issued = 0
|
||||
|
||||
@@ -142,29 +153,71 @@
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/proc/explode()
|
||||
|
||||
set waitfor = 0
|
||||
|
||||
message_admins("Supermatter exploded at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("SUPERMATTER([x],[y],[z]) Exploded. Power:[power], Oxygen:[oxygen], Damage:[damage], Integrity:[get_integrity()]")
|
||||
anchored = 1
|
||||
grav_pulling = 1
|
||||
exploded = 1
|
||||
var/turf/TS = get_turf(src) // The turf supermatter is on. SM being in a locker, mecha, or other container shouldn't block it's effects that way.
|
||||
if(!TS)
|
||||
sleep(pull_time)
|
||||
var/turf/TS = get_turf(src) // The turf supermatter is on. SM being in a locker, exosuit, or other container shouldn't block it's effects that way.
|
||||
if(!istype(TS))
|
||||
return
|
||||
for(var/z in GetConnectedZlevels(TS.z))
|
||||
|
||||
var/list/affected_z = GetConnectedZlevels(TS.z)
|
||||
|
||||
// Effect 1: Radiation, weakening to all mobs on Z level
|
||||
for(var/z in affected_z)
|
||||
SSradiation.z_radiate(locate(1, 1, z), DETONATION_RADS, 1)
|
||||
|
||||
for(var/mob/living/mob in living_mob_list)
|
||||
var/turf/T = get_turf(mob)
|
||||
if(T && (loc.z == T.z))
|
||||
if(istype(mob, /mob/living/carbon/human))
|
||||
//Hilariously enough, running into a closet should make you get hit the hardest.
|
||||
var/mob/living/carbon/human/H = mob
|
||||
H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
|
||||
spawn(pull_time)
|
||||
explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1)
|
||||
spawn(5) //to allow the explosion to finish
|
||||
new /obj/item/broken_sm(TS)
|
||||
var/turf/TM = get_turf(mob)
|
||||
if(!TM)
|
||||
continue
|
||||
if(!(TM.z in affected_z))
|
||||
continue
|
||||
|
||||
mob.Weaken(DETONATION_MOB_CONCUSSION)
|
||||
to_chat(mob, "<span class='danger'>An invisible force slams you against the ground!</span>")
|
||||
|
||||
// Effect 2: Z-level wide electrical pulse
|
||||
for(var/obj/machinery/power/apc/A in machines)
|
||||
if(!(A.z in affected_z))
|
||||
continue
|
||||
|
||||
// Overloads lights
|
||||
if(prob(DETONATION_APC_OVERLOAD_PROB))
|
||||
A.overload_lighting()
|
||||
// Causes the APCs to go into system failure mode.
|
||||
var/random_change = rand(100 - DETONATION_SHUTDOWN_RNG_FACTOR, 100 + DETONATION_SHUTDOWN_RNG_FACTOR) / 100
|
||||
if(A.is_critical)
|
||||
A.energy_fail(round(DETONATION_SHUTDOWN_CRITAPC * random_change))
|
||||
else
|
||||
A.energy_fail(round(DETONATION_SHUTDOWN_APC * random_change))
|
||||
|
||||
// Effect 3: Break solar arrays
|
||||
for(var/obj/machinery/power/solar/S in machines)
|
||||
if(!(S.z in affected_z))
|
||||
continue
|
||||
if(prob(DETONATION_SOLAR_BREAK_CHANCE))
|
||||
S.health = -1
|
||||
S.broken()
|
||||
|
||||
// Effect 4: Medium scale explosion
|
||||
spawn(0)
|
||||
var/explosion_power = min_explosion_power
|
||||
if(power > 0)
|
||||
// 0-100% where 0% is at DETONATION_EXPLODE_MIN_POWER or lower and 100% is at DETONATION_EXPLODE_MAX_POWER or higher
|
||||
var/strength_percentage = between(0, (power - DETONATION_EXPLODE_MIN_POWER) / ((DETONATION_EXPLODE_MAX_POWER - DETONATION_EXPLODE_MIN_POWER) / 100), 100)
|
||||
explosion_power = between(min_explosion_power, (((max_explosion_power - min_explosion_power) * (strength_percentage / 100)) + min_explosion_power), max_explosion_power)
|
||||
|
||||
explosion(TS, explosion_power/2, explosion_power, max_explosion_power, explosion_power * 4, 1)
|
||||
qdel(src)
|
||||
return
|
||||
// Allow the explosion to finish
|
||||
spawn(5)
|
||||
new /obj/item/broken_sm(TS)
|
||||
|
||||
//Changes color and luminosity of the light to these values if they were not already set
|
||||
/obj/machinery/power/supermatter/proc/shift_light(var/lum, var/clr)
|
||||
@@ -211,20 +264,6 @@
|
||||
global_announcer.autosay(alert_msg, "Supermatter Monitor")
|
||||
public_alert = 0
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/get_transit_zlevel()
|
||||
//don't send it back to the station -- most of the time
|
||||
if(prob(99))
|
||||
var/list/candidates = using_map.accessible_z_levels.Copy()
|
||||
for(var/zlevel in using_map.station_levels)
|
||||
candidates.Remove("[zlevel]")
|
||||
candidates.Remove("[src.z]")
|
||||
|
||||
if(candidates.len)
|
||||
return text2num(pickweight(candidates))
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/supermatter/process()
|
||||
|
||||
var/turf/L = loc
|
||||
@@ -465,7 +504,8 @@
|
||||
|
||||
pull_radius = 5
|
||||
pull_time = 45
|
||||
explosion_power = 3
|
||||
min_explosion_power = 3
|
||||
max_explosion_power = 6
|
||||
|
||||
/obj/machinery/power/supermatter/shard/announce_warning() //Shards don't get announcements
|
||||
return
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
icon_state = "compressor"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
can_atmos_pass = ATMOS_PASS_PROC
|
||||
circuit = /obj/item/weapon/circuitboard/machine/power_compressor
|
||||
var/obj/machinery/power/turbine/turbine
|
||||
var/datum/gas_mixture/gas_contained
|
||||
@@ -96,7 +97,7 @@
|
||||
|
||||
// When anchored, don't let air past us.
|
||||
/obj/machinery/compressor/CanZASPass(turf/T, is_zone)
|
||||
return anchored ? ATMOS_PASS_NO : ATMOS_PASS_YES
|
||||
return !anchored
|
||||
|
||||
/obj/machinery/compressor/proc/locate_machinery()
|
||||
if(turbine)
|
||||
|
||||
@@ -24,15 +24,16 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/broken_gun/examine(mob/user)
|
||||
..()
|
||||
if(get_dist(get_turf(user),get_turf(src)) <= 1)
|
||||
to_chat(user, "<span class='notice'>You begin inspecting \the [src].</span>")
|
||||
. = ..()
|
||||
spawn()
|
||||
if(get_dist(get_turf(user),get_turf(src)) <= 1)
|
||||
to_chat(user, "<span class='notice'>You begin inspecting \the [src].</span>")
|
||||
|
||||
if(do_after(user, 5 SECONDS))
|
||||
to_chat(user, "<span class='notice'>\The [src] can possibly be restored with:</span>")
|
||||
for(var/resource in material_needs)
|
||||
if(material_needs[resource] > 0)
|
||||
to_chat(user, "<span class='notice'>- \icon [resource] x [material_needs[resource]] [resource]</span>")
|
||||
if(do_after(user, 5 SECONDS))
|
||||
to_chat(user, "<span class='notice'>\The [src] can possibly be restored with:</span>")
|
||||
for(var/resource in material_needs)
|
||||
if(material_needs[resource] > 0)
|
||||
to_chat(user, "<span class='notice'>- [bicon(resource)] x [material_needs[resource]] [resource]</span>")
|
||||
|
||||
/obj/item/weapon/broken_gun/proc/setup_gun(var/obj/item/weapon/gun/path)
|
||||
if(ispath(path))
|
||||
|
||||
@@ -365,14 +365,10 @@
|
||||
/obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon,
|
||||
)
|
||||
|
||||
/obj/machinery/reagentgrinder/New()
|
||||
..()
|
||||
/obj/machinery/reagentgrinder/Initialize()
|
||||
. = ..()
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/motor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/gear(src)
|
||||
RefreshParts()
|
||||
return
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/reagentgrinder/update_icon()
|
||||
icon_state = "juicer"+num2text(!isnull(beaker))
|
||||
|
||||
@@ -38,13 +38,7 @@
|
||||
operating = FORWARDS
|
||||
setmove()
|
||||
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/gear(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/motor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/gear(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/motor(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src,5)
|
||||
RefreshParts()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/conveyor/proc/setmove()
|
||||
if(operating == FORWARDS)
|
||||
|
||||
@@ -26,12 +26,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/Initialize()
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
RefreshParts()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/process()
|
||||
..()
|
||||
|
||||
@@ -63,3 +63,12 @@ datum/design/item/general/laserpointer
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 500)
|
||||
build_path = /obj/item/weapon/storage/box/syndie_kit/chameleon
|
||||
sort_string = "TBAAB"
|
||||
|
||||
/datum/design/item/general/bsflare
|
||||
name = "bluespace flare"
|
||||
desc = "A marker that can be detected by shuttle landing systems."
|
||||
id = "bsflare"
|
||||
req_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 4000, MAT_GLASS = 2000, MAT_SILVER = 2000)
|
||||
build_path = /obj/item/device/spaceflare
|
||||
sort_string = "TBAAC"
|
||||
|
||||
@@ -16,13 +16,9 @@ Note: Must be placed within 3 tiles of the R&D Console
|
||||
idle_power_usage = 30
|
||||
active_power_usage = 2500
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
RefreshParts()
|
||||
/obj/machinery/r_n_d/destructive_analyzer/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/RefreshParts()
|
||||
var/T = 0
|
||||
|
||||
@@ -21,14 +21,7 @@
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/Initialize()
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
RefreshParts()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/process()
|
||||
..()
|
||||
|
||||
@@ -48,6 +48,9 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
|
||||
req_access = list(access_research) //Data and setting manipulation requires scientist access.
|
||||
|
||||
var/protofilter //String to filter protolathe designs by
|
||||
var/circuitfilter //String to filter circuit designs by
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallMaterialName(var/ID)
|
||||
var/return_name = ID
|
||||
switch(return_name)
|
||||
@@ -169,7 +172,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
|
||||
else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk.
|
||||
screen = 0.0
|
||||
spawn(50)
|
||||
spawn(5 SECONDS)
|
||||
screen = 1.2
|
||||
files.AddTech2Known(t_disk.stored)
|
||||
updateUsrDialog()
|
||||
@@ -192,7 +195,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
|
||||
else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk.
|
||||
screen = 0.0
|
||||
spawn(50)
|
||||
spawn(5 SECONDS)
|
||||
screen = 1.4
|
||||
files.AddDesign2Known(d_disk.blueprint)
|
||||
updateUsrDialog()
|
||||
@@ -235,7 +238,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
screen = 0.1
|
||||
updateUsrDialog()
|
||||
flick("d_analyzer_process", linked_destroy)
|
||||
spawn(24)
|
||||
spawn(2.4 SECONDS)
|
||||
if(linked_destroy)
|
||||
linked_destroy.busy = 0
|
||||
if(!linked_destroy.loaded_item)
|
||||
@@ -283,7 +286,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
to_chat(usr, "<span class='notice'>You must connect to the network first.</span>")
|
||||
else
|
||||
griefProtection() //Putting this here because I dont trust the sync process
|
||||
spawn(30)
|
||||
spawn(3 SECONDS)
|
||||
if(src)
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
var/server_processed = 0
|
||||
@@ -319,8 +322,38 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(being_built)
|
||||
linked_lathe.addToQueue(being_built)
|
||||
|
||||
else if(href_list["buildfive"]) //Causes the Protolathe to build 5 of something.
|
||||
if(linked_lathe)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == href_list["buildfive"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
for(var/i = 1 to 5)
|
||||
linked_lathe.addToQueue(being_built)
|
||||
|
||||
screen = 3.1
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["protofilter"])
|
||||
var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", protofilter) as null|text
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
if(isnull(filterstring)) //Clicked Cancel
|
||||
return
|
||||
if(filterstring == "") //Cleared value
|
||||
protofilter = null
|
||||
protofilter = sanitize(filterstring, 25)
|
||||
|
||||
else if(href_list["circuitfilter"])
|
||||
var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", circuitfilter) as null|text
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
if(isnull(filterstring)) //Clicked Cancel
|
||||
return
|
||||
if(filterstring == "") //Cleared value
|
||||
circuitfilter = null
|
||||
circuitfilter = sanitize(filterstring, 25)
|
||||
|
||||
else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something.
|
||||
if(linked_imprinter)
|
||||
@@ -332,7 +365,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(being_built)
|
||||
linked_imprinter.addToQueue(being_built)
|
||||
screen = 4.1
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it)
|
||||
linked_imprinter.reagents.del_reagent(href_list["dispose"])
|
||||
@@ -489,7 +521,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
else if(d_disk)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=1.4'>Disk Operations</A>"
|
||||
else
|
||||
dat += "<LI>Disk Operations"
|
||||
dat += "<LI><span class='linkOff'>Disk Operations</span>"
|
||||
if(linked_destroy)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=2.2'>Destructive Analyzer Menu</A>"
|
||||
if(linked_lathe)
|
||||
@@ -638,9 +670,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
dat += "<B>Material Amount:</B> [linked_lathe.TotalMaterials()] cm<sup>3</sup> (MAX: [linked_lathe.max_material_storage])<BR>"
|
||||
dat += "<B>Chemical Volume:</B> [linked_lathe.reagents.total_volume] (MAX: [linked_lathe.reagents.maximum_volume])<HR>"
|
||||
dat += "<UL>"
|
||||
dat += "<B>Filter:</B> <A href='?src=\ref[src];protofilter=1'>[protofilter ? protofilter : "None Set"]</A>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!D.build_path || !(D.build_type & PROTOLATHE))
|
||||
continue
|
||||
if(protofilter && findtext(D.name, protofilter) == 0)
|
||||
continue
|
||||
var/temp_dat
|
||||
for(var/M in D.materials)
|
||||
temp_dat += ", [D.materials[M]*linked_lathe.mat_efficiency] [CallMaterialName(M)]"
|
||||
@@ -649,7 +684,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(temp_dat)
|
||||
temp_dat = " \[[copytext(temp_dat, 3)]\]"
|
||||
if(linked_lathe.canBuild(D))
|
||||
dat += "<LI><B><A href='?src=\ref[src];build=[D.id]'>[D.name]</A></B>[temp_dat]"
|
||||
dat += "<LI><B><A href='?src=\ref[src];build=[D.id]'>[D.name]</A></B>(<A href='?src=\ref[src];buildfive=[D.id]'>x5</A>)[temp_dat]"
|
||||
else
|
||||
dat += "<LI><B>[D.name]</B>[temp_dat]"
|
||||
dat += "</UL>"
|
||||
@@ -683,7 +718,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(3.3) //Protolathe Chemical Storage Submenu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Chemical Storage<BR><HR>"
|
||||
dat += "Chemical Storage:<BR><HR>"
|
||||
for(var/datum/reagent/R in linked_lathe.reagents.reagent_list)
|
||||
dat += "Name: [R.name] | Units: [R.volume] "
|
||||
dat += "<A href='?src=\ref[src];disposeP=[R.id]'>(Purge)</A><BR>"
|
||||
@@ -692,7 +727,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(3.4) // Protolathe queue
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Queue<BR><HR>"
|
||||
dat += "Protolathe Construction Queue:<BR><HR>"
|
||||
if(!linked_lathe.queue.len)
|
||||
dat += "Empty"
|
||||
else
|
||||
@@ -721,9 +756,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
dat += "Material Amount: [linked_imprinter.TotalMaterials()] cm<sup>3</sup><BR>"
|
||||
dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]<HR>"
|
||||
dat += "<UL>"
|
||||
dat += "<B>Filter:</B> <A href='?src=\ref[src];circuitfilter=1'>[circuitfilter ? circuitfilter : "None Set"]</A>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!D.build_path || !(D.build_type & IMPRINTER))
|
||||
continue
|
||||
if(circuitfilter && findtext(D.name, circuitfilter) == 0)
|
||||
continue
|
||||
var/temp_dat
|
||||
for(var/M in D.materials)
|
||||
temp_dat += ", [D.materials[M]*linked_imprinter.mat_efficiency] [CallMaterialName(M)]"
|
||||
@@ -794,8 +832,10 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
dat += "List of Researched Technologies and Designs:"
|
||||
dat += GetResearchListInfo()
|
||||
|
||||
user << browse("<TITLE>Research and Development Console</TITLE><HR>[dat.Join()]", "window=rdconsole;size=850x600")
|
||||
onclose(user, "rdconsole")
|
||||
dat = jointext(dat, null)
|
||||
var/datum/browser/popup = new(user, "rdconsole", "Research and Development Console", 850, 600)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/rdconsole/robotics
|
||||
name = "Robotics R&D Console"
|
||||
|
||||
@@ -15,13 +15,9 @@
|
||||
req_access = list(access_rd) //Only the R&D can change server settings.
|
||||
circuit = /obj/item/weapon/circuitboard/rdserver
|
||||
|
||||
/obj/machinery/r_n_d/server/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src)
|
||||
RefreshParts()
|
||||
/obj/machinery/r_n_d/server/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/r_n_d/server/Destroy()
|
||||
griefProtection()
|
||||
|
||||
@@ -64,10 +64,6 @@
|
||||
else
|
||||
security_announcement_down.Announce("[config.alert_desc_red_downto]", "Attention! Code red!")
|
||||
security_level = SEC_LEVEL_RED
|
||||
/* - At the time of commit, setting status displays didn't work properly
|
||||
var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world)
|
||||
if(CC)
|
||||
CC.post_status("alert", "redalert")*/
|
||||
if(SEC_LEVEL_DELTA)
|
||||
security_announcement_up.Announce("[config.alert_desc_delta]", "Attention! Delta alert level reached!", new_sound = 'sound/effects/siren.ogg')
|
||||
security_level = SEC_LEVEL_DELTA
|
||||
@@ -85,6 +81,9 @@
|
||||
else
|
||||
atc.reroute_traffic(yes = 0)
|
||||
|
||||
spawn()
|
||||
SSnightshift.check_nightshift()
|
||||
|
||||
|
||||
/proc/get_security_level()
|
||||
switch(security_level)
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
var/tmp/depart_time = 0 //Similar to above, set when the shuttle leaves when long jumping. Used for progress bars.
|
||||
|
||||
var/debug_logging = FALSE // If set to true, the shuttle will start broadcasting its debug messages to admins
|
||||
|
||||
// Future Thoughts: Baystation put "docking" stuff in a subtype, leaving base type pure and free of docking stuff. Is this best?
|
||||
|
||||
/datum/shuttle/New(_name, var/obj/effect/shuttle_landmark/initial_location)
|
||||
@@ -52,7 +54,8 @@
|
||||
else
|
||||
current_location = SSshuttles.get_landmark(current_location)
|
||||
if(!istype(current_location))
|
||||
log_debug("UM whoops, no initial? [src]")
|
||||
if(debug_logging)
|
||||
log_shuttle("UM whoops, no initial? [src]")
|
||||
CRASH("Shuttle '[name]' could not find its starting location landmark [current_location].")
|
||||
|
||||
if(src.name in SSshuttles.shuttles)
|
||||
@@ -236,20 +239,25 @@
|
||||
// Returns TRUE if we actually moved, otherwise FALSE.
|
||||
/datum/shuttle/proc/attempt_move(var/obj/effect/shuttle_landmark/destination, var/interim = FALSE)
|
||||
if(current_location == destination)
|
||||
log_shuttle("Shuttle [src] attempted to move to [destination] but is already there!")
|
||||
if(debug_logging)
|
||||
log_shuttle("Shuttle [src] attempted to move to [destination] but is already there!")
|
||||
return FALSE
|
||||
|
||||
if(!destination.is_valid(src))
|
||||
log_shuttle("Shuttle [src] aborting attempt_move() because destination=[destination] is not valid")
|
||||
if(debug_logging)
|
||||
log_shuttle("Shuttle [src] aborting attempt_move() because destination=[destination] is not valid")
|
||||
return FALSE
|
||||
if(current_location.cannot_depart(src))
|
||||
log_shuttle("Shuttle [src] aborting attempt_move() because current_location=[current_location] refuses.")
|
||||
if(debug_logging)
|
||||
log_shuttle("Shuttle [src] aborting attempt_move() because current_location=[current_location] refuses.")
|
||||
return FALSE
|
||||
|
||||
log_shuttle("[src] moving to [destination]. Areas are [english_list(shuttle_area)]")
|
||||
if(debug_logging)
|
||||
log_shuttle("[src] moving to [destination]. Areas are [english_list(shuttle_area)]")
|
||||
var/list/translation = list()
|
||||
for(var/area/A in shuttle_area)
|
||||
log_shuttle("Translating [A]")
|
||||
if(debug_logging)
|
||||
log_shuttle("Translating [A]")
|
||||
translation += get_turf_translation(get_turf(current_location), get_turf(destination), A.contents)
|
||||
var/old_location = current_location
|
||||
|
||||
@@ -259,11 +267,11 @@
|
||||
|
||||
// Actually do it! (This never fails)
|
||||
perform_shuttle_move(destination, translation)
|
||||
|
||||
|
||||
// Observer pattern post-move
|
||||
destination.shuttle_arrived(src)
|
||||
GLOB.shuttle_moved_event.raise_event(src, old_location, destination)
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -271,7 +279,8 @@
|
||||
//A note to anyone overriding move in a subtype. perform_shuttle_move() must absolutely not, under any circumstances, fail to move the shuttle.
|
||||
//If you want to conditionally cancel shuttle launches, that logic must go in short_jump() or long_jump()
|
||||
/datum/shuttle/proc/perform_shuttle_move(var/obj/effect/shuttle_landmark/destination, var/list/turf_translation)
|
||||
log_shuttle("perform_shuttle_move() current=[current_location] destination=[destination]")
|
||||
if(debug_logging)
|
||||
log_shuttle("perform_shuttle_move() current=[current_location] destination=[destination]")
|
||||
//to_world("move_shuttle() called for [name] leaving [origin] en route to [destination].")
|
||||
|
||||
//to_world("area_coming_from: [origin]")
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
current_dock_target = docking_controller_tag
|
||||
shuttle_docking_controller = SSshuttles.docking_registry[current_dock_target]
|
||||
if(current_dock_target && !shuttle_docking_controller)
|
||||
to_world("<span class='danger'>warning: shuttle [src] can't find its controller with tag [current_dock_target]!</span>")
|
||||
log_shuttle("<span class='danger'>warning: shuttle [src] can't find its controller with tag [current_dock_target]!</span>") // No toggle because this is an error message that needs to be seen
|
||||
/*
|
||||
Docking stuff
|
||||
*/
|
||||
|
||||
@@ -64,11 +64,13 @@
|
||||
var/cannot_depart = shuttle.current_location.cannot_depart(shuttle)
|
||||
if(cannot_depart)
|
||||
to_chat(user, "<span class='warning'>[cannot_depart]</span>")
|
||||
log_shuttle("Shuttle [shuttle] cannot depart [shuttle.current_location] because: [cannot_depart].")
|
||||
if(shuttle.debug_logging)
|
||||
log_shuttle("Shuttle [shuttle] cannot depart [shuttle.current_location] because: [cannot_depart].")
|
||||
return FALSE
|
||||
if(!shuttle.next_location.is_valid(shuttle))
|
||||
to_chat(user, "<span class='warning'>Destination zone is invalid or obstructed.</span>")
|
||||
log_shuttle("Shuttle [shuttle] destination [shuttle.next_location] is invalid.")
|
||||
if(shuttle.debug_logging)
|
||||
log_shuttle("Shuttle [shuttle] destination [shuttle.next_location] is invalid.")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
|
||||
if (emergency_shuttle.autopilot)
|
||||
emergency_shuttle.autopilot = 0
|
||||
to_chat(world, "<span class='notice'><b>Alert: The shuttle autopilot has been overridden. Launch sequence initiated!</b></span>")
|
||||
to_world("<span class='notice'><b>Alert: The shuttle autopilot has been overridden. Launch sequence initiated!</b></span>")
|
||||
|
||||
if(usr)
|
||||
log_admin("[key_name(usr)] has overridden the departure shuttle's autopilot and activated the launch sequence.")
|
||||
@@ -84,7 +84,7 @@
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
|
||||
if (emergency_shuttle.autopilot)
|
||||
emergency_shuttle.autopilot = 0
|
||||
to_chat(world, "<span class='notice'><b>Alert: The shuttle autopilot has been overridden. Bluespace drive engaged!</b></span>")
|
||||
to_world("<span class='notice'><b>Alert: The shuttle autopilot has been overridden. Bluespace drive engaged!</b></span>")
|
||||
|
||||
if(usr)
|
||||
log_admin("[key_name(usr)] has overridden the departure shuttle's autopilot and forced immediate launch.")
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
my_doors[find_doors[A.id_tag]] = A
|
||||
find_doors -= A.id_tag
|
||||
for(var/lost in find_doors)
|
||||
log_debug("[my_area] shuttle computer couldn't find [lost] door!")
|
||||
log_shuttle("[my_area] shuttle computer couldn't find [lost] door!")
|
||||
|
||||
if(my_sensors)
|
||||
var/list/find_sensors = my_sensors
|
||||
@@ -191,7 +191,7 @@
|
||||
my_sensors[find_sensors[S.id_tag]] = S
|
||||
find_sensors -= S.id_tag
|
||||
for(var/lost in find_sensors)
|
||||
log_debug("[my_area] shuttle computer couldn't find [lost] sensor!")
|
||||
log_shuttle("[my_area] shuttle computer couldn't find [lost] sensor!")
|
||||
|
||||
/obj/machinery/computer/shuttle_control/web/attackby(obj/I, mob/user)
|
||||
var/datum/shuttle/autodock/web_shuttle/shuttle = shuttle_controller.shuttles[shuttle_tag]
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
/datum/shuttle_destination/New(var/new_master)
|
||||
my_landmark = SSshuttles.get_landmark(my_landmark)
|
||||
if(!my_landmark)
|
||||
log_debug("Web shuttle destination '[name]' could not find its landmark '[my_landmark]'.")
|
||||
log_debug("Web shuttle destination '[name]' could not find its landmark '[my_landmark]'.") // Important error message
|
||||
master = new_master
|
||||
|
||||
/datum/shuttle_destination/Destroy()
|
||||
|
||||
@@ -18,16 +18,10 @@
|
||||
var/operatingcolor = "#FFFF22"
|
||||
|
||||
|
||||
/obj/machinery/slime/extractor/New()
|
||||
..()
|
||||
/obj/machinery/slime/extractor/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
update_light_color()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/slime/extractor/attackby(var/obj/item/W, var/mob/user)
|
||||
|
||||
|
||||
@@ -123,17 +123,10 @@
|
||||
var/datum/xeno/traits/genetics // Currently scanned xeno genetic structure.
|
||||
var/degradation = 0 // Increments with each scan, stops allowing gene mods after a certain point.
|
||||
|
||||
/obj/machinery/xenobio/extractor/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/xenobio/extractor/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/xenobio/extractor/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/xenoproduct))
|
||||
if(product)
|
||||
@@ -265,16 +258,9 @@
|
||||
|
||||
var/mob/living/simple_animal/xeno/slime/occupant
|
||||
|
||||
/obj/machinery/xenobio/editor/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
RefreshParts()
|
||||
/obj/machinery/xenobio/editor/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/xenobio/editor/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/grab))
|
||||
|
||||
@@ -19,18 +19,13 @@
|
||||
|
||||
circuit = /obj/item/weapon/circuitboard/xenobioinjectormachine
|
||||
|
||||
/obj/machinery/xenobio2/manualinjector/New()
|
||||
..()
|
||||
/obj/machinery/xenobio2/manualinjector/Initialize()
|
||||
. = ..()
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
RefreshParts()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/xenobio2/manualinjector/update_icon()
|
||||
if(beaker)
|
||||
|
||||
@@ -17,17 +17,11 @@
|
||||
var/emptycolor = "#FF2222"
|
||||
var/operatingcolor = "#FFFF22"
|
||||
|
||||
/obj/machinery/slime/replicator/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
RefreshParts()
|
||||
/obj/machinery/slime/replicator/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
update_light_color()
|
||||
|
||||
|
||||
/obj/machinery/slime/replicator/attackby(var/obj/item/W, var/mob/user)
|
||||
//Let's try to deconstruct first.
|
||||
if(W.is_screwdriver() && !inuse)
|
||||
|
||||
Reference in New Issue
Block a user