Merge branch 'master' into upstream-merge-31198

This commit is contained in:
LetterJay
2017-10-04 19:06:42 -04:00
committed by GitHub
408 changed files with 77323 additions and 10128 deletions
+5 -1
View File
@@ -151,7 +151,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/maintenance/department/medical
name = "Medbay Maintenance"
icon_state = "asmaint"
icon_state = "medbay_maint"
/area/maintenance/department/medical/morgue
name = "Morgue Maintenance"
icon_state = "morgue_maint"
/area/maintenance/department/science
name = "Science Maintenance"
+1 -1
View File
@@ -118,7 +118,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
else if(dynamic_lighting != DYNAMIC_LIGHTING_IFSTARLIGHT)
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
if(dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
dynamic_lighting = config.starlight ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED
dynamic_lighting = CONFIG_GET(flag/starlight) ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED
. = ..()
+1
View File
@@ -189,6 +189,7 @@
/atom/proc/CollidedWith(atom/movable/AM)
set waitfor = FALSE
return
// Convenience proc to see if a container is open for chemistry handling
+1 -1
View File
@@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(blobs_legit) //used for win-score calculations, contains only
var/mob/camera/blob/B = blob.current.become_overmind(TRUE, round(blob_base_starting_points/blob_overminds.len))
B.mind.name = B.name
var/turf/T = pick(GLOB.blobstart)
B.loc = T
B.forceMove(T)
B.base_point_rate = blob_point_rate
SSshuttle.registerHostileEnvironment(src)
+1 -1
View File
@@ -7,7 +7,7 @@
if(B.blob_core || !B.placed)
return 0
if(!GLOB.blob_cores.len) //blob is dead
if(config.continuous["blob"])
if(CONFIG_GET(keyed_flag_list/continuous)["blob"])
message_sent = FALSE //disable the win count at this point
continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise
SSshuttle.clearHostileEnvironment(src)
+1 -1
View File
@@ -59,7 +59,7 @@
set name = "Jump to Core"
set desc = "Move your camera to your core."
if(blob_core)
src.loc = blob_core.loc
forceMove(blob_core.drop_location())
/mob/camera/blob/verb/jump_to_node()
set category = "Blob"
+1 -1
View File
@@ -190,7 +190,7 @@
B.density = TRUE
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
B.density = initial(B.density)
B.loc = T
B.forceMove(T)
B.update_icon()
if(B.overmind && expand_reaction)
B.overmind.blob_reagent_datum.expand_reaction(src, B, T, controller)
+6 -5
View File
@@ -17,7 +17,7 @@
/datum/objective_team/brother_team/proc/forge_brother_objectives()
objectives = list()
var/is_hijacker = prob(10)
for(var/i = 1 to max(1, config.brother_objectives_amount + (members.len > 2) - is_hijacker))
for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker))
forge_single_objective()
if(is_hijacker)
if(!locate(/datum/objective/hijack) in objectives)
@@ -58,16 +58,17 @@
var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library")
/datum/game_mode/traitor/bros/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER)
var/num_teams = team_amount
if(config.brother_scaling_coeff)
num_teams = max(1, round(num_players()/config.brother_scaling_coeff))
var/bsc = CONFIG_GET(number/brother_scaling_coeff)
if(bsc)
num_teams = max(1, round(num_players() / bsc))
for(var/j = 1 to num_teams)
if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies)
+18 -10
View File
@@ -52,16 +52,17 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
/datum/game_mode/changeling/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_changelings = 1
if(config.changeling_scaling_coeff)
num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) ))
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
if(csc)
num_changelings = max(1, min(round(num_players() / (csc * 2)) + 2, round(num_players() / csc)))
else
num_changelings = max(1, min(num_players(), changeling_amount))
@@ -102,10 +103,11 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
..()
/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
var/changelingcap = min( round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*2))+2, round(GLOB.joined_player_list.len/config.changeling_scaling_coeff) )
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc))
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
return
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
if(ROLE_CHANGELING in character.client.prefs.be_special)
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
@@ -131,10 +133,16 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
changeling.objectives += absorb_objective
if(prob(60))
var/datum/objective/steal/steal_objective = new
steal_objective.owner = changeling
steal_objective.find_target()
changeling.objectives += steal_objective
if(prob(85))
var/datum/objective/steal/steal_objective = new
steal_objective.owner = changeling
steal_objective.find_target()
changeling.objectives += steal_objective
else
var/datum/objective/download/download_objective = new
download_objective.owner = changeling
download_objective.gen_amount_goal()
changeling.objectives += download_objective
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
@@ -30,7 +30,7 @@
sleep(5) // So it's not killed in explosion
var/mob/living/simple_animal/hostile/headcrab/crab = new(turf)
for(var/obj/item/organ/I in organs)
I.loc = crab
I.forceMove(crab)
crab.origin = M
if(crab.origin)
crab.origin.active = 1
@@ -77,10 +77,10 @@
return
..()
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/target)
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target)
if(!..())
return
if((target.disabilities & HUSK) || !target.has_dna())
if((target.disabilities & HUSK) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
@@ -25,18 +25,19 @@
return 1
/datum/game_mode/traitor/changeling/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
var/num_changelings = 1
if(config.changeling_scaling_coeff)
num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) ))
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
if(csc)
num_changelings = max(1, min(round(num_players() / (csc * 4)) + 2, round(num_players() / (csc * 2))))
else
num_changelings = max(1, min(num_players(), changeling_amount/2))
@@ -64,11 +65,12 @@
return
/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
var/changelingcap = min( round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*4))+2, round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*2)) )
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2)))
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
..()
return
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4)))
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
if(ROLE_CHANGELING in character.client.prefs.be_special)
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
+4 -2
View File
@@ -53,6 +53,8 @@ Credit where due:
return FALSE
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
return FALSE
if(M.mind.unconvertable)
return FALSE
else
return FALSE
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
@@ -107,9 +109,9 @@ Credit where due:
var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.)
/datum/game_mode/clockwork_cult/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/starter_servants = 4 //Guaranteed four servants
var/number_players = num_players()
@@ -75,7 +75,7 @@
if(GLOB.ratvar_awakens && L)
L.adjust_fire_stacks(damage_per_tick)
L.IgniteMob()
else if(istype(target, /obj/mecha))
else if(ismecha(target))
var/obj/mecha/M = target
M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M))
@@ -90,7 +90,7 @@
if(isliving(target))
var/mob/living/L = target
to_chat(L, "<span class='neovgre'>\"I SEE YOU!\"</span>\n<span class='userdanger'>[src]'s gaze [GLOB.ratvar_awakens ? "melts you alive" : "burns you"]!</span>")
else if(istype(target, /obj/mecha))
else if(ismecha(target))
var/obj/mecha/M = target
to_chat(M.occupant, "<span class='neovgre'>\"I SEE YOU!\"</span>" )
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
+4 -2
View File
@@ -21,6 +21,8 @@
return FALSE
if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
return FALSE
if(M.mind.unconvertable)
return FALSE
else
return FALSE
if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M))
@@ -55,10 +57,10 @@
/datum/game_mode/cult/pre_setup()
cult_objectives += "sacrifice"
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
//cult scaling goes here
+164
View File
@@ -72,6 +72,170 @@
if(is_servant_of_ratvar(C) && C.reagents)
C.reagents.add_reagent("heparin", 1)
/obj/item/twohanded/required/cult_bastard
name = "bloody bastard sword"
desc = "An enormous sword used by Nar-Sien cultists to rapidly harvest the souls of non-believers."
w_class = WEIGHT_CLASS_HUGE
block_chance = 50
throwforce = 20
force = 35
armour_penetration = 45
throw_speed = 1
throw_range = 3
sharpness = IS_SHARP
light_color = "#ff0000"
attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved")
icon_state = "cultbastard"
item_state = "cultbastard"
hitsound = 'sound/weapons/bladeslice.ogg'
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
actions_types = list()
flags_2 = SLOWS_WHILE_IN_HAND_2
var/datum/action/innate/dash/cult/jaunt
var/datum/action/innate/cult/spin2win/linked_action
var/spinning = FALSE
var/spin_cooldown = 250
var/list/shards = list()
var/dash_toggled = TRUE
/obj/item/twohanded/required/cult_bastard/Initialize()
. = ..()
set_light(4)
jaunt = new(src)
linked_action = new(src)
/obj/item/twohanded/required/cult_bastard/can_be_pulled(user)
return FALSE
/obj/item/twohanded/required/cult_bastard/attack_self(mob/user)
dash_toggled = !dash_toggled
if(dash_toggled)
to_chat(loc, "<span class='notice'>You raise the [src] and prepare to jaunt with it.</span>")
else
to_chat(loc, "<span class='notice'>You lower the [src] and prepare to swing it normally.</span>")
/obj/item/twohanded/required/cult_bastard/pickup(mob/living/user)
. = ..()
if(!iscultist(user))
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
to_chat(user, "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>")
user.Dizzy(80)
user.Knockdown(30)
return
else
to_chat(user, "<span class='cultlarge'>\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"</span>")
to_chat(user, "<span class='userdanger'>A horrible force yanks at your arm!</span>")
user.emote("scream")
user.apply_damage(30, BRUTE, pick("l_arm", "r_arm"))
user.Knockdown(50)
return
jaunt.Grant(user, src)
linked_action.Grant(user, src)
user.update_icons()
/obj/item/twohanded/required/cult_bastard/dropped(mob/user)
. = ..()
linked_action.Remove(user)
jaunt.Remove(user)
user.update_icons()
/obj/item/twohanded/required/cult_bastard/IsReflect()
if(spinning)
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return TRUE
else
..()
/obj/item/twohanded/required/cult_bastard/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(prob(final_block_chance))
if(attack_type == PROJECTILE_ATTACK)
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 100, 1)
return TRUE
else
playsound(src, 'sound/weapons/parry.ogg', 75, 1)
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
return TRUE
return FALSE
/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters)
. = ..()
if(dash_toggled && jaunt.IsAvailable())
jaunt.Teleport(user, target)
return
if(!proximity)
return
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.stat != CONSCIOUS)
var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src)
SS.attack(H, user)
shards += SS
return
if(istype(target, /obj/structure/constructshell) && contents.len)
var/obj/item/device/soulstone/SS = contents[1]
if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user))
qdel(SS)
/datum/action/innate/dash/cult
name = "Rend the Veil"
desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target."
icon_icon = 'icons/mob/actions/actions_cult.dmi'
button_icon_state = "phaseshift"
dash_sound = 'sound/magic/enter_blood.ogg'
recharge_sound = 'sound/magic/exit_blood.ogg'
beam_effect = "sendbeam"
phasein = /obj/effect/temp_visual/dir_setting/cult/phase
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
/datum/action/innate/dash/cult/IsAvailable()
if(iscultist(holder) && charged)
return TRUE
else
return FALSE
/datum/action/innate/cult/spin2win
name = "Geometer's Fury"
desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks."
background_icon_state = "bg_demon"
button_icon_state = "sintouch"
var/cooldown = 0
var/mob/living/carbon/human/holder
var/obj/item/twohanded/required/cult_bastard/sword
/datum/action/innate/cult/spin2win/Grant(mob/user, obj/bastard)
. = ..()
sword = bastard
holder = user
/datum/action/innate/cult/spin2win/IsAvailable()
if(iscultist(holder) && cooldown <= world.time)
return TRUE
else
return FALSE
/datum/action/innate/cult/spin2win/Activate()
cooldown = world.time + sword.spin_cooldown
holder.changeNext_move(50)
holder.apply_status_effect(/datum/status_effect/sword_spin)
sword.spinning = TRUE
sword.block_chance = 100
sword.slowdown += 1.5
addtimer(CALLBACK(src, .proc/stop_spinning), 50)
holder.update_action_buttons_icon()
/datum/action/innate/cult/spin2win/proc/stop_spinning()
sword.spinning = FALSE
sword.block_chance = 50
sword.slowdown -= 1.5
sleep(sword.spin_cooldown)
holder.update_action_buttons_icon()
/obj/item/restraints/legcuffs/bola/cult
name = "nar'sien bola"
+1 -6
View File
@@ -100,17 +100,13 @@
if(cooldowntime > world.time)
to_chat(user, "<span class='cultitalic'>The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].</span>")
return
var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Nar-Sien Hardsuit")
var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Bastard Sword")
var/pickedtype
switch(choice)
if("Shielded Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield
if("Flagellant's Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/berserker
<<<<<<< HEAD
if("Nar-Sien Hardsuit")
pickedtype = /obj/item/clothing/suit/space/hardsuit/cult
=======
if("Bastard Sword")
if((world.time - SSticker.round_start_time) >= 12000)
pickedtype = /obj/item/twohanded/required/cult_bastard
@@ -119,7 +115,6 @@
to_chat(user, "<span class='cultitalic'>The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime)].</span>")
cooldowntime = 0
return
>>>>>>> e997bc4... Merge pull request #31198 from Jordie0608/apparentlythisbuildcompletedthefirsttimeidkhow
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
cooldowntime = world.time + 2400
var/obj/item/N = new pickedtype(get_turf(src))
+5 -4
View File
@@ -20,15 +20,16 @@
+ <span class='notice'>Crew</span>: Resist the lure of sin and remain pure!"
/datum/game_mode/devil/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_devils = 1
if(config.traitor_scaling_coeff)
num_devils = max(minimum_devils, min( round(num_players()/(config.traitor_scaling_coeff*3))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff*1.5)) + num_modifier ))
var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
if(tsc)
num_devils = max(minimum_devils, min( round(num_players() / (tsc * 3))+ 2 + num_modifier, round(num_players() / (tsc * 1.5)) + num_modifier))
else
num_devils = max(minimum_devils, min(num_players(), traitors_possible))
+18 -14
View File
@@ -78,7 +78,7 @@
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report.
if(!report)
report = config.intercept
report = !CONFIG_GET(flag/no_intercept_report)
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
if(SSdbcore.Connect())
@@ -113,8 +113,9 @@
for(var/mob/Player in GLOB.mob_list)
if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client)
living_crew += Player
if(living_crew.len / GLOB.joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh
message_admins("Convert_roundtype failed due to too many dead people. Limit is [config.midround_antag_life_check * 100]% living crew")
var/malc = CONFIG_GET(number/midround_antag_life_check)
if(living_crew.len / GLOB.joined_player_list.len <= malc) //If a lot of the player base died, we start fresh
message_admins("Convert_roundtype failed due to too many dead people. Limit is [malc * 100]% living crew")
return null
var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len)
@@ -138,8 +139,9 @@
if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5)
return 1
if(world.time >= (config.midround_antag_time_check * 600))
message_admins("Convert_roundtype failed due to round length. Limit is [config.midround_antag_time_check] minutes.")
var/matc = CONFIG_GET(number/midround_antag_time_check)
if(world.time >= (matc * 600))
message_admins("Convert_roundtype failed due to round length. Limit is [matc] minutes.")
return null
var/list/antag_candidates = list()
@@ -154,9 +156,9 @@
antag_candidates = shuffle(antag_candidates)
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
replacementmode.restricted_jobs += replacementmode.protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
replacementmode.restricted_jobs += "Assistant"
message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit <A HREF='?_src_=holder;[HrefToken()];toggle_midround_antag=\ref[usr]'>stop the creation of antags</A> or <A HREF='?_src_=holder;[HrefToken()];end_round=\ref[usr]'>end the round now</A>.")
@@ -168,7 +170,7 @@
round_converted = 0
return
//somewhere between 1 and 3 minutes from now
if(!config.midround_antag[SSticker.mode.config_tag])
if(!CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
round_converted = 0
return 1
for(var/mob/living/carbon/human/H in antag_candidates)
@@ -189,7 +191,9 @@
return TRUE
if(station_was_nuked)
return TRUE
if(!round_converted && (!config.continuous[config_tag] || (config.continuous[config_tag] && config.midround_antag[config_tag]))) //Non-continuous or continous with replacement antags
var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
if(!round_converted && (!continuous[config_tag] || (continuous[config_tag] && midround_antag[config_tag]))) //Non-continuous or continous with replacement antags
if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place
for(var/mob/Player in GLOB.mob_list)
if(Player.mind)
@@ -198,8 +202,8 @@
return 0
if(!continuous_sanity_checked)
message_admins("The roundtype ([config_tag]) has no antagonists, continuous round has been defaulted to on and midround_antag has been defaulted to off.")
config.continuous[config_tag] = 1
config.midround_antag[config_tag] = 0
continuous[config_tag] = TRUE
midround_antag[config_tag] = FALSE
SSshuttle.clearHostileEnvironment(src)
return 0
@@ -213,7 +217,7 @@
living_antag_player = Player
return 0
if(!config.continuous[config_tag] || force_ending)
if(!continuous[config_tag] || force_ending)
return 1
else
@@ -222,7 +226,7 @@
if(round_ends_with_antag_death)
return 1
else
config.midround_antag[config_tag] = 0
midround_antag[config_tag] = 0
return 0
return 0
@@ -517,7 +521,7 @@
/datum/game_mode/proc/get_remaining_days(client/C)
if(!C)
return 0
if(!config.use_age_restriction_for_jobs)
if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
+4 -3
View File
@@ -31,15 +31,16 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart))
var/startSide = pick(GLOB.cardinals)
pickedstart = spaceDebrisStartLoc(startSide, ZLEVEL_STATION_PRIMARY)
pickedgoal = spaceDebrisFinishLoc(startSide, ZLEVEL_STATION_PRIMARY)
var/startZ = pick(GLOB.station_z_levels)
pickedstart = spaceDebrisStartLoc(startSide, startZ)
pickedgoal = spaceDebrisFinishLoc(startSide, startZ)
max_i--
if(max_i<=0)
return
var/Me = pickweight(meteortypes)
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
M.z_original = ZLEVEL_STATION_PRIMARY
M.z_original = M.z
spawn(0)
walk_towards(M, M.dest, 1)
@@ -34,7 +34,7 @@
to_chat(world, "<b>Crew</b> - don't get abducted and stop the abductors.")
/datum/game_mode/abduction/pre_setup()
var/num_teams = max(1, min(max_teams, round(num_players() / config.abductor_scaling_coeff)))
var/num_teams = max(1, min(max_teams, round(num_players() / CONFIG_GET(number/abductor_scaling_coeff))))
var/possible_teams = max(1, round(antag_candidates.len / 2))
num_teams = min(num_teams, possible_teams)
@@ -218,7 +218,7 @@
/obj/structure/spider/cocoon/abductor/proc/Copy(mob/living/carbon/human/H)
var/mob/living/carbon/human/interactive/greytide/clone = new(src)
clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features)
clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species, H.dna.features)
/obj/structure/spider/cocoon/abductor/proc/Start()
hatch_time = world.time + 600
@@ -60,9 +60,8 @@
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/organ/heart/gland))
if(!user.drop_item())
if(!user.transferItemToLoc(W, src))
return
W.loc = src
for(var/i=1,i<=gland_colors.len,i++)
if(gland_types[i] == W.type)
amounts[i]++
@@ -62,7 +62,7 @@
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
var/icon/photo = null
var/g = (H.gender == FEMALE) ? "f" : "m"
if(!config.mutant_races || H.dna.species.use_skintones)
if(!CONFIG_GET(flag/join_with_mutant_race) || H.dna.species.use_skintones)
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]")
else
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]")
@@ -468,11 +468,8 @@
return
var/turf/open/floor/F
switch(z) //Only the station/lavaland
if(ZLEVEL_STATION_PRIMARY)
F =find_safe_turf(zlevels = ZLEVEL_STATION_PRIMARY, extended_safety_checks = TRUE)
if(ZLEVEL_LAVALAND)
F = find_safe_turf(zlevels = ZLEVEL_LAVALAND, extended_safety_checks = TRUE)
F = find_safe_turf(zlevels = z, extended_safety_checks = TRUE)
if(!F)
return
// If we're getting rid of a human, slap some energy cuffs on
@@ -502,7 +499,7 @@
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
M.amount = 5
for(var/obj/item/I in target.component_parts)
I.loc = M.loc
I.forceMove(M.drop_location())
var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target))
N.pixel_x = target.pixel_x
N.pixel_y = target.pixel_y
@@ -511,7 +508,7 @@
if(istype(target, /obj/machinery/computer))
var/obj/machinery/computer/C = target
if(C.circuit)
C.circuit.loc = M.loc
C.circuit.forceMove(M.drop_location())
qdel(target)
@@ -77,7 +77,7 @@
/mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A)
if(A && A.loc != src)
visible_message("<span class='warning'>[src] swallows [A] whole!</span>")
A.loc = src
A.forceMove(src)
return 1
return 0
@@ -153,7 +153,7 @@
/mob/living/simple_animal/hostile/morph/proc/barf_contents()
for(var/atom/movable/AM in src)
AM.loc = loc
AM.forceMove(loc)
if(prob(90))
step(AM, pick(GLOB.alldirs))
@@ -34,17 +34,13 @@
var/list/spawn_locs = list()
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
for(var/obj/effect/landmark/revenantspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
switch(L.name)
if("revenantspawn")
spawn_locs += L.loc
spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find any revenant spawns, try the carp spawns
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
switch(L.name)
if("carpspawn")
spawn_locs += L.loc
spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find either, just spawn the revenant at the player's location
spawn_locs += get_turf(selected)
if(!spawn_locs.len) //If we can't find THAT, then just give up and cry
@@ -23,11 +23,9 @@
player_mind.active = 1
var/list/spawn_locs = list()
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
switch(L.name)
if("carpspawn")
spawn_locs += L.loc
spawn_locs += L.loc
if(!spawn_locs)
message_admins("No valid spawn locations found, aborting...")
+1 -1
View File
@@ -110,7 +110,7 @@
P.info = "The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code"
var/mob/living/carbon/human/H = synd_mind.current
P.loc = H.loc
P.forceMove(H.drop_location())
H.put_in_hands_or_del(P)
H.update_icons()
else
@@ -58,7 +58,7 @@
U.hidden_uplink.owner = "[user.key]"
U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS
U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY)
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
SSblackbox.set_val("nuclear_challenge_mode",1)
qdel(src)
+33 -36
View File
@@ -17,14 +17,6 @@
if(owner)
. += owner
/datum/objective/proc/considered_alive(var/datum/mind/M)
if(M && M.current)
var/mob/living/carbon/human/H
if(ishuman(M.current))
H = M.current
return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies")
return FALSE
/datum/objective/proc/considered_escaped(datum/mind/M)
if(!considered_alive(M))
return FALSE
@@ -37,9 +29,6 @@
return FALSE
return location.onCentCom() || location.onSyndieBase()
/datum/objective/proc/considered_afk(datum/mind/M)
return !M || !M.current || !M.current.client || M.current.client.is_afk()
/datum/objective/proc/check_completion()
return completed
@@ -348,13 +337,14 @@
return FALSE
return TRUE
//Like survive, but works for silicons and zombies and such.
/datum/objective/survive/exist/considered_alive(var/datum/mind/M)
if(M && M.current)
if(isliving(M.current))
var/mob/living/L = M.current
return L.stat != DEAD
return FALSE
/datum/objective/survive/exist //Like survive, but works for silicons and zombies and such.
/datum/objective/survive/exist/check_completion()
var/list/datum/mind/owners = get_owners()
for(var/datum/mind/M in owners)
if(!considered_alive(M, FALSE))
return FALSE
return TRUE
/datum/objective/martyr
explanation_text = "Die a glorious death."
@@ -506,24 +496,31 @@ GLOBAL_LIST_EMPTY(possible_items_special)
explanation_text = "Download [target_amount] research level\s."
return target_amount
/datum/objective/download/check_completion()//NINJACODE.
var/current_amount = 0
/datum/objective/download/check_completion()
var/list/current_tech = list()
var/list/datum/mind/owners = get_owners()
for(var/datum/mind/M in owners)
if(!ishuman(owner.current))
continue
var/mob/living/carbon/human/H = owner.current
if(!H || H.stat == DEAD || !istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
continue
var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
if(!SN.s_initialized)
continue
for(var/datum/tech/current_data in SN.stored_research)
if(current_data.level)
current_amount += (current_data.level-1)
return current_amount >= target_amount
for(var/datum/mind/owner in owners)
if(ismob(owner.current))
var/mob/M = owner.current //Yeah if you get morphed and you eat a quantum tech disk with the RD's latest backup good on you soldier.
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H && (H.stat != DEAD) && istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit
for(var/datum/tech/T in S.stored_research)
current_tech[T.id] = T.level? T.level : 0
var/list/otherwise = M.GetAllContents()
for(var/obj/item/disk/tech_disk/TD in otherwise)
for(var/datum/tech/T in TD.tech_stored)
if(!T.id || !T.level)
continue
else if(!current_tech[T.id])
current_tech[T.id] = T.level
else if(T.level > current_tech[T.id])
current_tech[T.id] = T.level
var/total = 0
for(var/i in current_tech)
total += current_tech[i]
return total >= target_amount
/datum/objective/capture
@@ -586,7 +583,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
for(var/datum/mind/M in owners)
if(!owner || !owner.changeling || !owner.changeling.stored_profiles)
continue
absorbedcount += M.changeling.absorbedcount
absorbedcount += M.changeling.absorbedcount
return absorbedcount >= target_amount
+10 -8
View File
@@ -44,10 +44,10 @@
///////////////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
for (var/i=1 to max_headrevs)
@@ -230,7 +230,7 @@
//Checks if the round is over//
///////////////////////////////
/datum/game_mode/revolution/check_finished()
if(config.continuous["revolution"])
if(CONFIG_GET(keyed_flag_list/continuous)["revolution"])
if(finished)
SSshuttle.clearHostileEnvironment(src)
return ..()
@@ -253,12 +253,14 @@
/datum/game_mode/proc/add_revolutionary(datum/mind/rev_mind)
if(rev_mind.assigned_role in GLOB.command_positions)
return 0
return FALSE
var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted
if(H.isloyal())
return 0
return FALSE
if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries))
return 0
return FALSE
if(rev_mind.unconvertable)
return FALSE
revolutionaries += rev_mind
if(iscarbon(rev_mind.current))
var/mob/living/carbon/carbon_mob = rev_mind.current
@@ -271,7 +273,7 @@
update_rev_icons_added(rev_mind)
if(jobban_isbanned(rev_mind.current, ROLE_REV))
INVOKE_ASYNC(src, .proc/replace_jobbaned_player, rev_mind.current, ROLE_REV, ROLE_REV)
return 1
return TRUE
//////////////////////////////////////////////////////////////////////////////
//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph.
//////////////////////////////////////////////////////////////////////////////
@@ -329,7 +331,7 @@
/datum/game_mode/revolution/proc/check_heads_victory()
for(var/datum/mind/rev_mind in head_revolutionaries)
var/turf/T = get_turf(rev_mind.current)
if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != DEAD) && T && (T.z in GLOB.station_z_levels))
if(!considered_afk(rev_mind) && considered_alive(rev_mind) && (T.z in GLOB.station_z_levels))
if(ishuman(rev_mind.current))
return 0
return 1
+298 -298
View File
@@ -1,303 +1,303 @@
GLOBAL_VAR_INIT(hsboxspawn, TRUE)
/mob
var/datum/hSB/sandbox = null
/mob/proc/CanBuild()
sandbox = new/datum/hSB
sandbox.owner = src.ckey
if(src.client.holder)
sandbox.admin = 1
verbs += new/mob/proc/sandbox_panel
/mob/proc/sandbox_panel()
set name = "Sandbox Panel"
if(sandbox)
sandbox.update()
/datum/hSB
var/owner = null
var/admin = 0
GLOBAL_VAR_INIT(hsboxspawn, TRUE)
/mob
var/datum/hSB/sandbox = null
/mob/proc/CanBuild()
sandbox = new/datum/hSB
sandbox.owner = src.ckey
if(src.client.holder)
sandbox.admin = 1
verbs += new/mob/proc/sandbox_panel
/mob/proc/sandbox_panel()
set name = "Sandbox Panel"
if(sandbox)
sandbox.update()
/datum/hSB
var/owner = null
var/admin = 0
var/static/clothinfo = null
var/static/reaginfo = null
var/static/objinfo = null
var/canisterinfo = null
var/hsbinfo = null
//items that shouldn't spawn on the floor because they would bug or act weird
var/global/list/spawn_forbidden = list(
/obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you
var/canisterinfo = null
var/hsbinfo = null
//items that shouldn't spawn on the floor because they would bug or act weird
var/global/list/spawn_forbidden = list(
/obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you
/obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai,
/obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile,
/obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile,
/obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module)
/datum/hSB/proc/update()
var/global/list/hrefs = list(
"Space Gear",
"Suit Up (Space Travel Gear)" = "hsbsuit",
"Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]",
"Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]",
"Standard Tools",
"Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]",
"Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]",
"Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]",
"Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]",
"Spawn All-Access ID" = "hsbaaid",
"Building Supplies",
"Spawn 50 Wood" = "hsbwood",
"Spawn 50 Metal" = "hsbmetal",
"Spawn 50 Plasteel" = "hsbplasteel",
"Spawn 50 Reinforced Glass" = "hsbrglass",
"Spawn 50 Glass" = "hsbglass",
"Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]",
"Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]",
"Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]",
"Spawn Rapid Construction Device" = "hsbrcd",
"Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]",
"Spawn Airlock" = "hsbairlock",
"Miscellaneous",
"Spawn Air Scrubber" = "hsbscrubber",
"Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]",
"Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]",
"Bots",
"Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]",
"Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]",
"Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]",
"Canisters",
"Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]",
"Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]")
if(!hsbinfo)
hsbinfo = "<center><b>Sandbox Panel</b></center><hr>"
if(admin)
hsbinfo += "<b>Administration</b><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><br>"
hsbinfo += "<b>Canister Spawning</b><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/toxins]'>Spawn Plasma Canister</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/carbon_dioxide]'>Spawn CO2 Canister</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrogen]'>Spawn Nitrogen Canister</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrous_oxide]'>Spawn N2O Canister</a><hr>"
else
hsbinfo += "<i>Some item spawning may be disabled by the administrators.</i><br>"
hsbinfo += "<i>Only administrators may spawn dangerous canisters.</i><br>"
for(var/T in hrefs)
var/href = hrefs[T]
if(href)
hsbinfo += "- <a href='?\ref[src];hsb=[hrefs[T]]'>[T]</a><br>"
else
hsbinfo += "<br><b>[T]</b><br>"
hsbinfo += "<hr>"
hsbinfo += "- <a href='?\ref[src];hsb=hsbcloth'>Spawn Clothing...</a><br>"
hsbinfo += "- <a href='?\ref[src];hsb=hsbreag'>Spawn Reagent Container...</a><br>"
hsbinfo += "- <a href='?\ref[src];hsb=hsbobj'>Spawn Other Item...</a><br><br>"
usr << browse(hsbinfo, "window=hsbpanel")
/datum/hSB/Topic(href, href_list)
if(!usr || !src || !(src.owner == usr.ckey))
if(usr)
usr << browse(null,"window=sandbox")
return
if(href_list["hsb"])
switch(href_list["hsb"])
//
// Admin: toggle spawning
//
if("hsbtobj")
if(!admin) return
if(GLOB.hsboxspawn)
to_chat(world, "<span class='boldannounce'>Sandbox:</span> <b>\black[usr.key] has disabled object spawning!</b>")
GLOB.hsboxspawn = FALSE
return
else
to_chat(world, "<span class='boldnotice'>Sandbox:</span> <b>\black[usr.key] has enabled object spawning!</b>")
GLOB.hsboxspawn = TRUE
return
//
// Admin: Toggle auto-close
//
if("hsbtac")
if(!admin) return
if(config.sandbox_autoclose)
to_chat(world, "<span class='boldnotice'>Sandbox:</span> <b>\black [usr.key] has removed the object spawn limiter.</b>")
config.sandbox_autoclose = FALSE
else
to_chat(world, "<span class='danger'>Sandbox:</span> <b>\black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.</b>")
config.sandbox_autoclose = TRUE
return
//
// Spacesuit with full air jetpack set as internals
//
if("hsbsuit")
var/mob/living/carbon/human/P = usr
if(!istype(P)) return
if(P.wear_suit)
P.wear_suit.loc = P.loc
P.wear_suit.layer = initial(P.wear_suit.layer)
P.wear_suit.plane = initial(P.wear_suit.plane)
P.wear_suit = null
P.wear_suit = new/obj/item/clothing/suit/space(P)
P.wear_suit.layer = ABOVE_HUD_LAYER
P.wear_suit.plane = ABOVE_HUD_PLANE
P.update_inv_wear_suit()
if(P.head)
P.head.loc = P.loc
P.head.layer = initial(P.head.layer)
P.head.plane = initial(P.head.plane)
P.head = null
P.head = new/obj/item/clothing/head/helmet/space(P)
P.head.layer = ABOVE_HUD_LAYER
P.head.plane = ABOVE_HUD_PLANE
P.update_inv_head()
if(P.wear_mask)
P.wear_mask.loc = P.loc
P.wear_mask.layer = initial(P.wear_mask.layer)
P.wear_mask.plane = initial(P.wear_mask.plane)
P.wear_mask = null
P.wear_mask = new/obj/item/clothing/mask/gas(P)
P.wear_mask.layer = ABOVE_HUD_LAYER
P.wear_mask.plane = ABOVE_HUD_PLANE
P.update_inv_wear_mask()
if(P.back)
P.back.loc = P.loc
P.back.layer = initial(P.back.layer)
P.back.plane = initial(P.back.plane)
P.back = null
P.back = new/obj/item/tank/jetpack/oxygen(P)
P.back.layer = ABOVE_HUD_LAYER
P.back.plane = ABOVE_HUD_PLANE
P.update_inv_back()
P.internal = P.back
P.update_internals_hud_icon(1)
if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it
var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc)
hsb.update_icon() // hackish but it wasn't meant to be spawned I guess?
//
// Stacked Materials
//
if("hsbrglass")
new/obj/item/stack/sheet/rglass{amount=50}(usr.loc)
if("hsbmetal")
new/obj/item/stack/sheet/metal{amount=50}(usr.loc)
if("hsbplasteel")
new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
if("hsbglass")
new/obj/item/stack/sheet/glass{amount=50}(usr.loc)
if("hsbwood")
new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc)
//
// All access ID
//
if("hsbaaid")
var/obj/item/card/id/gold/ID = new(usr.loc)
ID.registered_name = usr.real_name
ID.assignment = "Sandbox"
ID.access = get_all_accesses()
ID.update_label()
//
// RCD - starts with full clip
// Spawn check due to grief potential (destroying floors, walls, etc)
//
if("hsbrcd")
if(!GLOB.hsboxspawn) return
new/obj/item/construction/rcd/combat(usr.loc)
//
// New sandbox airlock maker
//
if("hsbairlock")
new /datum/airlock_maker(usr.loc)
//
// Object spawn window
//
// Clothing
if("hsbcloth")
if(!GLOB.hsboxspawn) return
if(!clothinfo)
clothinfo = "<b>Clothing</b> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
var/list/all_items = subtypesof(/obj/item/clothing)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
clothinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
usr << browse(clothinfo,"window=sandbox")
// Reagent containers
if("hsbreag")
if(!GLOB.hsboxspawn) return
if(!reaginfo)
reaginfo = "<b>Reagent Containers</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
var/list/all_items = subtypesof(/obj/item/reagent_containers)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
reaginfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
usr << browse(reaginfo,"window=sandbox")
// Other items
if("hsbobj")
if(!GLOB.hsboxspawn) return
if(!objinfo)
objinfo = "<b>Other Items</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a><hr><br>"
var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
objinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
usr << browse(objinfo,"window=sandbox")
//
// Safespawn checks to see if spawning is disabled.
//
if("hsb_safespawn")
if(!GLOB.hsboxspawn)
usr << browse(null,"window=sandbox")
return
var/typepath = text2path(href_list["path"])
if(!typepath)
to_chat(usr, "Bad path: \"[href_list["path"]]\"")
return
new typepath(usr.loc)
if(config.sandbox_autoclose)
usr << browse(null,"window=sandbox")
//
// For everything else in the href list
//
if("hsbspawn")
var/typepath = text2path(href_list["path"])
if(!typepath)
to_chat(usr, "Bad path: \"[href_list["path"]]\"")
return
new typepath(usr.loc)
if(config.sandbox_autoclose)
usr << browse(null,"window=sandbox")
/datum/hSB/proc/update()
var/global/list/hrefs = list(
"Space Gear",
"Suit Up (Space Travel Gear)" = "hsbsuit",
"Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]",
"Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]",
"Standard Tools",
"Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]",
"Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]",
"Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]",
"Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]",
"Spawn All-Access ID" = "hsbaaid",
"Building Supplies",
"Spawn 50 Wood" = "hsbwood",
"Spawn 50 Metal" = "hsbmetal",
"Spawn 50 Plasteel" = "hsbplasteel",
"Spawn 50 Reinforced Glass" = "hsbrglass",
"Spawn 50 Glass" = "hsbglass",
"Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]",
"Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]",
"Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]",
"Spawn Rapid Construction Device" = "hsbrcd",
"Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]",
"Spawn Airlock" = "hsbairlock",
"Miscellaneous",
"Spawn Air Scrubber" = "hsbscrubber",
"Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]",
"Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]",
"Bots",
"Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]",
"Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]",
"Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]",
"Canisters",
"Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]",
"Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]")
if(!hsbinfo)
hsbinfo = "<center><b>Sandbox Panel</b></center><hr>"
if(admin)
hsbinfo += "<b>Administration</b><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><br>"
hsbinfo += "<b>Canister Spawning</b><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/toxins]'>Spawn Plasma Canister</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/carbon_dioxide]'>Spawn CO2 Canister</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrogen]'>Spawn Nitrogen Canister</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrous_oxide]'>Spawn N2O Canister</a><hr>"
else
hsbinfo += "<i>Some item spawning may be disabled by the administrators.</i><br>"
hsbinfo += "<i>Only administrators may spawn dangerous canisters.</i><br>"
for(var/T in hrefs)
var/href = hrefs[T]
if(href)
hsbinfo += "- <a href='?\ref[src];hsb=[hrefs[T]]'>[T]</a><br>"
else
hsbinfo += "<br><b>[T]</b><br>"
hsbinfo += "<hr>"
hsbinfo += "- <a href='?\ref[src];hsb=hsbcloth'>Spawn Clothing...</a><br>"
hsbinfo += "- <a href='?\ref[src];hsb=hsbreag'>Spawn Reagent Container...</a><br>"
hsbinfo += "- <a href='?\ref[src];hsb=hsbobj'>Spawn Other Item...</a><br><br>"
usr << browse(hsbinfo, "window=hsbpanel")
/datum/hSB/Topic(href, href_list)
if(!usr || !src || !(src.owner == usr.ckey))
if(usr)
usr << browse(null,"window=sandbox")
return
if(href_list["hsb"])
switch(href_list["hsb"])
//
// Admin: toggle spawning
//
if("hsbtobj")
if(!admin) return
if(GLOB.hsboxspawn)
to_chat(world, "<span class='boldannounce'>Sandbox:</span> <b>\black[usr.key] has disabled object spawning!</b>")
GLOB.hsboxspawn = FALSE
return
else
to_chat(world, "<span class='boldnotice'>Sandbox:</span> <b>\black[usr.key] has enabled object spawning!</b>")
GLOB.hsboxspawn = TRUE
return
//
// Admin: Toggle auto-close
//
if("hsbtac")
if(!admin) return
var/sbac = CONFIG_GET(flag/sandbox_autoclose)
if(sbac)
to_chat(world, "<span class='boldnotice'>Sandbox:</span> <b>\black [usr.key] has removed the object spawn limiter.</b>")
else
to_chat(world, "<span class='danger'>Sandbox:</span> <b>\black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.</b>")
CONFIG_SET(flag/sandbox_autoclose, !sbac)
return
//
// Spacesuit with full air jetpack set as internals
//
if("hsbsuit")
var/mob/living/carbon/human/P = usr
if(!istype(P)) return
if(P.wear_suit)
P.wear_suit.forceMove(P.drop_location())
P.wear_suit.layer = initial(P.wear_suit.layer)
P.wear_suit.plane = initial(P.wear_suit.plane)
P.wear_suit = null
P.wear_suit = new/obj/item/clothing/suit/space(P)
P.wear_suit.layer = ABOVE_HUD_LAYER
P.wear_suit.plane = ABOVE_HUD_PLANE
P.update_inv_wear_suit()
if(P.head)
P.head.forceMove(P.drop_location())
P.head.layer = initial(P.head.layer)
P.head.plane = initial(P.head.plane)
P.head = null
P.head = new/obj/item/clothing/head/helmet/space(P)
P.head.layer = ABOVE_HUD_LAYER
P.head.plane = ABOVE_HUD_PLANE
P.update_inv_head()
if(P.wear_mask)
P.wear_mask.forceMove(P.drop_location())
P.wear_mask.layer = initial(P.wear_mask.layer)
P.wear_mask.plane = initial(P.wear_mask.plane)
P.wear_mask = null
P.wear_mask = new/obj/item/clothing/mask/gas(P)
P.wear_mask.layer = ABOVE_HUD_LAYER
P.wear_mask.plane = ABOVE_HUD_PLANE
P.update_inv_wear_mask()
if(P.back)
P.back.forceMove(P.drop_location())
P.back.layer = initial(P.back.layer)
P.back.plane = initial(P.back.plane)
P.back = null
P.back = new/obj/item/tank/jetpack/oxygen(P)
P.back.layer = ABOVE_HUD_LAYER
P.back.plane = ABOVE_HUD_PLANE
P.update_inv_back()
P.internal = P.back
P.update_internals_hud_icon(1)
if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it
var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc)
hsb.update_icon() // hackish but it wasn't meant to be spawned I guess?
//
// Stacked Materials
//
if("hsbrglass")
new/obj/item/stack/sheet/rglass{amount=50}(usr.loc)
if("hsbmetal")
new/obj/item/stack/sheet/metal{amount=50}(usr.loc)
if("hsbplasteel")
new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
if("hsbglass")
new/obj/item/stack/sheet/glass{amount=50}(usr.loc)
if("hsbwood")
new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc)
//
// All access ID
//
if("hsbaaid")
var/obj/item/card/id/gold/ID = new(usr.loc)
ID.registered_name = usr.real_name
ID.assignment = "Sandbox"
ID.access = get_all_accesses()
ID.update_label()
//
// RCD - starts with full clip
// Spawn check due to grief potential (destroying floors, walls, etc)
//
if("hsbrcd")
if(!GLOB.hsboxspawn) return
new/obj/item/construction/rcd/combat(usr.loc)
//
// New sandbox airlock maker
//
if("hsbairlock")
new /datum/airlock_maker(usr.loc)
//
// Object spawn window
//
// Clothing
if("hsbcloth")
if(!GLOB.hsboxspawn) return
if(!clothinfo)
clothinfo = "<b>Clothing</b> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
var/list/all_items = subtypesof(/obj/item/clothing)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
clothinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
usr << browse(clothinfo,"window=sandbox")
// Reagent containers
if("hsbreag")
if(!GLOB.hsboxspawn) return
if(!reaginfo)
reaginfo = "<b>Reagent Containers</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
var/list/all_items = subtypesof(/obj/item/reagent_containers)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
reaginfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
usr << browse(reaginfo,"window=sandbox")
// Other items
if("hsbobj")
if(!GLOB.hsboxspawn) return
if(!objinfo)
objinfo = "<b>Other Items</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a><hr><br>"
var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers)
for(var/typekey in spawn_forbidden)
all_items -= typesof(typekey)
for(var/O in reverseRange(all_items))
objinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
usr << browse(objinfo,"window=sandbox")
//
// Safespawn checks to see if spawning is disabled.
//
if("hsb_safespawn")
if(!GLOB.hsboxspawn)
usr << browse(null,"window=sandbox")
return
var/typepath = text2path(href_list["path"])
if(!typepath)
to_chat(usr, "Bad path: \"[href_list["path"]]\"")
return
new typepath(usr.loc)
if(CONFIG_GET(flag/sandbox_autoclose))
usr << browse(null,"window=sandbox")
//
// For everything else in the href list
//
if("hsbspawn")
var/typepath = text2path(href_list["path"])
if(!typepath)
to_chat(usr, "Bad path: \"[href_list["path"]]\"")
return
new typepath(usr.loc)
if(CONFIG_GET(flag/sandbox_autoclose))
usr << browse(null,"window=sandbox")
+8 -6
View File
@@ -31,16 +31,17 @@
/datum/game_mode/traitor/pre_setup()
if(config.protect_roles_from_antagonist)
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_traitors = 1
if(config.traitor_scaling_coeff)
num_traitors = max(1, min( round(num_players()/(config.traitor_scaling_coeff*2))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff)) + num_modifier ))
var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
if(tsc)
num_traitors = max(1, min(round(num_players() / (tsc * 2)) + 2 + num_modifier, round(num_players() / tsc) + num_modifier))
else
num_traitors = max(1, min(num_players(), traitors_possible))
@@ -68,10 +69,11 @@
return 1
/datum/game_mode/traitor/make_antag_chance(mob/living/carbon/human/character) //Assigns traitor to latejoiners
var/traitorcap = min(round(GLOB.joined_player_list.len / (config.traitor_scaling_coeff * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len/config.traitor_scaling_coeff) + num_modifier )
var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
var/traitorcap = min(round(GLOB.joined_player_list.len / (tsc * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len / tsc) + num_modifier)
if((SSticker.mode.traitors.len + pre_traitors.len) >= traitorcap) //Upper cap for number of latejoin antagonists
return
if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * 2)))
if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (tsc * 2)))
if(ROLE_TRAITOR in character.client.prefs.be_special)
if(!jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
+4 -5
View File
@@ -234,11 +234,10 @@
if(!link)
if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL)
user.drop_item()
I.loc = src
link = I
to_chat(user, "You attach [I] to the doll.")
update_targets()
if (user.transferItemToLoc(I,src))
link = I
to_chat(user, "You attach [I] to the doll.")
update_targets()
/obj/item/voodoo/check_eye(mob/user)
if(loc != user)
+1 -2
View File
@@ -164,7 +164,7 @@
if(contents.len)
to_chat(user, "<span class='userdanger'>Capture failed!</span>: The soulstone is full! Free an existing soul to make room.")
else
T.loc = src //put shade in stone
T.forceMove(src) //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
@@ -199,7 +199,6 @@
SSticker.mode.cult -= A.mind
SSticker.mode.update_cult_icons_removed(A.mind)
qdel(T)
user.drop_item()
qdel(src)
else
to_chat(user, "<span class='userdanger'>Creation failed!</span>: The soul stone is empty! Go kill someone!")
+3 -3
View File
@@ -478,7 +478,7 @@
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return (!config.no_summon_guns)
return !CONFIG_GET(flag/no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
@@ -495,7 +495,7 @@
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return (!config.no_summon_magic)
return !CONFIG_GET(flag/no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
@@ -513,7 +513,7 @@
/datum/spellbook_entry/summon/events/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return (!config.no_summon_events)
return !CONFIG_GET(flag/no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
+1 -10
View File
@@ -30,7 +30,7 @@
to_chat(wizard.current, "<span class='boldannounce'>A starting location for you could not be found, please report this bug!</span>")
return 0
for(var/datum/mind/wiz in wizards)
wiz.current.loc = pick(GLOB.wizardstart)
wiz.current.forceMove(pick(GLOB.wizardstart))
return 1
@@ -245,15 +245,6 @@
//OTHER PROCS
//To batch-remove wizard spells. Linked to mind.dm.
/mob/proc/spellremove(mob/M)
if(!mind)
return
for(var/X in src.mind.spell_list)
var/obj/effect/proc_holder/spell/spell_to_remove = X
qdel(spell_to_remove)
mind.spell_list -= spell_to_remove
//returns whether the mob is a wizard (or apprentice)
/proc/iswizard(mob/living/M)
return istype(M) && M.mind && SSticker && SSticker.mode && ((M.mind in SSticker.mode.wizards) || (M.mind in SSticker.mode.apprentices))
+2 -2
View File
@@ -44,10 +44,10 @@
var/turf/T = loc
Beacon = new /obj/item/device/radio/beacon
Beacon.invisibility = INVISIBILITY_MAXIMUM
Beacon.loc = T
Beacon.forceMove(T)
if(Beacon)
if(Beacon.loc != loc)
Beacon.loc = loc
Beacon.forceMove(loc)
updateicon()
+2 -1
View File
@@ -95,6 +95,7 @@ Class Procs:
/obj/machinery
name = "machinery"
icon = 'icons/obj/stationobjs.dmi'
desc = "Some kind of machine."
verb_say = "beeps"
verb_yell = "blares"
pressure_resistance = 15
@@ -429,7 +430,7 @@ Class Procs:
W.handle_item_insertion(A, 1)
component_parts -= A
component_parts += B
B.loc = null
B.moveToNullspace()
to_chat(user, "<span class='notice'>[A.name] replaced with [B.name].</span>")
shouldplaysound = 1 //Only play the sound when parts are actually replaced!
break
+5 -6
View File
@@ -134,12 +134,11 @@
if(ispath(lit, /obj/item/ore/bluespace_crystal))
use_power(max(500,M.last_amount_inserted/10))
else
var/obj/item/stack/S = lit
var/list/initmats = initial(S.materials)
if (initmats[MAT_METAL])
flick("autolathe_o",src)//plays metal insertion animation
if (initmats[MAT_GLASS])
flick("autolathe_r",src)//plays glass insertion animation
switch(M.last_inserted_id)
if (MAT_METAL)
flick("autolathe_o",src)//plays metal insertion animation
if (MAT_GLASS)
flick("autolathe_r",src)//plays glass insertion animation
use_power(M.last_amount_inserted*100)
updateUsrDialog()
+1 -1
View File
@@ -43,7 +43,7 @@
say("Station funds depleted. Halting siphon.")
siphoning = FALSE
else
new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack
new /obj/item/stack/spacecash/c200(drop_location()) // will autostack
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
SSshuttle.points -= 200
if(next_warning < world.time && prob(15))
+2 -2
View File
@@ -127,10 +127,10 @@
if(panel_open)
if(device || board)
if(device)
device.loc = get_turf(src)
device.forceMove(drop_location())
device = null
if(board)
board.loc = get_turf(src)
board.forceMove(drop_location())
req_access = list()
req_one_access = list()
board = null
+1 -1
View File
@@ -246,7 +246,7 @@
if(disassembled)
if(!assembly)
assembly = new()
assembly.loc = src.loc
assembly.forceMove(drop_location())
assembly.state = 1
assembly.setDir(dir)
assembly = null
+141 -141
View File
@@ -1,145 +1,145 @@
/obj/item/wallframe/camera
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
icon = 'icons/obj/monitors.dmi'
icon_state = "cameracase"
materials = list(MAT_METAL=400, MAT_GLASS=250)
result_path = /obj/structure/camera_assembly
/obj/structure/camera_assembly
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
icon = 'icons/obj/monitors.dmi'
icon_state = "camera1"
max_integrity = 150
// Motion, EMP-Proof, X-Ray
var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer))
var/list/upgrades
var/state = 1
/*
1 = Wrenched in place
2 = Welded in place
3 = Wires attached to it (you can now attach/dettach upgrades)
4 = Screwdriver panel closed and is fully built (you cannot attach upgrades)
*/
/obj/structure/camera_assembly/Initialize(mapload, ndir, building)
. = ..()
if(building)
setDir(ndir)
upgrades = list()
/obj/structure/camera_assembly/Destroy()
QDEL_LIST(upgrades)
return ..()
/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params)
switch(state)
if(1)
// State 1
if(istype(W, /obj/item/weldingtool))
if(weld(W, user))
to_chat(user, "<span class='notice'>You weld the assembly securely into place.</span>")
/obj/item/wallframe/camera
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
icon = 'icons/obj/monitors.dmi'
icon_state = "cameracase"
materials = list(MAT_METAL=400, MAT_GLASS=250)
result_path = /obj/structure/camera_assembly
/obj/structure/camera_assembly
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
icon = 'icons/obj/monitors.dmi'
icon_state = "camera1"
max_integrity = 150
// Motion, EMP-Proof, X-Ray
var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer))
var/list/upgrades
var/state = 1
/*
1 = Wrenched in place
2 = Welded in place
3 = Wires attached to it (you can now attach/dettach upgrades)
4 = Screwdriver panel closed and is fully built (you cannot attach upgrades)
*/
/obj/structure/camera_assembly/Initialize(mapload, ndir, building)
. = ..()
if(building)
setDir(ndir)
upgrades = list()
/obj/structure/camera_assembly/Destroy()
QDEL_LIST(upgrades)
return ..()
/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params)
switch(state)
if(1)
// State 1
if(istype(W, /obj/item/weldingtool))
if(weld(W, user))
to_chat(user, "<span class='notice'>You weld the assembly securely into place.</span>")
anchored = TRUE
state = 2
return
else if(istype(W, /obj/item/wrench))
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unattach the assembly from its place.</span>")
new /obj/item/wallframe/camera(get_turf(src))
qdel(src)
return
if(2)
// State 2
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(C.use(2))
to_chat(user, "<span class='notice'>You add wires to the assembly.</span>")
state = 3
else
to_chat(user, "<span class='warning'>You need two lengths of cable to wire a camera!</span>")
return
return
else if(istype(W, /obj/item/weldingtool))
if(weld(W, user))
to_chat(user, "<span class='notice'>You unweld the assembly from its place.</span>")
state = 1
state = 2
return
else if(istype(W, /obj/item/wrench))
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unattach the assembly from its place.</span>")
new /obj/item/wallframe/camera(get_turf(src))
qdel(src)
return
if(2)
// State 2
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(C.use(2))
to_chat(user, "<span class='notice'>You add wires to the assembly.</span>")
state = 3
else
to_chat(user, "<span class='warning'>You need two lengths of cable to wire a camera!</span>")
return
return
else if(istype(W, /obj/item/weldingtool))
if(weld(W, user))
to_chat(user, "<span class='notice'>You unweld the assembly from its place.</span>")
state = 1
anchored = TRUE
return
if(3)
// State 3
if(istype(W, /obj/item/screwdriver))
playsound(src.loc, W.usesound, 50, 1)
return
if(3)
// State 3
if(istype(W, /obj/item/screwdriver))
playsound(src.loc, W.usesound, 50, 1)
var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")
if(!input)
to_chat(user, "<span class='warning'>No input found, please hang up and try your call again!</span>")
return
var/list/tempnetwork = splittext(input, ",")
if(tempnetwork.len < 1)
to_chat(user, "<span class='warning'>No network found, please hang up and try your call again!</span>")
return
state = 4
var/obj/machinery/camera/C = new(src.loc)
src.loc = C
C.assembly = src
C.setDir(src.dir)
C.network = tempnetwork
var/area/A = get_area(src)
C.c_tag = "[A.name] ([rand(1, 999)])"
else if(istype(W, /obj/item/wirecutters))
new/obj/item/stack/cable_coil(get_turf(src), 2)
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
state = 2
return
// Upgrades!
if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
if(!user.drop_item(W))
return
to_chat(user, "<span class='notice'>You attach \the [W] into the assembly inner circuits.</span>")
upgrades += W
W.forceMove(src)
return
// Taking out upgrades
else if(istype(W, /obj/item/crowbar) && upgrades.len)
var/obj/U = locate(/obj) in upgrades
if(U)
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
playsound(src.loc, W.usesound, 50, 1)
U.loc = get_turf(src)
upgrades -= U
return
return ..()
/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
if(!WT.remove_fuel(0, user))
return 0
to_chat(user, "<span class='notice'>You start to weld \the [src]...</span>")
playsound(src.loc, WT.usesound, 50, 1)
if(do_after(user, 20*WT.toolspeed, target = src))
if(WT.isOn())
playsound(loc, 'sound/items/welder2.ogg', 50, 1)
return 1
return 0
/obj/structure/camera_assembly/deconstruct(disassembled = TRUE)
if(!input)
to_chat(user, "<span class='warning'>No input found, please hang up and try your call again!</span>")
return
var/list/tempnetwork = splittext(input, ",")
if(tempnetwork.len < 1)
to_chat(user, "<span class='warning'>No network found, please hang up and try your call again!</span>")
return
state = 4
var/obj/machinery/camera/C = new(src.loc)
forceMove(C)
C.assembly = src
C.setDir(src.dir)
C.network = tempnetwork
var/area/A = get_area(src)
C.c_tag = "[A.name] ([rand(1, 999)])"
else if(istype(W, /obj/item/wirecutters))
new/obj/item/stack/cable_coil(get_turf(src), 2)
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
state = 2
return
// Upgrades!
if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
if(!user.drop_item(W))
return
to_chat(user, "<span class='notice'>You attach \the [W] into the assembly inner circuits.</span>")
upgrades += W
W.forceMove(src)
return
// Taking out upgrades
else if(istype(W, /obj/item/crowbar) && upgrades.len)
var/obj/U = locate(/obj) in upgrades
if(U)
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
playsound(src.loc, W.usesound, 50, 1)
U.forceMove(drop_location())
upgrades -= U
return
return ..()
/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
if(!WT.remove_fuel(0, user))
return 0
to_chat(user, "<span class='notice'>You start to weld \the [src]...</span>")
playsound(src.loc, WT.usesound, 50, 1)
if(do_after(user, 20*WT.toolspeed, target = src))
if(WT.isOn())
playsound(loc, 'sound/items/welder2.ogg', 50, 1)
return 1
return 0
/obj/structure/camera_assembly/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/sheet/metal(loc)
qdel(src)
new /obj/item/stack/sheet/metal(loc)
qdel(src)
+5 -6
View File
@@ -45,14 +45,13 @@
if(!isarea(a))
return
if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
to_chat(user, "<span class='warning'>The [name] blinks red as you try to insert the cell!</span>")
to_chat(user, "<span class='warning'>The [src] blinks red as you try to insert the cell!</span>")
return
if(!user.drop_item())
if(!user.transferItemToLoc(W,src))
return
W.loc = src
charging = W
user.visible_message("[user] inserts a cell into the charger.", "<span class='notice'>You insert a cell into the charger.</span>")
user.visible_message("[user] inserts a cell into [src].", "<span class='notice'>You insert a cell into [src].</span>")
chargelevel = -1
updateicon()
else if(istype(W, /obj/item/wrench))
@@ -61,7 +60,7 @@
return
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground</span>")
to_chat(user, "<span class='notice'>You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground</span>")
playsound(src.loc, W.usesound, 75, 1)
else
return ..()
@@ -80,7 +79,7 @@
user.put_in_hands(charging)
charging.add_fingerprint(user)
user.visible_message("[user] removes the cell from the charger.", "<span class='notice'>You remove the cell from the charger.</span>")
user.visible_message("[user] removes [charging] from [src].", "<span class='notice'>You remove [charging] from [src].</span>")
removecell()
+3 -3
View File
@@ -231,9 +231,9 @@
else if(mob_occupant.cloneloss > (100 - heal_level))
mob_occupant.Unconscious(80)
var/dmg_mult = CONFIG_GET(number/damage_multiplier)
//Slowly get that clone healed and finished.
mob_occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
mob_occupant.adjustCloneLoss(-((speed_coeff / 2) * dmg_mult))
var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss()
// To avoid the default cloner making incomplete clones
progress += (100 - MINIMUM_HEAL_LEVEL)
@@ -251,7 +251,7 @@
BP.attach_limb(mob_occupant)
//Premature clones may have brain damage.
mob_occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier))
mob_occupant.adjustBrainLoss(-((speed_coeff / 2) * dmg_mult))
check_brine()
+146 -146
View File
@@ -1,146 +1,146 @@
/obj/machinery/computer/aifixer
name = "\improper AI system integrity restorer"
desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order."
req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS)
var/mob/living/silicon/ai/occupier = null
var/active = 0
circuit = /obj/item/circuitboard/computer/aifixer
icon_keyboard = "tech_key"
icon_screen = "ai-fixer"
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
if(occupier && istype(I, /obj/item/screwdriver))
if(stat & (NOPOWER|BROKEN))
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge.</span>")
else
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge and it emits a warning beep.</span>")
else
return ..()
/obj/machinery/computer/aifixer/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/computer/aifixer/interact(mob/user)
var/dat = ""
if (src.occupier)
var/laws
dat += "<h3>Stored AI: [src.occupier.name]</h3>"
dat += "<b>System integrity:</b> [(src.occupier.health+100)/2]%<br>"
if (src.occupier.laws.zeroth)
laws += "<b>0:</b> [src.occupier.laws.zeroth]<BR>"
for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
var/law = src.occupier.laws.ion[index]
if (length(law) > 0)
var/num = ionnum()
laws += "<b>[num]:</b> [law]<BR>"
var/number = 1
for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
var/law = src.occupier.laws.inherent[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
for (var/index = 1, index <= src.occupier.laws.supplied.len, index++)
var/law = src.occupier.laws.supplied[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
dat += "<b>Laws:</b><br>[laws]<br>"
if (src.occupier.stat == DEAD)
dat += "<span class='bad'>AI non-functional</span>"
else
dat += "<span class='good'>AI functional</span>"
if (!src.active)
dat += {"<br><br><A href='byond://?src=\ref[src];fix=1'>Begin Reconstruction</A>"}
else
dat += "<br><br>Reconstruction in process, please wait.<br>"
dat += {"<br><A href='?src=\ref[user];mach_close=computer'>Close</A>"}
var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/aifixer/proc/Fix()
use_power(1000)
occupier.adjustOxyLoss(-1, 0)
occupier.adjustFireLoss(-1, 0)
occupier.adjustToxLoss(-1, 0)
occupier.adjustBruteLoss(-1, 0)
occupier.updatehealth()
occupier.updatehealth()
if(occupier.health >= 0 && occupier.stat == DEAD)
occupier.revive()
return occupier.health < 100
/obj/machinery/computer/aifixer/process()
if(..())
if(active)
active = Fix()
updateDialog()
update_icon()
/obj/machinery/computer/aifixer/Topic(href, href_list)
if(..())
return
if(href_list["fix"])
to_chat(usr, "<span class='notice'>Reconstruction in progress. This will take several minutes.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
active = TRUE
add_fingerprint(usr)
/obj/machinery/computer/aifixer/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
return
else
if(active)
add_overlay("ai-fixer-on")
if (occupier)
switch (occupier.stat)
if (0)
add_overlay("ai-fixer-full")
if (2)
add_overlay("ai-fixer-404")
else
add_overlay("ai-fixer-empty")
/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
if(!..())
return
//Downloading AI from card to terminal.
if(interaction == AI_TRANS_FROM_CARD)
if(stat & (NOPOWER|BROKEN))
to_chat(user, "[src] is offline and cannot take an AI at this time!")
return
AI.forceMove(src)
occupier = AI
AI.control_disabled = 1
AI.radio_enabled = 0
to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
card.AI = null
update_icon()
else //Uploading AI from terminal to card
if(occupier && !active)
to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
occupier.loc = card
card.AI = occupier
occupier = null
update_icon()
else if (active)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Reconstruction in progress.")
else if (!occupier)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Unable to locate artificial intelligence.")
/obj/machinery/computer/aifixer
name = "\improper AI system integrity restorer"
desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order."
req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS)
var/mob/living/silicon/ai/occupier = null
var/active = 0
circuit = /obj/item/circuitboard/computer/aifixer
icon_keyboard = "tech_key"
icon_screen = "ai-fixer"
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
if(occupier && istype(I, /obj/item/screwdriver))
if(stat & (NOPOWER|BROKEN))
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge.</span>")
else
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge and it emits a warning beep.</span>")
else
return ..()
/obj/machinery/computer/aifixer/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/computer/aifixer/interact(mob/user)
var/dat = ""
if (src.occupier)
var/laws
dat += "<h3>Stored AI: [src.occupier.name]</h3>"
dat += "<b>System integrity:</b> [(src.occupier.health+100)/2]%<br>"
if (src.occupier.laws.zeroth)
laws += "<b>0:</b> [src.occupier.laws.zeroth]<BR>"
for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
var/law = src.occupier.laws.ion[index]
if (length(law) > 0)
var/num = ionnum()
laws += "<b>[num]:</b> [law]<BR>"
var/number = 1
for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
var/law = src.occupier.laws.inherent[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
for (var/index = 1, index <= src.occupier.laws.supplied.len, index++)
var/law = src.occupier.laws.supplied[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
dat += "<b>Laws:</b><br>[laws]<br>"
if (src.occupier.stat == DEAD)
dat += "<span class='bad'>AI non-functional</span>"
else
dat += "<span class='good'>AI functional</span>"
if (!src.active)
dat += {"<br><br><A href='byond://?src=\ref[src];fix=1'>Begin Reconstruction</A>"}
else
dat += "<br><br>Reconstruction in process, please wait.<br>"
dat += {"<br><A href='?src=\ref[user];mach_close=computer'>Close</A>"}
var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/aifixer/proc/Fix()
use_power(1000)
occupier.adjustOxyLoss(-1, 0)
occupier.adjustFireLoss(-1, 0)
occupier.adjustToxLoss(-1, 0)
occupier.adjustBruteLoss(-1, 0)
occupier.updatehealth()
occupier.updatehealth()
if(occupier.health >= 0 && occupier.stat == DEAD)
occupier.revive()
return occupier.health < 100
/obj/machinery/computer/aifixer/process()
if(..())
if(active)
active = Fix()
updateDialog()
update_icon()
/obj/machinery/computer/aifixer/Topic(href, href_list)
if(..())
return
if(href_list["fix"])
to_chat(usr, "<span class='notice'>Reconstruction in progress. This will take several minutes.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
active = TRUE
add_fingerprint(usr)
/obj/machinery/computer/aifixer/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
return
else
if(active)
add_overlay("ai-fixer-on")
if (occupier)
switch (occupier.stat)
if (0)
add_overlay("ai-fixer-full")
if (2)
add_overlay("ai-fixer-404")
else
add_overlay("ai-fixer-empty")
/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
if(!..())
return
//Downloading AI from card to terminal.
if(interaction == AI_TRANS_FROM_CARD)
if(stat & (NOPOWER|BROKEN))
to_chat(user, "[src] is offline and cannot take an AI at this time!")
return
AI.forceMove(src)
occupier = AI
AI.control_disabled = 1
AI.radio_enabled = 0
to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
card.AI = null
update_icon()
else //Uploading AI from terminal to card
if(occupier && !active)
to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
occupier.forceMove(card)
card.AI = occupier
occupier = null
update_icon()
else if (active)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Reconstruction in progress.")
else if (!occupier)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Unable to locate artificial intelligence.")
@@ -19,7 +19,7 @@
var/obj/item/weldingtool/WT = P
if(!WT.remove_fuel(0, user))
if(!WT.isOn())
to_chat(user, "<span class='warning'>The welding tool must be on to complete this task!</span>")
to_chat(user, "<span class='warning'>[WT] must be on to complete this task!</span>")
return
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You start deconstructing the frame...</span>")
@@ -40,14 +40,13 @@
state = 0
return
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
if(!user.drop_item())
if(!user.transferItemToLoc(P, null))
return
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
to_chat(user, "<span class='notice'>You place [P] inside the frame.</span>")
icon_state = "1"
circuit = P
circuit.add_fingerprint(user)
P.loc = null
return
else if(istype(P, /obj/item/circuitboard) && !circuit)
@@ -55,16 +54,16 @@
return
if(istype(P, /obj/item/screwdriver) && circuit)
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
to_chat(user, "<span class='notice'>You screw [circuit] into place.</span>")
state = 2
icon_state = "2"
return
if(istype(P, /obj/item/crowbar) && circuit)
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
to_chat(user, "<span class='notice'>You remove [circuit].</span>")
state = 1
icon_state = "0"
circuit.loc = src.loc
circuit.forceMove(drop_location())
circuit.add_fingerprint(user)
circuit = null
return
+10 -15
View File
@@ -47,29 +47,26 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
/obj/machinery/computer/card/Initialize()
. = ..()
change_position_cooldown = config.id_console_jobslot_delay
change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay)
/obj/machinery/computer/card/attackby(obj/O, mob/user, params)//TODO:SANITY
if(istype(O, /obj/item/card/id))
var/obj/item/card/id/idcard = O
if(check_access(idcard))
if(!scan)
if(!usr.drop_item())
if (!user.transferItemToLoc(idcard,src))
return
idcard.loc = src
scan = idcard
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
else if(!modify)
if(!usr.drop_item())
if (!user.transferItemToLoc(idcard,src))
return
idcard.loc = src
modify = idcard
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
else
if(!modify)
if(!usr.drop_item())
if (!user.transferItemToLoc(idcard,src))
return
idcard.loc = src
modify = idcard
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
else
@@ -95,10 +92,10 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
/obj/machinery/computer/card/on_deconstruction()
if(scan)
scan.forceMove(loc)
scan.forceMove(drop_location())
scan = null
if(modify)
modify.forceMove(loc)
modify.forceMove(drop_location())
modify = null
//Check if you can't open a new position for a certain job
@@ -355,7 +352,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if (modify)
GLOB.data_core.manifest_modify(modify.registered_name, modify.assignment)
modify.update_label()
modify.loc = loc
modify.forceMove(drop_location())
modify.verb_pickup()
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
modify = null
@@ -364,26 +361,24 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
var/obj/item/I = usr.get_active_held_item()
if (istype(I, /obj/item/card/id))
if(!usr.drop_item())
if (!usr.transferItemToLoc(I,src))
return
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
I.loc = src
modify = I
authenticated = 0
if ("scan")
if (scan)
scan.loc = src.loc
scan.forceMove(drop_location())
scan.verb_pickup()
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
scan = null
else
var/obj/item/I = usr.get_active_held_item()
if (istype(I, /obj/item/card/id))
if(!usr.drop_item())
if (!usr.transferItemToLoc(I,src))
return
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
I.loc = src
scan = I
authenticated = 0
if ("auth")
+496 -497
View File
@@ -1,502 +1,501 @@
/obj/machinery/computer/cloning
name = "cloning console"
desc = "Used to clone people and manage DNA."
icon_screen = "dna"
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/cloning
/obj/machinery/computer/cloning
name = "cloning console"
desc = "Used to clone people and manage DNA."
icon_screen = "dna"
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/cloning
req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW.
var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
var/list/pods //Linked cloning pods
var/temp = "Inactive"
var/scantemp_ckey
var/scantemp = "Ready to Scan"
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/data/record/active_record = null
var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
var/loading = 0 // Nice loading text
var/autoprocess = 0
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/cloning/Initialize()
var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
var/list/pods //Linked cloning pods
var/temp = "Inactive"
var/scantemp_ckey
var/scantemp = "Ready to Scan"
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/data/record/active_record = null
var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
var/loading = 0 // Nice loading text
var/autoprocess = 0
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/cloning/Initialize()
. = ..()
updatemodules(TRUE)
/obj/machinery/computer/cloning/Destroy()
if(pods)
for(var/P in pods)
DetachCloner(P)
pods = null
return ..()
/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null)
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.occupant && pod.clonemind == mind)
return null
if(pod.is_operational() && !(pod.occupant || pod.mess))
return pod
/obj/machinery/computer/cloning/proc/HasEfficientPod()
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.is_operational() && pod.efficiency > 5)
return TRUE
/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null)
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.occupant && pod.clonemind == mind)
return pod
else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
. = pod
/obj/machinery/computer/cloning/process()
if(!(scanner && LAZYLEN(pods) && autoprocess))
return
if(scanner.occupant && scanner.scan_level > 2)
scan_occupant(scanner.occupant)
for(var/datum/data/record/R in records)
var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"])
if(!pod)
return
if(pod.occupant)
continue //how though?
if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"]))
records -= R
/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
src.scanner = findscanner()
if(findfirstcloner && !LAZYLEN(pods))
findcloner()
/obj/machinery/computer/cloning/proc/findscanner()
var/obj/machinery/dna_scannernew/scannerf = null
// Loop through every direction
for(dir in list(NORTH,EAST,SOUTH,WEST))
// Try to find a scanner in that direction
scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
// If found and operational, return the scanner
if (!isnull(scannerf) && scannerf.is_operational())
return scannerf
// If no scanner was found, it will return null
return null
/obj/machinery/computer/cloning/proc/findcloner()
var/obj/machinery/clonepod/podf = null
for(dir in list(NORTH,EAST,SOUTH,WEST))
podf = locate(/obj/machinery/clonepod, get_step(src, dir))
if (!isnull(podf) && podf.is_operational())
AttachCloner(podf)
/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod)
if(!pod.connected)
pod.connected = src
LAZYADD(pods, pod)
/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod)
pod.connected = null
LAZYREMOVE(pods, pod)
/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
if(!user.drop_item())
return
W.loc = src
src.diskette = W
to_chat(user, "<span class='notice'>You insert [W].</span>")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
src.updateUsrDialog()
updatemodules(TRUE)
/obj/machinery/computer/cloning/Destroy()
if(pods)
for(var/P in pods)
DetachCloner(P)
pods = null
return ..()
/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null)
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.occupant && pod.clonemind == mind)
return null
if(pod.is_operational() && !(pod.occupant || pod.mess))
return pod
/obj/machinery/computer/cloning/proc/HasEfficientPod()
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.is_operational() && pod.efficiency > 5)
return TRUE
/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null)
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.occupant && pod.clonemind == mind)
return pod
else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
. = pod
/obj/machinery/computer/cloning/process()
if(!(scanner && LAZYLEN(pods) && autoprocess))
return
if(scanner.occupant && scanner.scan_level > 2)
scan_occupant(scanner.occupant)
for(var/datum/data/record/R in records)
var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"])
if(!pod)
return
if(pod.occupant)
continue //how though?
if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"]))
records -= R
/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
src.scanner = findscanner()
if(findfirstcloner && !LAZYLEN(pods))
findcloner()
/obj/machinery/computer/cloning/proc/findscanner()
var/obj/machinery/dna_scannernew/scannerf = null
// Loop through every direction
for(dir in list(NORTH,EAST,SOUTH,WEST))
// Try to find a scanner in that direction
scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
// If found and operational, return the scanner
if (!isnull(scannerf) && scannerf.is_operational())
return scannerf
// If no scanner was found, it will return null
return null
/obj/machinery/computer/cloning/proc/findcloner()
var/obj/machinery/clonepod/podf = null
for(dir in list(NORTH,EAST,SOUTH,WEST))
podf = locate(/obj/machinery/clonepod, get_step(src, dir))
if (!isnull(podf) && podf.is_operational())
AttachCloner(podf)
/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod)
if(!pod.connected)
pod.connected = src
LAZYADD(pods, pod)
/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod)
pod.connected = null
LAZYREMOVE(pods, pod)
/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
if (!user.transferItemToLoc(W,src))
return
src.diskette = W
to_chat(user, "<span class='notice'>You insert [W].</span>")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
src.updateUsrDialog()
else if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/P = W
if(istype(P.buffer, /obj/machinery/clonepod))
if(get_area(P.buffer) != get_area(src))
to_chat(user, "<font color = #666633>-% Cannot link machines across power zones. Buffer cleared %-</font color>")
P.buffer = null
return
to_chat(user, "<font color = #666633>-% Successfully linked [P.buffer] with [src] %-</font color>")
var/obj/machinery/clonepod/pod = P.buffer
if(pod.connected)
pod.connected.DetachCloner(pod)
AttachCloner(pod)
else
P.buffer = src
to_chat(user, "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>")
return
else
return ..()
/obj/machinery/computer/cloning/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/computer/cloning/interact(mob/user)
user.set_machine(src)
add_fingerprint(user)
if(..())
return
updatemodules(TRUE)
var/dat = ""
dat += "<a href='byond://?src=\ref[src];refresh=1'>Refresh</a>"
if(scanner && HasEfficientPod() && scanner.scan_level > 2)
if(!autoprocess)
dat += "<a href='byond://?src=\ref[src];task=autoprocess'>Autoprocess</a>"
else
dat += "<a href='byond://?src=\ref[src];task=stopautoprocess'>Stop autoprocess</a>"
else
dat += "<span class='linkOff'>Autoprocess</span>"
dat += "<h3>Cloning Pod Status</h3>"
dat += "<div class='statusDisplay'>[temp]&nbsp;</div>"
switch(src.menu)
if(1)
// Modules
if (isnull(src.scanner) || !LAZYLEN(pods))
dat += "<h3>Modules</h3>"
//dat += "<a href='byond://?src=\ref[src];relmodules=1'>Reload Modules</a>"
if (isnull(src.scanner))
dat += "<font class='bad'>ERROR: No Scanner detected!</font><br>"
if (!LAZYLEN(pods))
dat += "<font class='bad'>ERROR: No Pod detected</font><br>"
// Scanner
if (!isnull(src.scanner))
var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
dat += "<h3>Scanner Functions</h3>"
dat += "<div class='statusDisplay'>"
if(!scanner_occupant)
dat += "Scanner Unoccupied"
else if(loading)
dat += "[scanner_occupant] => Scanning..."
else
if(scanner_occupant.ckey != scantemp_ckey)
scantemp = "Ready to Scan"
scantemp_ckey = scanner_occupant.ckey
dat += "[scanner_occupant] => [scantemp]"
dat += "</div>"
if(scanner_occupant)
dat += "<a href='byond://?src=\ref[src];scan=1'>Start Scan</a>"
dat += "<br><a href='byond://?src=\ref[src];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
else
dat += "<span class='linkOff'>Start Scan</span>"
// Database
dat += "<h3>Database Functions</h3>"
if (src.records.len && src.records.len > 0)
dat += "<a href='byond://?src=\ref[src];menu=2'>View Records ([src.records.len])</a><br>"
else
dat += "<span class='linkOff'>View Records (0)</span><br>"
if (src.diskette)
dat += "<a href='byond://?src=\ref[src];disk=eject'>Eject Disk</a><br>"
if(2)
dat += "<h3>Current records</h3>"
dat += "<a href='byond://?src=\ref[src];menu=1'><< Back</a><br><br>"
for(var/datum/data/record/R in records)
dat += "<h4>[R.fields["name"]]</h4>Scan ID [R.fields["id"]] <a href='byond://?src=\ref[src];view_rec=[R.fields["id"]]'>View Record</a>"
if(3)
dat += "<h3>Selected Record</h3>"
dat += "<a href='byond://?src=\ref[src];menu=2'><< Back</a><br>"
if (!src.active_record)
dat += "<font class='bad'>Record not found.</font>"
else
dat += "<h4>[src.active_record.fields["name"]]</h4>"
dat += "Scan ID [src.active_record.fields["id"]] <a href='byond://?src=\ref[src];clone=[active_record.fields["id"]]'>Clone</a><br>"
var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
if ((H) && (istype(H)))
dat += "<b>Health Implant Data:</b><br />[H.sensehealth()]<br><br />"
else
dat += "<font class='bad'>Unable to locate Health Implant.</font><br /><br />"
dat += "<b>Unique Identifier:</b><br /><span class='highlight'>[src.active_record.fields["UI"]]</span><br>"
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>[src.active_record.fields["SE"]]</span><br>"
if(diskette && diskette.fields)
dat += "<div class='block'>"
dat += "<h4>Inserted Disk</h4>"
dat += "<b>Contents:</b> "
var/list/L = list()
if(diskette.fields["UI"])
L += "Unique Identifier"
if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
L += "Unique Enzymes"
if(diskette.fields["SE"])
L += "Structural Enzymes"
dat += english_list(L, "Empty", " + ", " + ")
dat += "<br /><a href='byond://?src=\ref[src];disk=load'>Load from Disk</a>"
dat += "<br /><a href='byond://?src=\ref[src];disk=save'>Save to Disk</a>"
dat += "</div>"
dat += "<font size=1><a href='byond://?src=\ref[src];del_rec=1'>Delete Record</a></font>"
if(4)
if (!src.active_record)
src.menu = 2
dat = "[src.temp]<br>"
dat += "<h3>Confirm Record Deletion</h3>"
dat += "<b><a href='byond://?src=\ref[src];del_rec=1'>Scan card to confirm.</a></b><br>"
dat += "<b><a href='byond://?src=\ref[src];menu=3'>Cancel</a></b>"
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/cloning/Topic(href, href_list)
if(..())
return
if(loading)
return
if(href_list["task"])
switch(href_list["task"])
if("autoprocess")
autoprocess = 1
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if("stopautoprocess")
autoprocess = 0
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
scantemp = ""
loading = 1
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
say("Initiating scan...")
spawn(20)
src.scan_occupant(scanner.occupant)
loading = 0
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
//No locking an open scanner.
else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational())
if ((!scanner.locked) && (scanner.occupant))
var/obj/item/device/multitool/P = W
if(istype(P.buffer, /obj/machinery/clonepod))
if(get_area(P.buffer) != get_area(src))
to_chat(user, "<font color = #666633>-% Cannot link machines across power zones. Buffer cleared %-</font color>")
P.buffer = null
return
to_chat(user, "<font color = #666633>-% Successfully linked [P.buffer] with [src] %-</font color>")
var/obj/machinery/clonepod/pod = P.buffer
if(pod.connected)
pod.connected.DetachCloner(pod)
AttachCloner(pod)
else
P.buffer = src
to_chat(user, "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>")
return
else
return ..()
/obj/machinery/computer/cloning/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/computer/cloning/interact(mob/user)
user.set_machine(src)
add_fingerprint(user)
if(..())
return
updatemodules(TRUE)
var/dat = ""
dat += "<a href='byond://?src=\ref[src];refresh=1'>Refresh</a>"
if(scanner && HasEfficientPod() && scanner.scan_level > 2)
if(!autoprocess)
dat += "<a href='byond://?src=\ref[src];task=autoprocess'>Autoprocess</a>"
else
dat += "<a href='byond://?src=\ref[src];task=stopautoprocess'>Stop autoprocess</a>"
else
dat += "<span class='linkOff'>Autoprocess</span>"
dat += "<h3>Cloning Pod Status</h3>"
dat += "<div class='statusDisplay'>[temp]&nbsp;</div>"
switch(src.menu)
if(1)
// Modules
if (isnull(src.scanner) || !LAZYLEN(pods))
dat += "<h3>Modules</h3>"
//dat += "<a href='byond://?src=\ref[src];relmodules=1'>Reload Modules</a>"
if (isnull(src.scanner))
dat += "<font class='bad'>ERROR: No Scanner detected!</font><br>"
if (!LAZYLEN(pods))
dat += "<font class='bad'>ERROR: No Pod detected</font><br>"
// Scanner
if (!isnull(src.scanner))
var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
dat += "<h3>Scanner Functions</h3>"
dat += "<div class='statusDisplay'>"
if(!scanner_occupant)
dat += "Scanner Unoccupied"
else if(loading)
dat += "[scanner_occupant] => Scanning..."
else
if(scanner_occupant.ckey != scantemp_ckey)
scantemp = "Ready to Scan"
scantemp_ckey = scanner_occupant.ckey
dat += "[scanner_occupant] => [scantemp]"
dat += "</div>"
if(scanner_occupant)
dat += "<a href='byond://?src=\ref[src];scan=1'>Start Scan</a>"
dat += "<br><a href='byond://?src=\ref[src];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
else
dat += "<span class='linkOff'>Start Scan</span>"
// Database
dat += "<h3>Database Functions</h3>"
if (src.records.len && src.records.len > 0)
dat += "<a href='byond://?src=\ref[src];menu=2'>View Records ([src.records.len])</a><br>"
else
dat += "<span class='linkOff'>View Records (0)</span><br>"
if (src.diskette)
dat += "<a href='byond://?src=\ref[src];disk=eject'>Eject Disk</a><br>"
if(2)
dat += "<h3>Current records</h3>"
dat += "<a href='byond://?src=\ref[src];menu=1'><< Back</a><br><br>"
for(var/datum/data/record/R in records)
dat += "<h4>[R.fields["name"]]</h4>Scan ID [R.fields["id"]] <a href='byond://?src=\ref[src];view_rec=[R.fields["id"]]'>View Record</a>"
if(3)
dat += "<h3>Selected Record</h3>"
dat += "<a href='byond://?src=\ref[src];menu=2'><< Back</a><br>"
if (!src.active_record)
dat += "<font class='bad'>Record not found.</font>"
else
dat += "<h4>[src.active_record.fields["name"]]</h4>"
dat += "Scan ID [src.active_record.fields["id"]] <a href='byond://?src=\ref[src];clone=[active_record.fields["id"]]'>Clone</a><br>"
var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
if ((H) && (istype(H)))
dat += "<b>Health Implant Data:</b><br />[H.sensehealth()]<br><br />"
else
dat += "<font class='bad'>Unable to locate Health Implant.</font><br /><br />"
dat += "<b>Unique Identifier:</b><br /><span class='highlight'>[src.active_record.fields["UI"]]</span><br>"
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>[src.active_record.fields["SE"]]</span><br>"
if(diskette && diskette.fields)
dat += "<div class='block'>"
dat += "<h4>Inserted Disk</h4>"
dat += "<b>Contents:</b> "
var/list/L = list()
if(diskette.fields["UI"])
L += "Unique Identifier"
if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
L += "Unique Enzymes"
if(diskette.fields["SE"])
L += "Structural Enzymes"
dat += english_list(L, "Empty", " + ", " + ")
dat += "<br /><a href='byond://?src=\ref[src];disk=load'>Load from Disk</a>"
dat += "<br /><a href='byond://?src=\ref[src];disk=save'>Save to Disk</a>"
dat += "</div>"
dat += "<font size=1><a href='byond://?src=\ref[src];del_rec=1'>Delete Record</a></font>"
if(4)
if (!src.active_record)
src.menu = 2
dat = "[src.temp]<br>"
dat += "<h3>Confirm Record Deletion</h3>"
dat += "<b><a href='byond://?src=\ref[src];del_rec=1'>Scan card to confirm.</a></b><br>"
dat += "<b><a href='byond://?src=\ref[src];menu=3'>Cancel</a></b>"
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/cloning/Topic(href, href_list)
if(..())
return
if(loading)
return
if(href_list["task"])
switch(href_list["task"])
if("autoprocess")
autoprocess = 1
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if("stopautoprocess")
autoprocess = 0
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
scantemp = ""
loading = 1
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
say("Initiating scan...")
spawn(20)
src.scan_occupant(scanner.occupant)
loading = 0
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
//No locking an open scanner.
else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational())
if ((!scanner.locked) && (scanner.occupant))
scanner.locked = TRUE
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
scanner.locked = FALSE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
else if(href_list["view_rec"])
playsound(src, "terminal_type", 25, 0)
src.active_record = find_record("id", href_list["view_rec"], records)
if(active_record)
if(!active_record.fields["ckey"])
records -= active_record
active_record = null
src.temp = "<font class='bad'>Record Corrupt</font>"
else
src.menu = 3
else
src.temp = "Record missing."
else if (href_list["del_rec"])
if ((!src.active_record) || (src.menu < 3))
return
if (src.menu == 3) //If we are viewing a record, confirm deletion
src.temp = "Delete record?"
src.menu = 4
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
else if (src.menu == 4)
var/obj/item/card/id/C = usr.get_active_held_item()
if (istype(C)||istype(C, /obj/item/device/pda))
if(src.check_access(C))
src.temp = "[src.active_record.fields["name"]] => Record deleted."
src.records.Remove(active_record)
active_record = null
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
src.menu = 2
else
src.temp = "<font class='bad'>Access Denied.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if (href_list["disk"]) //Load or eject.
switch(href_list["disk"])
if("load")
if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields)
src.temp = "<font class='bad'>Load error.</font>"
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if (!src.active_record)
src.temp = "<font class='bad'>Record error.</font>"
src.menu = 1
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
for(var/key in diskette.fields)
src.active_record.fields[key] = diskette.fields[key]
src.temp = "Load successful."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if("eject")
if(src.diskette)
src.diskette.loc = src.loc
src.diskette = null
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
if("save")
if(!diskette || diskette.read_only || !active_record || !active_record.fields)
src.temp = "<font class='bad'>Save error.</font>"
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
diskette.fields = active_record.fields.Copy()
diskette.name = "data disk - '[src.diskette.fields["name"]]'"
src.temp = "Save successful."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
else if (href_list["refresh"])
src.updateUsrDialog()
playsound(src, "terminal_type", 25, 0)
else if (href_list["clone"])
var/datum/data/record/C = find_record("id", href_list["clone"], records)
//Look for that player! They better be dead!
if(C)
var/obj/machinery/clonepod/pod = GetAvailablePod()
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!LAZYLEN(pods))
temp = "<font class='bad'>No Clonepods detected.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(!pod)
temp = "<font class='bad'>No Clonepods available.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(!config.revival_cloning)
temp = "<font class='bad'>Unable to initiate cloning cycle.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"]))
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
records.Remove(C)
if(active_record == C)
active_record = null
menu = 1
else
temp = "[C.fields["name"]] => <font class='bad'>Initialisation failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
temp = "<font class='bad'>Data corruption.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if (href_list["menu"])
src.menu = text2num(href_list["menu"])
playsound(src, "terminal_type", 25, 0)
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer/cloning/proc/scan_occupant(occupant)
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
var/datum/dna/dna
if(iscarbon(mob_occupant))
var/mob/living/carbon/C = mob_occupant
dna = C.has_dna()
if(isbrain(mob_occupant))
var/mob/living/brain/B = mob_occupant
dna = B.stored_dna
if(!istype(dna))
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if(mob_occupant.suiciding || mob_occupant.hellbound)
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2))
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return
if ((!mob_occupant.ckey) || (!mob_occupant.client))
scantemp = "<font class='bad'>Mental interface failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if (find_record("ckey", mob_occupant.ckey, records))
scantemp = "<font class='average'>Subject already in database.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
var/datum/data/record/R = new()
if(dna.species)
// We store the instance rather than the path, because some
// species (abductors, slimepeople) store state in their
// species datums
R.fields["mrace"] = dna.species
else
var/datum/species/rando_race = pick(config.roundstart_races)
R.fields["mrace"] = rando_race.type
R.fields["ckey"] = mob_occupant.ckey
R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
R.fields["UI"] = dna.uni_identity
R.fields["SE"] = dna.struc_enzymes
R.fields["blood_type"] = dna.blood_type
R.fields["features"] = dna.features
R.fields["factions"] = mob_occupant.faction
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "\ref[mob_occupant.mind]"
//Add an implant if needed
var/obj/item/implant/health/imp
for(var/obj/item/implant/health/HI in mob_occupant.implants)
imp = HI
break
if(!imp)
imp = new /obj/item/implant/health(mob_occupant)
imp.implant(mob_occupant)
R.fields["imp"] = "\ref[imp]"
src.records += R
scantemp = "Subject successfully scanned."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
else if(href_list["view_rec"])
playsound(src, "terminal_type", 25, 0)
src.active_record = find_record("id", href_list["view_rec"], records)
if(active_record)
if(!active_record.fields["ckey"])
records -= active_record
active_record = null
src.temp = "<font class='bad'>Record Corrupt</font>"
else
src.menu = 3
else
src.temp = "Record missing."
else if (href_list["del_rec"])
if ((!src.active_record) || (src.menu < 3))
return
if (src.menu == 3) //If we are viewing a record, confirm deletion
src.temp = "Delete record?"
src.menu = 4
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
else if (src.menu == 4)
var/obj/item/card/id/C = usr.get_active_held_item()
if (istype(C)||istype(C, /obj/item/device/pda))
if(src.check_access(C))
src.temp = "[src.active_record.fields["name"]] => Record deleted."
src.records.Remove(active_record)
active_record = null
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
src.menu = 2
else
src.temp = "<font class='bad'>Access Denied.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if (href_list["disk"]) //Load or eject.
switch(href_list["disk"])
if("load")
if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields)
src.temp = "<font class='bad'>Load error.</font>"
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if (!src.active_record)
src.temp = "<font class='bad'>Record error.</font>"
src.menu = 1
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
for(var/key in diskette.fields)
src.active_record.fields[key] = diskette.fields[key]
src.temp = "Load successful."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if("eject")
if(src.diskette)
src.diskette.forceMove(drop_location())
src.diskette = null
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
if("save")
if(!diskette || diskette.read_only || !active_record || !active_record.fields)
src.temp = "<font class='bad'>Save error.</font>"
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
diskette.fields = active_record.fields.Copy()
diskette.name = "data disk - '[src.diskette.fields["name"]]'"
src.temp = "Save successful."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
else if (href_list["refresh"])
src.updateUsrDialog()
playsound(src, "terminal_type", 25, 0)
else if (href_list["clone"])
var/datum/data/record/C = find_record("id", href_list["clone"], records)
//Look for that player! They better be dead!
if(C)
var/obj/machinery/clonepod/pod = GetAvailablePod()
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!LAZYLEN(pods))
temp = "<font class='bad'>No Clonepods detected.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(!pod)
temp = "<font class='bad'>No Clonepods available.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(!CONFIG_GET(flag/revival_cloning))
temp = "<font class='bad'>Unable to initiate cloning cycle.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"]))
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
records.Remove(C)
if(active_record == C)
active_record = null
menu = 1
else
temp = "[C.fields["name"]] => <font class='bad'>Initialisation failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
temp = "<font class='bad'>Data corruption.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if (href_list["menu"])
src.menu = text2num(href_list["menu"])
playsound(src, "terminal_type", 25, 0)
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer/cloning/proc/scan_occupant(occupant)
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
var/datum/dna/dna
if(iscarbon(mob_occupant))
var/mob/living/carbon/C = mob_occupant
dna = C.has_dna()
if(isbrain(mob_occupant))
var/mob/living/brain/B = mob_occupant
dna = B.stored_dna
if(!istype(dna))
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if(mob_occupant.suiciding || mob_occupant.hellbound)
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2))
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return
if ((!mob_occupant.ckey) || (!mob_occupant.client))
scantemp = "<font class='bad'>Mental interface failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if (find_record("ckey", mob_occupant.ckey, records))
scantemp = "<font class='average'>Subject already in database.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
var/datum/data/record/R = new()
if(dna.species)
// We store the instance rather than the path, because some
// species (abductors, slimepeople) store state in their
// species datums
R.fields["mrace"] = dna.species
else
var/datum/species/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
R.fields["mrace"] = rando_race.type
R.fields["ckey"] = mob_occupant.ckey
R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
R.fields["UI"] = dna.uni_identity
R.fields["SE"] = dna.struc_enzymes
R.fields["blood_type"] = dna.blood_type
R.fields["features"] = dna.features
R.fields["factions"] = mob_occupant.faction
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "\ref[mob_occupant.mind]"
//Add an implant if needed
var/obj/item/implant/health/imp
for(var/obj/item/implant/health/HI in mob_occupant.implants)
imp = HI
break
if(!imp)
imp = new /obj/item/implant/health(mob_occupant)
imp.implant(mob_occupant)
R.fields["imp"] = "\ref[imp]"
src.records += R
scantemp = "Subject successfully scanned."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
@@ -454,7 +454,7 @@
if (src.authenticated==2)
dat += "<BR><BR><B>Captain Functions</B>"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=announce'>Make a Captain's Announcement</A> \]"
if(config.cross_allowed)
if(CONFIG_GET(string/cross_server_address))
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=crossserver'>Send a message to an allied station</A> \]"
if(SSmapping.config.allow_custom_shuttles == "yes")
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=purchase_menu'>Purchase Shuttle</A> \]"
+3 -4
View File
@@ -43,9 +43,8 @@
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
if(!user.drop_item())
if (!user.transferItemToLoc(I,src))
return
I.loc = src
src.diskette = I
to_chat(user, "<span class='notice'>You insert [I].</span>")
src.updateUsrDialog()
@@ -169,7 +168,7 @@
if("working")
temp_html += status
temp_html += "<h1>System Busy</h1>"
temp_html += "Working ... Please wait ([DisplayTimeText(radduration)])"
temp_html += "Working ... Please wait ([DisplayTimeText(radduration*10)])"
if("buffer")
temp_html += status
temp_html += buttons
@@ -448,7 +447,7 @@
diskette.fields = buffer_slot.Copy()
if("ejectdisk")
if(diskette)
diskette.loc = get_turf(src)
diskette.forceMove(drop_location())
diskette = null
if("setdelayed")
if(num)
@@ -27,9 +27,8 @@
/obj/machinery/computer/gulag_teleporter_computer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/card/id/prisoner))
if(!id)
if(!user.drop_item())
if (!user.transferItemToLoc(W,src))
return
W.forceMove(src)
id = W
to_chat(user, "<span class='notice'>You insert [W].</span>")
return
+2 -2
View File
@@ -124,7 +124,7 @@
dat += "<tr><td>ID:</td><td>[active1.fields["id"]]</td></tr>"
dat += "<tr><td>Sex:</td><td><A href='?src=\ref[src];field=sex'>&nbsp;[active1.fields["sex"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Age:</td><td><A href='?src=\ref[src];field=age'>&nbsp;[active1.fields["age"]]&nbsp;</A></td></tr>"
if(config.mutant_races)
if(CONFIG_GET(flag/join_with_mutant_race))
dat += "<tr><td>Species:</td><td><A href='?src=\ref[src];field=species'>&nbsp;[active1.fields["species"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Fingerprint:</td><td><A href='?src=\ref[src];field=fingerprint'>&nbsp;[active1.fields["fingerprint"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Physical Status:</td><td><A href='?src=\ref[src];field=p_stat'>&nbsp;[active1.fields["p_stat"]]&nbsp;</A></td></tr>"
@@ -543,7 +543,7 @@
P.info = "<CENTER><B>Medical Record - (MR-[GLOB.data_core.medicalPrintCount])</B></CENTER><BR>"
if(active1 in GLOB.data_core.general)
P.info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"])
if(config.mutant_races)
if(CONFIG_GET(flag/join_with_mutant_race))
P.info += "\nSpecies: [active1.fields["species"]]<BR>"
P.info += text("\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"])
else
+5 -5
View File
@@ -186,7 +186,7 @@
<tr><td>ID:</td><td><A href='?src=\ref[src];choice=Edit Field;field=id'>&nbsp;[active1.fields["id"]]&nbsp;</A></td></tr>
<tr><td>Sex:</td><td><A href='?src=\ref[src];choice=Edit Field;field=sex'>&nbsp;[active1.fields["sex"]]&nbsp;</A></td></tr>
<tr><td>Age:</td><td><A href='?src=\ref[src];choice=Edit Field;field=age'>&nbsp;[active1.fields["age"]]&nbsp;</A></td></tr>"}
if(config.mutant_races)
if(CONFIG_GET(flag/join_with_mutant_race))
dat += "<tr><td>Species:</td><td><A href ='?src=\ref[src];choice=Edit Field;field=species'>&nbsp;[active1.fields["species"]]&nbsp;</A></td></tr>"
dat += {"<tr><td>Rank:</td><td><A href='?src=\ref[src];choice=Edit Field;field=rank'>&nbsp;[active1.fields["rank"]]&nbsp;</A></td></tr>
<tr><td>Fingerprint:</td><td><A href='?src=\ref[src];choice=Edit Field;field=fingerprint'>&nbsp;[active1.fields["fingerprint"]]&nbsp;</A></td></tr>
@@ -373,7 +373,7 @@ What a mess.*/
P.info = "<CENTER><B>Security Record - (SR-[GLOB.data_core.securityPrintCount])</B></CENTER><BR>"
if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))
P.info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"])
if(config.mutant_races)
if(CONFIG_GET(flag/join_with_mutant_race))
P.info += "\nSpecies: [active1.fields["species"]]<BR>"
P.info += text("\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"])
else
@@ -519,7 +519,7 @@ What a mess.*/
G.fields["rank"] = "Unassigned"
G.fields["sex"] = "Male"
G.fields["age"] = "Unknown"
if(config.mutant_races)
if(CONFIG_GET(flag/join_with_mutant_race))
G.fields["species"] = "Human"
G.fields["photo_front"] = new /icon()
G.fields["photo_side"] = new /icon()
@@ -604,7 +604,7 @@ What a mess.*/
active1.fields["age"] = t1
if("species")
if(istype(active1, /datum/data/record))
var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_species
var/t1 = input("Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races)
if(!canUseSecurityRecordsConsole(usr, t1, a1))
return
active1.fields["species"] = t1
@@ -772,7 +772,7 @@ What a mess.*/
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
if(7)
R.fields["species"] = pick(GLOB.roundstart_species)
R.fields["species"] = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
if(8)
var/datum/data/record/G = pick(GLOB.data_core.general)
R.fields["photo_front"] = G.fields["photo_front"]
@@ -5,6 +5,10 @@
var/list/accesses = list()
var/one_access = 0
/obj/item/electronics/airlock/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Has a neat <i>selection menu</i> for modifying airlock access levels.</span>")
/obj/item/electronics/airlock/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+5 -1
View File
@@ -33,6 +33,10 @@
var/damage_deflection = 10
var/real_explosion_block //ignore this, just use explosion_block
/obj/machinery/door/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Its maintenance panel is <b>screwed</b> in place.</span>")
/obj/machinery/door/New()
..()
if(density)
@@ -79,7 +83,7 @@
bumpopen(M)
return
if(istype(AM, /obj/mecha))
if(ismecha(AM))
var/obj/mecha/mecha = AM
if(density)
if(mecha.occupant)
+1 -1
View File
@@ -62,7 +62,7 @@
if( operating || !src.density )
return
if (!( ismob(AM) ))
if(istype(AM, /obj/mecha))
if(ismecha(AM))
var/obj/mecha/mecha = AM
if(mecha.occupant && src.allowed(mecha.occupant))
open_and_close()
@@ -42,6 +42,7 @@
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_button_standby"
name = "access button"
desc = "A button used for the explicit purpose of opening an airlock."
var/idDoor
var/obj/machinery/door/airlock/door
var/obj/machinery/doorButtons/airlock_controller/controller
@@ -107,6 +108,7 @@
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_control_standby"
name = "access console"
desc = "A small console that can cycle opening between two airlocks."
var/obj/machinery/door/airlock/interiorAirlock
var/obj/machinery/door/airlock/exteriorAirlock
var/idInterior
+1
View File
@@ -6,6 +6,7 @@
icon = 'icons/obj/power.dmi'
icon_state = "light1"
anchored = TRUE
desc = "Make dark."
var/on = TRUE
var/area/area = null
var/otherarea = null
+1 -1
View File
@@ -20,7 +20,7 @@
var/O_limit
var/atom/target = get_edge_target_turf(src, dir)
for(var/atom/movable/O in loc)
if(!O.anchored || istype(O, /obj/mecha)) //Mechs need their launch platforms.
if(!O.anchored || ismecha(O)) //Mechs need their launch platforms.
O_limit++
if(O_limit >= 20)
audible_message("<span class='notice'>[src] lets out a screech, it doesn't seem to be able to handle the load.</span>")
@@ -2,6 +2,7 @@
name = "pipe dispenser"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
desc = "Dispenses countless types of pipes. Very useful if you need pipes."
density = TRUE
anchored = TRUE
var/wait = 0
@@ -108,6 +109,7 @@
name = "disposal pipe dispenser"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
desc = "Dispenses pipes that will ultimately be used to move trash around."
density = TRUE
anchored = TRUE
@@ -183,6 +185,7 @@ Nah
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
density = TRUE
desc = "Dispenses pipes that will move beings around."
anchored = TRUE
/obj/machinery/pipedispenser/disposal/transit_tube/attack_hand(mob/user)
@@ -12,6 +12,7 @@
layer = OBJ_LAYER
invisibility = INVISIBILITY_OBSERVER //the turret is invisible if it's inside its cover
density = TRUE
desc = "A covered turret that shoots at its enemies."
use_power = IDLE_POWER_USE //this turret uses and requires power
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
@@ -389,7 +390,7 @@
if(!in_faction(C))
targets += C
if(istype(A, /obj/mecha))
if(ismecha(A))
var/obj/mecha/M = A
//If there is a user and they're not in our faction
if(M.occupant && !in_faction(M.occupant))
@@ -552,6 +553,7 @@
base_icon_state = "syndie"
faction = "syndicate"
emp_vunerable = 0
desc = "A ballistic machine gun auto-turret."
/obj/machinery/porta_turret/syndicate/energy
icon_state = "standard_stun"
@@ -560,6 +562,7 @@
stun_projectile_sound = 'sound/weapons/taser.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
desc = "An energy blaster auto-turret."
/obj/machinery/porta_turret/syndicate/setup()
return
@@ -12,6 +12,7 @@
name = "turret frame"
icon = 'icons/obj/turrets.dmi'
icon_state = "turret_frame"
desc = "An unfinished covered turret frame."
density = TRUE
var/build_step = PTURRET_UNSECURED //the current step in the building process
var/finish_name = "turret" //the name applied to the product turret
+198 -197
View File
@@ -1,197 +1,198 @@
#define SAFETY_COOLDOWN 100
/obj/machinery/recycler
name = "recycler"
desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side."
icon = 'icons/obj/recycling.dmi'
icon_state = "grinder-o0"
layer = ABOVE_ALL_MOB_LAYER // Overhead
anchored = TRUE
density = TRUE
circuit = /obj/item/circuitboard/machine/recycler
var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
var/icon_name = "grinder-o"
var/blood = 0
var/eat_dir = WEST
var/amount_produced = 50
var/crush_damage = 1000
var/eat_victim_items = TRUE
var/item_recycle_sound = 'sound/items/welder.ogg'
/obj/machinery/recycler/Initialize()
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
. = ..()
update_icon()
/obj/machinery/recycler/RefreshParts()
var/amt_made = 0
var/mat_mod = 0
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
mat_mod = 2 * B.rating
mat_mod *= 50000
for(var/obj/item/stock_parts/manipulator/M in component_parts)
amt_made = 12.5 * M.rating //% of materials salvaged
GET_COMPONENT(materials, /datum/component/material_container)
materials.max_amount = mat_mod
amount_produced = min(50, amt_made) + 50
/obj/machinery/recycler/examine(mob/user)
..()
to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
/obj/machinery/recycler/power_change()
..()
update_icon()
/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
return
if(exchange_parts(user, I))
return
if(default_pry_open(I))
return
if(default_unfasten_wrench(user, I))
return
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/recycler/emag_act(mob/user)
if(emagged)
return
emagged = TRUE
if(safety_mode)
safety_mode = FALSE
update_icon()
playsound(src, "sparks", 75, 1, -1)
to_chat(user, "<span class='notice'>You use the cryptographic sequencer on the [src].</span>")
/obj/machinery/recycler/update_icon()
..()
var/is_powered = !(stat & (BROKEN|NOPOWER))
if(safety_mode)
is_powered = FALSE
icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
/obj/machinery/recycler/CollidedWith(atom/movable/AM)
if(stat & (BROKEN|NOPOWER))
return
if(!anchored)
return
if(safety_mode)
return
var/move_dir = get_dir(loc, AM.loc)
if(move_dir == eat_dir)
eat(AM)
/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
var/list/to_eat
if(istype(AM0, /obj/item))
to_eat = AM0.GetAllContents()
else
to_eat = list(AM0)
var/items_recycled = 0
for(var/i in to_eat)
var/atom/movable/AM = i
var/obj/item/bodypart/head/as_head = AM
var/obj/item/device/mmi/as_mmi = AM
var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
if(isliving(AM) || brain_holder)
if(emagged)
if(!brain_holder)
crush_living(AM)
else
emergency_stop(AM)
else if(istype(AM, /obj/item))
recycle_item(AM)
items_recycled++
else
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
AM.loc = src.loc
if(items_recycled && sound)
playsound(src.loc, item_recycle_sound, 50, 1)
/obj/machinery/recycler/proc/recycle_item(obj/item/I)
I.loc = src.loc
GET_COMPONENT(materials, /datum/component/material_container)
var/material_amount = materials.get_item_material_amount(I)
if(!material_amount)
qdel(I)
return
materials.insert_item(I, multiplier = (amount_produced / 100))
qdel(I)
materials.retrieve_all()
/obj/machinery/recycler/proc/emergency_stop(mob/living/L)
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
safety_mode = TRUE
update_icon()
L.loc = src.loc
addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
/obj/machinery/recycler/proc/reboot()
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
safety_mode = FALSE
update_icon()
/obj/machinery/recycler/proc/crush_living(mob/living/L)
L.loc = src.loc
if(issilicon(L))
playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
else
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
var/gib = TRUE
// By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
if(iscarbon(L))
gib = FALSE
if(L.stat == CONSCIOUS)
L.say("ARRRRRRRRRRRGH!!!")
add_mob_blood(L)
if(!blood && !issilicon(L))
blood = TRUE
update_icon()
// Remove and recycle the equipped items
if(eat_victim_items)
for(var/obj/item/I in L.get_equipped_items())
if(L.dropItemToGround(I))
eat(I, sound=FALSE)
// Instantly lie down, also go unconscious from the pain, before you die.
L.Unconscious(100)
// For admin fun, var edit emagged to 2.
if(gib || emagged == 2)
L.gib()
else if(emagged == 1)
L.adjustBruteLoss(crush_damage)
/obj/machinery/recycler/deathtrap
name = "dangerous old crusher"
emagged = TRUE
crush_damage = 120
flags_1 = NODECONSTRUCT_1
/obj/item/paper/guides/recycler
name = "paper - 'garbage duty instructions'"
info = "<h2>New Assignment</h2> You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.<br><br>There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
#undef SAFETY_COOLDOWN
#define SAFETY_COOLDOWN 100
/obj/machinery/recycler
name = "recycler"
desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side."
icon = 'icons/obj/recycling.dmi'
icon_state = "grinder-o0"
layer = ABOVE_ALL_MOB_LAYER // Overhead
anchored = TRUE
density = TRUE
circuit = /obj/item/circuitboard/machine/recycler
var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
var/icon_name = "grinder-o"
var/blood = 0
var/eat_dir = WEST
var/amount_produced = 50
var/crush_damage = 1000
var/eat_victim_items = TRUE
var/item_recycle_sound = 'sound/items/welder.ogg'
/obj/machinery/recycler/Initialize()
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
. = ..()
update_icon()
/obj/machinery/recycler/RefreshParts()
var/amt_made = 0
var/mat_mod = 0
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
mat_mod = 2 * B.rating
mat_mod *= 50000
for(var/obj/item/stock_parts/manipulator/M in component_parts)
amt_made = 12.5 * M.rating //% of materials salvaged
GET_COMPONENT(materials, /datum/component/material_container)
materials.max_amount = mat_mod
amount_produced = min(50, amt_made) + 50
/obj/machinery/recycler/examine(mob/user)
..()
to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
/obj/machinery/recycler/power_change()
..()
update_icon()
/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
return
if(exchange_parts(user, I))
return
if(default_pry_open(I))
return
if(default_unfasten_wrench(user, I))
return
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/recycler/emag_act(mob/user)
if(emagged)
return
emagged = TRUE
if(safety_mode)
safety_mode = FALSE
update_icon()
playsound(src, "sparks", 75, 1, -1)
to_chat(user, "<span class='notice'>You use the cryptographic sequencer on the [src].</span>")
/obj/machinery/recycler/update_icon()
..()
var/is_powered = !(stat & (BROKEN|NOPOWER))
if(safety_mode)
is_powered = FALSE
icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
/obj/machinery/recycler/CollidedWith(atom/movable/AM)
if(stat & (BROKEN|NOPOWER))
return
if(!anchored)
return
if(safety_mode)
return
var/move_dir = get_dir(loc, AM.loc)
if(move_dir == eat_dir)
eat(AM)
/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
var/list/to_eat
if(istype(AM0, /obj/item))
to_eat = AM0.GetAllContents()
else
to_eat = list(AM0)
var/items_recycled = 0
for(var/i in to_eat)
var/atom/movable/AM = i
var/obj/item/bodypart/head/as_head = AM
var/obj/item/device/mmi/as_mmi = AM
var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
if(brain_holder)
emergency_stop(AM)
else if(isliving(AM))
if(emagged)
crush_living(AM)
else
emergency_stop(AM)
else if(istype(AM, /obj/item))
recycle_item(AM)
items_recycled++
else
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
AM.forceMove(loc)
if(items_recycled && sound)
playsound(src, item_recycle_sound, 50, 1)
/obj/machinery/recycler/proc/recycle_item(obj/item/I)
I.forceMove(loc)
GET_COMPONENT(materials, /datum/component/material_container)
var/material_amount = materials.get_item_material_amount(I)
if(!material_amount)
qdel(I)
return
materials.insert_item(I, multiplier = (amount_produced / 100))
qdel(I)
materials.retrieve_all()
/obj/machinery/recycler/proc/emergency_stop(mob/living/L)
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
safety_mode = TRUE
update_icon()
L.forceMove(loc)
addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
/obj/machinery/recycler/proc/reboot()
playsound(src, 'sound/machines/ping.ogg', 50, 0)
safety_mode = FALSE
update_icon()
/obj/machinery/recycler/proc/crush_living(mob/living/L)
L.forceMove(loc)
if(issilicon(L))
playsound(src, 'sound/items/welder.ogg', 50, 1)
else
playsound(src, 'sound/effects/splat.ogg', 50, 1)
var/gib = TRUE
// By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
if(iscarbon(L))
gib = FALSE
if(L.stat == CONSCIOUS)
L.say("ARRRRRRRRRRRGH!!!")
add_mob_blood(L)
if(!blood && !issilicon(L))
blood = TRUE
update_icon()
// Remove and recycle the equipped items
if(eat_victim_items)
for(var/obj/item/I in L.get_equipped_items())
if(L.dropItemToGround(I))
eat(I, sound=FALSE)
// Instantly lie down, also go unconscious from the pain, before you die.
L.Unconscious(100)
// For admin fun, var edit emagged to 2.
if(gib || emagged == 2)
L.gib()
else if(emagged == 1)
L.adjustBruteLoss(crush_damage)
/obj/machinery/recycler/deathtrap
name = "dangerous old crusher"
emagged = TRUE
crush_damage = 120
flags_1 = NODECONSTRUCT_1
/obj/item/paper/guides/recycler
name = "paper - 'garbage duty instructions'"
info = "<h2>New Assignment</h2> You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.<br><br>There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
#undef SAFETY_COOLDOWN
@@ -3,6 +3,7 @@
/obj/machinery/computer/telecomms/server
name = "telecommunications server monitoring console"
icon_screen = "comm_logs"
desc = "Has full access to all details and record of the telecommunications network it's monitoring."
var/screen = 0 // the screen number:
var/list/servers = list() // the servers located by the computer
@@ -8,6 +8,7 @@
/obj/machinery/computer/telecomms/monitor
name = "telecommunications monitoring console"
icon_screen = "comm_monitor"
desc = "Monitors the details of the telecommunications network it's synced with."
var/screen = 0 // the screen number:
var/list/machinelist = list() // the machines located by the computer
+1 -7
View File
@@ -420,13 +420,7 @@
var/datum/component/material_container/M = C
if(!M.last_insert_success)
return
var/lit = M.last_inserted_type
var/stack_name
if(ispath(lit, /obj/item/ore/bluespace_crystal))
stack_name = "bluespace"
else
var/obj/item/stack/S = lit
stack_name = material2name(initial(S.materials)[1])
var/stack_name = material2name(M.last_inserted_id)
add_overlay("fab-load-[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
updateUsrDialog()
+135 -135
View File
@@ -1,137 +1,137 @@
/obj/machinery/computer/mecha
name = "exosuit control console"
desc = "Used to remotely locate or lockdown exosuits."
icon_screen = "mecha"
icon_keyboard = "tech_key"
/obj/machinery/computer/mecha
name = "exosuit control console"
desc = "Used to remotely locate or lockdown exosuits."
icon_screen = "mecha"
icon_keyboard = "tech_key"
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/computer/mecha_control
var/list/located = list()
var/screen = 0
var/stored_data
/obj/machinery/computer/mecha/attack_hand(mob/user)
if(..())
return
user.set_machine(src)
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
if(screen == 0)
dat += "<h3>Tracking beacons data</h3>"
var/list/trackerlist = list()
for(var/obj/mecha/MC in GLOB.mechas_list)
trackerlist += MC.trackers
for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
var/answer = TR.get_mecha_info()
if(answer)
dat += {"<hr>[answer]<br/>
<a href='?src=\ref[src];send_message=\ref[TR]'>Send message</a><br/>
<a href='?src=\ref[src];get_log=\ref[TR]'>Show exosuit log</a> | <a style='color: #f00;' href='?src=\ref[src];shock=\ref[TR]'>(EMP pulse)</a><br>"}
if(screen==1)
dat += "<h3>Log contents</h3>"
dat += "<a href='?src=\ref[src];return=1'>Return</a><hr>"
dat += "[stored_data]"
dat += "<A href='?src=\ref[src];refresh=1'>(Refresh)</A><BR>"
dat += "</body></html>"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
/obj/machinery/computer/mecha/Topic(href, href_list)
if(..())
return
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
if(href_list["send_message"])
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
var/message = stripped_input(usr,"Input message","Transmit message")
var/obj/mecha/M = MT.in_mecha()
if(trim(message) && M)
M.occupant_message(message)
return
if(href_list["shock"])
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
MT.shock()
if(href_list["get_log"])
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
stored_data = MT.get_mecha_log()
screen = 1
if(href_list["return"])
screen = 0
updateUsrDialog()
return
/obj/item/mecha_parts/mecha_tracking
name = "exosuit tracking beacon"
desc = "Device used to transmit exosuit data."
icon = 'icons/obj/device.dmi'
icon_state = "motion2"
w_class = WEIGHT_CLASS_SMALL
origin_tech = "programming=2;magnets=2"
var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
if(!in_mecha())
return 0
var/obj/mecha/M = src.loc
var/cell_charge = M.get_charge()
var/answer = {"<b>Name:</b> [M.name]
<b>Integrity:</b> [M.obj_integrity/M.max_integrity*100]%
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
<b>Airtank:</b> [M.return_pressure()]kPa
<b>Pilot:</b> [M.occupant||"None"]
<b>Location:</b> [get_area(M)||"Unknown"]
<b>Active equipment:</b> [M.selected||"None"] "}
if(istype(M, /obj/mecha/working/ripley))
var/obj/mecha/working/ripley/RM = M
answer += "<b>Used cargo space:</b> [RM.cargo.len/RM.cargo_capacity*100]%<br>"
return answer
/obj/item/mecha_parts/mecha_tracking/emp_act()
qdel(src)
/obj/item/mecha_parts/mecha_tracking/Destroy()
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
if(src in M.trackers)
M.trackers -= src
return ..()
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
if(istype(src.loc, /obj/mecha))
return src.loc
return 0
/obj/item/mecha_parts/mecha_tracking/proc/shock()
var/obj/mecha/M = in_mecha()
if(M)
circuit = /obj/item/circuitboard/computer/mecha_control
var/list/located = list()
var/screen = 0
var/stored_data
/obj/machinery/computer/mecha/attack_hand(mob/user)
if(..())
return
user.set_machine(src)
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
if(screen == 0)
dat += "<h3>Tracking beacons data</h3>"
var/list/trackerlist = list()
for(var/obj/mecha/MC in GLOB.mechas_list)
trackerlist += MC.trackers
for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
var/answer = TR.get_mecha_info()
if(answer)
dat += {"<hr>[answer]<br/>
<a href='?src=\ref[src];send_message=\ref[TR]'>Send message</a><br/>
<a href='?src=\ref[src];get_log=\ref[TR]'>Show exosuit log</a> | <a style='color: #f00;' href='?src=\ref[src];shock=\ref[TR]'>(EMP pulse)</a><br>"}
if(screen==1)
dat += "<h3>Log contents</h3>"
dat += "<a href='?src=\ref[src];return=1'>Return</a><hr>"
dat += "[stored_data]"
dat += "<A href='?src=\ref[src];refresh=1'>(Refresh)</A><BR>"
dat += "</body></html>"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
/obj/machinery/computer/mecha/Topic(href, href_list)
if(..())
return
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
if(href_list["send_message"])
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
var/message = stripped_input(usr,"Input message","Transmit message")
var/obj/mecha/M = MT.in_mecha()
if(trim(message) && M)
M.occupant_message(message)
return
if(href_list["shock"])
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
MT.shock()
if(href_list["get_log"])
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
stored_data = MT.get_mecha_log()
screen = 1
if(href_list["return"])
screen = 0
updateUsrDialog()
return
/obj/item/mecha_parts/mecha_tracking
name = "exosuit tracking beacon"
desc = "Device used to transmit exosuit data."
icon = 'icons/obj/device.dmi'
icon_state = "motion2"
w_class = WEIGHT_CLASS_SMALL
origin_tech = "programming=2;magnets=2"
var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
if(!in_mecha())
return 0
var/obj/mecha/M = src.loc
var/cell_charge = M.get_charge()
var/answer = {"<b>Name:</b> [M.name]
<b>Integrity:</b> [M.obj_integrity/M.max_integrity*100]%
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
<b>Airtank:</b> [M.return_pressure()]kPa
<b>Pilot:</b> [M.occupant||"None"]
<b>Location:</b> [get_area(M)||"Unknown"]
<b>Active equipment:</b> [M.selected||"None"] "}
if(istype(M, /obj/mecha/working/ripley))
var/obj/mecha/working/ripley/RM = M
answer += "<b>Used cargo space:</b> [RM.cargo.len/RM.cargo_capacity*100]%<br>"
return answer
/obj/item/mecha_parts/mecha_tracking/emp_act()
qdel(src)
/obj/item/mecha_parts/mecha_tracking/Destroy()
if(ismecha(loc))
var/obj/mecha/M = loc
if(src in M.trackers)
M.trackers -= src
return ..()
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
if(ismecha(loc))
return loc
return 0
/obj/item/mecha_parts/mecha_tracking/proc/shock()
var/obj/mecha/M = in_mecha()
if(M)
M.emp_act(EMP_LIGHT)
qdel(src)
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
if(!istype(loc, /obj/mecha))
return 0
var/obj/mecha/M = src.loc
return M.get_log_html()
/obj/item/mecha_parts/mecha_tracking/ai_control
name = "exosuit AI control beacon"
desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
origin_tech = "programming=3;magnets=2;engineering=2"
ai_beacon = TRUE
/obj/item/storage/box/mechabeacons
name = "exosuit tracking beacons"
/obj/item/storage/box/mechabeacons/New()
..()
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
qdel(src)
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
if(!ismecha(loc))
return 0
var/obj/mecha/M = src.loc
return M.get_log_html()
/obj/item/mecha_parts/mecha_tracking/ai_control
name = "exosuit AI control beacon"
desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
origin_tech = "programming=3;magnets=2;engineering=2"
ai_beacon = TRUE
/obj/item/storage/box/mechabeacons
name = "exosuit tracking beacons"
/obj/item/storage/box/mechabeacons/New()
..()
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
new /obj/item/mecha_parts/mecha_tracking(src)
+154 -156
View File
@@ -1,156 +1,154 @@
/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
if(!istype(source) || !istype(destination))
return
var/turf/actual_destination = get_teleport_turf(destination, accuracy)
var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
if(!istype(P1)||!istype(P2))
return
P1.link_portal(P2)
P1.hardlinked = TRUE
return list(P1, P2)
/obj/effect/portal
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
anchored = TRUE
var/mech_sized = FALSE
var/obj/effect/portal/linked
var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
var/creator
var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
var/atmos_link = FALSE //Link source/destination atmos.
var/turf/open/atmos_source //Atmos link source
var/turf/open/atmos_destination //Atmos link destination
/obj/effect/portal/anom
name = "wormhole"
icon = 'icons/obj/objects.dmi'
icon_state = "anom"
mech_sized = TRUE
/obj/effect/portal/Move(newloc)
for(var/T in newloc)
if(istype(T, /obj/effect/portal))
return FALSE
return ..()
/obj/effect/portal/attackby(obj/item/W, mob/user, params)
if(user && Adjacent(user))
teleport(user)
/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
if(get_turf(oldloc) == get_turf(linked))
return ..()
if(!teleport(AM))
return ..()
/obj/effect/portal/attack_tk(mob/user)
return
/obj/effect/portal/attack_hand(mob/user)
if(Adjacent(user))
teleport(user)
/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
. = ..()
GLOB.portals += src
if(!istype(_linked) && automatic_link)
. = INITIALIZE_HINT_QDEL
CRASH("Somebody fucked up.")
if(_lifespan > 0)
QDEL_IN(src, _lifespan)
if(!isnull(atmos_link_override))
atmos_link = atmos_link_override
link_portal(_linked)
hardlinked = automatic_link
creator = _creator
if(isturf(hard_target_override))
hard_target = hard_target_override
/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
linked = newlink
if(atmos_link)
link_atmos()
/obj/effect/portal/proc/link_atmos()
if(atmos_source || atmos_destination)
unlink_atmos()
if(!isopenturf(get_turf(src)))
return FALSE
if(linked)
if(isopenturf(get_turf(linked)))
atmos_source = get_turf(src)
atmos_destination = get_turf(linked)
else if(hard_target)
if(isopenturf(hard_target))
atmos_source = get_turf(src)
atmos_destination = hard_target
else
return FALSE
if(!istype(atmos_source) || !istype(atmos_destination))
return FALSE
LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
return FALSE
atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
atmos_source.air_update_turf(FALSE)
atmos_destination.air_update_turf(FALSE)
/obj/effect/portal/proc/unlink_atmos()
if(istype(atmos_source))
if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
atmos_source = null
if(istype(atmos_destination))
if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
atmos_destination = null
/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
if(creator && hascall(creator, "on_portal_destroy"))
call(creator, "on_portal_destroy")(src, src.loc)
creator = null
GLOB.portals -= src
unlink_atmos()
if(hardlinked && !QDELETED(linked))
QDEL_NULL(linked)
else
linked = null
return ..()
/obj/effect/portal/proc/teleport(atom/movable/M)
if(!istype(M) || istype(M, /obj/effect) || (istype(M, /obj/mecha) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
return
var/turf/real_target = get_link_target_turf()
if(!istype(real_target))
return FALSE
if(ismegafauna(M))
message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
if(do_teleport(M, real_target, 0))
if(istype(M, /obj/item/projectile))
var/obj/item/projectile/P = M
P.ignore_source_check = TRUE
return TRUE
return FALSE
/obj/effect/portal/proc/get_link_target_turf()
var/turf/real_target
if(!istype(linked) || QDELETED(linked))
if(hardlinked)
qdel(src)
if(!istype(hard_target) || QDELETED(hard_target))
hard_target = null
return
else
real_target = hard_target
linked = null
else
real_target = get_turf(linked)
return real_target
/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
if(!istype(source) || !istype(destination))
return
var/turf/actual_destination = get_teleport_turf(destination, accuracy)
var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
if(!istype(P1)||!istype(P2))
return
P1.link_portal(P2)
P1.hardlinked = TRUE
return list(P1, P2)
/obj/effect/portal
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
anchored = TRUE
var/mech_sized = FALSE
var/obj/effect/portal/linked
var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
var/creator
var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
var/atmos_link = FALSE //Link source/destination atmos.
var/turf/open/atmos_source //Atmos link source
var/turf/open/atmos_destination //Atmos link destination
/obj/effect/portal/anom
name = "wormhole"
icon = 'icons/obj/objects.dmi'
icon_state = "anom"
mech_sized = TRUE
/obj/effect/portal/Move(newloc)
for(var/T in newloc)
if(istype(T, /obj/effect/portal))
return FALSE
return ..()
/obj/effect/portal/attackby(obj/item/W, mob/user, params)
if(user && Adjacent(user))
user.forceMove(get_turf(src))
/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
if(linked && (get_turf(oldloc) == get_turf(linked)))
return ..()
if(!teleport(AM))
return ..()
/obj/effect/portal/attack_tk(mob/user)
return
/obj/effect/portal/attack_hand(mob/user)
if(Adjacent(user))
user.forceMove(get_turf(src))
/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
. = ..()
GLOB.portals += src
if(!istype(_linked) && automatic_link)
. = INITIALIZE_HINT_QDEL
CRASH("Somebody fucked up.")
if(_lifespan > 0)
QDEL_IN(src, _lifespan)
if(!isnull(atmos_link_override))
atmos_link = atmos_link_override
link_portal(_linked)
hardlinked = automatic_link
creator = _creator
if(isturf(hard_target_override))
hard_target = hard_target_override
/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
linked = newlink
if(atmos_link)
link_atmos()
/obj/effect/portal/proc/link_atmos()
if(atmos_source || atmos_destination)
unlink_atmos()
if(!isopenturf(get_turf(src)))
return FALSE
if(linked)
if(isopenturf(get_turf(linked)))
atmos_source = get_turf(src)
atmos_destination = get_turf(linked)
else if(hard_target)
if(isopenturf(hard_target))
atmos_source = get_turf(src)
atmos_destination = hard_target
else
return FALSE
if(!istype(atmos_source) || !istype(atmos_destination))
return FALSE
LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
return FALSE
atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
atmos_source.air_update_turf(FALSE)
atmos_destination.air_update_turf(FALSE)
/obj/effect/portal/proc/unlink_atmos()
if(istype(atmos_source))
if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
atmos_source = null
if(istype(atmos_destination))
if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
atmos_destination = null
/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
if(creator && hascall(creator, "on_portal_destroy"))
call(creator, "on_portal_destroy")(src, src.loc)
creator = null
GLOB.portals -= src
unlink_atmos()
if(hardlinked && !QDELETED(linked))
QDEL_NULL(linked)
else
linked = null
return ..()
/obj/effect/portal/proc/teleport(atom/movable/M)
if(!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
return
var/turf/real_target = get_link_target_turf()
if(!istype(real_target))
return FALSE
if(ismegafauna(M))
message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
if(do_teleport(M, real_target, 0))
if(istype(M, /obj/item/projectile))
var/obj/item/projectile/P = M
P.ignore_source_check = TRUE
return TRUE
return FALSE
/obj/effect/portal/proc/get_link_target_turf()
var/turf/real_target
if(!istype(linked) || QDELETED(linked))
if(hardlinked)
qdel(src)
if(!istype(hard_target) || QDELETED(hard_target))
hard_target = null
return
else
real_target = hard_target
linked = null
else
real_target = get_turf(linked)
return real_target
@@ -213,7 +213,7 @@
/obj/effect/temp_visual/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
light_range = 3
light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
duration = 10
+1 -1
View File
@@ -54,7 +54,7 @@ AI MODULES
for(var/mylaw in lawlist)
if(mylaw != "")
tot_laws++
if(tot_laws > config.silicon_max_law_amount && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset
if(tot_laws > CONFIG_GET(number/silicon_max_law_amount) && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset
to_chat(user, "<span class='caution'>Not enough memory allocated to [law_datum.owner ? law_datum.owner : "the AI core"]'s law processor to handle this amount of laws.</span>")
message_admins("[key_name_admin(user)] tried to upload laws to [law_datum.owner ? key_name_admin(law_datum.owner) : "an AI core"] that would exceed the law cap.")
overflow = TRUE
+5 -6
View File
@@ -72,16 +72,15 @@
user.visible_message("<span class='suicide'>[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS|OXYLOSS)
/obj/item/toy/crayon/New()
..()
/obj/item/toy/crayon/Initialize()
. = ..()
// Makes crayons identifiable in things like grinders
if(name == "crayon")
name = "[item_color] crayon"
if(config)
if(config.mutant_races == 1)
graffiti |= "antilizard"
graffiti |= "prolizard"
if(CONFIG_GET(flag/join_with_mutant_race))
graffiti |= "antilizard"
graffiti |= "prolizard"
all_drawables = graffiti + letters + numerals + oriented + runes + graffiti_large_h
drawtype = pick(all_drawables)
@@ -143,4 +143,82 @@ Code:
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
return
return
/obj/item/device/electropack/shockcollar
name = "shock collar"
desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.."
icon = 'icons/obj/clothing/neck.dmi'
icon_state = "shockcollar"
item_state = "shockcollar"
body_parts_covered = NECK
slot_flags = SLOT_NECK
w_class = WEIGHT_CLASS_SMALL
strip_delay = 60
equip_delay_other = 60
materials = list(MAT_METAL=5000, MAT_GLASS=2000)
var/tagname = null
/obj/item/device/electropack/shockcollar/attack_hand(mob/user)
if(loc == user)
if(slot_flags == SLOT_NECK)
to_chat(user, "<span class='warning'>The collar is fastened tight! You'll need help taking this off!</span>")
return
..()
/obj/item/device/electropack/shockcollar/receive_signal(datum/signal/signal)
if(!signal || signal.encryption != code)
return
if(isliving(loc) && on)
if(shock_cooldown != 0)
return
shock_cooldown = 1
spawn(100)
shock_cooldown = 0
var/mob/living/L = loc
step(L, pick(GLOB.cardinals))
to_chat(L, "<span class='danger'>You feel a sharp shock from the collar!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, L)
s.start()
L.Knockdown(100)
if(master)
master.receive_signal()
return
/obj/item/device/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle..
var/option = "Change Name"
option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency")
switch(option)
if("Change Name")
var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
if(t)
tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
name = "[initial(name)] - [tagname]"
if("Change Frequency")
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"<SK><BR>
<B>Frequency/Code</B> for shock collar:<BR>
Frequency:
<A href='byond://?src=\ref[src];freq=-10'>-</A>
<A href='byond://?src=\ref[src];freq=-2'>-</A> [format_frequency(frequency)]
<A href='byond://?src=\ref[src];freq=2'>+</A>
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
Code:
<A href='byond://?src=\ref[src];code=-5'>-</A>
<A href='byond://?src=\ref[src];code=-1'>-</A> [code]
<A href='byond://?src=\ref[src];code=1'>+</A>
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
</SK>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
return
@@ -4,6 +4,7 @@
suffix = "\[3\]"
icon_state = "walkietalkie"
item_state = "walkietalkie"
desc = "A basic handheld radio that communicates with local telecommunication networks."
dog_fashion = /datum/dog_fashion/back
var/on = TRUE // 0 for off
var/last_transmission
+73 -8
View File
@@ -73,6 +73,7 @@ MASS SPECTROMETER
origin_tech = "magnets=1;biotech=1"
var/mode = 1
var/scanmode = 0
var/advanced = FALSE
/obj/item/device/healthanalyzer/attack_self(mob/user)
if(!scanmode)
@@ -97,7 +98,7 @@ MASS SPECTROMETER
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>")
if(scanmode == 0)
healthscan(user, M, mode)
healthscan(user, M, mode, advanced)
else if(scanmode == 1)
chemscan(user, M)
@@ -105,7 +106,7 @@ MASS SPECTROMETER
// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
/proc/healthscan(mob/living/user, mob/living/M, mode = 1, advanced = FALSE)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
@@ -115,8 +116,8 @@ MASS SPECTROMETER
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat == DEAD ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
if(M.status_flags & FAKEDEATH)
mob_status = "<span class='alert'>Deceased</span>"
if(M.status_flags & FAKEDEATH && !advanced)
mob_status = "<span class='alert'><b>Deceased</b></span>"
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
if(ishuman(M))
@@ -141,19 +142,77 @@ MASS SPECTROMETER
if(oxy_loss > 10)
to_chat(user, "\t<span class='info'><span class='alert'>[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.</span>")
if(tox_loss > 10)
to_chat(user, "\t<span class='alert'>[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected.</span>")
to_chat(user, "\t<span class='alert'>[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected.</span>")
if(M.getStaminaLoss())
to_chat(user, "\t<span class='alert'>Subject appears to be suffering from fatigue.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Fatigue Level: [M.getStaminaLoss()]%.</span>")
if (M.getCloneLoss())
to_chat(user, "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>")
if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
to_chat(user, "\t<span class='info'>Bloodstream analysis located [M.reagents.get_reagent_amount("epinephrine")] units of rejuvenation chemicals.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\t<span class='alert'>Subject brain function is non-existent.</span>")
else if (M.getBrainLoss() >= 60)
to_chat(user, "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental retardation.</span>")
else if (M.getBrainLoss() >= 10)
to_chat(user, "\t<span class='alert'>Brain damage detected. Subject may have had a concussion.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Brain Activity Level: [100 - M.getBrainLoss()]%.</span>")
if (M.radiation)
to_chat(user, "\t<span class='alert'>Subject is irradiated.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Radiation Level: [M.radiation]%.</span>")
if(advanced && M.hallucinating())
to_chat(user, "\t<span class='info'>Subject is hallucinating.</span>")
//Eyes and ears
if(advanced)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/ears/ears = C.getorganslot("ears")
to_chat(user, "\t<span class='info'><b>==EAR STATUS==</b></span>")
if(istype(ears))
var/healthy = TRUE
if(C.disabilities & DEAF)
healthy = FALSE
to_chat(user, "\t<span class='alert'>Subject is genetically deaf.</span>")
else
if(ears.ear_damage)
to_chat(user, "\t<span class='alert'>Subject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.</span>")
healthy = FALSE
if(ears.deaf)
to_chat(user, "\t<span class='alert'>Subject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.</span>")
healthy = FALSE
if(healthy)
to_chat(user, "\t<span class='info'>Healthy.</span>")
else
to_chat(user, "\t<span class='alert'>Subject does not have ears.</span>")
var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
to_chat(user, "\t<span class='info'><b>==EYE STATUS==</b></span>")
if(istype(eyes))
var/healthy = TRUE
if(C.disabilities & BLIND)
to_chat(user, "\t<span class='alert'>Subject is blind.</span>")
healthy = FALSE
if(C.disabilities & NEARSIGHT)
to_chat(user, "\t<span class='alert'>Subject is nearsighted.</span>")
healthy = FALSE
if(eyes.eye_damage > 30)
to_chat(user, "\t<span class='alert'>Subject has severe eye damage.</span>")
healthy = FALSE
else if(eyes.eye_damage > 20)
to_chat(user, "\t<span class='alert'>Subject has significant eye damage.</span>")
healthy = FALSE
else if(eyes.eye_damage)
to_chat(user, "\t<span class='alert'>Subject has minor eye damage.</span>")
healthy = FALSE
if(healthy)
to_chat(user, "\t<span class='info'>Healthy.</span>")
else
to_chat(user, "\t<span class='alert'>Subject does not have eyes.</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -177,7 +236,7 @@ MASS SPECTROMETER
to_chat(user, "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] &deg;C ([round(M.bodytemperature*1.8-459.67,0.1)] &deg;F)</span>")
// Time of death
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
if(M.tod && (M.stat == DEAD || ((M.status_flags & FAKEDEATH) && !advanced)))
to_chat(user, "<span class='info'>Time of Death:</span> [M.tod]")
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
@@ -251,6 +310,12 @@ MASS SPECTROMETER
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
/obj/item/device/healthanalyzer/advanced
name = "advanced health analyzer"
icon_state = "health_adv"
desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
origin_tech = "magnets=3;biotech=3"
advanced = TRUE
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
+2 -2
View File
@@ -335,8 +335,8 @@
/obj/item/nullrod/carp
name = "carp-sie plushie"
desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie."
icon = 'icons/obj/toy.dmi'
icon_state = "carpplushie"
icon = 'icons/obj/plushes.dmi'
icon_state = "carpplush"
item_state = "carp_plushie"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
@@ -19,12 +19,12 @@
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = 0)
if(..())
if((target.mind in (SSticker.mode.head_revolutionaries)))
if((target.mind in (SSticker.mode.head_revolutionaries)) || target.mind.unconvertable)
if(!silent)
target.visible_message("<span class='warning'>[target] seems to resist the implant!</span>", "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
removed(target, 1)
qdel(src)
return 0
return FALSE
if(target.mind in SSticker.mode.revolutionaries)
SSticker.mode.remove_revolutionary(target.mind, FALSE, user)
if(!silent)
@@ -32,8 +32,8 @@
to_chat(target, "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
else
to_chat(target, "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
return 1
return 0
return TRUE
return FALSE
/obj/item/implant/mindshield/removed(mob/target, silent = 0, special = 0)
if(..())
+3 -2
View File
@@ -882,7 +882,8 @@
..()
/obj/item/book/manual/wiki/proc/initialize_wikibook()
if(config.wikiurl)
var/wikiurl = CONFIG_GET(string/wikiurl)
if(wikiurl)
dat = {"
<html><head>
@@ -900,7 +901,7 @@
}
</script>
<p id='loading'>You start skimming through the manual...</p>
<iframe width='100%' height='97%' onload="pageloaded(this)" src="[config.wikiurl]/[page_link]?printable=yes&remove_links=1" frameborder="0" id="main_frame"></iframe>
<iframe width='100%' height='97%' onload="pageloaded(this)" src="[wikiurl]/[page_link]?printable=yes&remove_links=1" frameborder="0" id="main_frame"></iframe>
</body>
</html>
+1 -1
View File
@@ -41,7 +41,7 @@
/obj/item/target/syndicate
icon_state = "target_s"
desc = "A shooting target that looks like a syndicate scum."
desc = "A shooting target that looks like syndicate scum."
hp = 2600
/obj/item/target/alien
+1 -1
View File
@@ -1,7 +1,7 @@
/obj/item/picket_sign
icon_state = "picket"
name = "blank picket sign"
desc = "It's blank"
desc = "It's blank."
force = 5
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed","smacked")
+18
View File
@@ -156,6 +156,24 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/unholy2clean = A.reagents.get_reagent_amount("unholywater")
A.reagents.del_reagent("unholywater")
A.reagents.add_reagent("holywater",unholy2clean)
if(istype(A, /obj/item/twohanded/required/cult_bastard))
var/obj/item/twohanded/required/cult_bastard/sword = A
to_chat(user, "<span class='notice'>You begin to exorcise [sword].</span>")
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
if(do_after(user, 40, target = sword))
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
for(var/obj/item/device/soulstone/SS in sword.shards)
SS.usability = TRUE
for(var/mob/living/simple_animal/shade/EX in SS)
SSticker.mode.remove_cultist(EX.mind, 1, 0)
EX.icon_state = "ghost1"
EX.name = "Purified [EX.name]"
SS.release_shades(user)
qdel(SS)
new /obj/item/nullrod/claymore(get_turf(sword))
user.visible_message("<span class='notice'>[user] has purified the [sword]!!</span>")
qdel(sword)
/obj/item/storage/book/bible/booze
desc = "To be applied to the head repeatedly."
+1
View File
@@ -17,6 +17,7 @@
icon = 'icons/obj/food/containers.dmi'
icon_state = "donutbox6"
name = "donut box"
desc = "Mmm. Donuts."
resistance_flags = FLAMMABLE
var/icon_type = "donut"
var/spawn_type = null
@@ -177,6 +177,14 @@
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/silver/security(src)
/obj/item/storage/lockbox/medal/cargo
name = "cargo award box"
desc = "A locked box used to store awards to be given to members of the cargo department."
req_access = list(ACCESS_QM)
/obj/item/storage/lockbox/medal/cargo/PopulateContents()
new /obj/item/clothing/accessory/medal/ribbon/cargo(src)
/obj/item/storage/lockbox/medal/sci
name = "science medal box"
desc = "A locked box used to store medals to be given to members of the science department."
@@ -25,6 +25,7 @@
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
max_combined_w_class = 14
desc = "This shouldn't exist. If it does, create an issue report."
/obj/item/storage/secure/examine(mob/user)
..()
@@ -177,6 +178,7 @@
icon_opened = "safe0"
icon_locking = "safeb"
icon_sparking = "safespark"
desc = "Excellent for securing things away from grubby hands."
force = 8
w_class = WEIGHT_CLASS_GIGANTIC
max_w_class = 8
+1 -1
View File
@@ -34,7 +34,7 @@
if(!over_object)
return
if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
if (ismecha(M.loc)) // stops inventory actions in a mech
return
// this must come before the screen objects only block, dunno why it wasn't before
+1
View File
@@ -5,6 +5,7 @@
icon = 'icons/obj/vending_restock.dmi'
icon_state = "refill_snack"
item_state = "restock_unit"
desc = "A vending machine restock cart."
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
+2 -1
View File
@@ -4,6 +4,7 @@
name = "\improper AI core"
icon = 'icons/mob/ai.dmi'
icon_state = "0"
desc = "The framework for an artificial intelligence core."
max_integrity = 500
var/state = 0
var/datum/ai_laws/laws = new()
@@ -134,7 +135,7 @@
to_chat(user, "<span class='warning'>Sticking an inactive [M.name] into the frame would sort of defeat the purpose.</span>")
return
if((config) && (!config.allow_ai) || jobban_isbanned(M.brainmob, "AI"))
if(!CONFIG_GET(flag/allow_ai) || jobban_isbanned(M.brainmob, "AI"))
to_chat(user, "<span class='warning'>This [M.name] does not seem to fit!</span>")
return
@@ -21,6 +21,10 @@
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 2
/obj/structure/bed/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It's held together by a couple of <b>bolts</b>.</span>")
/obj/structure/bed/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(buildstacktype)
@@ -1,6 +1,6 @@
/obj/structure/chair
name = "chair"
desc = "You sit in this. Either by will or force.\n<span class='notice'>Drag your sprite to sit in the chair. Alt-click to rotate it clockwise.</span>"
desc = "You sit in this. Either by will or force."
icon = 'icons/obj/chairs.dmi'
icon_state = "chair"
anchored = TRUE
@@ -14,6 +14,14 @@
var/item_chair = /obj/item/chair // if null it can't be picked up
layer = OBJ_LAYER
/obj/structure/chair/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It's held together by a couple of <b>bolts</b>.</span>")
if(!has_buckled_mobs())
to_chat(user, "<span class='notice'>Drag your sprite to sit in it. Alt-click to rotate.</span>")
else
to_chat(user, "<span class='notice'>Alt-click to rotate.</span>")
/obj/structure/chair/Initialize()
. = ..()
if(!anchored) //why would you put these on the shuttle?
@@ -98,7 +106,7 @@
set category = "Object"
set src in oview(1)
if(config.ghost_interaction)
if(CONFIG_GET(flag/ghost_interaction))
spin()
else
if(!usr || !isturf(usr.loc))
@@ -140,7 +148,7 @@
/obj/structure/chair/comfy
name = "comfy chair"
desc = "It looks comfy.\n<span class='notice'>Alt-click to rotate it clockwise.</span>"
desc = "It looks comfy."
icon_state = "comfychair"
color = rgb(255,255,255)
resistance_flags = FLAMMABLE
@@ -76,8 +76,12 @@
/obj/structure/closet/examine(mob/user)
..()
if(welded)
to_chat(user, "<span class='notice'>It's welded shut.</span>")
if(anchored)
to_chat(user, "It is anchored to the ground.")
to_chat(user, "<span class='notice'>It is <b>bolted</b> to the ground.</span>")
if(opened)
to_chat(user, "<span class='notice'>The parts are <b>welded</b> together.</span>")
else if(secure && !opened)
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>")
@@ -453,4 +457,4 @@
/obj/structure/closet/return_temperature()
return
return
@@ -23,7 +23,7 @@
return
move_delay = 1
if(step(src, direction))
spawn(config.walk_speed*move_speed_multiplier)
spawn(CONFIG_GET(number/walk_delay) * move_speed_multiplier)
move_delay = 0
else
move_delay = 0
@@ -1,19 +1,20 @@
/obj/structure/closet/secure_closet/quartermaster
name = "\proper quartermaster's locker"
/obj/structure/closet/secure_closet/quartermaster
name = "\proper quartermaster's locker"
req_access = list(ACCESS_QM)
icon_state = "qm"
/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/qm(src)
new /obj/item/clothing/under/rank/cargo(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/device/radio/headset/headset_cargo(src)
new /obj/item/clothing/suit/fire/firefighter(src)
new /obj/item/clothing/gloves/fingerless(src)
new /obj/item/device/megaphone/cargo(src)
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/head/soft(src)
new /obj/item/device/export_scanner(src)
new /obj/item/door_remote/quartermaster(src)
icon_state = "qm"
/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/qm(src)
new /obj/item/storage/lockbox/medal/cargo/(src)
new /obj/item/clothing/under/rank/cargo(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/device/radio/headset/headset_cargo(src)
new /obj/item/clothing/suit/fire/firefighter(src)
new /obj/item/clothing/gloves/fingerless(src)
new /obj/item/device/megaphone/cargo(src)
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/head/soft(src)
new /obj/item/device/export_scanner(src)
new /obj/item/door_remote/quartermaster(src)
@@ -1,93 +1,94 @@
/obj/structure/closet/secure_closet/medical1
name = "medicine closet"
desc = "Filled to the brim with medical junk."
icon_state = "med"
/obj/structure/closet/secure_closet/medical1
name = "medicine closet"
desc = "Filled to the brim with medical junk."
icon_state = "med"
req_access = list(ACCESS_MEDICAL)
/obj/structure/closet/secure_closet/medical1/PopulateContents()
..()
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/storage/box/syringes(src)
new /obj/item/reagent_containers/glass/bottle/toxin(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/charcoal(src)
new /obj/item/storage/box/rxglasses(src)
/obj/structure/closet/secure_closet/medical2
name = "anesthetic closet"
desc = "Used to knock people out."
/obj/structure/closet/secure_closet/medical1/PopulateContents()
..()
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/storage/box/syringes(src)
new /obj/item/reagent_containers/glass/bottle/toxin(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/charcoal(src)
new /obj/item/storage/box/rxglasses(src)
/obj/structure/closet/secure_closet/medical2
name = "anesthetic closet"
desc = "Used to knock people out."
req_access = list(ACCESS_SURGERY)
/obj/structure/closet/secure_closet/medical2/PopulateContents()
..()
for(var/i in 1 to 3)
new /obj/item/tank/internals/anesthetic(src)
for(var/i in 1 to 3)
new /obj/item/clothing/mask/breath/medical(src)
/obj/structure/closet/secure_closet/medical3
name = "medical doctor's locker"
/obj/structure/closet/secure_closet/medical2/PopulateContents()
..()
for(var/i in 1 to 3)
new /obj/item/tank/internals/anesthetic(src)
for(var/i in 1 to 3)
new /obj/item/clothing/mask/breath/medical(src)
/obj/structure/closet/secure_closet/medical3
name = "medical doctor's locker"
req_access = list(ACCESS_SURGERY)
icon_state = "med_secure"
/obj/structure/closet/secure_closet/medical3/PopulateContents()
..()
new /obj/item/device/radio/headset/headset_med(src)
new /obj/item/defibrillator/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/clothing/glasses/hud/health(src)
return
/obj/structure/closet/secure_closet/CMO
name = "\proper chief medical officer's locker"
icon_state = "med_secure"
/obj/structure/closet/secure_closet/medical3/PopulateContents()
..()
new /obj/item/device/radio/headset/headset_med(src)
new /obj/item/defibrillator/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/clothing/glasses/hud/health(src)
return
/obj/structure/closet/secure_closet/CMO
name = "\proper chief medical officer's locker"
req_access = list(ACCESS_CMO)
icon_state = "cmo"
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/cmo(src)
new /obj/item/storage/backpack/duffelbag/med(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
new /obj/item/clothing/under/rank/chief_medical_officer(src)
new /obj/item/clothing/shoes/sneakers/brown (src)
new /obj/item/cartridge/cmo(src)
new /obj/item/device/radio/headset/heads/cmo(src)
new /obj/item/device/megaphone/command(src)
new /obj/item/defibrillator/compact/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/reagent_containers/hypospray/CMO(src)
new /obj/item/device/autosurgeon/cmo(src)
new /obj/item/door_remote/chief_medical_officer(src)
/obj/structure/closet/secure_closet/animal
name = "animal control"
icon_state = "cmo"
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/cmo(src)
new /obj/item/storage/backpack/duffelbag/med(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
new /obj/item/clothing/under/rank/chief_medical_officer(src)
new /obj/item/clothing/shoes/sneakers/brown (src)
new /obj/item/cartridge/cmo(src)
new /obj/item/device/radio/headset/heads/cmo(src)
new /obj/item/device/megaphone/command(src)
new /obj/item/defibrillator/compact/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/device/healthanalyzer/advanced(src)
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/reagent_containers/hypospray/CMO(src)
new /obj/item/device/autosurgeon/cmo(src)
new /obj/item/door_remote/chief_medical_officer(src)
/obj/structure/closet/secure_closet/animal
name = "animal control"
req_access = list(ACCESS_SURGERY)
/obj/structure/closet/secure_closet/animal/PopulateContents()
..()
new /obj/item/device/assembly/signaler(src)
for(var/i in 1 to 3)
new /obj/item/device/electropack(src)
/obj/structure/closet/secure_closet/chemical
name = "chemical closet"
desc = "Store dangerous chemicals in here."
icon_door = "chemical"
/obj/structure/closet/secure_closet/chemical/PopulateContents()
..()
new /obj/item/storage/box/pillbottles(src)
new /obj/item/storage/box/pillbottles(src)
/obj/structure/closet/secure_closet/animal/PopulateContents()
..()
new /obj/item/device/assembly/signaler(src)
for(var/i in 1 to 3)
new /obj/item/device/electropack(src)
/obj/structure/closet/secure_closet/chemical
name = "chemical closet"
desc = "Store dangerous chemicals in here."
icon_door = "chemical"
/obj/structure/closet/secure_closet/chemical/PopulateContents()
..()
new /obj/item/storage/box/pillbottles(src)
new /obj/item/storage/box/pillbottles(src)
@@ -6,6 +6,7 @@
anchored = FALSE
density = TRUE
max_integrity = 200
desc = "The mechanical framework for an airlock."
var/state = 0
var/mineral = null
var/typetext = ""
@@ -363,6 +364,23 @@
anchored = TRUE
state = 1
/obj/structure/door_assembly/examine(mob/user)
..()
switch(state)
if(0)
if(anchored)
to_chat(user, "<span class='notice'>The anchoring bolts are <b>wrenched</b> in place, but the maintenance panel lacks <i>wiring</i>.</span>")
else
to_chat(user, "<span class='notice'>The assembly is <b>welded together</b>, but the anchoring bolts are <i>unwrenched</i>.</span>")
if(1)
to_chat(user, "<span class='notice'>The maintenance panel is <b>wired</b>, but the circuit slot is <i>empty</i>.</span>")
if(2)
to_chat(user, "<span class='notice'>The circuit is <b>connected loosely</b> to its slot, but the maintenance panel is <i>unscrewed and open</i>.</span>")
if(!mineral || !material)
to_chat(user, "<span class='notice'>There is a small <i>paper</i> placard on the assembly. There are <i>empty</i> slots for glass windows or mineral covers.</span>")
else
to_chat(user, "<span class='notice'>There is a small <i>paper</i> placard on the assembly.</span>")
/obj/structure/door_assembly/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen))
var/t = stripped_input(user, "Enter the name for the door.", src.name, src.created_name,MAX_NAME_LEN)
+16 -3
View File
@@ -123,9 +123,12 @@
else
return ..()
/obj/structure/falsewall/proc/dismantle(mob/user, disassembled = TRUE)
user.visible_message("<span class='notice'>[user] dismantles the false wall.</span>", "<span class='notice'>You dismantle the false wall.</span>")
playsound(src, 'sound/items/welder.ogg', 100, 1)
/obj/structure/falsewall/proc/dismantle(mob/user, disassembled=TRUE, obj/item/tool = null)
user.visible_message("[user] dismantles the false wall.", "<span class='notice'>You dismantle the false wall.</span>")
if(tool)
playsound(src, tool.usesound, 100, 1)
else
playsound(src, 'sound/items/welder.ogg', 100, 1)
deconstruct(disassembled)
/obj/structure/falsewall/deconstruct(disassembled = TRUE)
@@ -141,6 +144,7 @@
return null
/obj/structure/falsewall/examine_status(mob/user) //So you can't detect falsewalls by examine.
to_chat(user, "<span class='notice'>The outer plating is <b>welded</b> firmly in place.</span>")
return null
/*
@@ -155,6 +159,15 @@
walltype = /turf/closed/wall/r_wall
mineral = /obj/item/stack/sheet/plasteel
/obj/structure/falsewall/reinforced/examine_status(mob/user)
to_chat(user, "<span class='notice'>The outer <b>grille</b> is fully intact.</span>")
return null
/obj/structure/falsewall/reinforced/attackby(obj/item/tool, mob/user)
..()
if(istype(tool, /obj/item/wirecutters))
dismantle(user, TRUE, tool)
/*
* Uranium Falsewalls
*/
+10
View File
@@ -6,6 +6,7 @@
//trees
/obj/structure/flora/tree
name = "tree"
desc = "A large tree."
density = TRUE
pixel_x = -16
layer = FLY_LAYER
@@ -40,6 +41,7 @@
/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
@@ -49,6 +51,7 @@
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
/obj/structure/flora/tree/pine/xmas/Initialize()
@@ -57,10 +60,12 @@
/obj/structure/flora/tree/dead
icon = 'icons/obj/flora/deadtrees.dmi'
desc = "A dead tree. How it died, you know not."
icon_state = "tree_1"
/obj/structure/flora/tree/palm
icon = 'icons/misc/beach2.dmi'
desc = "A tree straight from the tropics."
icon_state = "palm1"
/obj/structure/flora/tree/palm/Initialize()
@@ -98,6 +103,7 @@
//grass
/obj/structure/flora/grass
name = "grass"
desc = "A patch of overgrown grass."
icon = 'icons/obj/flora/snowflora.dmi'
gender = PLURAL //"this is grass" not "this is a grass"
@@ -127,6 +133,7 @@
//bushes
/obj/structure/flora/bush
name = "bush"
desc = "Some type of shrub."
icon = 'icons/obj/flora/snowflora.dmi'
icon_state = "snowbush1"
anchored = TRUE
@@ -139,6 +146,7 @@
/obj/structure/flora/ausbushes
name = "bush"
desc = "Some kind of plant."
icon = 'icons/obj/flora/ausflora.dmi'
icon_state = "firstbush_1"
@@ -256,6 +264,7 @@
name = "potted plant"
icon = 'icons/obj/flora/plants.dmi'
icon_state = "plant-01"
desc = "A little bit of nature contained in a pot."
layer = ABOVE_MOB_LAYER
w_class = WEIGHT_CLASS_HUGE
force = 10
@@ -365,6 +374,7 @@
/obj/structure/flora/junglebush
name = "bush"
desc = "A wild plant that is found in jungles."
icon = 'icons/obj/flora/jungleflora.dmi'
icon_state = "busha"
+1
View File
@@ -1,6 +1,7 @@
/obj/structure/girder
name = "girder"
icon_state = "girder"
desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
layer = BELOW_OBJ_LAYER
+8 -1
View File
@@ -1,5 +1,5 @@
/obj/structure/grille
desc = "A flimsy lattice of metal rods, with screws to secure it to the floor."
desc = "A flimsy framework of metal rods."
name = "grille"
icon = 'icons/obj/structures.dmi'
icon_state = "grille"
@@ -17,6 +17,13 @@
var/grille_type = null
var/broken_type = /obj/structure/grille/broken
/obj/structure/grille/examine(mob/user)
..()
if(anchored)
to_chat(user, "<span class='notice'>It's secured in place with <b>screws</b>. The rods look like they could be <b>cut</b> through.</span>")
if(!anchored)
to_chat(user, "<span class='notice'>The anchoring screws are <i>unscrewed</i>. The rods look like they could be <b>cut</b> through.</span>")
/obj/structure/grille/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)

Some files were not shown because too many files have changed in this diff Show More