Merge branch 'master' into upstream-merge-31198
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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...")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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] </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] </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> \]"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'> [active1.fields["sex"]] </A></td></tr>"
|
||||
dat += "<tr><td>Age:</td><td><A href='?src=\ref[src];field=age'> [active1.fields["age"]] </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'> [active1.fields["species"]] </A></td></tr>"
|
||||
dat += "<tr><td>Fingerprint:</td><td><A href='?src=\ref[src];field=fingerprint'> [active1.fields["fingerprint"]] </A></td></tr>"
|
||||
dat += "<tr><td>Physical Status:</td><td><A href='?src=\ref[src];field=p_stat'> [active1.fields["p_stat"]] </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
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
<tr><td>ID:</td><td><A href='?src=\ref[src];choice=Edit Field;field=id'> [active1.fields["id"]] </A></td></tr>
|
||||
<tr><td>Sex:</td><td><A href='?src=\ref[src];choice=Edit Field;field=sex'> [active1.fields["sex"]] </A></td></tr>
|
||||
<tr><td>Age:</td><td><A href='?src=\ref[src];choice=Edit Field;field=age'> [active1.fields["age"]] </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'> [active1.fields["species"]] </A></td></tr>"
|
||||
dat += {"<tr><td>Rank:</td><td><A href='?src=\ref[src];choice=Edit Field;field=rank'> [active1.fields["rank"]] </A></td></tr>
|
||||
<tr><td>Fingerprint:</td><td><A href='?src=\ref[src];choice=Edit Field;field=fingerprint'> [active1.fields["fingerprint"]] </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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °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."
|
||||
|
||||
@@ -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(..())
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,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")
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user