Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into auxmos-2
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#define DISABLE_ARRIVALRATTLE (1<<13)
|
||||
#define COMBOHUD_LIGHTING (1<<14)
|
||||
#define SOUND_BARK (1<<15)
|
||||
#define NO_ANTAG (1<<16)
|
||||
|
||||
#define DEADMIN_ALWAYS (1<<0)
|
||||
#define DEADMIN_ANTAGONIST (1<<1)
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
#define NANITE_HUD "20"
|
||||
#define DIAG_NANITE_FULL_HUD "21"
|
||||
#define RAD_HUD "22" //radation alerts for medical huds
|
||||
#define DIAG_LAUNCHPAD_HUD "23" //Displays launchpads' targeting reticle
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define ANTAG_HUD "23"
|
||||
#define ANTAG_HUD "24"
|
||||
|
||||
//by default everything in the hud_list of an atom is an image
|
||||
//a value in hud_list with one of these will change that behavior
|
||||
|
||||
@@ -44,15 +44,12 @@
|
||||
#define ROLE_GHOSTCAFE "ghostcafe"
|
||||
#define ROLE_MINOR_ANTAG "minorantag"
|
||||
#define ROLE_RESPAWN "respawnsystem"
|
||||
/// Not an actual antag. Lets players force all antags off.
|
||||
#define ROLE_NO_ANTAGONISM "NO_ANTAGS"
|
||||
//Define for disabling individual antagonists for dynamic
|
||||
#define HAS_ANTAG_PREF(C,ROLE) (!(ROLE_NO_ANTAGONISM in C.prefs.be_special) && (ROLE in C.prefs.be_special))
|
||||
#define HAS_ANTAG_PREF(C,ROLE) (!(NO_ANTAG & C.prefs.toggles) && (ROLE in C.prefs.be_special))
|
||||
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
|
||||
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
|
||||
//(in game days played) to play that role
|
||||
GLOBAL_LIST_INIT(special_roles, list(
|
||||
ROLE_NO_ANTAGONISM,
|
||||
ROLE_TRAITOR = /datum/game_mode/traitor,
|
||||
ROLE_BROTHER = /datum/game_mode/traitor/bros,
|
||||
ROLE_OPERATIVE = /datum/game_mode/nuclear,
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#define CHANNEL_DIGEST 1009
|
||||
#define CHANNEL_PREYLOOP 1008
|
||||
|
||||
|
||||
//Reactor Channel
|
||||
#define CHANNEL_REACTOR_ALERT 1007 // Is that radiation I hear? (ported from hyper)
|
||||
|
||||
///Default range of a sound.
|
||||
#define SOUND_RANGE 17
|
||||
///default extra range for sounds considered to be quieter
|
||||
@@ -34,7 +38,7 @@
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1008 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1007 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS
|
||||
|
||||
#define MAX_INSTRUMENT_CHANNELS (128 * 6)
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/atom/proc/shake_animation(var/intensity = 8) //Makes the object visibly shake
|
||||
var/initial_transform = new/matrix(transform)
|
||||
var/init_px = pixel_x
|
||||
var/shake_dir = pick(-1, 1)
|
||||
var/rotation = 2+soft_cap(intensity, 1, 1, 0.94)
|
||||
var/offset = 1+soft_cap(intensity*0.3, 1, 1, 0.8)
|
||||
var/time = 2+soft_cap(intensity*0.3, 2, 1, 0.92)
|
||||
animate(src, transform=turn(transform, rotation*shake_dir), pixel_x=init_px + offset*shake_dir, time=1)
|
||||
animate(transform=initial_transform, pixel_x=init_px, time=time, easing=ELASTIC_EASING)
|
||||
|
||||
/*
|
||||
This proc makes the input taper off above cap. But there's no absolute cutoff.
|
||||
Chunks of the input value above cap, are reduced more and more with each successive one and added to the output
|
||||
A higher input value always makes a higher output value. but the rate of growth slows
|
||||
*/
|
||||
/proc/soft_cap(var/input, var/cap = 0, var/groupsize = 1, var/groupmult = 0.9)
|
||||
|
||||
//The cap is a ringfenced amount. If we're below that, just return the input
|
||||
if (input <= cap)
|
||||
return input
|
||||
|
||||
var/output = 0
|
||||
var/buffer = 0
|
||||
var/power = 1//We increment this after each group, then apply it to the groupmult as a power
|
||||
|
||||
//Ok its above, so the cap is a safe amount, we move that to the output
|
||||
input -= cap
|
||||
output += cap
|
||||
|
||||
//Now we start moving groups from input to buffer
|
||||
|
||||
|
||||
while (input > 0)
|
||||
buffer = min(input, groupsize) //We take the groupsize, or all the input has left if its less
|
||||
input -= buffer
|
||||
|
||||
buffer *= groupmult**power //This reduces the group by the groupmult to the power of which index we're on.
|
||||
//This ensures that each successive group is reduced more than the previous one
|
||||
|
||||
output += buffer
|
||||
power++ //Transfer to output, increment power, repeat until the input pile is all used
|
||||
|
||||
return output
|
||||
@@ -27,6 +27,10 @@
|
||||
/proc/radiation_pulse(atom/source, intensity, range_modifier, log=FALSE, can_contaminate=TRUE)
|
||||
if(!SSradiation.can_fire)
|
||||
return
|
||||
var/turf/open/pool/PL = get_turf(source)
|
||||
if(istype(PL))
|
||||
if(PL.filled == TRUE)
|
||||
intensity *= 0.15
|
||||
var/area/A = get_area(source)
|
||||
var/atom/nested_loc = source.loc
|
||||
var/spawn_waves = TRUE
|
||||
@@ -52,6 +56,5 @@
|
||||
thing.rad_act(intensity)
|
||||
|
||||
if(log)
|
||||
var/turf/_source_T = get_turf(source)
|
||||
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)][spawn_waves ? "" : " (contained by [nested_loc.name])"]")
|
||||
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(PL)][spawn_waves ? "" : " (contained by [nested_loc.name])"]")
|
||||
return TRUE
|
||||
|
||||
@@ -321,7 +321,7 @@ GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
|
||||
|
||||
//LANGUAGE CHARACTER CUSTOMIZATION
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks"))
|
||||
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien))
|
||||
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien/hybrid))
|
||||
|
||||
/proc/get_roundstart_languages()
|
||||
var/list/languages = subtypesof(/datum/language)
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#define ui_back "CENTER-2:14,SOUTH:5"
|
||||
#define ui_storage1 "CENTER+1:18,SOUTH:5"
|
||||
#define ui_storage2 "CENTER+2:20,SOUTH:5"
|
||||
#define ui_combo "CENTER+4:24,SOUTH+1:7" // combo meter for martial arts
|
||||
|
||||
//Lower right, persistent menu
|
||||
#define ui_drop_throw "EAST-1:28,SOUTH+1:7"
|
||||
|
||||
@@ -33,6 +33,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
var/atom/movable/screen/alien_plasma_display
|
||||
var/atom/movable/screen/alien_queen_finder
|
||||
|
||||
var/atom/movable/screen/combo/combo_display
|
||||
|
||||
var/atom/movable/screen/devil/soul_counter/devilsouldisplay
|
||||
|
||||
var/atom/movable/screen/synth/coolant_counter/coolant_display
|
||||
@@ -130,6 +132,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
blobpwrdisplay = null
|
||||
alien_plasma_display = null
|
||||
alien_queen_finder = null
|
||||
combo_display = null
|
||||
|
||||
QDEL_LIST_ASSOC_VAL(plane_masters)
|
||||
QDEL_LIST(screenoverlays)
|
||||
|
||||
@@ -461,6 +461,9 @@
|
||||
zone_select.update_icon()
|
||||
static_inventory += zone_select
|
||||
|
||||
combo_display = new /atom/movable/screen/combo()
|
||||
infodisplay += combo_display
|
||||
|
||||
for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory))
|
||||
if(inv.slot_id)
|
||||
inv.hud = src
|
||||
|
||||
@@ -720,3 +720,28 @@
|
||||
/atom/movable/screen/component_button/Click(params)
|
||||
if(parent)
|
||||
parent.component_click(src, params)
|
||||
|
||||
/atom/movable/screen/combo
|
||||
icon_state = ""
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
screen_loc = ui_combo
|
||||
layer = ABOVE_HUD_LAYER
|
||||
var/timerid
|
||||
|
||||
/atom/movable/screen/combo/proc/clear_streak()
|
||||
cut_overlays()
|
||||
icon_state = ""
|
||||
|
||||
/atom/movable/screen/combo/update_icon_state(streak = "")
|
||||
clear_streak()
|
||||
if (timerid)
|
||||
deltimer(timerid)
|
||||
if (!streak)
|
||||
return
|
||||
timerid = addtimer(CALLBACK(src, .proc/clear_streak), 20, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
icon_state = "combo"
|
||||
for (var/i = 1; i <= length(streak); ++i)
|
||||
var/intent_text = copytext(streak, i, i + 1)
|
||||
var/image/intent_icon = image(icon,src,"combo_[intent_text]")
|
||||
intent_icon.pixel_x = 16 * (i - 1) - 8 * length(streak)
|
||||
add_overlay(intent_icon)
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
/datum/atom_hud/data/diagnostic
|
||||
|
||||
/datum/atom_hud/data/diagnostic/basic
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD)
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_LAUNCHPAD_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic/advanced
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_PATH_HUD)
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_PATH_HUD,DIAG_LAUNCHPAD_HUD)
|
||||
|
||||
/datum/atom_hud/data/bot_path
|
||||
hud_icons = list(DIAG_PATH_HUD)
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
SUBSYSTEM_DEF(pai)
|
||||
name = "pAI"
|
||||
|
||||
flags = SS_NO_INIT|SS_NO_FIRE
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/candidates = list()
|
||||
var/ghost_spam = FALSE
|
||||
var/spam_delay = 100
|
||||
var/list/pai_card_list = list()
|
||||
var/list/restricted_areas = list()
|
||||
|
||||
/datum/controller/subsystem/pai/Initialize(var/time_of_day)
|
||||
restricted_areas += typesof(/area/command/heads_quarters, /area/ai_monitored) // heads quarters and AI monitored places (like the armory)
|
||||
initialized = TRUE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/pai/Topic(href, href_list)
|
||||
if(href_list["download"])
|
||||
|
||||
@@ -119,3 +119,8 @@
|
||||
// volume = 70
|
||||
// falloff_distance = 5
|
||||
// falloff_exponent = 20
|
||||
|
||||
/datum/looping_sound/rbmk_reactor
|
||||
mid_length = 16
|
||||
mid_sounds = list('sound/effects/rbmk/reactor_hum.ogg' = 10)
|
||||
volume = 10
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
/// Set this variable to something not null, this'll be the preferred unarmed parry in most cases if [can_martial_parry] is TRUE. YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
var/datum/block_parry_data/block_parry_data
|
||||
var/pugilist = FALSE
|
||||
var/datum/weakref/holder //owner of the martial art
|
||||
var/display_combos = FALSE //shows combo meter if true
|
||||
|
||||
/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
return FALSE
|
||||
@@ -25,7 +27,7 @@
|
||||
/datum/martial_art/proc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
return FALSE
|
||||
|
||||
/datum/martial_art/proc/can_use(mob/living/carbon/human/H)
|
||||
/datum/martial_art/proc/can_use(mob/living/carbon/human/owner_human)
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/proc/add_to_streak(element,mob/living/carbon/human/D)
|
||||
@@ -34,11 +36,16 @@
|
||||
streak = streak+element
|
||||
if(length(streak) > max_streak_length)
|
||||
streak = copytext(streak, 1 + length(streak[1]))
|
||||
if(display_combos)
|
||||
var/mob/living/holder_living = holder.resolve()
|
||||
holder_living?.hud_used?.combo_display.update_icon_state(streak)
|
||||
return
|
||||
|
||||
/datum/martial_art/proc/reset_streak(mob/living/carbon/human/new_target)
|
||||
current_target = new_target
|
||||
streak = ""
|
||||
var/mob/living/holder_living = holder.resolve()
|
||||
holder_living?.hud_used?.combo_display.update_icon_state(streak)
|
||||
|
||||
/datum/martial_art/proc/damage_roll(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
//Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode.
|
||||
@@ -47,46 +54,48 @@
|
||||
damage *= 0.7
|
||||
return damage
|
||||
|
||||
/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE)
|
||||
if(!istype(H) || !H.mind)
|
||||
/datum/martial_art/proc/teach(mob/living/carbon/human/owner_human, make_temporary = FALSE)
|
||||
if(!istype(owner_human) || !owner_human.mind)
|
||||
return FALSE
|
||||
if(H.mind.martial_art)
|
||||
if(owner_human.mind.martial_art)
|
||||
if(make_temporary)
|
||||
if(!H.mind.martial_art.allow_temp_override)
|
||||
if(!owner_human.mind.martial_art.allow_temp_override)
|
||||
return FALSE
|
||||
store(H.mind.martial_art,H)
|
||||
store(owner_human.mind.martial_art,owner_human)
|
||||
else
|
||||
H.mind.martial_art.on_remove(H)
|
||||
owner_human.mind.martial_art.on_remove(owner_human)
|
||||
else if(make_temporary)
|
||||
base = H.mind.default_martial_art
|
||||
base = owner_human.mind.default_martial_art
|
||||
if(help_verb)
|
||||
add_verb(H, help_verb)
|
||||
H.mind.martial_art = src
|
||||
add_verb(owner_human, help_verb)
|
||||
owner_human.mind.martial_art = src
|
||||
holder = WEAKREF(owner_human)
|
||||
if(pugilist)
|
||||
ADD_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
|
||||
ADD_TRAIT(owner_human, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/proc/store(datum/martial_art/M,mob/living/carbon/human/H)
|
||||
M.on_remove(H)
|
||||
/datum/martial_art/proc/store(datum/martial_art/M,mob/living/carbon/human/owner_human)
|
||||
M.on_remove(owner_human)
|
||||
if(M.base) //Checks if M is temporary, if so it will not be stored.
|
||||
base = M.base
|
||||
else //Otherwise, M is stored.
|
||||
base = M
|
||||
|
||||
/datum/martial_art/proc/remove(mob/living/carbon/human/H)
|
||||
if(!istype(H) || !H.mind || H.mind.martial_art != src)
|
||||
/datum/martial_art/proc/remove(mob/living/carbon/human/owner_human)
|
||||
if(!istype(owner_human) || !owner_human.mind || owner_human.mind.martial_art != src)
|
||||
return
|
||||
on_remove(H)
|
||||
on_remove(owner_human)
|
||||
if(base)
|
||||
base.teach(H)
|
||||
base.teach(owner_human)
|
||||
else
|
||||
var/datum/martial_art/X = H.mind.default_martial_art
|
||||
X.teach(H)
|
||||
REMOVE_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
|
||||
var/datum/martial_art/X = owner_human.mind.default_martial_art
|
||||
X.teach(owner_human)
|
||||
REMOVE_TRAIT(owner_human, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
|
||||
holder = null
|
||||
|
||||
/datum/martial_art/proc/on_remove(mob/living/carbon/human/H)
|
||||
/datum/martial_art/proc/on_remove(mob/living/carbon/human/owner_human)
|
||||
if(help_verb)
|
||||
remove_verb(H, help_verb)
|
||||
remove_verb(owner_human, help_verb)
|
||||
return
|
||||
|
||||
///Gets called when a projectile hits the owner. Returning anything other than BULLET_ACT_HIT will stop the projectile from hitting the mob.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
block_chance = 75
|
||||
pugilist = TRUE
|
||||
var/old_grab_state = null
|
||||
display_combos = TRUE
|
||||
|
||||
/datum/martial_art/cqc/reset_streak(mob/living/carbon/human/new_target)
|
||||
. = ..()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
id = MARTIALART_PLASMAFIST
|
||||
help_verb = /mob/living/carbon/human/proc/plasma_fist_help
|
||||
pugilist = TRUE
|
||||
display_combos = TRUE
|
||||
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/datum/action/risingbassmove/sidekick = new/datum/action/risingbassmove/sidekick()
|
||||
var/datum/action/risingbassmove/deftswitch = new/datum/action/risingbassmove/deftswitch()
|
||||
var/repulsecool = 0
|
||||
display_combos = TRUE
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,SIDE_KICK_COMBO))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
|
||||
block_parry_data = /datum/block_parry_data/sleeping_carp
|
||||
pugilist = TRUE
|
||||
display_combos = TRUE
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,STRONG_PUNCH_COMBO))
|
||||
|
||||
@@ -55,6 +55,11 @@
|
||||
suffix = "Box/Engine/budget.dmm"
|
||||
name = "Box P.A.C.M.A.N"
|
||||
|
||||
/datum/map_template/ruin/station/box/engine/rbmk
|
||||
id = "engine_rbmk"
|
||||
suffix = "Box/Engine/engine_rbmk.dmm"
|
||||
name = "Box RBMK"
|
||||
|
||||
// Lavaland
|
||||
// Mining Base
|
||||
/datum/map_template/ruin/station/lavaland/mining_base
|
||||
|
||||
@@ -864,6 +864,10 @@
|
||||
return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
|
||||
|
||||
/atom/proc/rad_act(strength)
|
||||
var/turf/open/pool/PL = get_turf(src)
|
||||
if(istype(PL))
|
||||
if(PL.filled == TRUE)
|
||||
strength *= 0.15
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength)
|
||||
|
||||
/atom/proc/narsie_act()
|
||||
|
||||
@@ -210,10 +210,6 @@
|
||||
candidates.Remove(candidate_player)
|
||||
continue
|
||||
|
||||
if(ROLE_NO_ANTAGONISM in candidate_player.client.prefs.be_special)
|
||||
candidates.Remove(candidate_player)
|
||||
continue
|
||||
|
||||
if(antag_flag_override)
|
||||
if(!(HAS_ANTAG_PREF(candidate_player.client, antag_flag_override)))
|
||||
candidates.Remove(candidate_player)
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
candidates.Remove(P)
|
||||
else if((exclusive_roles.len > 0) && !(P.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job?
|
||||
candidates.Remove(P)
|
||||
else if(ROLE_NO_ANTAGONISM in P.client.prefs.be_special)
|
||||
candidates.Remove(P)
|
||||
else if(antag_flag_override)
|
||||
if(!(HAS_ANTAG_PREF(P.client, antag_flag_override)))
|
||||
candidates.Remove(P)
|
||||
|
||||
@@ -46,9 +46,6 @@
|
||||
if(!mode.check_age(M.client, minimum_required_age))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(ROLE_NO_ANTAGONISM in M.client.prefs.be_special)
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(antag_flag_override)
|
||||
if(!(HAS_ANTAG_PREF(M.client, antag_flag_override)))
|
||||
trimmed_list.Remove(M)
|
||||
|
||||
@@ -348,8 +348,9 @@
|
||||
var/list/curr_tickets = list() //how many tickets someone has for *this* antag roll, so with the free tickets
|
||||
var/list/datum/mind/insufficient = list() //who got cucked out of an antag roll due to not having *any* tickets
|
||||
for(var/datum/mind/M in candidates)
|
||||
var/weight = clamp(candidates[M], 0, 1)
|
||||
var/mind_ckey = ckey(M.key)
|
||||
var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll
|
||||
var/can_spend = min(prev_tickets[mind_ckey], additional_tickets * weight) //they can only spend up to config/max_tickets_per_roll
|
||||
var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free
|
||||
if(amount <= 0) //if they don't have any
|
||||
insufficient += M //too bad!
|
||||
@@ -425,10 +426,11 @@
|
||||
|
||||
for(var/mob/dead/new_player/player in players)
|
||||
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
|
||||
if((role in player.client.prefs.be_special) && !(ROLE_NO_ANTAGONISM in player.client.prefs.be_special))
|
||||
if(HAS_ANTAG_PREF(player.client, role))
|
||||
if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans
|
||||
if(age_check(player.client)) //Must be older than the minimum age
|
||||
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
|
||||
candidates[player.mind] = player.client.prefs.be_special[role]
|
||||
|
||||
if(restricted_jobs)
|
||||
for(var/datum/mind/player in candidates)
|
||||
@@ -449,35 +451,11 @@
|
||||
if(player.assigned_role == job)
|
||||
drafted -= player
|
||||
|
||||
drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie
|
||||
|
||||
while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates
|
||||
if(drafted.len > 0)
|
||||
applicant = pick(drafted)
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
drafted.Remove(applicant)
|
||||
|
||||
else // Not enough scrubs, ABORT ABORT ABORT
|
||||
break
|
||||
|
||||
if(restricted_jobs)
|
||||
for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist
|
||||
for(var/job in restricted_jobs)
|
||||
if(player.assigned_role == job)
|
||||
drafted -= player
|
||||
|
||||
drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie
|
||||
|
||||
while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates
|
||||
if(drafted.len > 0)
|
||||
applicant = pick(drafted)
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
drafted.Remove(applicant)
|
||||
|
||||
else // Not enough scrubs, ABORT ABORT ABORT
|
||||
break
|
||||
while(candidates.len < recommended_enemies && length(drafted)) // Pick randomlly just the number of people we need and add them to our list of candidates
|
||||
applicant = pick_n_take(drafted)
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
candidates[applicant] = 0
|
||||
|
||||
return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies
|
||||
// recommended_enemies if the number of people with that role set to yes is less than recomended_enemies,
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
var/new_x = text2num(params["x"])
|
||||
var/new_y = text2num(params["y"])
|
||||
current_pad.set_offset(new_x, new_y)
|
||||
current_pad.update_indicator()
|
||||
. = TRUE
|
||||
if("move_pos")
|
||||
var/plus_x = text2num(params["x"])
|
||||
@@ -108,6 +109,7 @@
|
||||
x = current_pad.x_offset + plus_x,
|
||||
y = current_pad.y_offset + plus_y
|
||||
)
|
||||
current_pad.update_indicator()
|
||||
. = TRUE
|
||||
if("rename")
|
||||
. = TRUE
|
||||
@@ -119,12 +121,15 @@
|
||||
if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort")
|
||||
launchpads -= current_pad
|
||||
selected_id = null
|
||||
current_pad.update_indicator()
|
||||
. = TRUE
|
||||
if("launch")
|
||||
teleport(usr, current_pad, TRUE)
|
||||
current_pad.update_indicator()
|
||||
. = TRUE
|
||||
|
||||
if("pull")
|
||||
teleport(usr, current_pad, FALSE)
|
||||
current_pad.update_indicator()
|
||||
. = TRUE
|
||||
. = TRUE
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
use_power = TRUE
|
||||
idle_power_usage = 200
|
||||
active_power_usage = 2500
|
||||
hud_possible = list(DIAG_LAUNCHPAD_HUD)
|
||||
circuit = /obj/item/circuitboard/machine/launchpad
|
||||
var/icon_teleport = "lpad-beam"
|
||||
var/stationary = TRUE //to prevent briefcase pad deconstruction and such
|
||||
@@ -24,6 +25,25 @@
|
||||
E += M.rating*15
|
||||
range = E
|
||||
|
||||
/obj/machinery/launchpad/Initialize()
|
||||
. = ..()
|
||||
prepare_huds()
|
||||
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
|
||||
diag_hud.add_to_hud(src)
|
||||
|
||||
var/image/holder = hud_list[DIAG_LAUNCHPAD_HUD]
|
||||
var/mutable_appearance/MA = new /mutable_appearance()
|
||||
MA.icon = 'icons/effects/effects.dmi'
|
||||
MA.icon_state = "launchpad_target"
|
||||
MA.layer = ABOVE_OPEN_TURF_LAYER
|
||||
MA.plane = 0
|
||||
holder.appearance = MA
|
||||
update_indicator()
|
||||
|
||||
/obj/machinery/launchpad/Destroy()
|
||||
qdel(hud_list[DIAG_LAUNCHPAD_HUD])
|
||||
return ..()
|
||||
|
||||
/obj/machinery/launchpad/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
@@ -32,6 +52,7 @@
|
||||
/obj/machinery/launchpad/attackby(obj/item/I, mob/user, params)
|
||||
if(stationary)
|
||||
if(default_deconstruction_screwdriver(user, "lpad-idle-o", "lpad-idle", I))
|
||||
update_indicator()
|
||||
return
|
||||
|
||||
if(panel_open)
|
||||
@@ -63,6 +84,17 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/launchpad/proc/update_indicator()
|
||||
var/image/holder = hud_list[DIAG_LAUNCHPAD_HUD]
|
||||
var/turf/target_turf
|
||||
if(isAvailable())
|
||||
target_turf = locate(x + x_offset, y + y_offset, z)
|
||||
if(target_turf)
|
||||
holder.icon_state = indicator_icon
|
||||
holder.loc = target_turf
|
||||
else
|
||||
holder.icon_state = null
|
||||
|
||||
/obj/machinery/launchpad/proc/set_offset(x, y)
|
||||
if(teleporting)
|
||||
return
|
||||
@@ -89,11 +121,13 @@
|
||||
|
||||
flick(icon_teleport, src)
|
||||
|
||||
|
||||
//Change the indicator's icon to show that we're teleporting
|
||||
if(sending)
|
||||
indicator_icon = "launchpad_launch"
|
||||
else
|
||||
indicator_icon = "launchpad_pull"
|
||||
update_indicator()
|
||||
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, TRUE)
|
||||
teleporting = TRUE
|
||||
@@ -103,6 +137,7 @@
|
||||
|
||||
//Set the indicator icon back to normal
|
||||
indicator_icon = "launchpad_target"
|
||||
update_indicator()
|
||||
|
||||
if(QDELETED(src) || !isAvailable())
|
||||
return
|
||||
@@ -213,6 +248,7 @@
|
||||
if(do_after(usr, 30, target = usr))
|
||||
usr.put_in_hands(briefcase)
|
||||
moveToNullspace() //hides it from suitcase contents
|
||||
update_indicator()
|
||||
closed = TRUE
|
||||
|
||||
/obj/machinery/launchpad/briefcase/attackby(obj/item/I, mob/user, params)
|
||||
@@ -249,6 +285,7 @@
|
||||
user.visible_message("<span class='notice'>[user] starts setting down [src]...", "You start setting up [pad]...</span>")
|
||||
if(do_after(user, 30, target = user))
|
||||
pad.forceMove(get_turf(src))
|
||||
pad.update_indicator()
|
||||
pad.closed = FALSE
|
||||
user.transferItemToLoc(src, pad, TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
@@ -322,6 +359,7 @@
|
||||
var/new_x = text2num(params["x"])
|
||||
var/new_y = text2num(params["y"])
|
||||
pad.set_offset(new_x, new_y)
|
||||
pad.update_indicator()
|
||||
. = TRUE
|
||||
if("move_pos")
|
||||
var/plus_x = text2num(params["x"])
|
||||
@@ -330,6 +368,7 @@
|
||||
x = pad.x_offset + plus_x,
|
||||
y = pad.y_offset + plus_y
|
||||
)
|
||||
pad.update_indicator()
|
||||
. = TRUE
|
||||
if("rename")
|
||||
. = TRUE
|
||||
@@ -340,12 +379,15 @@
|
||||
if("remove")
|
||||
. = TRUE
|
||||
if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort")
|
||||
pad.update_indicator()
|
||||
pad = null
|
||||
if("launch")
|
||||
sending = TRUE
|
||||
teleport(usr, pad)
|
||||
pad.update_indicator()
|
||||
. = TRUE
|
||||
if("pull")
|
||||
sending = FALSE
|
||||
teleport(usr, pad)
|
||||
pad.update_indicator()
|
||||
. = TRUE
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//ported from TG, credit to XDTM
|
||||
/obj/item/swapper
|
||||
name = "quantum spin inverter"
|
||||
desc = "An experimental device that is able to swap the locations of two entities by switching their particles' spin values. Must be linked to another device to function."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "swapper"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = NOBLUDGEON
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
|
||||
var/cooldown = 300
|
||||
var/next_use = 0
|
||||
var/obj/item/swapper/linked_swapper
|
||||
|
||||
/obj/item/swapper/Destroy()
|
||||
if(linked_swapper)
|
||||
linked_swapper.linked_swapper = null //*inception music*
|
||||
linked_swapper.update_appearance()
|
||||
linked_swapper = null
|
||||
return ..()
|
||||
|
||||
/obj/item/swapper/update_icon_state()
|
||||
icon_state = "swapper[linked_swapper ? "-linked" : null]"
|
||||
return ..()
|
||||
|
||||
/obj/item/swapper/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/swapper))
|
||||
var/obj/item/swapper/other_swapper = I
|
||||
if(other_swapper.linked_swapper)
|
||||
to_chat(user, span_warning("[other_swapper] is already linked. Break the current link to establish a new one."))
|
||||
return
|
||||
if(linked_swapper)
|
||||
to_chat(user, span_warning("[src] is already linked. Break the current link to establish a new one."))
|
||||
return
|
||||
to_chat(user, span_notice("You establish a quantum link between the two devices."))
|
||||
linked_swapper = other_swapper
|
||||
other_swapper.linked_swapper = src
|
||||
update_appearance()
|
||||
linked_swapper.update_appearance()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/swapper/attack_self(mob/living/user)
|
||||
if(world.time < next_use)
|
||||
to_chat(user, span_warning("[src] is still recharging."))
|
||||
return
|
||||
if(QDELETED(linked_swapper))
|
||||
to_chat(user, span_warning("[src] is not linked with another swapper."))
|
||||
return
|
||||
playsound(src, 'sound/weapons/flash.ogg', 25, TRUE)
|
||||
to_chat(user, span_notice("You activate [src]."))
|
||||
playsound(linked_swapper, 'sound/weapons/flash.ogg', 25, TRUE)
|
||||
if(ismob(linked_swapper.loc))
|
||||
var/mob/holder = linked_swapper.loc
|
||||
to_chat(holder, span_notice("[linked_swapper] starts buzzing."))
|
||||
next_use = world.time + cooldown //only the one used goes on cooldown
|
||||
addtimer(CALLBACK(src, .proc/swap, user), 25)
|
||||
|
||||
/obj/item/swapper/examine(mob/user)
|
||||
. = ..()
|
||||
if(world.time < next_use)
|
||||
. += span_warning("Time left to recharge: [DisplayTimeText(next_use - world.time)].")
|
||||
if(linked_swapper)
|
||||
. += span_notice("<b>Linked.</b> Alt-Click to break the quantum link.")
|
||||
else
|
||||
. += span_notice("<b>Not Linked.</b> Use on another quantum spin inverter to establish a quantum link.")
|
||||
|
||||
/obj/item/swapper/AltClick(mob/living/user)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERY,, FALSE, !iscyborg(user))) //someone mispelled dexterity
|
||||
return
|
||||
to_chat(user, span_notice("You break the current quantum link."))
|
||||
if(!QDELETED(linked_swapper))
|
||||
linked_swapper.linked_swapper = null
|
||||
linked_swapper.update_appearance()
|
||||
linked_swapper = null
|
||||
update_appearance()
|
||||
|
||||
//Gets the topmost teleportable container
|
||||
/obj/item/swapper/proc/get_teleportable_container()
|
||||
var/atom/movable/teleportable = src
|
||||
while(ismovable(teleportable.loc))
|
||||
var/atom/movable/AM = teleportable.loc
|
||||
if(AM.anchored)
|
||||
break
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.buckled)
|
||||
if(L.buckled.anchored)
|
||||
break
|
||||
else
|
||||
var/obj/buckled_obj = L.buckled
|
||||
buckled_obj.unbuckle_mob(L)
|
||||
teleportable = AM
|
||||
return teleportable
|
||||
|
||||
/obj/item/swapper/proc/swap(mob/user)
|
||||
if(QDELETED(linked_swapper) || world.time < linked_swapper.cooldown)
|
||||
return
|
||||
|
||||
var/atom/movable/A = get_teleportable_container()
|
||||
var/atom/movable/B = linked_swapper.get_teleportable_container()
|
||||
var/target_A = A.drop_location()
|
||||
var/target_B = B.drop_location()
|
||||
|
||||
//TODO: add a sound effect or visual effect
|
||||
if(do_teleport(A, target_B, channel = TELEPORT_CHANNEL_QUANTUM))
|
||||
do_teleport(B, target_A, channel = TELEPORT_CHANNEL_QUANTUM)
|
||||
if(ismob(B))
|
||||
var/mob/M = B
|
||||
to_chat(M, span_warning("[linked_swapper] activates, and you find yourself somewhere else."))
|
||||
@@ -494,6 +494,38 @@
|
||||
title = "Toxins or: How I Learned to Stop Worrying and Love the Maxcap"
|
||||
page_link = "Guide_to_toxins"
|
||||
|
||||
/obj/item/book/manual/wiki/rbmk
|
||||
name = "\improper Haynes nuclear reactor owner's manual"
|
||||
icon_state = "bookEngineering2"
|
||||
author = "CogWerk Engineering Reactor Design Department"
|
||||
title = "Haynes nuclear reactor owner's manual"
|
||||
page_link = "Guide_to_the_Nuclear_Reactor"
|
||||
|
||||
/obj/item/book/manual/wiki/rbmk/initialize_wikibook()
|
||||
var/wikiurl = "https://nsv.beestation13.com/wiki"
|
||||
if(wikiurl)
|
||||
dat = {"
|
||||
<html><head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<style>
|
||||
iframe {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
function pageloaded(myframe) {
|
||||
document.getElementById("loading").style.display = "none";
|
||||
myframe.style.display = "inline";
|
||||
}
|
||||
</script>
|
||||
<p id='loading'>You start skimming through the manual...</p>
|
||||
<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>
|
||||
"}
|
||||
|
||||
/obj/item/book/manual/wiki/toxins/suicide_act(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
user.visible_message("<span class='suicide'>[user] starts dancing to the Rhumba Beat! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
@@ -664,7 +664,7 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
if(disk_comfort_level >= 2) //Sleep tight, disky.
|
||||
if(!(process_tick % 30))
|
||||
visible_message("<span class='notice'>[src] sleeps soundly. Sleep tight, disky.</span>")
|
||||
if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001))
|
||||
if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001 / max(disk_comfort_level,1)))
|
||||
var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control
|
||||
if(istype(loneop) && loneop.occurrences < loneop.max_occurrences)
|
||||
loneop.weight += 1
|
||||
|
||||
@@ -117,7 +117,8 @@
|
||||
if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
to_chat(src,"<span class='userlove'>You used your [G.name] to fill [container].</span>")
|
||||
message_admins("[src] used their [G.name] to fill [container].")
|
||||
message_admins("[ADMIN_LOOKUPFLW(src)] used their [G.name] to fill [container].")
|
||||
log_consent("[key_name(src)] used their [G.name] to fill [container].")
|
||||
do_climax(fluid_source, container, G, FALSE)
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_genitals(silent = FALSE)
|
||||
@@ -159,8 +160,8 @@
|
||||
if(consenting == "Yes")
|
||||
return target
|
||||
else
|
||||
message_admins("[src] tried to climax with [target], but [target] did not consent.")
|
||||
log_consent("[src] tried to climax with [target], but [target] did not consent.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(src)] tried to climax with [target], but [target] did not consent.")
|
||||
log_consent("[key_name(src)] tried to climax with [target], but [target] did not consent.")
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_container(silent = FALSE)
|
||||
var/list/containers_list = list()
|
||||
|
||||
@@ -280,11 +280,7 @@ we use a hook instead
|
||||
parse_gas_string(model.initial_gas_mix)
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/__auxtools_parse_gas_string(gas_string)
|
||||
|
||||
/datum/gas_mixture/parse_gas_string(gas_string)
|
||||
__auxtools_parse_gas_string(gas_string)
|
||||
/*
|
||||
gas_string = SSair.preprocess_gas_string(gas_string)
|
||||
|
||||
var/list/gas = params2list(gas_string)
|
||||
@@ -298,7 +294,6 @@ we use a hook instead
|
||||
for(var/id in gas)
|
||||
set_moles(id, text2num(gas[id]))
|
||||
archive()
|
||||
*/
|
||||
return 1
|
||||
/*
|
||||
/datum/gas_mixture/react(datum/holder)
|
||||
|
||||
@@ -69,8 +69,6 @@
|
||||
|
||||
// no test cause it's entirely based on location
|
||||
|
||||
GLOBAL_VAR_INIT(condensation_priority, 0)
|
||||
|
||||
/datum/gas_reaction/condensation
|
||||
priority = 0
|
||||
name = "Condensation"
|
||||
@@ -89,8 +87,6 @@ GLOBAL_VAR_INIT(condensation_priority, 0)
|
||||
name = "[R.name] condensation"
|
||||
id = "[R.type] condensation"
|
||||
condensing_reagent = GLOB.chemical_reagents_list[R.type]
|
||||
GLOB.condensation_priority += 0.000000000001
|
||||
priority = GLOB.condensation_priority
|
||||
exclude = FALSE
|
||||
|
||||
/datum/gas_reaction/condensation/react(datum/gas_mixture/air, datum/holder)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/datum/export/plutonium_rod
|
||||
cost = 20000
|
||||
unit_name = "Plutonium Rod"
|
||||
export_types = list(/obj/item/fuel_rod/plutonium)
|
||||
@@ -158,6 +158,14 @@
|
||||
/obj/item/clothing/head/hardhat/red)
|
||||
crate_name = "firefighting crate"
|
||||
|
||||
/datum/supply_pack/emergency/Flexiseal
|
||||
name = "Flexi Seal Crate"
|
||||
desc = "Flexi Seal, the perfect stuff for fixing a nuclear reactor safely!"
|
||||
cost = 1000
|
||||
contains = list(/obj/item/sealant)
|
||||
crate_name = "Flexi Seal Crate"
|
||||
crate_type = /obj/structure/closet/crate/radiation
|
||||
|
||||
/datum/supply_pack/emergency/atmostank
|
||||
name = "Firefighting Tank Backpack"
|
||||
desc = "Mow down fires with this high-capacity fire fighting tank backpack. Requires Atmospherics access to open."
|
||||
|
||||
@@ -166,3 +166,40 @@
|
||||
cost = 7000
|
||||
contains = list(/obj/machinery/the_singularitygen/tesla)
|
||||
crate_name = "tesla generator crate"
|
||||
/datum/supply_pack/engine/fuel_rod
|
||||
name = "Uranium Fuel Rod crate"
|
||||
desc = "Two additional fuel rods for use in a reactor, requires CE access to open. Caution: Radioactive"
|
||||
cost = 3000
|
||||
access = ACCESS_CE
|
||||
contains = list(/obj/item/fuel_rod,
|
||||
/obj/item/fuel_rod)
|
||||
crate_name = "Uranium-235 Fuel Rod crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
dangerous = TRUE
|
||||
|
||||
/datum/supply_pack/engine/bananium_fuel_rod
|
||||
name = "Bananium Fuel Rod crate"
|
||||
desc = "Two fuel rods designed to utilize and multiply bananium in a reactor, requires CE access to open. Caution: Radioactive"
|
||||
cost = 4000
|
||||
access = ACCESS_CE // Nag your local CE
|
||||
contains = list(/obj/item/fuel_rod/material/bananium,
|
||||
/obj/item/fuel_rod/material/bananium)
|
||||
crate_name = "Bluespace Crystal Fuel Rod crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
dangerous = TRUE
|
||||
contraband = TRUE
|
||||
|
||||
/datum/supply_pack/engine/reactor
|
||||
name = "RMBK Nuclear Reactor Kit" // (not) a toy
|
||||
desc = "Contains a reactor beacon and 3 reactor consoles. Uranium rods not included."
|
||||
cost = 12000
|
||||
access = ACCESS_CE
|
||||
contains = list(/obj/item/survivalcapsule/reactor,
|
||||
/obj/machinery/computer/reactor/control_rods/cargo,
|
||||
/obj/machinery/computer/reactor/stats/cargo,
|
||||
/obj/machinery/computer/reactor/fuel_rods/cargo,
|
||||
/obj/item/paper/fluff/rbmkcargo,
|
||||
/obj/item/book/manual/wiki/rbmk)
|
||||
crate_name = "Build Your Own Reactor Kit"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
dangerous = TRUE
|
||||
|
||||
@@ -1005,11 +1005,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<font color=red><b>You are banned from antagonist roles.</b></font>"
|
||||
src.be_special = list()
|
||||
|
||||
dat += "<b>DISABLE ALL ANTAGONISM</b> <a href='?_src_=prefs;preference=disable_antag'>[(toggles & NO_ANTAG) ? "YES" : "NO"]</a><br>"
|
||||
|
||||
for (var/i in GLOB.special_roles)
|
||||
if(i == ROLE_NO_ANTAGONISM)
|
||||
dat += "<b>DISABLE ALL ANTAGONISM</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "YES" : "NO"]</a><br>"
|
||||
continue
|
||||
if(jobban_isbanned(user, i))
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;jobbancheck=[i]'>BANNED</a><br>"
|
||||
else
|
||||
@@ -1022,7 +1020,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(days_remaining)
|
||||
dat += "<b>Be [capitalize(i)]:</b> <font color=red> \[IN [days_remaining] DAYS]</font><br>"
|
||||
else
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Enabled" : "Disabled"]</a><br>"
|
||||
var/enabled_text = ""
|
||||
if(i in be_special)
|
||||
if(be_special[i] >= 1)
|
||||
enabled_text = "Enabled"
|
||||
else
|
||||
enabled_text = "Low"
|
||||
else
|
||||
enabled_text = "Disabled"
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[enabled_text]</a><br>"
|
||||
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
|
||||
|
||||
dat += "<br>"
|
||||
@@ -2936,12 +2942,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
deadmin ^= DEADMIN_POSITION_SILICON
|
||||
//
|
||||
|
||||
if("disable_antag")
|
||||
toggles ^= NO_ANTAG
|
||||
|
||||
if("be_special")
|
||||
var/be_special_type = href_list["be_special_type"]
|
||||
if(be_special_type in be_special)
|
||||
be_special -= be_special_type
|
||||
if(be_special[be_special_type] >= 1)
|
||||
be_special -= be_special_type
|
||||
else
|
||||
be_special[be_special_type] = 1
|
||||
else
|
||||
be_special += be_special_type
|
||||
be_special[be_special_type] = 0
|
||||
|
||||
if("name")
|
||||
be_random_name = !be_random_name
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 55
|
||||
#define SAVEFILE_VERSION_MAX 56
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -42,14 +42,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
//if your savefile is 3 months out of date, then 'tough shit'.
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
if(current_version < 55) //Bitflag toggles don't set their defaults when they're added, always defaulting to off instead.
|
||||
toggles |= SOUND_BARK
|
||||
if(current_version < 46) //If you remove this, remove force_reset_keybindings() too.
|
||||
force_reset_keybindings_direct(TRUE)
|
||||
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
|
||||
if(current_version < 30)
|
||||
outline_enabled = TRUE
|
||||
outline_color = COLOR_THEME_MIDNIGHT
|
||||
if(current_version < 46) //If you remove this, remove force_reset_keybindings() too.
|
||||
force_reset_keybindings_direct(TRUE)
|
||||
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
|
||||
if(current_version < 55) //Bitflag toggles don't set their defaults when they're added, always defaulting to off instead.
|
||||
toggles |= SOUND_BARK
|
||||
if(current_version < 56)
|
||||
if("NO_ANTAGS" in be_special)
|
||||
toggles |= NO_ANTAG
|
||||
be_special -= "NO_ANTAGS"
|
||||
for(var/be_special_type in be_special)
|
||||
be_special[be_special_type] = 1
|
||||
|
||||
/datum/preferences/proc/update_character(current_version, savefile/S)
|
||||
if(current_version < 19)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
/datum/round_event/ghost_role/alien_infestation/announce(fake)
|
||||
if(successSpawn || fake)
|
||||
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens")
|
||||
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens", has_important_message = TRUE)
|
||||
|
||||
|
||||
/datum/round_event/ghost_role/alien_infestation/spawn_role()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
CRASH("Anomaly : No valid turfs found for [impact_area] - [impact_area.type]")
|
||||
|
||||
/datum/round_event/anomaly/announce(fake)
|
||||
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
|
||||
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/anomaly/start()
|
||||
var/list/turf/valid = list()
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/bluespace
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/announce(fake)
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE)
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
anomaly_path = /obj/effect/anomaly/flux
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/announce(fake)
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE)
|
||||
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/grav
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/announce(fake)
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE)
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/pyro
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro/announce(fake)
|
||||
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE)
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
anomaly_path = /obj/effect/anomaly/bhole
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/announce(fake)
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert", has_important_message = TRUE)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/datum/round_event/ghost_role/blob/announce(fake)
|
||||
if(prob(75))
|
||||
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5")
|
||||
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5", has_important_message = TRUE)
|
||||
else
|
||||
print_command_report("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "level 5 biohazard")
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
source = initial(example.name)
|
||||
else if(originMachine)
|
||||
source = originMachine.name
|
||||
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert")
|
||||
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/brand_intelligence/start()
|
||||
for(var/obj/machinery/vending/V in GLOB.machines)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/datum/round_event/cat_surgeon/announce(fake)
|
||||
priority_announce("One of our... ahem... 'special' cases has escaped. As it happens their last known location before their tracker went dead is your station so keep an eye out for them. On an unrelated note, has anyone seen our cats?",
|
||||
sender_override = "Nanotrasen Psych Ward")
|
||||
sender_override = "Nanotrasen Psych Ward", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/cat_surgeon/start()
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/sandstorm/announce(fake)
|
||||
priority_announce("The station is passing through a heavy debris cloud. Watch out for breaches.", "Collision Alert")
|
||||
priority_announce("The station is passing through a heavy debris cloud. Watch out for breaches.", "Collision Alert", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/sandstorm/tick()
|
||||
spawn_meteors(rand(6,10), GLOB.meteorsC)
|
||||
|
||||
@@ -27,7 +27,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
announceWhen = 5
|
||||
|
||||
/datum/round_event/immovable_rod/announce(fake)
|
||||
priority_announce("What the fuck was that?!", "General Alert")
|
||||
priority_announce("What the fuck was that?!", "General Alert", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/immovable_rod/start()
|
||||
var/datum/round_event_control/immovable_rod/C = control
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/datum/round_event/ion_storm/announce(fake)
|
||||
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || fake)
|
||||
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm")
|
||||
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm", has_important_message = prob(80))
|
||||
|
||||
|
||||
/datum/round_event/ion_storm/start()
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
"A neighbouring station is throwing rocks at you. (Perhaps they've \
|
||||
grown tired of your messages.)")
|
||||
if(prob(50))
|
||||
priority_announce(pick(reason), "Collision Alert")
|
||||
priority_announce(pick(reason), "Collision Alert", has_important_message = prob(75))
|
||||
else
|
||||
print_command_report("[pick(reason)]", "Collision Alert")
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
wave_name = "meaty"
|
||||
|
||||
/datum/round_event/meteor_wave/meaty/announce(fake)
|
||||
priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", "meteors")
|
||||
priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", "meteors", has_important_message = TRUE)
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
kill()
|
||||
|
||||
/datum/round_event/meteor_wave/announce(fake)
|
||||
priority_announce(generateMeteorString(startWhen,TRUE,direction), "Meteor Alert", "meteors")
|
||||
priority_announce(generateMeteorString(startWhen,TRUE,direction), "Meteor Alert", "meteors", has_important_message = TRUE)
|
||||
|
||||
/proc/generateMeteorString(startWhen,syndiealert,direction)
|
||||
var/directionstring
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
// if(PIRATES_DUTCHMAN)
|
||||
// ship_name = "Flying Dutchman"
|
||||
|
||||
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
|
||||
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound(), has_important_message = TRUE)
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(D)
|
||||
payoff = max(payoff_min, FLOOR(D.account_balance * 0.80, 1000))
|
||||
@@ -63,16 +63,16 @@
|
||||
|
||||
/proc/pirates_answered(datum/comm_message/threat_msg, payoff, ship_name, initial_send_time, response_max_time, ship_template)
|
||||
if(world.time > initial_send_time + response_max_time)
|
||||
priority_announce("Too late to beg for mercy!",sender_override = ship_name)
|
||||
priority_announce("Too late to beg for mercy!",sender_override = ship_name, has_important_message = TRUE)
|
||||
return
|
||||
if(threat_msg && threat_msg.answered == 1)
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(D)
|
||||
if(D.adjust_money(-payoff))
|
||||
priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name)
|
||||
priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name, has_important_message = TRUE)
|
||||
return
|
||||
else
|
||||
priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name)
|
||||
priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name, has_important_message = TRUE)
|
||||
spawn_pirates(threat_msg, ship_template, TRUE)
|
||||
|
||||
/proc/spawn_pirates(datum/comm_message/threat_msg, ship_template, skip_answer_check)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/radiation_storm/announce(fake)
|
||||
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation")
|
||||
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation", has_important_message = TRUE)
|
||||
//sound not longer matches the text, but an audible warning is probably good
|
||||
|
||||
/datum/round_event/radiation_storm/start()
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
announceWhen = 10
|
||||
|
||||
/datum/round_event/ghost_role/space_dragon/announce(fake)
|
||||
priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert")
|
||||
|
||||
priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/ghost_role/space_dragon/spawn_role()
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list)
|
||||
@@ -24,11 +24,11 @@
|
||||
if(!spawn_locs.len)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
return MAP_ERROR
|
||||
|
||||
|
||||
var/list/candidates = get_candidates(ROLE_SPACE_DRAGON, null, ROLE_SPACE_DRAGON)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
|
||||
var/mob/dead/selected = pick_n_take(candidates)
|
||||
|
||||
var/datum/mind/player_mind = new /datum/mind(selected.key)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
var/static/list/stray_spawnable_supply_packs = list() ///List of default spawnable supply packs, filtered from the cargo list
|
||||
|
||||
/datum/round_event/stray_cargo/announce(fake)
|
||||
priority_announce("Stray cargo pod detected on long-range scanners. Expected location of impact: [impact_area.name].", "Collision Alert")
|
||||
priority_announce("Stray cargo pod detected on long-range scanners. Expected location of impact: [impact_area.name].", "Collision Alert", has_important_message = TRUE)
|
||||
|
||||
/**
|
||||
* Tries to find a valid area, throws an error if none are found
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
/datum/round_event/supermatter_surge/announce()
|
||||
var/severity = ""
|
||||
var/important = FALSE
|
||||
switch(power)
|
||||
if(-INFINITY to 100000)
|
||||
var/low_threat_perc = 100-round(100*((power-200)/(100000-200)))
|
||||
@@ -30,10 +31,12 @@
|
||||
severity = "medium; the supermatter should return to normal operation, but regardless, check if the emitters may need to be turned off temporarily."
|
||||
else
|
||||
severity = "high; the emitters likely need to be turned off, and if the supermatter's cooling loop is not fortified, pre-cooled gas may need to be added."
|
||||
important = TRUE
|
||||
if(100000 to INFINITY)
|
||||
severity = "extreme; emergency action is likely to be required even if coolant loop is fine. Turn off the emitters and make sure the loop is properly cooling gases."
|
||||
important = TRUE
|
||||
if(power > 20000 || prob(round(power/200)))
|
||||
priority_announce("Supermatter surge detected. Estimated severity is [severity]", "Anomaly Alert")
|
||||
priority_announce("Supermatter surge detected. Estimated severity is [severity]", "Anomaly Alert", has_important_message = important)
|
||||
|
||||
/datum/round_event/supermatter_surge/start()
|
||||
var/obj/machinery/power/supermatter_crystal/supermatter = GLOB.main_supermatter_engine
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/datum/round_event/supernova/announce()
|
||||
var/message = "[station_name()]: Our tachyon-doppler array has detected a supernova in your vicinity. Peak flux from the supernova estimated to be [round(power,0.1)] times current solar flux; if the supernova is close to your sun in the sky, your solars may receive this as a power boost.[power > 1 ? " Short burts of radiation may be possible, so please prepare accordingly." : "We expect no radiation bursts from this one."] We hope you enjoy the light."
|
||||
if(prob(power * 25))
|
||||
priority_announce(message, sender_override = "Nanotrasen Meteorology Division")
|
||||
priority_announce(message, sender_override = "Nanotrasen Meteorology Division", has_important_message = TRUE)
|
||||
announced = TRUE
|
||||
else
|
||||
print_command_report(message)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
trader.visible_message("<b>[trader]</b> suddenly appears in a puff of smoke!")
|
||||
|
||||
/datum/round_event/travelling_trader/announce(fake)
|
||||
priority_announce("A mysterious figure has been detected on sensors at [get_area(spawn_location)]", "Mysterious Figure")
|
||||
priority_announce("A mysterious figure has been detected on sensors at [get_area(spawn_location)]", "Mysterious Figure", has_important_message = !fake)
|
||||
|
||||
/datum/round_event/travelling_trader/end()
|
||||
if(trader) // the /datum/round_event/travelling_trader has given up on waiting!
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/datum/round_event_control/untied_shoes
|
||||
name = "Untied Shoes"
|
||||
typepath = /datum/round_event/untied_shoes
|
||||
weight = 100
|
||||
max_occurrences = 20
|
||||
weight = 50
|
||||
max_occurrences = 10
|
||||
alert_observers = FALSE
|
||||
|
||||
/datum/round_event/untied_shoes
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
//needs to be chemid unit checked at some point
|
||||
|
||||
/datum/round_event/vent_clog/announce()
|
||||
priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert")
|
||||
priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/vent_clog/setup()
|
||||
endWhen = rand(120, 180)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
wormholes += new /obj/effect/portal/wormhole(T, 0, null, FALSE)
|
||||
|
||||
/datum/round_event/wormholes/announce(fake)
|
||||
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", "spanomalies")
|
||||
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", "spanomalies", has_important_message = TRUE)
|
||||
|
||||
/datum/round_event/wormholes/tick()
|
||||
if(activeFor % shift_frequency == 0)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
CRASH("dynamic preview is unsupported")
|
||||
. = H.AIize(latejoin,preference_source)
|
||||
|
||||
/datum/job/ai/after_spawn(mob/H, mob/M, latejoin)
|
||||
/datum/job/ai/after_spawn(mob/H, client/C, latejoin)
|
||||
. = ..()
|
||||
if(latejoin)
|
||||
var/obj/structure/AIcore/latejoin_inactive/lateJoinCore
|
||||
@@ -41,8 +41,8 @@
|
||||
H.forceMove(lateJoinCore.loc)
|
||||
qdel(lateJoinCore)
|
||||
var/mob/living/silicon/ai/AI = H
|
||||
AI.apply_pref_name("ai", M.client) //If this runtimes oh well jobcode is fucked.
|
||||
AI.set_core_display_icon(null, M.client)
|
||||
AI.apply_pref_name("ai", C) //If this runtimes oh well jobcode is fucked.
|
||||
AI.set_core_display_icon(null, C)
|
||||
|
||||
//we may have been created after our borg
|
||||
if(SSticker.current_state == GAME_STATE_SETTING_UP)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
backpack_contents = list(/obj/item/storage/box/beanbag=1,/obj/item/book/granter/action/drink_fling=1)
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
|
||||
/datum/job/bartender/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
|
||||
/datum/job/bartender/after_spawn(mob/living/H, client/C, latejoin = FALSE)
|
||||
. = ..()
|
||||
var/datum/action/innate/drink_fling/D = new
|
||||
D.Grant(H)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
threat = 0.5
|
||||
|
||||
|
||||
/datum/job/chaplain/after_spawn(mob/living/H, mob/M)
|
||||
/datum/job/chaplain/after_spawn(mob/living/H, client/C)
|
||||
. = ..()
|
||||
if(H.mind)
|
||||
H.mind.isholy = TRUE
|
||||
@@ -41,12 +41,12 @@
|
||||
return
|
||||
|
||||
var/new_religion = DEFAULT_RELIGION
|
||||
if(M.client && M.client.prefs.custom_names["religion"])
|
||||
new_religion = M.client.prefs.custom_names["religion"]
|
||||
if(C && C.prefs.custom_names["religion"])
|
||||
new_religion = C.prefs.custom_names["religion"]
|
||||
|
||||
var/new_deity = DEFAULT_DEITY
|
||||
if(M.client && M.client.prefs.custom_names["deity"])
|
||||
new_deity = M.client.prefs.custom_names["deity"]
|
||||
if(C && C.prefs.custom_names["deity"])
|
||||
new_deity = C.prefs.custom_names["deity"]
|
||||
|
||||
B.deity_name = new_deity
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
threat = 0
|
||||
|
||||
/datum/job/mime/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
/datum/job/mime/after_spawn(mob/living/carbon/human/H, client/C)
|
||||
. = ..()
|
||||
H.apply_pref_name("mime", M.client)
|
||||
H.apply_pref_name("mime", C)
|
||||
|
||||
/datum/outfit/job/mime
|
||||
name = "Mime"
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
/datum/job/prisoner/get_latejoin_spawn_point()
|
||||
return get_roundstart_spawn_point()
|
||||
|
||||
/datum/job/prisoner/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
/datum/job/prisoner/after_spawn(mob/living/carbon/human/H, client/C)
|
||||
. = ..()
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_JOB_PRISONER]
|
||||
if(policy)
|
||||
var/mob/found = (M?.client && M) || (H?.client && H)
|
||||
var/mob/found = (H?.client && H)
|
||||
to_chat(found, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(found, "<br><br>")
|
||||
to_chat(found, "<span class='boldnotice'>[policy]</span>")
|
||||
|
||||
@@ -98,6 +98,16 @@
|
||||
name = "garden & kitchen bluespace shelter capsule"
|
||||
desc = "Everything someone needs to make a home cooked meal while surviving the depths of hell... or space."
|
||||
template_id = "shelter_zeta"
|
||||
|
||||
// RBMK reactor beacon so people can create the engine
|
||||
|
||||
/obj/item/survivalcapsule/reactor // the not-so-survival capsule
|
||||
name = "RMBK Reactor Beacon"
|
||||
desc = "A special bluespace beacon designed to implement a reactor into the hull of the ship or station that it is activated on."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "beacon"
|
||||
template_id = "reactor"
|
||||
|
||||
//Pod objects
|
||||
|
||||
//Window
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/structure/punching_bag
|
||||
name = "punching bag"
|
||||
desc = "A punching bag. Can you get to speed level 4???"
|
||||
icon = 'goon/icons/obj/fitness.dmi'
|
||||
icon = 'icons/obj/fitness.dmi'
|
||||
icon_state = "punchingbag"
|
||||
anchored = TRUE
|
||||
layer = WALL_OBJ_LAYER
|
||||
@@ -12,7 +12,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
flick("[icon_state]2", src)
|
||||
flick("[icon_state]-punch", src)
|
||||
playsound(loc, pick(hit_sounds), 25, 1, -1)
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
@@ -20,15 +20,24 @@
|
||||
L.apply_status_effect(STATUS_EFFECT_EXERCISED)
|
||||
|
||||
/obj/structure/weightmachine
|
||||
name = "Weight Machine"
|
||||
desc = "Just looking at this thing makes you feel tired."
|
||||
icon = 'icons/obj/fitness.dmi'
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/icon_state_inuse
|
||||
|
||||
/obj/structure/weightmachine/proc/AnimateMachine(mob/living/user)
|
||||
return
|
||||
|
||||
/obj/structure/weightmachine/update_icon_state()
|
||||
. = ..()
|
||||
icon_state = (obj_flags & IN_USE) ? "[base_icon_state]-u" : base_icon_state
|
||||
|
||||
/obj/structure/weightmachine/update_overlays()
|
||||
. = ..()
|
||||
|
||||
if(obj_flags & IN_USE)
|
||||
. += mutable_appearance(icon, "[base_icon_state]-o", layer = ABOVE_MOB_LAYER, alpha = src.alpha)
|
||||
|
||||
/obj/structure/weightmachine/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -38,7 +47,7 @@
|
||||
return
|
||||
else
|
||||
obj_flags |= IN_USE
|
||||
icon_state = icon_state_inuse
|
||||
update_appearance()
|
||||
user.setDir(SOUTH)
|
||||
user.Stun(80)
|
||||
user.forceMove(src.loc)
|
||||
@@ -48,17 +57,17 @@
|
||||
|
||||
playsound(user, 'sound/machines/click.ogg', 60, 1)
|
||||
obj_flags &= ~IN_USE
|
||||
update_appearance()
|
||||
user.pixel_y = 0
|
||||
var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!")
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "exercise", /datum/mood_event/exercise)
|
||||
icon_state = initial(icon_state)
|
||||
to_chat(user, finishmessage)
|
||||
user.apply_status_effect(STATUS_EFFECT_EXERCISED)
|
||||
|
||||
/obj/structure/weightmachine/stacklifter
|
||||
icon = 'goon/icons/obj/fitness.dmi'
|
||||
icon_state = "fitnesslifter"
|
||||
icon_state_inuse = "fitnesslifter2"
|
||||
name = "chest press machine"
|
||||
icon_state = "stacklifter"
|
||||
base_icon_state = "stacklifter"
|
||||
|
||||
/obj/structure/weightmachine/stacklifter/AnimateMachine(mob/living/user)
|
||||
var/lifts = 0
|
||||
@@ -69,27 +78,24 @@
|
||||
animate(user, pixel_y = -2, time = 3)
|
||||
sleep(3)
|
||||
animate(user, pixel_y = -4, time = 3)
|
||||
sleep(3)
|
||||
playsound(user, 'goon/sound/effects/spring.ogg', 60, 1)
|
||||
sleep(2)
|
||||
playsound(user, 'sound/machines/creak.ogg', 60, 1)
|
||||
|
||||
/obj/structure/weightmachine/weightlifter
|
||||
icon = 'goon/icons/obj/fitness.dmi'
|
||||
icon_state = "fitnessweight"
|
||||
icon_state_inuse = "fitnessweight-c"
|
||||
name = "inline bench press"
|
||||
icon_state = "benchpress"
|
||||
base_icon_state = "benchpress"
|
||||
|
||||
/obj/structure/weightmachine/weightlifter/AnimateMachine(mob/living/user)
|
||||
var/mutable_appearance/swole_overlay = mutable_appearance(icon, "fitnessweight-w", WALL_OBJ_LAYER)
|
||||
add_overlay(swole_overlay)
|
||||
var/reps = 0
|
||||
user.pixel_y = 5
|
||||
while (reps++ < 6)
|
||||
if (user.loc != src.loc)
|
||||
break
|
||||
for (var/innerReps = max(reps, 1), innerReps > 0, innerReps--)
|
||||
sleep(3)
|
||||
sleep(4)
|
||||
animate(user, pixel_y = (user.pixel_y == 3) ? 5 : 3, time = 3)
|
||||
playsound(user, 'goon/sound/effects/spring.ogg', 60, 1)
|
||||
playsound(user, 'sound/machines/creak.ogg', 60, 1)
|
||||
sleep(3)
|
||||
animate(user, pixel_y = 2, time = 3)
|
||||
sleep(3)
|
||||
cut_overlay(swole_overlay)
|
||||
|
||||
@@ -107,3 +107,11 @@
|
||||
. = ..()
|
||||
whitelisted_turfs = typecacheof(/turf/closed/mineral)
|
||||
banned_objects = typecacheof(/obj/structure/stone_tile)
|
||||
|
||||
// yes, I COULD make it a seperate object from the surv capsule but the code needed is indeticle soo...
|
||||
|
||||
/datum/map_template/shelter/reactor
|
||||
name = "RBMK Reactor"
|
||||
shelter_id = "reactor"
|
||||
description = "A reactor core, coolant and moderator loop not included."
|
||||
mappath = "_maps/templates/reactor_1.dmm"
|
||||
|
||||
@@ -216,6 +216,26 @@
|
||||
icon_state = "harpywings"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/deco_wings/harpywingsalt
|
||||
name = "Harpy (Alt)"
|
||||
icon_state = "harpywingsalt"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/deco_wings/harpywingsaltcollar
|
||||
name = "Harpy (Alt Collar)"
|
||||
icon_state = "harpywingsaltcollar"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/deco_wings/harpywingsbat
|
||||
name = "Harpy (Bat)"
|
||||
icon_state = "harpywingsbat"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/deco_wings/harpywingsbatcollar
|
||||
name = "Harpy (Bat Collar)"
|
||||
icon_state = "harpywingsbatcollar"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/deco_wings/roboticwing
|
||||
name = "Robotic"
|
||||
icon_state = "drago"
|
||||
@@ -420,6 +440,26 @@
|
||||
icon_state = "harpywings"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/insect_wings/harpywingsalt
|
||||
name = "Harpy (Alt)"
|
||||
icon_state = "harpywingsalt"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/insect_wings/harpywingsaltcollar
|
||||
name = "Harpy (Alt Collar)"
|
||||
icon_state = "harpywingsaltcollar"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/insect_wings/harpywingsbat
|
||||
name = "Harpy (Bat)"
|
||||
icon_state = "harpywingsbat"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/insect_wings/harpywingsbatcollar
|
||||
name = "Harpy (Bat Collar)"
|
||||
icon_state = "harpywingsbatcollar"
|
||||
upgrade_to = SPECIES_WINGS_ANGEL
|
||||
|
||||
/datum/sprite_accessory/insect_wings/roboticwing
|
||||
name = "Robotic"
|
||||
icon_state = "drago"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/xeno
|
||||
exotic_bloodtype = "X*"
|
||||
damage_overlay_type = "xeno"
|
||||
disliked_food = JUNKFOOD
|
||||
disliked_food = null
|
||||
liked_food = GROSS | MEAT
|
||||
species_category = SPECIES_CATEGORY_ALIEN
|
||||
wings_icons = SPECIES_WINGS_DRAGON //most depictions of xenomorphs with wings are closest to this.
|
||||
|
||||
@@ -322,6 +322,30 @@
|
||||
else
|
||||
to_chat(user, "Encryption Key ports not configured.")
|
||||
|
||||
/obj/item/paicard/attack_ghost(mob/dead/observer/user)
|
||||
if(pai)
|
||||
to_chat(user, "<span class='warning'>This pAI is already in use!</span>")
|
||||
return
|
||||
|
||||
var/area/A = get_area(get_turf(src))
|
||||
if(A.type in SSpai.restricted_areas) // set in subsystem/pai.dm on initialize of the subsystem
|
||||
to_chat(user, "<span class='warning'>You can't download yourself into a restricted area!</span>")
|
||||
return
|
||||
|
||||
var/pai_name = reject_bad_name(stripped_input(usr, "Enter a name for your pAI", "pAI Name", user.name, MAX_NAME_LEN), TRUE)
|
||||
if(!pai_name)
|
||||
to_chat(user, "<span class='warning'>Entered name is not valid.</span>")
|
||||
return
|
||||
|
||||
var/mob/living/silicon/pai/new_pai = new(src)
|
||||
new_pai.name = pai_name
|
||||
new_pai.real_name = new_pai.name
|
||||
new_pai.key = user.key
|
||||
|
||||
setPersonality(new_pai)
|
||||
|
||||
SSticker.mode.update_cult_icons_removed(pai.mind)
|
||||
|
||||
/obj/item/paicard/emag_act(mob/user) // Emag to wipe the master DNA and supplemental directive
|
||||
. = ..()
|
||||
if(!pai)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
hard_drive.store_file(new/datum/computer_file/program/power_monitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/nuclear_monitor())
|
||||
|
||||
// ===== RESEARCH CONSOLE =====
|
||||
/obj/machinery/modular_computer/console/preset/research
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
/obj/item/fuel_rod
|
||||
name = "Uranium-235 Fuel Rod"
|
||||
desc = "A titanium sheathed rod containing a measure of enriched uranium-dioxide powder inside, and a breeding blanket of uranium-238 around it, used to kick off a fission reaction and breed plutonium fuel respectivly."
|
||||
icon = 'icons/obj/control_rod.dmi'
|
||||
icon_state = "irradiated"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/depletion = 0 //Each fuel rod will deplete in around 30 minutes.
|
||||
var/fuel_power = 0.10
|
||||
var/rad_strength = 500
|
||||
var/half_life = 2000 // how many depletion ticks are needed to half the fuel_power (1 tick = 1 second)
|
||||
var/time_created = 0
|
||||
var/og_fuel_power = 0.20 //the original fuel power value
|
||||
var/process = FALSE
|
||||
// The depletion where depletion_final() will be called (and does something)
|
||||
var/depletion_threshold = 100
|
||||
// How fast this rod will deplete
|
||||
var/depletion_speed_modifier = 1
|
||||
var/depleted_final = FALSE // depletion_final should run only once
|
||||
var/depletion_conversion_type = "plutonium"
|
||||
|
||||
/obj/item/fuel_rod/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, require_twohands = TRUE)
|
||||
|
||||
/obj/item/fuel_rod/Initialize()
|
||||
. = ..()
|
||||
time_created = world.time
|
||||
AddComponent(/datum/component/radioactive, rad_strength, src) // This should be temporary for it won't make rads go lower than 350
|
||||
if(process)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/fuel_rod/Destroy()
|
||||
if(process)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc
|
||||
if(istype(N))
|
||||
N.fuel_rods -= src
|
||||
. = ..()
|
||||
|
||||
// This proc will try to convert your fuel rod if you don't override this proc
|
||||
// So, ideally, you should write an override of this for every fuel rod you want to create
|
||||
/obj/item/fuel_rod/proc/depletion_final(result_rod)
|
||||
if(!result_rod)
|
||||
return
|
||||
var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc
|
||||
// Rod conversion is moot when you can't find the reactor
|
||||
if(istype(N))
|
||||
var/obj/item/fuel_rod/R
|
||||
|
||||
// You can add your own depletion scheme and not override this proc if you are going to convert a fuel rod into another type
|
||||
switch(result_rod)
|
||||
if("plutonium")
|
||||
R = new /obj/item/fuel_rod/plutonium(loc)
|
||||
R.depletion = depletion
|
||||
if(prob(1))
|
||||
R.name = "Plush-239 Fuel Rod"
|
||||
R.desc = "NanoTrasen would like to remind you that it is not liable for any permanent radioactive damage done to its employees."
|
||||
R.icon = 'icons/obj/plushes.dmi'
|
||||
R.icon_state = "romanian"
|
||||
R.fuel_power = 0.25 //Funny easter egg, slightly more powerful too.
|
||||
if("depleted")
|
||||
if(fuel_power < 10)
|
||||
fuel_power = 0
|
||||
playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE)
|
||||
R = new /obj/item/fuel_rod/depleted(loc)
|
||||
R.depletion = depletion
|
||||
|
||||
// Finalization of conversion
|
||||
if(istype(R))
|
||||
N.fuel_rods += R
|
||||
qdel(src)
|
||||
else
|
||||
depleted_final = FALSE // Maybe try again later?
|
||||
|
||||
/obj/item/fuel_rod/proc/deplete(amount=0.035)
|
||||
depletion += amount * depletion_speed_modifier
|
||||
if(depletion >= depletion_threshold && !depleted_final)
|
||||
depleted_final = TRUE
|
||||
depletion_final(depletion_conversion_type)
|
||||
|
||||
/obj/item/fuel_rod/plutonium
|
||||
fuel_power = 0.20
|
||||
name = "Plutonium-239 Fuel Rod"
|
||||
desc = "A highly energetic titanium sheathed rod containing a sizeable measure of weapons grade plutonium, it's highly efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised."
|
||||
icon_state = "inferior"
|
||||
rad_strength = 1500
|
||||
process = TRUE // for half life code
|
||||
depletion_threshold = 300
|
||||
depletion_conversion_type = "depleted"
|
||||
|
||||
/obj/item/fuel_rod/process()
|
||||
fuel_power = og_fuel_power * 0.5**((world.time - time_created) / half_life SECONDS) // halves the fuel power every half life (33 minutes)
|
||||
|
||||
/obj/item/fuel_rod/depleted
|
||||
fuel_power = 0.05
|
||||
name = "Depleted Fuel Rod"
|
||||
desc = "A highly radioactive fuel rod which has expended most of it's useful energy."
|
||||
icon_state = "normal"
|
||||
rad_strength = 6000 // smelly
|
||||
depletion_conversion_type = null // It means that it won't turn into anything
|
||||
process = TRUE
|
||||
|
||||
// Master type for material optional (or requiring, wyci) and/or producing rods
|
||||
/obj/item/fuel_rod/material
|
||||
// Whether the rod has been harvested. Should be set in expend().
|
||||
var/expended = FALSE
|
||||
// The material that will be inserted and then multiplied (or not). Should be some sort of /obj/item/stack
|
||||
var/material_type
|
||||
// The name of material that'll be used for texts
|
||||
var/material_name
|
||||
var/material_name_singular
|
||||
var/initial_amount = 0
|
||||
// The maximum amount of material the rod can hold
|
||||
var/max_initial_amount = 10
|
||||
var/grown_amount = 0
|
||||
// The multiplier for growth. 1 for the same 2 for double etc etc
|
||||
var/multiplier = 2
|
||||
// After this depletion, you won't be able to add new materials
|
||||
var/material_input_deadline = 25
|
||||
// Material fuel rods generally don't get converted into another fuel object
|
||||
depletion_conversion_type = null
|
||||
|
||||
// Called when the rod is fully harvested
|
||||
/obj/item/fuel_rod/material/proc/expend()
|
||||
expended = TRUE
|
||||
|
||||
// Basic checks for material rods
|
||||
/obj/item/fuel_rod/material/proc/check_material_input(mob/user)
|
||||
if(depletion >= material_input_deadline)
|
||||
to_chat(user, "<span class='warning'>The sample slots have sealed themselves shut, it's too late to add [material_name] now!</span>") // no cheesing in crystals at 100%
|
||||
return FALSE
|
||||
if(expended)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s material slots have already been used.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// The actual growth
|
||||
/obj/item/fuel_rod/material/depletion_final(result_rod)
|
||||
if(result_rod)
|
||||
..() // So if you put anything into depletion_conversion_type then your fuel rod will be converted (or not) and *won't grow*
|
||||
else
|
||||
grown_amount = initial_amount * multiplier
|
||||
|
||||
/obj/item/fuel_rod/material/attackby(obj/item/W, mob/user, params)
|
||||
var/obj/item/stack/M = W
|
||||
if(istype(M, material_type))
|
||||
if(!check_material_input(user))
|
||||
return
|
||||
if(initial_amount < max_initial_amount)
|
||||
var/adding = min((max_initial_amount - initial_amount), M.amount)
|
||||
M.amount -= adding
|
||||
initial_amount += adding
|
||||
if (adding == 1)
|
||||
to_chat(user, "<span class='notice'>You insert [adding] [material_name_singular] into \the [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You insert [adding] [material_name] into \the [src].</span>")
|
||||
M.zero_amount()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src]'s material slots are full!</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/fuel_rod/material/attack_self(mob/user)
|
||||
if(expended)
|
||||
to_chat(user, "<span class='notice'>You have already removed [material_name] from \the [src].</span>")
|
||||
return
|
||||
|
||||
if(depleted_final)
|
||||
new material_type(user.loc, grown_amount)
|
||||
if (grown_amount == 1)
|
||||
to_chat(user, "<span class='notice'>You harvest [grown_amount] [material_name_singular] from \the [src].</span>") // Unlikely
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You harvest [grown_amount] [material_name] from \the [src].</span>")
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
|
||||
grown_amount = 0
|
||||
expend()
|
||||
else if(depletion)
|
||||
to_chat(user, "<span class='warning'>\The [src] has not fissiled enough to fully grow the sample. The progress bar shows it is [min(depletion/depletion_threshold*100,100)]% complete.</span>")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
else if(initial_amount)
|
||||
new material_type(user.loc, initial_amount)
|
||||
if (initial_amount == 1)
|
||||
to_chat(user, "<span class='notice'>You remove [initial_amount] [material_name_singular] from \the [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You remove [initial_amount] [material_name] from \the [src].</span>")
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
|
||||
initial_amount = 0
|
||||
|
||||
/obj/item/fuel_rod/material/examine(mob/user)
|
||||
. = ..()
|
||||
if(expended)
|
||||
. += "<span class='warning'>The material slots have been slagged by the extreme heat, you can't grow [material_name] in this rod again...</span>"
|
||||
return
|
||||
else if(depleted_final)
|
||||
. += "<span class='warning'>This fuel rod's [material_name] are now fully grown, and it currently bears [grown_amount] harvestable [material_name_singular]\s.</span>"
|
||||
return
|
||||
if(depletion)
|
||||
. += "<span class='danger'>The sample is [min(depletion/depletion_threshold*100,100)]% fissiled.</span>"
|
||||
. += "<span class='disarm'>[initial_amount]/[max_initial_amount] of the slots for [material_name] are full.</span>"
|
||||
|
||||
/obj/item/fuel_rod/material/telecrystal
|
||||
name = "Telecrystal Fuel Rod"
|
||||
desc = "A disguised titanium sheathed rod containing several small slots infused with uranium dioxide. Permits the insertion of telecrystals to grow more. Fissiles much faster than its standard counterpart"
|
||||
icon_state = "telecrystal"
|
||||
fuel_power = 0.30 // twice as powerful as a normal rod, you're going to need some engineering autism if you plan to mass produce TC
|
||||
depletion_speed_modifier = 3 // headstart, otherwise it takes two hours
|
||||
rad_strength = 1500
|
||||
max_initial_amount = 8
|
||||
multiplier = 3
|
||||
material_type = /obj/item/stack/telecrystal
|
||||
material_name = "telecrystals"
|
||||
material_name_singular = "telecrystal"
|
||||
|
||||
/obj/item/fuel_rod/material/telecrystal/depletion_final(result_rod)
|
||||
..()
|
||||
if(result_rod)
|
||||
return
|
||||
fuel_power = 0.60 // thrice as powerful as plutonium, you'll want to get this one out quick!
|
||||
name = "Exhausted Telecrystal Fuel Rod"
|
||||
desc = "A highly energetic, disguised titanium sheathed rod containing a number of slots filled with greatly expanded telecrystals which can be removed by hand. It's extremely efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised."
|
||||
icon_state = "telecrystal_used"
|
||||
AddComponent(/datum/component/radioactive, 3000, src)
|
||||
|
||||
/obj/item/fuel_rod/material/bananium
|
||||
name = "Bananium Fuel Rod"
|
||||
desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than its cowardly counterparts. However, its cutting-edge cosmic clown technology allows rooms for extraordinarily exhilarating extraterrestrial element called bananium to menacingly multiply."
|
||||
icon_state = "bananium"
|
||||
fuel_power = 0.15
|
||||
depletion_speed_modifier = 3
|
||||
rad_strength = 350
|
||||
max_initial_amount = 10
|
||||
multiplier = 3
|
||||
material_type = /obj/item/stack/sheet/mineral/bananium
|
||||
material_name = "sheets of bananium"
|
||||
material_name_singular = "sheet of bananium"
|
||||
|
||||
/obj/item/fuel_rod/material/bananium/deplete(amount=0.035)
|
||||
..()
|
||||
if(initial_amount == max_initial_amount && prob(10))
|
||||
playsound(src, pick('sound/items/bikehorn.ogg', 'sound/misc/bikehorn_creepy.ogg'), 50) // HONK
|
||||
|
||||
/obj/item/fuel_rod/material/bananium/depletion_final(result_rod)
|
||||
..()
|
||||
if(result_rod)
|
||||
return
|
||||
fuel_power = 0.3 // Be warned
|
||||
name = "Fully Grown Bananium Fuel Rod"
|
||||
desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than it cowardly counterparts. Its greatly grimacing grwoth stage is now over, and bananium outgrowth hums as if it's blatantly honking bike horns."
|
||||
icon_state = "bananium_used"
|
||||
AddComponent(/datum/component/radioactive, 1250, src)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
// modular shitcode but it works:tm:
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if(istype(I))
|
||||
to_chat(user, "<span class='notice'>You add \the [src]'s ID into the multitool's buffer.</span>")
|
||||
I.buffer = src.id
|
||||
return TRUE
|
||||
/obj/machinery/computer/reactor/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if(istype(I))
|
||||
to_chat(user, "<span class='notice'>You add the reactor's ID to \the [src]>")
|
||||
src.id = I.buffer
|
||||
link_to_reactor()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo // easier on the brain
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo/New()
|
||||
. = ..()
|
||||
id = rand(1, 9999999) // cmon, what are the chances? The chances are... Very low friend... But maybe we can make this a bit better.
|
||||
|
||||
// Cargo variants can be wrenched down and don't start linked to the default RMBK reactor
|
||||
|
||||
/obj/machinery/computer/reactor/control_rods/cargo
|
||||
anchored = FALSE
|
||||
id = null
|
||||
|
||||
/obj/machinery/computer/reactor/stats/cargo
|
||||
anchored = FALSE
|
||||
id = null
|
||||
|
||||
/obj/machinery/computer/reactor/fuel_rods/cargo
|
||||
anchored = FALSE
|
||||
id = null
|
||||
|
||||
/obj/item/paper/fluff/rbmkcargo
|
||||
name = "Nuclear Reactor Instructions"
|
||||
info = "Make sure a 5x5 area is completely clear of pipes, cables and machinery when using the beacon. Those will be provided automatically with the beacon's bluespace decompression. Use a multitool on the reactor then on the computers provided to link them together. Also make sure the reactor has a proper pipeline filled with cooling gas before inserting fuel rods. Good luck!"
|
||||
@@ -34,6 +34,7 @@ field_generator power level display
|
||||
max_integrity = 500
|
||||
//100% immune to lasers and energy projectiles since it absorbs their energy.
|
||||
armor = list(MELEE = 25, BULLET = 10, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70)
|
||||
var/obj/item/radio/radio
|
||||
var/const/num_power_levels = 6 // Total number of power level icon has
|
||||
var/power_level = 0
|
||||
var/active = FG_OFFLINE
|
||||
@@ -58,6 +59,9 @@ field_generator power level display
|
||||
. = ..()
|
||||
fields = list()
|
||||
connected_gens = list()
|
||||
radio = new(src)
|
||||
radio.listening = 0
|
||||
radio.recalculateChannels()
|
||||
|
||||
/obj/machinery/field/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -166,6 +170,7 @@ field_generator power level display
|
||||
|
||||
/obj/machinery/field/generator/Destroy()
|
||||
cleanup()
|
||||
QDEL_NULL(radio)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -333,6 +338,7 @@ field_generator power level display
|
||||
if((world.time - O.last_warning) > 50) //to stop message-spam
|
||||
temp = 0
|
||||
var/turf/T = get_turf(src)
|
||||
radio.talk_into(src, "A containment field has failed in [get_area_name(src, TRUE)] while a singularity exists.", null, language = get_selected_language())
|
||||
message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].")
|
||||
investigate_log("has <font color='red'>failed</font> whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO)
|
||||
O.last_warning = world.time
|
||||
|
||||
@@ -415,17 +415,13 @@
|
||||
|
||||
/obj/singularity/proc/mezzer()
|
||||
for(var/mob/living/carbon/M in oviewers(8, src))
|
||||
if(isbrain(M)) //Ignore brains
|
||||
continue
|
||||
|
||||
if(M.stat == CONSCIOUS)
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/meson))
|
||||
var/obj/item/clothing/glasses/meson/MS = H.glasses
|
||||
if(MS.vision_flags == SEE_TURFS)
|
||||
to_chat(H, "<span class='notice'>You look directly into the [src.name], good thing you had your protective eyewear on!</span>")
|
||||
return
|
||||
if(M.stat == CONSCIOUS && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/meson))
|
||||
var/obj/item/clothing/glasses/meson/MS = H.glasses
|
||||
if(MS.vision_flags == SEE_TURFS)
|
||||
to_chat(H, "<span class='notice'>You look directly into the [src.name], good thing you had your protective eyewear on!</span>")
|
||||
return
|
||||
|
||||
M.apply_effect(60, EFFECT_STUN)
|
||||
M.visible_message("<span class='danger'>[M] stares blankly at the [src.name]!</span>", \
|
||||
|
||||
@@ -1686,14 +1686,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
var/heal_points = 10
|
||||
if(L.health <= 0)
|
||||
heal_points = 20 //heal more if we're in softcrit
|
||||
for(var/i in 1 to min(volume, heal_points)) //only heals 1 point of damage per unit on add, for balance reasons
|
||||
L.adjustBruteLoss(-1)
|
||||
L.adjustFireLoss(-1)
|
||||
L.adjustToxLoss(-1)
|
||||
L.adjustOxyLoss(-1)
|
||||
L.adjustStaminaLoss(-1)
|
||||
heal_points = min(volume, heal_points)
|
||||
L.adjustBruteLoss(-heal_points)
|
||||
L.adjustFireLoss(-heal_points)
|
||||
L.adjustToxLoss(-heal_points)
|
||||
L.adjustOxyLoss(-heal_points)
|
||||
L.adjustStaminaLoss(-heal_points)
|
||||
L.visible_message("<span class='warning'>[L] shivers with renewed vigor!</span>", "<span class='notice'>One taste of [lowertext(name)] fills you with energy!</span>")
|
||||
if(!L.stat && heal_points == 20) //brought us out of softcrit
|
||||
if(!L.stat && L.health > 0) //brought us out of softcrit
|
||||
L.visible_message("<span class='danger'>[L] lurches to [L.p_their()] feet!</span>", "<span class='boldnotice'>Up and at 'em, kid.</span>")
|
||||
|
||||
/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_life(mob/living/L)
|
||||
|
||||
@@ -115,3 +115,13 @@
|
||||
build_path = /obj/item/pipe/bluespace
|
||||
category = list("Bluespace Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/datum/design/swapper //ported from TG, credit to XDTM
|
||||
name = "Quantum Spin Inverter"
|
||||
desc = "An experimental device that is able to swap the locations of two entities by switching their particles' spin values. Must be linked to another device to function."
|
||||
id = "swapper"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/iron = 500, /datum/material/diamond = 1500, /datum/material/glass = 1000, /datum/material/bluespace = 2000, /datum/material/silver=1000)
|
||||
build_path = /obj/item/swapper
|
||||
category = list("Bluespace Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
@@ -84,15 +84,7 @@ Note: Must be placed within 3 tiles of the R&D Console
|
||||
reclaim_materials_from(thing)
|
||||
for(var/mob/M in thing)
|
||||
M.death()
|
||||
if(istype(thing, /obj/item/stack/sheet))
|
||||
var/obj/item/stack/sheet/S = thing
|
||||
if(S.amount > 1 && !innermode)
|
||||
S.amount--
|
||||
loaded_item = S
|
||||
else
|
||||
qdel(S)
|
||||
else
|
||||
qdel(thing)
|
||||
qdel(thing)
|
||||
if (!innermode)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
display_name = "Bluespace Travel"
|
||||
description = "Application of Bluespace for static teleportation technology."
|
||||
prereq_ids = list("adv_power", "adv_bluespace")
|
||||
design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick", "bluespace_pipe")
|
||||
design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick", "bluespace_pipe","swapper")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
|
||||
/datum/techweb_node/unregulated_bluespace
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/list/accents = list() //done in order of priority (please always apply abductor accent and stuttering last)
|
||||
var/static/list/languages_possible_base = typecacheof(list(
|
||||
/datum/language/common,
|
||||
/datum/language/machine,
|
||||
/datum/language/draconic,
|
||||
/datum/language/codespeak,
|
||||
/datum/language/monkey,
|
||||
@@ -142,7 +143,7 @@
|
||||
icon_state = "tonguexeno"
|
||||
say_mod = "hisses"
|
||||
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
|
||||
maxHealth = 500 //They've a little mouth for a tongue, so it's pretty rhobust
|
||||
maxHealth = 500 //They've a little mouth for a tongue, so it's pretty robust
|
||||
initial_accents = list(/datum/accent/alien)
|
||||
var/static/list/languages_possible_alien = typecacheof(list(
|
||||
/datum/language/xenocommon,
|
||||
@@ -155,6 +156,13 @@
|
||||
. = ..()
|
||||
languages_possible = languages_possible_alien
|
||||
|
||||
/obj/item/organ/tongue/alien/hybrid
|
||||
name = "xenohybrid tongue"
|
||||
|
||||
/obj/item/organ/tongue/alien/hybrid/Initialize(mapload)
|
||||
. = ..()
|
||||
languages_possible = languages_possible_base
|
||||
|
||||
/obj/item/organ/tongue/bone
|
||||
name = "bone \"tongue\""
|
||||
desc = "Apparently skeletons alter the sounds they produce through oscillation of their teeth, hence their characteristic rattling."
|
||||
@@ -248,6 +256,7 @@
|
||||
taste_sensitivity = 101 // Not a tongue, they can't taste shit
|
||||
var/static/list/languages_possible_ethereal = typecacheof(list(
|
||||
/datum/language/common,
|
||||
/datum/language/machine,
|
||||
/datum/language/draconic,
|
||||
/datum/language/codespeak,
|
||||
/datum/language/monkey,
|
||||
@@ -269,6 +278,7 @@
|
||||
say_mod = "chitters"
|
||||
var/static/list/languages_possible_arachnid = typecacheof(list(
|
||||
/datum/language/common,
|
||||
/datum/language/machine,
|
||||
/datum/language/draconic,
|
||||
/datum/language/codespeak,
|
||||
/datum/language/monkey,
|
||||
|
||||
@@ -275,6 +275,18 @@
|
||||
purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS
|
||||
restricted = TRUE
|
||||
|
||||
//this seems like a terrible idea to me, so commenting it out for now. -Shell
|
||||
/*
|
||||
/datum/uplink_item/device_tools/tc_rod
|
||||
name = "Telecrystal Fuel Rod"
|
||||
desc = "This special fuel rod has eight material slots that can be inserted with telecrystals, \
|
||||
once the rod has been fully depleted, you will be able to harvest the extra telecrystals. \
|
||||
Please note: This Rod fissiles much faster than it's regular counterpart, it doesn't take \
|
||||
much to overload the reactor with these..."
|
||||
item = /obj/item/twohanded/required/fuel_rod/material/telecrystal
|
||||
cost = 7
|
||||
*/
|
||||
|
||||
/* for now
|
||||
/datum/uplink_item/device_tools/suspiciousphone
|
||||
name = "Protocol CRAB-17 Phone"
|
||||
|
||||
Reference in New Issue
Block a user