Merge branch 'master' into Ghommie-cit425
This commit is contained in:
@@ -177,6 +177,7 @@
|
||||
#define COMSIG_MOB_PRE_PLAYER_CHANGE "mob_pre_player_change" //sent to the target mob from base of /mob/transfer_ckey() and /mind/transfer_to(): (our_character, their_character)
|
||||
// #define COMPONENT_STOP_MIND_TRANSFER 1
|
||||
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
|
||||
#define COMSIG_MOB_ON_NEW_MIND "mob_on_new_mind" //called when a new mind is assigned to a mob: ()
|
||||
#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list)
|
||||
#define COMPONENT_UPPERCASE_SPEECH 1
|
||||
// used to access COMSIG_MOB_SAY argslist
|
||||
|
||||
@@ -444,12 +444,8 @@
|
||||
candidates -= M
|
||||
|
||||
/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE)
|
||||
var/list/candidates = list()
|
||||
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
if(G.can_reenter_round(TRUE))
|
||||
candidates += G
|
||||
|
||||
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
|
||||
var/list/candidates = eligibility.get_all_ghost_role_eligible()
|
||||
return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates)
|
||||
|
||||
/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null)
|
||||
|
||||
@@ -23,6 +23,8 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes
|
||||
|
||||
GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details
|
||||
|
||||
GLOBAL_LIST_EMPTY(clientless_round_timeouts) // ckey -> time that ckey can rejoin round
|
||||
|
||||
// All religion stuff
|
||||
GLOBAL_VAR(religion)
|
||||
GLOBAL_VAR(deity)
|
||||
|
||||
@@ -46,8 +46,8 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
badquirk = TRUE
|
||||
if(badquirk)
|
||||
cli.prefs.save_character()
|
||||
if(!silent && LAZYLEN(cut))
|
||||
to_chat(to_chat_target || user, "<span class='boldwarning'>All of your non-neutral character quirks have been cut due to these quirks conflicting with your job assignment: [english_list(cut)].</span>")
|
||||
if (!silent && LAZYLEN(cut))
|
||||
to_chat(to_chat_target || user, "<span class='boldwarning'>Some quirks have been cut from your character because of these quirks conflicting with your job assignment: [english_list(cut)].</span>")
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name)
|
||||
return quirks[name]
|
||||
@@ -66,6 +66,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/our_quirks, datum/job/job)
|
||||
var/list/cut = list()
|
||||
var/list/banned_names = list()
|
||||
var/pointscut = 0
|
||||
for(var/i in job.blacklisted_quirks)
|
||||
var/name = quirk_name_by_path(i)
|
||||
if(name)
|
||||
@@ -75,7 +76,17 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
for(var/i in blacklisted)
|
||||
our_quirks -= i
|
||||
cut += i
|
||||
|
||||
pointscut += quirk_points_by_name(i)
|
||||
if (pointscut != 0)
|
||||
for (var/i in shuffle(our_quirks))
|
||||
if (quirk_points_by_name(i) < pointscut || (pointscut < 0) ? quirk_points_by_name(i) <= 0 : quirk_points_by_name(i) >= 0)
|
||||
continue
|
||||
else
|
||||
our_quirks -= i
|
||||
cut += i
|
||||
pointscut += quirk_points_by_name(i)
|
||||
if (pointscut >= 0) //with how it works, it needs to be above zero, not below, as points for positive is positive, and negative is negative, we only want it to break if it's above zero, ie. we cut more positive than negative
|
||||
break
|
||||
/* //Code to automatically reduce positive quirks until balance is even.
|
||||
var/points_used = total_points(our_quirks)
|
||||
if(points_used > 0)
|
||||
@@ -91,10 +102,11 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
*/
|
||||
|
||||
//Nah, let's null all non-neutrals out.
|
||||
if(cut.len)
|
||||
for(var/i in our_quirks)
|
||||
if(quirk_points_by_name(i) != 0)
|
||||
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
|
||||
our_quirks -= i
|
||||
if (pointscut != 0)// only if the pointscutting didn't work.
|
||||
if(cut.len)
|
||||
for(var/i in our_quirks)
|
||||
if(quirk_points_by_name(i) != 0)
|
||||
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
|
||||
our_quirks -= i
|
||||
|
||||
return cut
|
||||
|
||||
@@ -141,6 +141,17 @@
|
||||
current_button.add_overlay(mutable_appearance(icon_icon, button_icon_state))
|
||||
current_button.button_icon_state = button_icon_state
|
||||
|
||||
/datum/action/ghost
|
||||
icon_icon = 'icons/mob/mob.dmi'
|
||||
button_icon_state = "ghost"
|
||||
name = "Ghostize"
|
||||
desc = "Turn into a ghost and freely come back to your body."
|
||||
|
||||
/datum/action/ghost/Trigger()
|
||||
if(!..())
|
||||
return 0
|
||||
var/mob/M = target
|
||||
M.ghostize(1)
|
||||
|
||||
//Presets for item actions
|
||||
/datum/action/item_action
|
||||
|
||||
@@ -87,3 +87,12 @@
|
||||
/datum/component/storage/concrete/pockets/pocketprotector/real_location()
|
||||
// if the component is reparented to a jumpsuit, the items still go in the protector
|
||||
return original_parent
|
||||
|
||||
/datum/component/storage/concrete/pockets/small/rushelmet
|
||||
max_items = 1
|
||||
quickdraw = TRUE
|
||||
|
||||
/datum/component/storage/concrete/pockets/small/rushelmet/Initialize()
|
||||
. = ..()
|
||||
can_hold = typecacheof(list(/obj/item/reagent_containers/glass/bottle,
|
||||
/obj/item/ammo_box/a762))
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
if(type == /datum/element)
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
if(element_flags & ELEMENT_DETACH)
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach)
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach, override = TRUE)
|
||||
|
||||
/datum/element/proc/Detach(datum/source, force)
|
||||
UnregisterSignal(source, COMSIG_PARENT_QDELETING)
|
||||
@@ -36,4 +36,4 @@
|
||||
*/
|
||||
/datum/proc/RemoveElement(eletype, ...)
|
||||
var/datum/element/ele = SSdcs.GetElement(arglist(args))
|
||||
ele.Detach(src)
|
||||
ele.Detach(src)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/datum/element/ghost_role_eligibility
|
||||
element_flags = ELEMENT_DETACH
|
||||
var/list/timeouts = list()
|
||||
var/list/mob/eligible_mobs = list()
|
||||
|
||||
/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE)
|
||||
. = ..()
|
||||
if(!ismob(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
var/mob/M = target
|
||||
if(!(M in eligible_mobs))
|
||||
eligible_mobs += M
|
||||
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
if(penalty)
|
||||
penalty += world.realtime
|
||||
if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
if(!(M.ckey in timeouts))
|
||||
timeouts += M.ckey
|
||||
timeouts[M.ckey] = 0
|
||||
timeouts[M.ckey] = max(timeouts[M.ckey],penalty)
|
||||
|
||||
/datum/element/ghost_role_eligibility/Detach(mob/M)
|
||||
. = ..()
|
||||
if(M in eligible_mobs)
|
||||
eligible_mobs -= M
|
||||
|
||||
/datum/element/ghost_role_eligibility/proc/get_all_ghost_role_eligible(silent = FALSE)
|
||||
var/list/candidates = list()
|
||||
for(var/m in eligible_mobs)
|
||||
var/mob/M = m
|
||||
if(M.can_reenter_round(TRUE))
|
||||
candidates += M
|
||||
return candidates
|
||||
|
||||
/mob/proc/can_reenter_round(silent = FALSE)
|
||||
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
|
||||
return eli.can_reenter_round(src,silent)
|
||||
|
||||
/datum/element/ghost_role_eligibility/proc/can_reenter_round(var/mob/M,silent = FALSE)
|
||||
if(!(M in eligible_mobs))
|
||||
return FALSE
|
||||
if(!(M.ckey in timeouts))
|
||||
return TRUE
|
||||
var/timeout = timeouts[M.ckey]
|
||||
if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
|
||||
return TRUE
|
||||
if(!silent && M.client)
|
||||
to_chat(M, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
|
||||
return FALSE
|
||||
@@ -140,6 +140,7 @@
|
||||
L.client.prefs.chat_toggles ^= CHAT_OOC
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
|
||||
SEND_SIGNAL(new_character, COMSIG_MOB_ON_NEW_MIND)
|
||||
|
||||
/datum/mind/proc/store_memory(new_text)
|
||||
if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN)
|
||||
@@ -747,6 +748,7 @@
|
||||
else
|
||||
mind = new /datum/mind(key)
|
||||
SSticker.minds += mind
|
||||
SEND_SIGNAL(src, COMSIG_MOB_ON_NEW_MIND)
|
||||
if(!mind.name)
|
||||
mind.name = real_name
|
||||
mind.current = src
|
||||
|
||||
@@ -10,6 +10,21 @@
|
||||
suffix = "Box/Engine/engine_sm.dmm"
|
||||
name = "Engine SM"
|
||||
|
||||
/datum/map_template/ruin/station/box/engine/onebythree
|
||||
id = "engine_sm_1x3"
|
||||
suffix = "Box/Engine/engine_sm_1x3.dmm"
|
||||
name = "Engine SM 1x3"
|
||||
|
||||
/datum/map_template/ruin/station/box/engine/fivebyfive
|
||||
id = "engine_sm_5x5"
|
||||
suffix = "Box/Engine/engine_sm_5x5.dmm"
|
||||
name = "Engine SM 5x5"
|
||||
|
||||
/datum/map_template/ruin/station/box/engine/threesm
|
||||
id = "engine_sm_3x"
|
||||
suffix = "Box/Engine/engine_sm_3x.dmm"
|
||||
name = "Engine SM 3x"
|
||||
|
||||
/datum/map_template/ruin/station/box/engine/singulo
|
||||
id = "engine_singulo"
|
||||
suffix = "Box/Engine/engine_singulo.dmm"
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
var/list/living_antags = list()
|
||||
var/list/dead_players = list()
|
||||
var/list/list_observers = list()
|
||||
var/list/ghost_eligible = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts
|
||||
weight = 0
|
||||
required_type = /mob/dead/observer
|
||||
/// Whether the ruleset should call generate_ruleset_body or not.
|
||||
var/makeBody = TRUE
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
|
||||
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
|
||||
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
|
||||
ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
|
||||
|
||||
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
|
||||
var/list/trimmed_list = L.Copy()
|
||||
@@ -70,6 +72,25 @@
|
||||
continue
|
||||
return trimmed_list
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/trim_list(list/L = list())
|
||||
var/list/trimmed_list = L.Copy()
|
||||
for(var/mob/M in trimmed_list)
|
||||
if (!M.client) // Are they connected?
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(!mode.check_age(M.client, minimum_required_age))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(antag_flag_override)
|
||||
if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
else
|
||||
if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
return trimmed_list
|
||||
|
||||
// You can then for example prompt dead players in execute() to join as strike teams or whatever
|
||||
// Or autotator someone
|
||||
|
||||
@@ -91,11 +112,15 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE)
|
||||
if (required_candidates > ghost_eligible.len)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/execute()
|
||||
var/list/possible_candidates = list()
|
||||
possible_candidates.Add(dead_players)
|
||||
possible_candidates.Add(list_observers)
|
||||
var/application_successful = send_applications(possible_candidates)
|
||||
var/application_successful = send_applications(ghost_eligible)
|
||||
return assigned.len > 0 && application_successful
|
||||
|
||||
/// This sends a poll to ghosts if they want to be a ghost spawn from a ruleset.
|
||||
@@ -303,9 +328,6 @@
|
||||
var/datum/mind/wizard
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
if(GLOB.wizardstart.len == 0)
|
||||
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
@@ -366,12 +388,6 @@
|
||||
required_candidates = operative_cap[indice_pop]
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/finish_setup(mob/new_character, index)
|
||||
new_character.mind.special_role = "Nuclear Operative"
|
||||
new_character.mind.assigned_role = "Nuclear Operative"
|
||||
@@ -404,12 +420,6 @@
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = -1, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/blob/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant)
|
||||
var/body = applicant.become_overmind()
|
||||
return body
|
||||
@@ -437,12 +447,6 @@
|
||||
property_weights = list("story_potential" = -1, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
var/list/vents = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
|
||||
// 50% chance of being incremented by one
|
||||
required_candidates += prob(50)
|
||||
@@ -539,12 +543,6 @@
|
||||
property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
|
||||
high_population_requirement = 5
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
|
||||
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
|
||||
applicant.transfer_ckey(virus, FALSE)
|
||||
@@ -583,9 +581,6 @@
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies
|
||||
var/turf/T = get_turf(L)
|
||||
if(T && is_station_level(T.z))
|
||||
@@ -632,9 +627,6 @@
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
@@ -685,9 +677,6 @@
|
||||
repeatable = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
team = new /datum/team/abductor_team
|
||||
if(team.team_number > ABDUCTOR_MAX_TEAMS)
|
||||
return FALSE
|
||||
@@ -726,9 +715,6 @@
|
||||
var/spawn_loc
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
if(!spawn_loc)
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
|
||||
@@ -491,4 +491,4 @@
|
||||
|
||||
//Attacks/effects.
|
||||
/obj/machinery/cryopod/blob_act()
|
||||
return //Sorta gamey, but we don't really want these to be destroyed.
|
||||
return //Sorta gamey, but we don't really want these to be destroyed.
|
||||
|
||||
@@ -260,9 +260,8 @@
|
||||
var/position = vending_names_paths.Find(build_path)
|
||||
position = (position == vending_names_paths.len) ? 1 : (position + 1)
|
||||
var/typepath = vending_names_paths[position]
|
||||
|
||||
to_chat(user, "<span class='notice'>You set the board to \"[vending_names_paths[typepath]]\".</span>")
|
||||
set_type(typepath)
|
||||
to_chat(user, "<span class='notice'>You set the board to \"[vending_names_paths[typepath]]\".</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -479,10 +479,10 @@
|
||||
|
||||
possessed = TRUE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
var/mob/living/simple_animal/shade/S = new(src)
|
||||
S.real_name = name
|
||||
S.name = name
|
||||
|
||||
@@ -225,16 +225,31 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
STR.max_items = 10
|
||||
|
||||
/obj/item/storage/toolbox/artistic/PopulateContents()
|
||||
new/obj/item/storage/crayons(src)
|
||||
new/obj/item/crowbar(src)
|
||||
new/obj/item/stack/cable_coil/red(src)
|
||||
new/obj/item/stack/cable_coil/yellow(src)
|
||||
new/obj/item/stack/cable_coil/blue(src)
|
||||
new/obj/item/stack/cable_coil/green(src)
|
||||
new/obj/item/stack/cable_coil/pink(src)
|
||||
new/obj/item/stack/cable_coil/orange(src)
|
||||
new/obj/item/stack/cable_coil/cyan(src)
|
||||
new/obj/item/stack/cable_coil/white(src)
|
||||
new /obj/item/storage/crayons(src)
|
||||
new /obj/item/crowbar(src)
|
||||
new /obj/item/stack/cable_coil/red(src)
|
||||
new /obj/item/stack/cable_coil/yellow(src)
|
||||
new /obj/item/stack/cable_coil/blue(src)
|
||||
new /obj/item/stack/cable_coil/green(src)
|
||||
new /obj/item/stack/cable_coil/pink(src)
|
||||
new /obj/item/stack/cable_coil/orange(src)
|
||||
new /obj/item/stack/cable_coil/cyan(src)
|
||||
new /obj/item/stack/cable_coil/white(src)
|
||||
|
||||
/obj/item/storage/toolbox/ammo
|
||||
name = "ammo box"
|
||||
desc = "It contains a few clips."
|
||||
icon_state = "ammobox"
|
||||
item_state = "ammobox"
|
||||
|
||||
/obj/item/storage/toolbox/ammo/PopulateContents()
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
|
||||
/obj/item/storage/toolbox/gold_real
|
||||
name = "golden toolbox"
|
||||
@@ -314,4 +329,4 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
generate_rubber_toolbox_icon()
|
||||
icon = GLOB.rubber_toolbox_icons[icon_state]
|
||||
. = ..()
|
||||
AddComponent(/datum/component/bouncy)
|
||||
AddComponent(/datum/component/bouncy)
|
||||
|
||||
@@ -626,7 +626,13 @@
|
||||
O.equip(new_spawn, FALSE, new_spawn.client)
|
||||
SSjob.equip_loadout(null, new_spawn, FALSE)
|
||||
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
|
||||
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
|
||||
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
|
||||
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
|
||||
to_chat(new_spawn,"<span class='boldwarning'>You maybe sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!</span>")
|
||||
to_chat(new_spawn,"<span class='boldwarning'>You can turn yourself into a ghost and freely reenter your body with the ghost action.</span>")
|
||||
var/datum/action/ghost/G = new(new_spawn)
|
||||
G.Grant(new_spawn)
|
||||
|
||||
/datum/outfit/ghostcafe
|
||||
name = "ID, jumpsuit and shoes"
|
||||
|
||||
@@ -16,8 +16,16 @@
|
||||
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
|
||||
log_access("Failed Login (invalid cid): [key] [address]-[computer_id]")
|
||||
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
|
||||
var/admin = 0
|
||||
|
||||
if (type == "world")
|
||||
return ..() //shunt world topic banchecks to purely to byond's internal ban system
|
||||
|
||||
var/ckey = ckey(key)
|
||||
var/client/C = GLOB.directory[ckey]
|
||||
if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address)
|
||||
return //don't recheck connected clients.
|
||||
|
||||
var/admin = FALSE
|
||||
if(GLOB.admin_datums[ckey] || GLOB.deadmins[ckey])
|
||||
admin = 1
|
||||
|
||||
@@ -126,7 +134,6 @@
|
||||
bannedckey = ban["ckey"]
|
||||
|
||||
var/newmatch = FALSE
|
||||
var/client/C = GLOB.directory[ckey]
|
||||
var/cachedban = SSstickyban.cache[bannedckey]
|
||||
|
||||
//rogue ban in the process of being reverted.
|
||||
|
||||
@@ -137,9 +137,9 @@
|
||||
|
||||
/datum/admins/proc/makeWizard()
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
|
||||
|
||||
var/mob/dead/observer/selected = pick_n_take(candidates)
|
||||
var/mob/selected = pick_n_take(candidates)
|
||||
|
||||
var/mob/living/carbon/human/new_character = makeBody(selected)
|
||||
new_character.mind.make_Wizard()
|
||||
@@ -214,9 +214,9 @@
|
||||
|
||||
/datum/admins/proc/makeNukeTeam()
|
||||
var/datum/game_mode/nuclear/temp = new
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
|
||||
var/list/mob/dead/observer/chosen = list()
|
||||
var/mob/dead/observer/theghost = null
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
|
||||
var/list/mob/chosen = list()
|
||||
var/mob/theghost = null
|
||||
|
||||
if(candidates.len)
|
||||
var/numagents = 5
|
||||
@@ -378,7 +378,7 @@
|
||||
ertemplate.enforce_human = prefs["enforce_human"]["value"] == "Yes" ? TRUE : FALSE
|
||||
ertemplate.opendoors = prefs["open_armory"]["value"] == "Yes" ? TRUE : FALSE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for [ertemplate.polldesc] ?", "deathsquad", null)
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for [ertemplate.polldesc] ?", "deathsquad", null)
|
||||
var/teamSpawned = FALSE
|
||||
|
||||
if(candidates.len > 0)
|
||||
@@ -404,7 +404,7 @@
|
||||
numagents--
|
||||
continue // This guy's unlucky, not enough spawn points, we skip him.
|
||||
var/spawnloc = spawnpoints[numagents]
|
||||
var/mob/dead/observer/chosen_candidate = pick(candidates)
|
||||
var/mob/chosen_candidate = pick(candidates)
|
||||
candidates -= chosen_candidate
|
||||
if(!chosen_candidate.key)
|
||||
continue
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
if(!can_buy(40))
|
||||
return
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
||||
if(LAZYLEN(candidates)) //if we got at least one candidate, they're a blobbernaut now.
|
||||
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
|
||||
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
|
||||
@@ -181,7 +181,7 @@
|
||||
blobber.update_icons()
|
||||
blobber.adjustHealth(blobber.maxHealth * 0.5)
|
||||
blob_mobs += blobber
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
C.transfer_ckey(blobber)
|
||||
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
|
||||
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
|
||||
|
||||
@@ -93,9 +93,12 @@
|
||||
|
||||
/datum/supply_pack/security/armory/trackingimp
|
||||
name = "Tracking Implants Crate"
|
||||
desc = "Contains four tracking implants. Requires Armory access to open."
|
||||
cost = 1050
|
||||
contains = list(/obj/item/storage/box/trackimp)
|
||||
desc = "Contains four tracking implants and three tracking speedloaders of tracing .38 ammo. Requires Armory access to open."
|
||||
cost = 1100
|
||||
contains = list(/obj/item/storage/box/trackimp,
|
||||
/obj/item/ammo_box/c38/trac,
|
||||
/obj/item/ammo_box/c38/trac,
|
||||
/obj/item/ammo_box/c38/trac)
|
||||
crate_name = "tracking implant crate"
|
||||
|
||||
/datum/supply_pack/security/armory/fire
|
||||
@@ -172,6 +175,32 @@
|
||||
/obj/item/storage/box/beanbag)
|
||||
crate_name = "riot shotgun crate"
|
||||
|
||||
/datum/supply_pack/security/armory/russian
|
||||
name = "Russian Surplus Crate"
|
||||
desc = "Hello Comrade, we have the most modern russian military equipment the black market can offer, for the right price of course. Sadly we couldnt remove the lock so it requires Armory access to open."
|
||||
cost = 5000
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/reagent_containers/food/snacks/rationpack,
|
||||
/obj/item/ammo_box/a762,
|
||||
/obj/item/storage/toolbox/ammo,
|
||||
/obj/item/clothing/suit/armor/vest/russian,
|
||||
/obj/item/clothing/head/helmet/rus_helmet,
|
||||
/obj/item/clothing/shoes/russian,
|
||||
/obj/item/clothing/gloves/combat,
|
||||
/obj/item/clothing/under/syndicate/rus_army,
|
||||
/obj/item/clothing/under/soviet,
|
||||
/obj/item/clothing/mask/russian_balaclava,
|
||||
/obj/item/clothing/head/helmet/rus_ushanka,
|
||||
/obj/item/clothing/suit/armor/vest/russian_coat,
|
||||
/obj/item/gun/ballistic/shotgun/boltaction,
|
||||
/obj/item/gun/ballistic/shotgun/boltaction)
|
||||
crate_name = "surplus military crate"
|
||||
|
||||
/datum/supply_pack/security/armory/russian/fill(obj/structure/closet/crate/C)
|
||||
for(var/i in 1 to 10)
|
||||
var/item = pick(contains)
|
||||
new item(C)
|
||||
|
||||
/datum/supply_pack/security/armory/swat
|
||||
name = "SWAT Crate"
|
||||
desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open."
|
||||
@@ -223,7 +252,7 @@
|
||||
/obj/item/ammo_box/magazine/wt550m9)
|
||||
crate_name = "auto rifle ammo crate"
|
||||
|
||||
/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stun crit someone
|
||||
/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stamcrit someone
|
||||
name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
|
||||
desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
|
||||
cost = 1000
|
||||
|
||||
@@ -23,6 +23,21 @@
|
||||
crate_name = "Biker Kit"
|
||||
crate_type = /obj/structure/closet/crate/large
|
||||
|
||||
/datum/supply_pack/emergency/bio
|
||||
name = "Biological Emergency Crate"
|
||||
desc = "This crate holds 2 full bio suits which will protect you from viruses, along with a bio bag and two spaceacillin syringes."
|
||||
cost = 2000
|
||||
contains = list(/obj/item/clothing/head/bio_hood,
|
||||
/obj/item/clothing/head/bio_hood,
|
||||
/obj/item/clothing/suit/bio_suit,
|
||||
/obj/item/clothing/suit/bio_suit,
|
||||
/obj/item/storage/bag/bio,
|
||||
/obj/item/reagent_containers/syringe/antiviral,
|
||||
/obj/item/reagent_containers/syringe/antiviral,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile)
|
||||
crate_name = "bio suit crate"
|
||||
|
||||
/datum/supply_pack/emergency/equipment
|
||||
name = "Emergency Bot/Internals Crate"
|
||||
desc = "Explosions got you down? These supplies are guaranteed to patch up holes, in stations and people alike! Comes with two floorbots, two medbots, five oxygen masks and five small oxygen tanks."
|
||||
@@ -112,8 +127,8 @@
|
||||
crate_type = /obj/structure/closet/crate/internals
|
||||
|
||||
/datum/supply_pack/emergency/soft_suit
|
||||
name = "Emergency Space Suit "
|
||||
desc = "Are there bombs going off left and right? Are there meteors shooting around the station? Well then! Here's two fragile space suit for emergencies. Comes with air and masks."
|
||||
name = "Emergency Space Suit"
|
||||
desc = "Are there bombs going off left and right? Are there meteors shooting around the station? Well then! Here's two fragile space suits for emergencies. Comes with air and masks."
|
||||
cost = 1200
|
||||
contains = list(/obj/item/tank/internals/air,
|
||||
/obj/item/tank/internals/air,
|
||||
@@ -126,6 +141,18 @@
|
||||
crate_name = "emergency crate"
|
||||
crate_type = /obj/structure/closet/crate/internals
|
||||
|
||||
/datum/supply_pack/emergency/bomb
|
||||
name = "Explosive Emergency Crate"
|
||||
desc = "Science gone bonkers? Beeping behind the airlock? Buy now and be the hero the station des... I mean needs! (Time not included.)"
|
||||
cost = 1500
|
||||
contains = list(/obj/item/clothing/head/bomb_hood,
|
||||
/obj/item/clothing/suit/bomb_suit,
|
||||
/obj/item/clothing/mask/gas,
|
||||
/obj/item/screwdriver,
|
||||
/obj/item/wirecutters,
|
||||
/obj/item/multitool)
|
||||
crate_name = "bomb suit crate"
|
||||
|
||||
/datum/supply_pack/emergency/firefighting
|
||||
name = "Firefighting Crate"
|
||||
desc = "Only you can prevent station fires. Partner up with two firefighter suits, gas masks, flashlights, large oxygen tanks, extinguishers, and hardhats!"
|
||||
@@ -307,4 +334,3 @@
|
||||
/obj/item/reagent_containers/spray/plantbgone)
|
||||
crate_name = "weed control crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/hydroponics
|
||||
|
||||
|
||||
@@ -25,6 +25,20 @@
|
||||
new /obj/item/reagent_containers/food/snacks/grown/wheat(.)
|
||||
|
||||
|
||||
/datum/supply_pack/critter/parrot
|
||||
name = "Bird Crate"
|
||||
desc = "Contains five expert telecommunication birds."
|
||||
cost = 4000
|
||||
contains = list(/mob/living/simple_animal/parrot)
|
||||
crate_name = "parrot crate"
|
||||
|
||||
/datum/supply_pack/critter/parrot/generate()
|
||||
. = ..()
|
||||
for(var/i in 1 to 4)
|
||||
new /mob/living/simple_animal/parrot(.)
|
||||
if(prob(1))
|
||||
new /mob/living/simple_animal/parrot/clock_hawk(.)
|
||||
|
||||
/datum/supply_pack/critter/butterfly
|
||||
name = "Butterflies Crate"
|
||||
desc = "Not a very dangerous insect, but they do give off a better image than, say, flies or cockroaches."//is that a motherfucking worm reference
|
||||
|
||||
@@ -57,6 +57,27 @@
|
||||
crate_name = "blood freezer"
|
||||
crate_type = /obj/structure/closet/crate/freezer
|
||||
|
||||
/datum/supply_pack/medical/chemical
|
||||
name = "Chemical Starter Kit Crate"
|
||||
desc = "Contains twelve different chemicals, for all the fun experiments you can make."
|
||||
cost = 1700
|
||||
contains = list(/obj/item/reagent_containers/glass/bottle/hydrogen,
|
||||
/obj/item/reagent_containers/glass/bottle/carbon,
|
||||
/obj/item/reagent_containers/glass/bottle/nitrogen,
|
||||
/obj/item/reagent_containers/glass/bottle/oxygen,
|
||||
/obj/item/reagent_containers/glass/bottle/fluorine,
|
||||
/obj/item/reagent_containers/glass/bottle/phosphorus,
|
||||
/obj/item/reagent_containers/glass/bottle/silicon,
|
||||
/obj/item/reagent_containers/glass/bottle/chlorine,
|
||||
/obj/item/reagent_containers/glass/bottle/radium,
|
||||
/obj/item/reagent_containers/glass/bottle/sacid,
|
||||
/obj/item/reagent_containers/glass/bottle/ethanol,
|
||||
/obj/item/reagent_containers/glass/bottle/potassium,
|
||||
/obj/item/clothing/glasses/science,
|
||||
/obj/item/reagent_containers/dropper,
|
||||
/obj/item/storage/box/beakers)
|
||||
crate_name = "chemical crate"
|
||||
|
||||
/datum/supply_pack/medical/defibs
|
||||
name = "Defibrillator Crate"
|
||||
desc = "Contains two defibrillators for bringing the recently deceased back to life."
|
||||
@@ -229,7 +250,7 @@
|
||||
|
||||
/datum/supply_pack/medical/anitvirus
|
||||
name = "Virus Containment Crate"
|
||||
desc = "Viro let out a death plague Mk II again? Someone didnt wash their hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it breaks out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
|
||||
desc = "Viro let out a death plague Mk II again? Someone didn't wash their hands? Old plagues born anew? Well, this crate is for you! Hope you cure it before it breaks out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
|
||||
cost = 3000
|
||||
access = ACCESS_MEDICAL
|
||||
contains = list(/mob/living/simple_animal/bot/medbot,
|
||||
@@ -245,4 +266,4 @@
|
||||
/obj/item/storage/box/syringes,
|
||||
/obj/item/storage/box/beakers)
|
||||
crate_name = "virus containment unit crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/plasma
|
||||
crate_type = /obj/structure/closet/crate/secure/plasma
|
||||
|
||||
@@ -281,8 +281,7 @@
|
||||
/obj/item/storage/book/bible/booze,
|
||||
/obj/item/storage/book/bible/booze,
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie,
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie
|
||||
)
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie)
|
||||
crate_name = "religious supplies crate"
|
||||
|
||||
/datum/supply_pack/misc/funeral
|
||||
|
||||
@@ -47,6 +47,26 @@
|
||||
/obj/item/storage/fancy/donut_box)
|
||||
crate_name = "candy crate"
|
||||
|
||||
/datum/supply_pack/organic/randomized/chef
|
||||
name = "Excellent Meat Crate"
|
||||
desc = "The best cuts in the whole galaxy."
|
||||
cost = 2000
|
||||
contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime,
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/killertomato,
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/bear,
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/spider,
|
||||
/obj/item/reagent_containers/food/snacks/meat/rawbacon,
|
||||
/obj/item/reagent_containers/food/snacks/spiderleg,
|
||||
/obj/item/reagent_containers/food/snacks/carpmeat,
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/human)
|
||||
crate_name = "food crate"
|
||||
|
||||
/datum/supply_pack/organic/randomized/chef/fill(obj/structure/closet/crate/C)
|
||||
for(var/i in 1 to 15)
|
||||
var/item = pick(contains)
|
||||
new item(C)
|
||||
|
||||
/datum/supply_pack/organic/exoticseeds
|
||||
name = "Exotic Seeds Crate"
|
||||
desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
|
||||
@@ -92,6 +112,26 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana)
|
||||
crate_name = "food crate"
|
||||
|
||||
/datum/supply_pack/organic/randomized/chef/fruits
|
||||
name = "Fruit Crate"
|
||||
desc = "Rich in vitamins, may contain oranges."
|
||||
cost = 1500
|
||||
contains = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/reagent_containers/food/snacks/grown/watermelon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/apple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/berries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/cherries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes/green,
|
||||
/obj/item/reagent_containers/food/snacks/grown/eggplant,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peach,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry)
|
||||
crate_name = "food crate"
|
||||
|
||||
/datum/supply_pack/organic/fiestatortilla
|
||||
name = "Fiesta Crate"
|
||||
desc = "Spice up the kitchen with this fiesta themed food order! Contains 8 tortilla based food items, as well as a sombrero, moustache, and cloak!"
|
||||
@@ -111,71 +151,6 @@
|
||||
/obj/item/reagent_containers/glass/bottle/capsaicin)
|
||||
crate_name = "fiesta crate"
|
||||
|
||||
/datum/supply_pack/organic/fruit_1
|
||||
name = "Fruit Basic Crate"
|
||||
desc = "Getting scurvy on the station? Well heres your fixing! Contains three of each - bananas, watermelons, limes, lemons, oranges and even three pineapple."
|
||||
cost = 2250
|
||||
contains = list(/obj/item/reagent_containers/food/snacks/grown/watermelon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/watermelon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/watermelon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana)
|
||||
crate_name = "fruit crate"
|
||||
|
||||
/datum/supply_pack/organic/fruit_2
|
||||
name = "Fruit Delux Crate"
|
||||
desc = "Getting tired of the basic fruits and want to have something a bit more decadent! This crate is for you! Contains three of each - bunches of berries, apples, pineapples, cherries, green & red grapes, eggplants, bananas, peaches, and lastly seven strawberry. Includes one serving tray."
|
||||
cost = 3500
|
||||
contains = list(/obj/item/reagent_containers/food/snacks/grown/berries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/berries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/berries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/apple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/apple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/apple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pineapple,
|
||||
/obj/item/reagent_containers/food/snacks/grown/cherries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/cherries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/cherries,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes/green,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes/green,
|
||||
/obj/item/reagent_containers/food/snacks/grown/grapes/green,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/reagent_containers/food/snacks/grown/eggplant,
|
||||
/obj/item/reagent_containers/food/snacks/grown/eggplant,
|
||||
/obj/item/reagent_containers/food/snacks/grown/eggplant,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peach,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peach,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peach,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry,
|
||||
/obj/item/storage/bag/tray)
|
||||
crate_name = "fruit crate"
|
||||
|
||||
/datum/supply_pack/organic/grill
|
||||
name = "Grilling Starter Kit"
|
||||
desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets."
|
||||
@@ -283,6 +258,19 @@
|
||||
considered <b>\[REDACTED\]</b> and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \
|
||||
of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.")
|
||||
|
||||
/datum/supply_pack/organic/randomized/chef/vegetables
|
||||
name = "Vegetables Crate"
|
||||
desc = "Grown in vats."
|
||||
cost = 1300
|
||||
contains = list(/obj/item/reagent_containers/food/snacks/grown/chili,
|
||||
/obj/item/reagent_containers/food/snacks/grown/corn,
|
||||
/obj/item/reagent_containers/food/snacks/grown/tomato,
|
||||
/obj/item/reagent_containers/food/snacks/grown/potato,
|
||||
/obj/item/reagent_containers/food/snacks/grown/carrot,
|
||||
/obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle,
|
||||
/obj/item/reagent_containers/food/snacks/grown/onion,
|
||||
/obj/item/reagent_containers/food/snacks/grown/pumpkin)
|
||||
crate_name = "food crate"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Hydroponics /////////////////////////////////////
|
||||
@@ -372,6 +360,8 @@
|
||||
/obj/item/hatchet,
|
||||
/obj/item/cultivator,
|
||||
/obj/item/plant_analyzer,
|
||||
/obj/item/clothing/gloves/botanic_leather,
|
||||
/obj/item/clothing/suit/apron,
|
||||
/obj/item/flashlight,
|
||||
/obj/item/seeds/carrot,
|
||||
/obj/item/seeds/carrot,
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
/datum/supply_pack/science/robotics/mecha_odysseus
|
||||
name = "Circuit Crate (Odysseus)"
|
||||
desc = "Ever wanted to build your own giant medical robot? Well, now you can! Contains the Odysseus main control board and Odysseus peripherals board. Requires Robotics access to open."
|
||||
cost = 2500
|
||||
cost = 1500
|
||||
access = ACCESS_ROBOTICS
|
||||
contains = list(/obj/item/circuitboard/mecha/odysseus/peripherals,
|
||||
/obj/item/circuitboard/mecha/odysseus/main)
|
||||
@@ -64,7 +64,7 @@
|
||||
/datum/supply_pack/science/robotics/mecha_ripley
|
||||
name = "Circuit Crate (Ripley APLU)"
|
||||
desc = "Rip apart rocks and xenomorphs alike with the Ripley APLU. Contains the Main Ripley control board, as well as the Ripley Peripherals board. Requires Robotics access to open."
|
||||
cost = 3000
|
||||
cost = 1200
|
||||
access = ACCESS_ROBOTICS
|
||||
contains = list(/obj/item/book/manual/ripley_build_and_repair,
|
||||
/obj/item/circuitboard/mecha/ripley/main,
|
||||
@@ -153,6 +153,13 @@
|
||||
crate_name = "robotics assembly crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
/datum/supply_pack/science/rped
|
||||
name = "RPED crate"
|
||||
desc = "Need to rebuild the ORM but science got annihilated after a bomb test? Buy this for the most advanced parts NT can give you."
|
||||
cost = 1500
|
||||
contains = list(/obj/item/storage/part_replacer/cargo)
|
||||
crate_name = "\improper RPED crate"
|
||||
|
||||
/datum/supply_pack/science/shieldwalls
|
||||
name = "Shield Generator Crate"
|
||||
desc = "These high powered Shield Wall Generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Contains four shield wall generators. Requires Teleporter access to open."
|
||||
@@ -188,7 +195,7 @@
|
||||
/datum/supply_pack/science/tablets
|
||||
name = "Tablet Crate"
|
||||
desc = "What's a computer? Contains five cargo tablets."
|
||||
cost = 3000
|
||||
cost = 1500
|
||||
contains = list(/obj/item/modular_computer/tablet/preset/cargo,
|
||||
/obj/item/modular_computer/tablet/preset/cargo,
|
||||
/obj/item/modular_computer/tablet/preset/cargo,
|
||||
|
||||
@@ -11,6 +11,23 @@
|
||||
access = ACCESS_SECURITY
|
||||
crate_type = /obj/structure/closet/crate/secure/gear
|
||||
|
||||
/datum/supply_pack/security/ammo
|
||||
name = "Ammo Crate - General Purpose"
|
||||
desc = "Contains two 20-round magazines for the WT-550 Auto Rifle, three boxes of buckshot ammo, three boxes of rubber ammo and special .38 speedloarders. Requires Security access to open."
|
||||
cost = 2500
|
||||
contains = list(/obj/item/ammo_box/magazine/wt550m9,
|
||||
/obj/item/ammo_box/magazine/wt550m9,
|
||||
/obj/item/storage/box/lethalshot,
|
||||
/obj/item/storage/box/lethalshot,
|
||||
/obj/item/storage/box/lethalshot,
|
||||
/obj/item/storage/box/rubbershot,
|
||||
/obj/item/storage/box/rubbershot,
|
||||
/obj/item/storage/box/rubbershot,
|
||||
/obj/item/ammo_box/c38/trac,
|
||||
/obj/item/ammo_box/c38/hotshot,
|
||||
/obj/item/ammo_box/c38/iceblox)
|
||||
crate_name = "ammo crate"
|
||||
|
||||
/datum/supply_pack/security/armor
|
||||
name = "Armor Crate"
|
||||
desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
|
||||
@@ -146,6 +163,13 @@
|
||||
/obj/item/storage/box/handcuffs)
|
||||
crate_name = "security supply crate"
|
||||
|
||||
/datum/supply_pack/security/vending/security
|
||||
name = "SecTech Supply Crate"
|
||||
desc = "Officer Paul bought all the donuts? Then refill the security vendor with ths crate."
|
||||
cost = 1500
|
||||
contains = list(/obj/machinery/vending/security)
|
||||
crate_name = "SecTech supply crate"
|
||||
|
||||
/datum/supply_pack/security/firingpins
|
||||
name = "Standard Firing Pins Crate"
|
||||
desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open."
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
/datum/supply_pack/service/cutlery
|
||||
name = "Kitchen Cutlery Deluxe Set"
|
||||
desc = "Need to slice and dice away those ''Tomatoes''? Well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
|
||||
desc = "Need to slice and dice away those \"Tomatoes\"? Well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
|
||||
cost = 10000
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/sharpener, //Deluxe for a reason
|
||||
@@ -127,6 +127,16 @@
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
|
||||
crate_name = "kitchen cutlery deluxe set"
|
||||
|
||||
/datum/supply_pack/service/replacementdb
|
||||
name = "Replacement Defensive Bar Shotgun"
|
||||
desc = "Someone stole the Bartender's twin-barreled possession? Give them another one at a significant markup. Comes with one unused double-barrel shotgun, shells not included. Requires bartender access to open."
|
||||
cost = 2200
|
||||
access = ACCESS_BAR
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/gun/ballistic/revolver/doublebarrel)
|
||||
crate_name = "replacement double-barrel crate"
|
||||
crate_type = /obj/structure/closet/crate/secure
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////// Janitor //////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -80,7 +80,3 @@
|
||||
var/next_keysend_reset = 0
|
||||
var/next_keysend_trip_reset = 0
|
||||
var/keysend_tripped = FALSE
|
||||
|
||||
// stops players from coming back through ghost/midround roles after suicide/cryo
|
||||
// for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
|
||||
var/reenter_round_timeout = 0
|
||||
|
||||
@@ -337,10 +337,28 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/durathread
|
||||
name = "makeshift helmet"
|
||||
desc = "A hardhat with strips of leather and durathread for additional blunt protection."
|
||||
icon_state = "durathread"
|
||||
item_state = "durathread"
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50)
|
||||
|
||||
/obj/item/clothing/head/helmet/rus_helmet
|
||||
name = "russian helmet"
|
||||
desc = "It can hold a bottle of vodka."
|
||||
icon_state = "rus_helmet"
|
||||
item_state = "rus_helmet"
|
||||
armor = list("melee" = 30, "bullet" = 25, "laser" = 20,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 50)
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/rushelmet
|
||||
|
||||
/obj/item/clothing/head/helmet/rus_ushanka
|
||||
name = "battle ushanka"
|
||||
desc = "100% bear."
|
||||
icon_state = "rus_ushanka"
|
||||
item_state = "rus_ushanka"
|
||||
clothing_flags = THICKMATERIAL
|
||||
body_parts_covered = HEAD
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 0)
|
||||
|
||||
@@ -57,3 +57,12 @@
|
||||
desc = "Worn by robust fighters who are willing to do anything to win."
|
||||
icon_state = "luchar"
|
||||
item_state = "luchar"
|
||||
|
||||
/obj/item/clothing/mask/russian_balaclava
|
||||
name = "russian balaclava"
|
||||
desc = "Protects your face from snow."
|
||||
icon_state = "rus_balaclava"
|
||||
item_state = "rus_balaclava"
|
||||
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
visor_flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
@@ -327,6 +327,13 @@
|
||||
lightCycle = 0
|
||||
active = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/russian
|
||||
name = "russian boots"
|
||||
desc = "Comfy shoes."
|
||||
icon_state = "rus_shoes"
|
||||
item_state = "rus_shoes"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
|
||||
// kevin is into feet
|
||||
/obj/item/clothing/shoes/wraps
|
||||
name = "gilded leg wraps"
|
||||
@@ -347,4 +354,4 @@
|
||||
/obj/item/clothing/shoes/wraps/blue
|
||||
name = "blue leg wraps"
|
||||
desc = "Ankle coverings. Hang ten, brother."
|
||||
icon_state = "bluecuffs"
|
||||
icon_state = "bluecuffs"
|
||||
|
||||
@@ -248,3 +248,20 @@
|
||||
max_integrity = 200
|
||||
resistance_flags = FLAMMABLE
|
||||
armor = list("melee" = 20, "bullet" = 10, "laser" = 30, "energy" = 5, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/russian
|
||||
name = "russian vest"
|
||||
desc = "A bulletproof vest with forest camo. Good thing there's plenty of forests to hide in around here, right?"
|
||||
icon_state = "rus_armor"
|
||||
item_state = "rus_armor"
|
||||
armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50)
|
||||
/obj/item/clothing/suit/armor/vest/russian_coat
|
||||
name = "russian battle coat"
|
||||
desc = "Used in extremly cold fronts, made out of real bears."
|
||||
icon_state = "rus_coat"
|
||||
item_state = "rus_coat"
|
||||
clothing_flags = THICKMATERIAL
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50)
|
||||
|
||||
@@ -68,9 +68,18 @@
|
||||
item_color = "syndicate_combat"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/syndicate/rus_army
|
||||
name = "advanced military tracksuit"
|
||||
desc = "Military grade tracksuits for frontline squatting."
|
||||
icon_state = "rus_under"
|
||||
item_color = "rus_under"
|
||||
can_adjust = FALSE
|
||||
armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/syndicate/baseball
|
||||
name = "major league, number unknown"
|
||||
desc = "A major league outfit with the number faded number on the back. Seems rather robust for just a game"
|
||||
desc = "A major league outfit with the number faded number on the back. Seems rather robust for just a game..."
|
||||
icon_state = "syndicatebaseball"
|
||||
item_state = "syndicatebaseball"
|
||||
item_color = "syndicatebaseball"
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
/datum/round_event/santa/start()
|
||||
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
|
||||
C.transfer_ckey(santa, FALSE)
|
||||
|
||||
|
||||
@@ -18,6 +18,3 @@
|
||||
|
||||
update_icon(preferred_form)
|
||||
updateghostimages()
|
||||
|
||||
client.reenter_round_timeout = max(client.reenter_round_timeout, clientless_round_timeout)
|
||||
clientless_round_timeout = client.reenter_round_timeout
|
||||
|
||||
@@ -19,7 +19,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
hud_type = /datum/hud/ghost
|
||||
movement_type = GROUND | FLYING
|
||||
var/can_reenter_corpse
|
||||
var/clientless_round_timeout = 0 //mobs will lack a client as long as their player is disconnected. See client_defines.dm "reenter_round_timeout"
|
||||
var/datum/hud/living/carbon/hud = null // hud
|
||||
var/bootime = 0
|
||||
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
|
||||
@@ -135,7 +134,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
AA.onNewMob(src)
|
||||
|
||||
. = ..()
|
||||
|
||||
AddElement(/datum/element/ghost_role_eligibility)
|
||||
grant_all_languages()
|
||||
|
||||
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
|
||||
@@ -270,23 +269,12 @@ Works together with spawning an observer, noted above.
|
||||
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
|
||||
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
|
||||
ghost.can_reenter_corpse = can_reenter_corpse
|
||||
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
if(penalty)
|
||||
penalty += world.realtime
|
||||
if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
if(client)
|
||||
client.reenter_round_timeout = penalty
|
||||
else //A disconnected player (quite likely for cryopods)
|
||||
ghost.clientless_round_timeout = penalty
|
||||
if (client && client.prefs && client.prefs.auto_ooc)
|
||||
if (!(client.prefs.chat_toggles & CHAT_OOC))
|
||||
client.prefs.chat_toggles ^= CHAT_OOC
|
||||
transfer_ckey(ghost, FALSE)
|
||||
ghost.AddElement(/datum/element/ghost_role_eligibility,penalize) // technically already run earlier, but this adds the penalty
|
||||
// needs to be done AFTER the ckey transfer, too
|
||||
return ghost
|
||||
|
||||
/*
|
||||
@@ -343,15 +331,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return
|
||||
ghostize(0, penalize = TRUE)
|
||||
|
||||
/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
|
||||
var/timeout = clientless_round_timeout
|
||||
if(client)
|
||||
timeout = client.reenter_round_timeout
|
||||
if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
|
||||
return TRUE
|
||||
if(!silent && client)
|
||||
to_chat(src, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/dead/observer/Move(NewLoc, direct)
|
||||
if(updatedir)
|
||||
|
||||
@@ -37,11 +37,16 @@
|
||||
H.dna.features["caps"] = "Round"
|
||||
handle_mutant_bodyparts(H)
|
||||
H.faction |= "mushroom"
|
||||
mush = new(null)
|
||||
mush.teach(H)
|
||||
mush = new()
|
||||
mush.teach(H, TRUE)
|
||||
RegisterSignal(C, COMSIG_MOB_ON_NEW_MIND, .proc/on_new_mind)
|
||||
|
||||
/datum/species/mush/proc/on_new_mind(mob/owner)
|
||||
mush.teach(owner, TRUE) //make_temporary TRUE as it shouldn't carry over to other mobs on mind transfer_to.
|
||||
|
||||
/datum/species/mush/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
UnregisterSignal(C, COMSIG_MOB_ON_NEW_MIND)
|
||||
C.faction -= "mushroom"
|
||||
mush.remove(C)
|
||||
QDEL_NULL(mush)
|
||||
|
||||
@@ -424,9 +424,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians
|
||||
if(G)
|
||||
to_chat(src, "<span class='holoparasite'>You attempt to reset <font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font>'s personality...</span>")
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
|
||||
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
|
||||
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
|
||||
@@ -498,10 +498,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
return
|
||||
used = TRUE
|
||||
to_chat(user, "[use_message]")
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
spawn_guardian(user, C.key)
|
||||
else
|
||||
to_chat(user, "[failure_message]")
|
||||
|
||||
@@ -567,9 +567,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
/mob/proc/is_muzzled()
|
||||
return 0
|
||||
|
||||
/mob/Stat(delayoverride)
|
||||
. = ..()
|
||||
var/statdelay = delayoverride || 10
|
||||
/mob/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
if (client)
|
||||
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
|
||||
@@ -577,7 +577,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
var/datum/map_config/cached = SSmapping.next_map_config
|
||||
if(cached)
|
||||
stat(null, "Next Map: [cached.map_name]")
|
||||
stat(null, "Round ID: [GLOB.round_id || "NULL"]")
|
||||
stat(null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]")
|
||||
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
|
||||
stat(null, "Round Time: [WORLDTIME2TEXT("hh:mm:ss")]")
|
||||
stat(null, "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]")
|
||||
@@ -587,9 +587,8 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
if(ETA)
|
||||
stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]")
|
||||
|
||||
if(client?.holder)
|
||||
if(client && client.holder)
|
||||
if(statpanel("MC"))
|
||||
statdelay = 0 //It's assumed that if you're doing this you are doing debug stuff, don't do ioditic things.
|
||||
var/turf/T = get_turf(client.eye)
|
||||
stat("Location:", COORD(T))
|
||||
stat("CPU:", "[world.cpu]")
|
||||
@@ -615,7 +614,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
GLOB.ahelp_tickets.stat_entry()
|
||||
if(length(GLOB.sdql2_queries))
|
||||
if(statpanel("SDQL2"))
|
||||
statdelay = 0 //It's assumed that if you're doing this you are doing debug stuff, don't do ioditic things.
|
||||
stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
|
||||
for(var/i in GLOB.sdql2_queries)
|
||||
var/datum/SDQL2_query/Q = i
|
||||
@@ -639,13 +637,14 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
if(A.IsObscured())
|
||||
continue
|
||||
statpanel(listed_turf.name, null, A)
|
||||
|
||||
|
||||
if(mind)
|
||||
add_spells_to_statpanel(mind.spell_list)
|
||||
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling)
|
||||
add_stings_to_statpanel(changeling.purchasedpowers)
|
||||
add_spells_to_statpanel(mob_spell_list)
|
||||
sleep(statdelay)
|
||||
|
||||
/mob/proc/add_spells_to_statpanel(list/spells)
|
||||
for(var/obj/effect/proc_holder/spell/S in spells)
|
||||
@@ -961,4 +960,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
|
||||
/mob/setMovetype(newval)
|
||||
. = ..()
|
||||
update_movespeed(FALSE)
|
||||
update_movespeed(FALSE)
|
||||
@@ -19,18 +19,38 @@
|
||||
var/container_HP = 2
|
||||
var/cached_icon
|
||||
|
||||
/obj/item/reagent_containers/verb/set_APTFT(mob/user) //set amount_per_transfer_from_this
|
||||
set name = "Set Transfer Amount"
|
||||
set category = "Object"
|
||||
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
|
||||
if(N)
|
||||
amount_per_transfer_from_this = N
|
||||
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
|
||||
|
||||
/obj/item/reagent_containers/Initialize(mapload, vol)
|
||||
. = ..()
|
||||
if(isnum(vol) && vol > 0)
|
||||
volume = vol
|
||||
if(!possible_transfer_amounts)
|
||||
src.verbs -= /obj/item/reagent_containers/verb/set_APTFT
|
||||
create_reagents(volume, reagent_flags)
|
||||
if(spawned_disease)
|
||||
var/datum/disease/F = new spawned_disease()
|
||||
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
|
||||
reagents.add_reagent("blood", disease_amount, data)
|
||||
|
||||
add_initial_reagents()
|
||||
|
||||
/obj/item/reagent_containers/examine(mob/user)
|
||||
. = ..()
|
||||
. += "Currently transferring [amount_per_transfer_from_this] units per use."
|
||||
if(possible_transfer_amounts && user.Adjacent(src))
|
||||
. += "<span class='notice'>Alt-click it to set its transfer amount.</span>"
|
||||
|
||||
/obj/item/reagent_containers/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(possible_transfer_amounts && user.Adjacent(src))
|
||||
set_APTFT()
|
||||
|
||||
/obj/item/reagent_containers/proc/add_initial_reagents()
|
||||
if(list_reagents)
|
||||
reagents.add_reagent_list(list_reagents)
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
icon_state = "beaker"
|
||||
item_state = "beaker"
|
||||
materials = list(MAT_GLASS=500)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,60)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50,60)
|
||||
beaker_weakness_bitflag = PH_WEAK
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/Initialize()
|
||||
@@ -169,7 +169,7 @@
|
||||
materials = list(MAT_GLASS=2500)
|
||||
volume = 120
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120)
|
||||
container_HP = 3
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/plastic
|
||||
@@ -179,7 +179,7 @@
|
||||
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
|
||||
volume = 180
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120,180)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
|
||||
beaker_weakness_bitflag &= ~PH_WEAK
|
||||
@@ -198,7 +198,7 @@
|
||||
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
|
||||
volume = 240
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120,200,240)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,200,240)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you
|
||||
beaker_weakness_bitflag &= ~PH_WEAK
|
||||
@@ -341,6 +341,7 @@
|
||||
materials = list(MAT_GLASS=0)
|
||||
volume = 50
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50)
|
||||
container_HP = 1
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
|
||||
@@ -357,6 +358,7 @@
|
||||
list_reagents = list("water" = 100)
|
||||
volume = 100
|
||||
amount_per_transfer_from_this = 20
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
|
||||
container_HP = 1
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
|
||||
|
||||
@@ -62,11 +62,11 @@
|
||||
/obj/item/reagent_containers/glass/bottle/vial/small
|
||||
name = "hypovial"
|
||||
volume = 60
|
||||
possible_transfer_amounts = list(1,2,5,10,20,30)
|
||||
possible_transfer_amounts = list(1,2,5,10,20)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/vial/small/bluespace
|
||||
volume = 120
|
||||
possible_transfer_amounts = list(1,2,5,10,20,30,40)
|
||||
possible_transfer_amounts = list(1,2,5,10,20)
|
||||
name = "bluespace hypovial"
|
||||
icon_state = "hypovialbs"
|
||||
unique_reskin = null
|
||||
@@ -76,7 +76,7 @@
|
||||
desc = "A large hypovial, for deluxe hypospray models."
|
||||
icon_state = "hypoviallarge"
|
||||
volume = 120
|
||||
possible_transfer_amounts = list(1,2,5,10,20,30,40,60)
|
||||
possible_transfer_amounts = list(1,2,5,10,20)
|
||||
unique_reskin = list("large hypovial" = "hypoviallarge",
|
||||
"large red hypovial" = "hypoviallarge-b",
|
||||
"large blue hypovial" = "hypoviallarge-d",
|
||||
@@ -108,7 +108,7 @@
|
||||
add_overlay(filling)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/vial/large/bluespace
|
||||
possible_transfer_amounts = list(1,2,5,10,20,30,40,60)
|
||||
possible_transfer_amounts = list(1,2,5,10,20)
|
||||
name = "bluespace large hypovial"
|
||||
volume = 240
|
||||
icon_state = "hypoviallargebs"
|
||||
|
||||
@@ -51,6 +51,56 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
|
||||
alt_sound = 'sound/items/pshoom_2.ogg'
|
||||
component_type = /datum/component/storage/concrete/bluespace/rped
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier1
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier1/PopulateContents()
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/stock_parts/capacitor(src)
|
||||
new /obj/item/stock_parts/scanning_module(src)
|
||||
new /obj/item/stock_parts/manipulator(src)
|
||||
new /obj/item/stock_parts/micro_laser(src)
|
||||
new /obj/item/stock_parts/matter_bin(src)
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier2
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier2/PopulateContents()
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/stock_parts/capacitor/adv(src)
|
||||
new /obj/item/stock_parts/scanning_module/adv(src)
|
||||
new /obj/item/stock_parts/manipulator/nano(src)
|
||||
new /obj/item/stock_parts/micro_laser/high(src)
|
||||
new /obj/item/stock_parts/matter_bin/adv(src)
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier3
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier3/PopulateContents()
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/stock_parts/capacitor/super(src)
|
||||
new /obj/item/stock_parts/scanning_module/phasic(src)
|
||||
new /obj/item/stock_parts/manipulator/pico(src)
|
||||
new /obj/item/stock_parts/micro_laser/ultra(src)
|
||||
new /obj/item/stock_parts/matter_bin/super(src)
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier4
|
||||
|
||||
/obj/item/storage/part_replacer/bluespace/tier4/PopulateContents()
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/stock_parts/capacitor/quadratic(src)
|
||||
new /obj/item/stock_parts/scanning_module/triphasic(src)
|
||||
new /obj/item/stock_parts/manipulator/femto(src)
|
||||
new /obj/item/stock_parts/micro_laser/quadultra(src)
|
||||
new /obj/item/stock_parts/matter_bin/bluespace(src)
|
||||
|
||||
/obj/item/storage/part_replacer/cargo //used in a cargo crate
|
||||
|
||||
/obj/item/storage/part_replacer/cargo/PopulateContents()
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/stock_parts/capacitor(src)
|
||||
new /obj/item/stock_parts/scanning_module(src)
|
||||
new /obj/item/stock_parts/manipulator(src)
|
||||
new /obj/item/stock_parts/micro_laser(src)
|
||||
new /obj/item/stock_parts/matter_bin(src)
|
||||
|
||||
/obj/item/storage/part_replacer/cyborg
|
||||
icon_state = "borgrped"
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
/obj/item/ssword_kit = 1)
|
||||
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
refill_canister = /obj/item/vending_refill/security
|
||||
|
||||
/obj/machinery/vending/security/pre_throw(obj/item/I)
|
||||
if(istype(I, /obj/item/grenade))
|
||||
@@ -33,3 +34,6 @@
|
||||
var/obj/item/flashlight/F = I
|
||||
F.on = TRUE
|
||||
F.update_brightness()
|
||||
|
||||
/obj/item/vending_refill/security
|
||||
icon_state = "snackorange"
|
||||
|
||||
Reference in New Issue
Block a user