Merge branch 'master' into aro-poismes

This commit is contained in:
Aronai Sieyes
2020-05-12 11:20:54 -04:00
committed by GitHub
178 changed files with 2085 additions and 1638 deletions

View File

@@ -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)

View File

@@ -44,7 +44,8 @@
STANCE_REPOSITION,
STANCE_MOVE,
STANCE_FOLLOW,
STANCE_FLEE
STANCE_FLEE,
STANCE_DISABLED
)
var/list/static/noprocess_stances = list(
STANCE_SLEEP

View File

@@ -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//

View File

@@ -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

View File

@@ -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"

View File

@@ -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))

View File

@@ -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

View File

@@ -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()
..()

View File

@@ -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

View File

@@ -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 (!..())

View File

@@ -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)

View File

@@ -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

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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."

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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))

View File

@@ -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)

View File

@@ -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 ..()

View File

@@ -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)

View File

@@ -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()

View 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
..()

View File

@@ -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)

View File

@@ -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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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()

View File

@@ -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.

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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()

View File

@@ -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())

View File

@@ -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)

View File

@@ -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)
. = ..()

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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>"

View File

@@ -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)

View File

@@ -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()

View File

@@ -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

View File

@@ -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 ..()

View File

@@ -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

View File

@@ -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>"

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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))

View File

@@ -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))

View File

@@ -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)

View File

@@ -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()
..()

View File

@@ -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"

View File

@@ -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

View File

@@ -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()
..()

View File

@@ -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"

View File

@@ -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()

View File

@@ -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)

View File

@@ -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]")

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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.")

View File

@@ -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]

View File

@@ -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()

View File

@@ -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)

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)