Merge remote-tracking branch 'upstream/master' into clothing

This commit is contained in:
Detective Google
2020-10-01 14:06:21 -05:00
189 changed files with 167220 additions and 84230 deletions
+6 -1
View File
@@ -9,7 +9,12 @@
#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag))
#define CHECK_BITFIELD(variable, flag) (variable & (flag))
#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag))
#define COPY_SPECIFIC_BITFIELDS(a,b,flags)\
do{\
var/_old = a & ~(flags);\
var/_cleaned = b & (flags);\
a = _old | _cleaned;\
} while(0);
#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) (((flagvar) & (flags)) == (flags))
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
-3
View File
@@ -230,9 +230,6 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define EXPLODE_LIGHT 3
#define EXPLODE_GIB_THRESHOLD 50
#define EMP_HEAVY 1
#define EMP_LIGHT 2
#define GRENADE_CLUMSY_FUMBLE 1
#define GRENADE_NONCLUMSY_FUMBLE 2
#define GRENADE_NO_FUMBLE 3
+2
View File
@@ -18,3 +18,5 @@
#define POLICYCONFIG_ON_DEFIB_INTACT "ON_DEFIB_INTACT"
/// Displayed to defibbed/revival surgery'd patients after the memory loss time threshold
#define POLICYCONFIG_ON_DEFIB_LATE "ON_DEFIB_LATE"
/// Displayed to pyroclastic slimes on spawn
#define POLICYCONFIG_ON_PYROCLASTIC_SENTIENT "PYROCLASTIC_SLIME"
+2 -2
View File
@@ -199,8 +199,8 @@
#define EXP_DISTRIBUTION(desired_mean) ( -(1/(1/desired_mean)) * log(rand(1, 1000) * 0.001) )
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan(TODEGREES(PI*(rand()-0.5))) + x )
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan((rand()-0.5)*180) + x )
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/180)*(arctan((x-y)/s)) + 1/2 )
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
// )
+1 -1
View File
@@ -312,7 +312,7 @@
#define HUMAN_FIRE_STACK_ICON_NUM 3
#define TYPING_INDICATOR_TIMEOUT 5 MINUTES
#define TYPING_INDICATOR_TIMEOUT 20 MINUTES
#define GRAB_PIXEL_SHIFT_PASSIVE 6
#define GRAB_PIXEL_SHIFT_AGGRESSIVE 12
+1 -1
View File
@@ -1,5 +1,5 @@
#define WOUND_DAMAGE_EXPONENT 1.225
#define WOUND_DAMAGE_EXPONENT 1.2
/// an attack must do this much damage after armor in order to roll for being a wound (incremental pressure damage need not apply)
#define WOUND_MINIMUM_DAMAGE 5
+4
View File
@@ -1254,6 +1254,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
var/obj/structure/window/W = O
if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
return FALSE
if(istype(O, /obj/structure/railing))
var/obj/structure/railing/rail = O
if(rail.ini_dir == dir_to_check || rail.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
return FALSE
return TRUE
/proc/pass()
+21
View File
@@ -149,6 +149,27 @@
name = "Choking (Plasma)"
desc = "There's highly flammable, toxic plasma in the air and you're breathing it in. Find some fresh air. The box in your backpack has an oxygen tank and gas mask in it."
icon_state = "too_much_tox"
/obj/screen/alert/not_enough_ch4
name = "Choking (No CH4)"
desc = "You're not getting enough methane. Find some good air before you pass out!"
icon_state = "not_enough_ch4"
/obj/screen/alert/too_much_ch4
name = "Choking (CH4)"
desc = "There's too much methane in the air, and you're breathing it in! Find some good air before you pass out!"
icon_state = "too_much_ch4"
/obj/screen/alert/not_enough_ch3br
name = "Choking (No CH3Br)"
desc = "You're not getting enough methyl bromide. Find some good air before you pass out!"
icon_state = "not_enough_tox"
/obj/screen/alert/too_much_ch3br
name = "Choking (CH3Br)"
desc = "There's highly toxic methyl bromide in the air and you're breathing it in. Find some fresh air. The box in your backpack has an oxygen tank and gas mask in it."
icon_state = "too_much_tox"
//End gas alerts
@@ -535,3 +535,15 @@
/datum/config_entry/number/max_shuttle_size
config_entry_value = 500
//wound config stuff (increases the max injury roll, making injuries more likely)
/datum/config_entry/number/wound_exponent
config_entry_value = WOUND_DAMAGE_EXPONENT
min_val = 0
integer = FALSE
//adds a set amount to any injury rolls on a limb using get_damage() multiplied by this number
/datum/config_entry/number/wound_damage_multiplier
config_entry_value = 0.333
min_val = 0
integer = FALSE
+1 -1
View File
@@ -366,7 +366,7 @@ SUBSYSTEM_DEF(air)
sleep(world.tick_lag)
var/timer = world.timeofday
log_mapping("There are [starting_ats] active turfs at roundstart caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required).")
var/list/turfs_to_check = get_amt_active_turfs()
var/list/turfs_to_check = get_active_turfs()
for(var/T in turfs_to_check)
GLOB.active_turfs_startlist += T
+4
View File
@@ -65,10 +65,14 @@
detonate(user)
/datum/component/killerqueen/proc/bump_detonate(datum/source, atom/A)
var/atom/us = parent
if(!us.density) // lazy anti-item-throw-OHKO, we need something better at some point
return
detonate(A)
/datum/component/killerqueen/proc/touch_detonate(datum/source, mob/user)
detonate(user)
return COMPONENT_NO_ATTACK_HAND
/datum/component/killerqueen/proc/on_examine(datum/source, mob/examiner, list/examine_return)
if(examine_message)
@@ -32,7 +32,7 @@ Bonus
"Stage Speed 10" = "Further increases cooling speed."
)
/datum/symptom/fever/Start(datum/disease/advance/A)
/datum/symptom/shivering/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 5) //dangerous cold
@@ -58,4 +58,4 @@ Bonus
if(unsafe)
limit = 0
M.adjust_bodytemperature(-get_cold * A.stage, limit)
return 1
return 1
+2 -2
View File
@@ -204,12 +204,12 @@
return S
/// Called from [/atom/proc/emp_act]
/datum/wires/proc/emp_pulse()
/datum/wires/proc/emp_pulse(severity)
var/list/possible_wires = shuffle(wires)
var/remaining_pulses = MAXIMUM_EMP_WIRES
for(var/wire in possible_wires)
if(prob(33))
if(prob(10 + severity/3.5))
pulse(wire)
remaining_pulses--
if(!remaining_pulses)
+68
View File
@@ -150,6 +150,74 @@
name = "Space Diner Solar Array"
icon_state = "yellow"
//Ruin of "Skelter" ship
/area/ruin/space/has_grav/skelter
name = "The Skelter"
icon_state = "red"
/area/ruin/space/has_grav/skelter/admin
name = "Administration"
icon_state = "bridge"
/area/ruin/space/has_grav/skelter/comms
name = "Communications"
icon_state = "tcomsatcomp"
/area/ruin/space/has_grav/skelter/sec
name = "Security Office"
icon_state = "security"
/area/ruin/space/has_grav/skelter/cafe
name = "Cafeteria"
icon_state = "cafeteria"
/area/ruin/space/has_grav/skelter/crew
name = "Crew Quarters"
icon_state = "crew_quarters"
/area/ruin/space/has_grav/skelter/med
name = "Med Bay"
icon_state = "medbay3"
/area/ruin/space/has_grav/skelter/engine
name = "Reactor"
icon_state = "engine"
/area/ruin/space/has_grav/skelter/engine/upper
name = "Port Engine"
/area/ruin/space/has_grav/skelter/engine/lower
name = "Starboard Engine"
/area/ruin/space/has_grav/skelter/engine/powerstorage
name = "Electrical"
icon_state = "engine_smes"
/area/ruin/space/has_grav/skelter/oxy
name = "02"
icon_state = "atmos"
/area/ruin/space/has_grav/skelter/nav
name = "Navigation"
icon_state = "start"
/area/ruin/space/has_grav/skelter/forehall
name = "Forward Hallway"
icon_state = "hallF"
/area/ruin/space/has_grav/skelter/afthall
name = "Aft Hallway"
icon_state = "hallA"
/area/ruin/space/has_grav/skelter/storage
name = "Storage"
icon_state = "storage"
/area/ruin/space/has_grav/skelter/shields
name = "Shields"
icon_state = "green"
//Ruin of Derelict Oupost
/area/ruin/space/has_grav/derelictoutpost
+1 -1
View File
@@ -296,7 +296,7 @@
/atom/proc/emp_act(severity)
var/protection = SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity)
if(!(protection & EMP_PROTECT_WIRES) && istype(wires))
wires.emp_pulse()
wires.emp_pulse(severity)
return protection // Pass the protection value collected here upwards
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
+4 -6
View File
@@ -173,7 +173,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
dat += "[DR.ruletype] - <b>[DR.name]</b><br>"
else
dat += "none.<br>"
dat += "<br>Injection Timers: (<b>[storyteller.get_injection_chance(TRUE)]%</b> chance)<BR>"
dat += "<br>Injection Timers:<BR>"
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
@@ -513,7 +513,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
drafted_rules -= starting_rule
starting_rule.trim_candidates()
starting_rule.scale_up(extra_rulesets_amount, threat_level)
starting_rule.scale_up(extra_rulesets_amount, threat_level-added_threat)
if (starting_rule.pre_execute())
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> [starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
if(starting_rule.flags & HIGHLANDER_RULESET)
@@ -675,13 +675,12 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
log_game("DYNAMIC: Checking for midround injection.")
update_playercounts()
if (prob(storyteller.get_injection_chance()))
if (storyteller.should_inject_antag())
SSblackbox.record_feedback("tally","dynamic",1,"Attempted midround injections")
var/list/drafted_rules = storyteller.midround_draft()
if (drafted_rules.len > 0)
SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
picking_midround_latejoin_rule(drafted_rules)
// get_injection_chance can do things on fail
/// Updates current_players.
/datum/game_mode/dynamic/proc/update_playercounts()
@@ -757,12 +756,11 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
picking_midround_latejoin_rule(list(forced_latejoin_rule), forced = TRUE)
forced_latejoin_rule = null
else if (latejoin_injection_cooldown < world.time && prob(storyteller.get_injection_chance()))
else if (storyteller.should_inject_antag())
SSblackbox.record_feedback("tally","dynamic",1,"Attempted latejoin injections")
var/list/drafted_rules = storyteller.latejoin_draft(newPlayer)
if (drafted_rules.len > 0 && picking_midround_latejoin_rule(drafted_rules))
SSblackbox.record_feedback("tally","dynamic",1,"Successful latejoin injections")
latejoin_injection_cooldown = storyteller.get_latejoin_cooldown() + world.time
/// Increase the threat level.
/datum/game_mode/dynamic/proc/create_threat(gain)
@@ -96,17 +96,11 @@ Property weights are added to the config weight of the ruleset. They are:
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min)
return round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max))
/datum/dynamic_storyteller/proc/get_latejoin_cooldown()
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_latejoin_delay_max + GLOB.dynamic_latejoin_delay_min)
return round(clamp(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_latejoin_delay_min, GLOB.dynamic_latejoin_delay_max))
/datum/dynamic_storyteller/proc/get_injection_chance(dry_run = FALSE)
/datum/dynamic_storyteller/proc/should_inject_antag(dry_run = FALSE)
if(mode.forced_injection)
mode.forced_injection = !dry_run
return 100
var/threat_perc = mode.threat/mode.threat_level
return clamp(round(100*(1-(threat_perc*threat_perc))**2,1),0,100)
return TRUE
return mode.threat < mode.threat_level
/datum/dynamic_storyteller/proc/roundstart_draft()
var/list/drafted_rules = list()
@@ -210,9 +204,6 @@ Property weights are added to the config weight of the ruleset. They are:
/datum/dynamic_storyteller/chaotic/get_midround_cooldown()
return ..() / 4
/datum/dynamic_storyteller/chaotic/get_latejoin_cooldown()
return ..() / 4
/datum/dynamic_storyteller/team
name = "Teamwork"
config_tag = "teamwork"
@@ -224,8 +215,8 @@ Property weights are added to the config weight of the ruleset. They are:
flags = WAROPS_ALWAYS_ALLOWED | USE_PREV_ROUND_WEIGHTS
property_weights = list("valid" = 3, "trust" = 5)
/datum/dynamic_storyteller/team/get_injection_chance(dry_run = FALSE)
return (mode.current_players[CURRENT_LIVING_ANTAGS].len ? 0 : ..())
/datum/dynamic_storyteller/team/should_inject_antag(dry_run = FALSE)
return (mode.current_players[CURRENT_LIVING_ANTAGS].len ? FALSE : ..())
/datum/dynamic_storyteller/conversion
name = "Conversion"
@@ -250,11 +241,8 @@ Property weights are added to the config weight of the ruleset. They are:
/datum/dynamic_storyteller/random/get_midround_cooldown()
return rand(GLOB.dynamic_midround_delay_min/2, GLOB.dynamic_midround_delay_max*2)
/datum/dynamic_storyteller/random/get_latejoin_cooldown()
return rand(GLOB.dynamic_latejoin_delay_min/2, GLOB.dynamic_latejoin_delay_max*2)
/datum/dynamic_storyteller/random/get_injection_chance()
return 50 // i would do rand(0,100) but it's actually the same thing when you do the math
/datum/dynamic_storyteller/random/should_inject_antag()
return prob(50)
/datum/dynamic_storyteller/random/roundstart_draft()
var/list/drafted_rules = list()
@@ -318,7 +306,7 @@ Property weights are added to the config weight of the ruleset. They are:
curve_width = 2
dead_player_weight = 2
flags = USE_PREV_ROUND_WEIGHTS
property_weights = list("trust" = -3)
property_weights = list("trust" = -2)
/datum/dynamic_storyteller/liteextended
name = "Calm"
@@ -326,7 +314,7 @@ Property weights are added to the config weight of the ruleset. They are:
desc = "Low-chaos round. Few antags. No conversion."
curve_centre = -3
curve_width = 0.5
flags = NO_ASSASSIN | FORCE_IF_WON
flags = NO_ASSASSIN
weight = 1
dead_player_weight = 5
property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "conversion" = -10)
@@ -344,5 +332,5 @@ Property weights are added to the config weight of the ruleset. They are:
/datum/dynamic_storyteller/no_antag/roundstart_draft()
return list()
/datum/dynamic_storyteller/no_antag/get_injection_chance(dry_run)
return 0
/datum/dynamic_storyteller/no_antag/should_inject_antag(dry_run)
return FALSE
+6 -7
View File
@@ -1,14 +1,15 @@
# DYNAMIC
Tries to keep the round at a certain level of action, based on the round's "threat level".
## ROUNDSTART
Dynamic rolls threat based on a special sauce formula:
"dynamic_curve_width \* tan((3.1416 \* (rand() - 0.5) \* 57.2957795)) + dynamic_curve_centre"
"dynamic_curve_width \* tan((rand() - 0.5) \* 180) + dynamic_curve_centre"
Latejoin and midround injection cooldowns are set using exponential distribution between
5 minutes and 25 for latejoin
15 minutes and 35 for midround
this value is then added to world.time and assigned to the injection cooldown variables.
Midround injection cooldowns are set using exponential distribution between 15 minutes and 35 minutes. This value is then added to world.time and assigned to the injection cooldown variables.
Latejoins are aggressively assigned whenever possible, to keep the round at a certain threat level.
rigged_roundstart() is called instead if there are forced rules (an admin set the mode)
@@ -26,8 +27,6 @@ If midround injection time is lower than world.time, it updates playercounts aga
make_antag_chance(newPlayer) -> [For each latespawn rule...]
-> acceptable(living players, threat_level) -> trim_candidates() -> ready(forced=FALSE)
**If true, add to drafted rules
**NOTE that acceptable uses threat_level not threat!
**NOTE Latejoin timer is ONLY reset if at least one rule was drafted.
**NOTE the new_player.dm AttemptLateSpawn() calls OnPostSetup for all roles (unless assigned role is MODE)
[After collecting all draftble rules...]
-> picking_latejoin_ruleset(drafted_rules) -> spend threat -> ruleset.execute()
+1 -1
View File
@@ -42,7 +42,7 @@
return ..()
/obj/machinery/dominator/emp_act(severity)
take_damage(100, BURN, "energy", 0)
take_damage(75+severity/4, BURN, "energy", 0)
..()
/obj/machinery/dominator/hulk_damage()
+1 -1
View File
@@ -95,7 +95,7 @@
inject_chem(R.type, occupant)
open_machine()
//Is this too much? Cit specific
if(severity == EMP_HEAVY)
if(severity >= 80)
var/chem = pick(available_chems)
available_chems -= chem
available_chems += get_random_reagent_id()
+2 -2
View File
@@ -175,7 +175,7 @@ Class Procs:
/obj/machinery/emp_act(severity)
. = ..()
if(use_power && !stat && !(. & EMP_PROTECT_SELF))
use_power(7500/severity)
use_power(1000 + severity*65)
new /obj/effect/temp_visual/emp(loc)
/obj/machinery/proc/open_machine(drop = TRUE)
@@ -535,7 +535,7 @@ Class Procs:
else if(zap_flags & ZAP_OBJ_DAMAGE)
take_damage(power/2000, BURN, "energy")
if(prob(40))
emp_act(EMP_LIGHT)
emp_act(50)
/obj/machinery/Exited(atom/movable/AM, atom/newloc)
. = ..()
+1 -1
View File
@@ -160,7 +160,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
/obj/machinery/announcement_system/emp_act(severity)
. = ..()
if(!(stat & (NOPOWER|BROKEN)) && !(. & EMP_PROTECT_SELF))
if(!(stat & (NOPOWER|BROKEN)) && !(. & EMP_PROTECT_SELF) && severity >= 30)
act_up()
/obj/machinery/announcement_system/emag_act()
+1 -1
View File
@@ -97,7 +97,7 @@
if(!status)
return
if(!(. & EMP_PROTECT_SELF))
if(prob(150/severity))
if(prob(severity/0.7))
update_icon()
var/list/previous_network = network
network = list()
+1 -1
View File
@@ -431,7 +431,7 @@
. = ..()
if (!(. & EMP_PROTECT_SELF))
var/mob/living/mob_occupant = occupant
if(mob_occupant && prob(100/(severity*efficiency)))
if(mob_occupant && prob((25+severity/1.34)/efficiency))
connected_message(Gibberish("EMP-caused Accidental Ejection", 0))
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of, ERROR: John Doe, prematurely." ,0))
mob_occupant.copy_from_prefs_vr()
+2 -7
View File
@@ -104,13 +104,8 @@
/obj/machinery/computer/emp_act(severity)
. = ..()
if (!(. & EMP_PROTECT_SELF))
switch(severity)
if(1)
if(prob(50))
obj_break("energy")
if(2)
if(prob(10))
obj_break("energy")
if(prob(severity/1.8))
obj_break("energy")
/obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user)
on_deconstruction()
+1 -6
View File
@@ -126,12 +126,7 @@
return
var/empprize = null
var/num_of_prizes = 0
switch(severity)
if(1)
num_of_prizes = rand(1,4)
if(2)
num_of_prizes = rand(0,2)
var/num_of_prizes = rand(round(severity/50),round(severity/100))
for(var/i = num_of_prizes; i > 0; i--)
empprize = pickweight(prizes)
new empprize(loc)
+2 -2
View File
@@ -541,7 +541,7 @@
. = ..()
if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF))
for(var/datum/data/record/R in GLOB.data_core.medical)
if(prob(10/severity))
if(prob(severity/10))
switch(rand(1,6))
if(1)
if(prob(10))
@@ -560,7 +560,7 @@
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
continue
else if(prob(1))
else if(prob(severity/80))
qdel(R)
continue
+2 -2
View File
@@ -769,7 +769,7 @@ What a mess.*/
return
for(var/datum/data/record/R in GLOB.data_core.security)
if(prob(10/severity))
if(prob(severity/10))
switch(rand(1,8))
if(1)
if(prob(10))
@@ -794,7 +794,7 @@ What a mess.*/
R.fields["photo_side"] = G.fields["photo_side"]
continue
else if(prob(1))
else if(prob(severity/80))
qdel(R)
continue
+1 -1
View File
@@ -612,7 +612,7 @@
. += "<span class='alloy'>The cogwheel has been <i>loosened</i>, but remains <b>connected loosely</b> to the door!</span>"
/obj/machinery/door/airlock/clockwork/emp_act(severity)
if(prob(80/severity))
if(prob(severity/1.25))
open()
/obj/machinery/door/airlock/clockwork/canAIControl(mob/user)
+1 -6
View File
@@ -243,13 +243,8 @@
. = ..()
if (. & EMP_PROTECT_SELF)
return
if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
if(prob(severity/5) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, .proc/open)
if(prob(severity*10 - 20))
if(secondsElectrified == MACHINE_NOT_ELECTRIFIED)
secondsElectrified = MACHINE_ELECTRIFIED_PERMANENT
LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\]EM Pulse")
addtimer(CALLBACK(src, .proc/unelectrify), 300)
/obj/machinery/door/proc/unelectrify()
secondsElectrified = MACHINE_NOT_ELECTRIFIED
+1 -1
View File
@@ -397,7 +397,7 @@
return ..()
/obj/machinery/door/window/clockwork/emp_act(severity)
if(prob(80/severity))
if(prob(severity/1.25))
open()
/obj/machinery/door/window/clockwork/ratvar_act()
+1 -1
View File
@@ -103,7 +103,7 @@
if (. & EMP_PROTECT_SELF)
return
if(prob(50 / severity))
if(prob(severity/1.8))
alarm()
/obj/machinery/firealarm/emag_act(mob/user)
@@ -719,9 +719,7 @@
/obj/machinery/porta_turret/syndicate/ComponentInitialize()
. = ..()
// AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) //this one or ^ one?
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
/obj/machinery/porta_turret/syndicate/setup()
return
+4 -5
View File
@@ -25,11 +25,10 @@
. = ..()
if (. & EMP_PROTECT_SELF)
return
switch(severity)
if(1)
qdel(src)
if(2)
take_damage(50, BRUTE, "energy", 0)
if(severity >= 70)
qdel(src)
else
take_damage(severity/1.3, BRUTE, "energy", 0)
/obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
+2 -2
View File
@@ -150,9 +150,9 @@
. = ..()
if(stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF)
return
if(prob(15 * severity))
if(prob(1500 / severity))
return
if(prob(1)) // :^)
if(prob(1 * severity/100)) // :^)
obj_flags |= EMAGGED
var/severity_ascending = 4 - severity
money = max(rand(money - (200 * severity_ascending), money + (200 * severity_ascending)), 0)
@@ -119,7 +119,7 @@ GLOBAL_LIST_EMPTY(telecomms_list)
/obj/machinery/telecomms/proc/update_power()
if(toggled)
// if powered, on. if not powered, off. if too damaged, off
if(CHECK_BITFIELD(stat, (BROKEN | NOPOWER | EMPED)))
if(CHECK_BITFIELD(stat, (BROKEN | NOPOWER | EMPED)))
on = FALSE
else
on = TRUE
@@ -139,9 +139,9 @@ GLOBAL_LIST_EMPTY(telecomms_list)
. = ..()
if(CHECK_BITFIELD(., EMP_PROTECT_SELF))
return
if(prob(100 / severity))
if(prob(severity))
if(!CHECK_BITFIELD(stat, EMPED))
ENABLE_BITFIELD(stat, EMPED)
var/duration = (300 * 10) / severity
var/duration = severity * 35
spawn(rand(duration - 20, duration + 20)) // Takes a long time for the machines to reboot.
DISABLE_BITFIELD(stat, EMPED)
+1 -1
View File
@@ -131,7 +131,7 @@
if(recharging)
return
if(chassis)
chassis.emp_act(EMP_HEAVY)
chassis.emp_act(80)
addtimer(CALLBACK(src, /obj/item/mecha_parts/mecha_tracking/proc/recharge), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
recharging = TRUE
+5 -9
View File
@@ -140,8 +140,8 @@
if (. & EMP_PROTECT_SELF)
return
if(get_charge())
use_power((cell.charge/3)/(severity*2))
take_damage(30 / severity, BURN, "energy", 1)
use_power(cell.charge*severity/100)
take_damage(severity/3, BURN, "energy", 1)
mecha_log_message("EMP detected", color="red")
if(istype(src, /obj/mecha/combat))
@@ -266,12 +266,8 @@
return 1
else if(istype(W, /obj/item/mecha_parts/mecha_tracking))
if(!user.transferItemToLoc(W, src))
to_chat(user, "<span class='warning'>\the [W] is stuck to your hand, you cannot put it in \the [src]!</span>")
return
trackers += W
user.visible_message("[user] attaches [W] to [src].", "<span class='notice'>You attach [W] to [src].</span>")
diag_hud_set_mechtracking()
var/obj/item/mecha_parts/mecha_tracking/tracker = W
tracker.try_attach_part(user, src)
return
else
return ..()
@@ -313,7 +309,7 @@
clearInternalDamage(MECHA_INT_CONTROL_LOST)
/obj/mecha/narsie_act()
emp_act(EMP_HEAVY)
emp_act(100)
/obj/mecha/ratvar_act()
if((GLOB.ratvar_awakens || GLOB.clockwork_gateway_activated) && occupant)
+13 -1
View File
@@ -291,7 +291,19 @@
S.rabid = TRUE
S.amount_grown = SLIME_EVOLUTION_THRESHOLD
S.Evolve()
offer_control(S,POLL_IGNORE_SENTIENCE_POTION)
var/list/candidates = pollCandidatesForMob("Do you want to play as a pyroclastic anomaly slime?",ROLE_SENTIENCE,null,ROLE_SENTIENCE,100,S,POLL_IGNORE_SENTIENCE_POTION)
if(length(candidates))
var/mob/C = pick(candidates)
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(S)])")
C.transfer_ckey(S, FALSE)
var/list/policies = CONFIG_GET(keyed_list/policyconfig)
var/policy = policies[POLICYCONFIG_ON_PYROCLASTIC_SENTIENT]
if(policy)
to_chat(S,policy)
return TRUE
else
message_admins("No ghosts were willing to take control of [ADMIN_LOOKUPFLW(S)])")
return FALSE
/////////////////////
+16 -20
View File
@@ -1,32 +1,28 @@
/proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
/proc/empulse(turf/epicenter, power, log=0)
if(!epicenter)
return
if(!isturf(epicenter))
epicenter = get_turf(epicenter.loc)
if(log)
message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
var/max_distance = max(round((power/7)^0.7), 1)
if(heavy_range >= 1)
if(log)
message_admins("EMP with power [power], max distance [max_distance] in area [epicenter.loc.name] ")
log_game("EMP with power [power], max distance [max_distance] in area [epicenter.loc.name] ")
if(power > 100)
new /obj/effect/temp_visual/emp/pulse(epicenter)
if(heavy_range > light_range)
light_range = heavy_range
for(var/A in spiral_range(light_range, epicenter))
for(var/A in spiral_range(max_distance, epicenter))
var/atom/T = A
var/distance = get_dist(epicenter, T)
if(distance < 0)
distance = 0
if(distance < heavy_range)
T.emp_act(EMP_HEAVY)
else if(distance == heavy_range)
if(prob(50))
T.emp_act(EMP_HEAVY)
else
T.emp_act(EMP_LIGHT)
else if(distance <= light_range)
T.emp_act(EMP_LIGHT)
var/severity = 100
if(distance != 0) //please dont divide by 0
severity = min(max((max_distance / distance^0.3) * (100/max_distance), 1),100) //if it goes below 1 or above 100 stuff gets bad
T.emp_act(severity)
return 1
/proc/empulse_using_range(turf/epicenter, range, log=0) //make an emp using range instead of power
var/power_from_range = (7*(range^(1/0.7)))
empulse(epicenter, power_from_range, log)
+1 -1
View File
@@ -101,7 +101,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
var/wipe_chance = 60 / severity
var/wipe_chance = severity/1.5
if(prob(wipe_chance))
visible_message("<span class='warning'>[src] fizzles and disappears!</span>")
qdel(src) //rip cash
+1 -1
View File
@@ -140,7 +140,7 @@
/obj/item/defibrillator/emp_act(severity)
. = ..()
if(cell && !(. & EMP_PROTECT_CONTENTS))
deductcharge(1000 / severity)
deductcharge(severity*10)
if (. & EMP_PROTECT_SELF)
return
if(safety)
+1 -1
View File
@@ -1206,7 +1206,7 @@ GLOBAL_LIST_EMPTY(PDAs)
A.emp_act(severity)
if (!(. & EMP_PROTECT_SELF))
emped += 1
spawn(200 * severity)
spawn(2 * severity)
emped -= 1
/proc/get_viewable_pdas()
@@ -225,7 +225,7 @@
if(C && istype(C) && C.bug == src)
if(!same_z_level(C))
return
C.emp_act(EMP_HEAVY)
C.emp_act(80)
C.bug = null
bugged_cameras -= C.c_tag
interact()
@@ -428,7 +428,7 @@
else
A.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].")
to_chat(user, "\The [src] now has [emp_cur_charges] charge\s.")
A.emp_act(EMP_HEAVY)
A.emp_act(80)
else
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
return
@@ -128,7 +128,7 @@
else if(istype(target, /obj/machinery/camera))
var/obj/machinery/camera/C = target
if(prob(effectchance * diode.rating))
C.emp_act(EMP_HEAVY)
C.emp_act(80)
outmsg = "<span class='notice'>You hit the lens of [C] with [src], temporarily disabling the camera!</span>"
log_combat(user, C, "EMPed", src)
else
+1 -1
View File
@@ -261,4 +261,4 @@
if (!(. & EMP_PROTECT_SELF))
turn_off()
if(!iscyborg(loc))
deductcharge(1000 / severity, TRUE, FALSE)
deductcharge(severity*10, TRUE, FALSE)
+1 -1
View File
@@ -351,7 +351,7 @@
/obj/item/book/granter/spell/charge/recoil(mob/user)
..()
to_chat(user,"<span class='warning'>[src] suddenly feels very warm!</span>")
empulse(src, 1, 1)
empulse_using_range(src, 1)
/obj/item/book/granter/spell/summonitem
spell = /obj/effect/proc_holder/spell/targeted/summonitem
@@ -7,5 +7,5 @@
/obj/item/grenade/empgrenade/prime(mob/living/lanced_by)
. = ..()
update_mob()
empulse(src, 4, 10)
empulse_using_range(src, 14)
qdel(src)
@@ -65,7 +65,7 @@
/obj/item/implant/emp/activate()
. = ..()
uses--
empulse(imp_in, 3, 5)
empulse_using_range(imp_in, 7)
if(!uses)
qdel(src)
+1
View File
@@ -2,6 +2,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("scooter frame", /obj/item/scooter_frame, 10, time = 25, one_per_turf = 0), \
new/datum/stack_recipe("railing", /obj/structure/railing, 3, time = 18, window_checks = TRUE), \
))
/obj/item/stack/rods
@@ -233,9 +233,13 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \
new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \
new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
new/datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \
null, \
new/datum/stack_recipe("wooden floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
new/datum/stack_recipe("large wooden floor tile", /obj/item/stack/tile/wood/wood_large, 1, 4, 20), \
new/datum/stack_recipe("tiled wooden floor tile", /obj/item/stack/tile/wood/wood_tiled, 1, 4, 20), \
new/datum/stack_recipe("diagonal wooden floor tile", /obj/item/stack/tile/wood/wood_diagonal, 1, 4, 20), \
null, \
new/datum/stack_recipe_list("pews", list(
new /datum/stack_recipe("pew (middle)", /obj/structure/chair/pew, 3, one_per_turf = TRUE, on_floor = TRUE),\
new /datum/stack_recipe("pew (left)", /obj/structure/chair/pew/left, 3, one_per_turf = TRUE, on_floor = TRUE),\
@@ -154,13 +154,31 @@
//Wood
/obj/item/stack/tile/wood
name = "wood floor tile"
name = "wooden plank floor tile"
singular_name = "wood floor tile"
desc = "An easy to fit wood floor tile."
icon_state = "tile-wood"
turf_type = /turf/open/floor/wood
resistance_flags = FLAMMABLE
/obj/item/stack/tile/wood/wood_large
name = "large wooden plank floor tile"
singular_name = "large wooden plank floor tile"
icon_state = "tile-wood_large"
turf_type = /turf/open/floor/wood/wood_large
/obj/item/stack/tile/wood/wood_tiled
name = "tiled wooden plank floor tile"
singular_name = "tiled wooden plank floor tile"
icon_state = "tile-wood_tile"
turf_type = /turf/open/floor/wood/wood_tiled
/obj/item/stack/tile/wood/wood_diagonal
name = "diagonal wooden plank floor tile"
singular_name = "diagonal wooden plank floor tile"
icon_state = "tile-wood_diagonal"
turf_type = /turf/open/floor/wood/wood_diagonal
//Cloth Floors
/obj/item/stack/tile/padded
+1 -1
View File
@@ -232,7 +232,7 @@
if (!(. & EMP_PROTECT_SELF))
switch_status(FALSE)
if(!iscyborg(loc))
deductcharge(1000 / severity, TRUE, FALSE)
deductcharge(severity*10, TRUE, FALSE)
/obj/item/melee/baton/stunsword
name = "stunsword"
@@ -182,3 +182,20 @@
/obj/item/tank/internals/emergency_oxygen/double/empty/populate_gas()
return
/*
* Methyl Bromide
*/
/obj/item/tank/internals/methyl_bromide
name = "mantid gas reactor"
desc = "A mantid gas processing plant that continuously synthesises 'breathable' atmosphere."
icon_state = "methyl_bromide"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
force = 6
distribute_pressure = 14
volume = 10
/obj/item/tank/internals/methyl_bromide/populate_gas()
air_contents.set_moles(/datum/gas/methyl_bromide, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
-24
View File
@@ -104,9 +104,6 @@
set_sign(new /datum/barsign/hiddensigns/empbarsign)
broken = TRUE
/obj/structure/sign/barsign/emag_act(mob/user)
. = ..()
if(broken || (obj_flags & EMAGGED))
@@ -128,8 +125,6 @@
return
set_sign(picked_name)
//Code below is to define useless variables for datums. It errors without these
@@ -140,95 +135,77 @@
var/desc = "desc"
var/hidden = FALSE
//Anything below this is where all the specific signs are. If people want to add more signs, add them below.
/datum/barsign/maltesefalcon
name = "Maltese Falcon"
icon = "maltesefalcon"
desc = "The Maltese Falcon, Space Bar and Grill."
/datum/barsign/thebark
name = "The Bark"
icon = "thebark"
desc = "Ian's bar of choice."
/datum/barsign/harmbaton
name = "The Harmbaton"
icon = "theharmbaton"
desc = "A great dining experience for both security members and assistants."
/datum/barsign/thesingulo
name = "The Singulo"
icon = "thesingulo"
desc = "Where people go that'd rather not be called by their name."
/datum/barsign/thedrunkcarp
name = "The Drunk Carp"
icon = "thedrunkcarp"
desc = "Don't drink and swim."
/datum/barsign/scotchservinwill
name = "Scotch Servin Willy's"
icon = "scotchservinwill"
desc = "Willy sure moved up in the world from clown to bartender."
/datum/barsign/officerbeersky
name = "Officer Beersky's"
icon = "officerbeersky"
desc = "Man eat a dong, these drinks are great."
/datum/barsign/thecavern
name = "The Cavern"
icon = "thecavern"
desc = "Fine drinks while listening to some fine tunes."
/datum/barsign/theouterspess
name = "The Outer Spess"
icon = "theouterspess"
desc = "This bar isn't actually located in outer space."
/datum/barsign/slipperyshots
name = "Slippery Shots"
icon = "slipperyshots"
desc = "Slippery slope to drunkeness with our shots!"
/datum/barsign/thegreytide
name = "The Grey Tide"
icon = "thegreytide"
desc = "Abandon your toolboxing ways and enjoy a lazy beer!"
/datum/barsign/honkednloaded
name = "Honked 'n' Loaded"
icon = "honkednloaded"
desc = "Honk."
/datum/barsign/thenest
name = "The Nest"
icon = "thenest"
desc = "A good place to retire for a drink after a long night of crime fighting."
/datum/barsign/thecoderbus
name = "The Coderbus"
icon = "thecoderbus"
desc = "A very controversial bar known for its wide variety of constantly-changing drinks."
/datum/barsign/theadminbus
name = "The Adminbus"
icon = "theadminbus"
@@ -313,7 +290,6 @@
hidden = TRUE
//Hidden signs list below this point
/datum/barsign/hiddensigns/empbarsign
name = "Haywire Barsign"
icon = "empbarsign"
@@ -571,10 +571,10 @@
O.emp_act(severity)
if(!secure || broken)
return ..()
if(prob(50 / severity))
if(prob(severity/2))
locked = !locked
update_icon()
if(prob(20 / severity) && !opened)
if(prob(severity/5) && !opened)
if(!locked)
open()
else
@@ -75,6 +75,8 @@
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.underwear = "Nude"
H.undershirt = "Nude"
H.socks = "Nude"
H.update_body()
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload)
+107
View File
@@ -0,0 +1,107 @@
/obj/structure/railing
name = "railing"
desc = "Basic railing meant to protect idiots like you from falling."
icon = 'icons/obj/fluff.dmi'
icon_state = "railing"
density = TRUE
anchored = TRUE
climbable = TRUE
///Initial direction of the railing.
var/ini_dir
/obj/structure/railing/corner //aesthetic corner sharp edges hurt oof ouch
icon_state = "railing_corner"
density = FALSE
climbable = FALSE
/obj/structure/railing/ComponentInitialize()
. = ..()
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation))
/obj/structure/railing/Initialize()
. = ..()
ini_dir = dir
/obj/structure/railing/attackby(obj/item/I, mob/living/user, params)
..()
add_fingerprint(user)
if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP)
if(obj_integrity < max_integrity)
if(!I.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You begin repairing [src]...</span>")
if(I.use_tool(src, user, 40, volume=50))
obj_integrity = max_integrity
to_chat(user, "<span class='notice'>You repair [src].</span>")
else
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
return
/obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I)
. = ..()
if(!anchored)
to_chat(user, "<span class='warning'>You cut apart the railing.</span>")
I.play_tool_sound(src, 100)
deconstruct()
return TRUE
/obj/structure/railing/deconstruct(disassembled)
. = ..()
if(!loc) //quick check if it's qdeleted already.
return
if(!(flags_1 & NODECONSTRUCT_1))
var/obj/item/stack/rods/rod = new /obj/item/stack/rods(drop_location(), 3)
transfer_fingerprints_to(rod)
qdel(src)
///Implements behaviour that makes it possible to unanchor the railing.
/obj/structure/railing/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(flags_1&NODECONSTRUCT_1)
return
to_chat(user, "<span class='notice'>You begin to [anchored ? "unfasten the railing from":"fasten the railing to"] the floor...</span>")
if(I.use_tool(src, user, volume = 75, extra_checks = CALLBACK(src, .proc/check_anchored, anchored)))
setAnchored(!anchored)
to_chat(user, "<span class='notice'>You [anchored ? "fasten the railing to":"unfasten the railing from"] the floor.</span>")
return TRUE
/obj/structure/railing/CanPass(atom/movable/mover, turf/target)
. = ..()
if(get_dir(loc, target) & dir)
var/checking = FLYING | FLOATING
return . || mover.throwing || mover.movement_type & checking
return TRUE
/obj/structure/railing/corner/CanPass()
..()
return TRUE
/obj/structure/railing/CheckExit(atom/movable/mover, turf/target)
..()
if(get_dir(loc, target) & dir)
var/checking = UNSTOPPABLE | FLYING | FLOATING
return !density || mover.throwing || mover.movement_type & checking || mover.move_force >= MOVE_FORCE_EXTREMELY_STRONG
return TRUE
/obj/structure/railing/corner/CheckExit()
return TRUE
/obj/structure/railing/proc/can_be_rotated(mob/user,rotation_type)
if(anchored)
to_chat(user, "<span class='warning'>[src] cannot be rotated while it is fastened to the floor!</span>")
return FALSE
var/target_dir = turn(dir, rotation_type == ROTATION_CLOCKWISE ? -90 : 90)
if(!valid_window_location(loc, target_dir)) //Expanded to include rails, as well!
to_chat(user, "<span class='warning'>[src] cannot be rotated in that direction!</span>")
return FALSE
return TRUE
/obj/structure/railing/proc/check_anchored(checked_anchored)
if(anchored == checked_anchored)
return TRUE
/obj/structure/railing/proc/after_rotation(mob/user,rotation_type)
air_update_turf(1)
ini_dir = dir
add_fingerprint(user)
+15
View File
@@ -16,6 +16,18 @@
var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC
var/turf/listeningTo
/obj/structure/stairs/north
dir = NORTH
/obj/structure/stairs/south
dir = SOUTH
/obj/structure/stairs/east
dir = EAST
/obj/structure/stairs/west
dir = WEST
/obj/structure/stairs/Initialize(mapload)
if(force_open_above)
force_open_above()
@@ -105,6 +117,9 @@
T.ChangeTurf(/turf/open/transparent/openspace, flags = CHANGETURF_INHERIT_AIR)
/obj/structure/stairs/proc/on_multiz_new(turf/source, dir)
//SIGNAL_HANDLER
SHOULD_NOT_SLEEP(TRUE) //the same thing.
if(dir == UP)
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
if(T && !istype(T))
@@ -74,6 +74,24 @@
/turf/open/floor/wood/airless
initial_gas_mix = AIRLESS_ATMOS
/turf/open/floor/wood/wood_large
desc = "Stylish dark wood."
icon_state = "large_wood"
floor_tile = /obj/item/stack/tile/wood/wood_large
broken_states = list("large_wood-broken", "large_wood-broken2", "large_wood-broken3")
/turf/open/floor/wood/wood_tiled
desc = "Stylish dark wood."
icon_state = "wood_tile"
floor_tile = /obj/item/stack/tile/wood/wood_tiled
broken_states = list("wood_tile-broken", "wood_tile-broken2", "wood_tile-broken3")
/turf/open/floor/wood/wood_diagonal
desc = "Stylish dark wood."
icon_state = "diagonal_wood"
floor_tile = /obj/item/stack/tile/wood/wood_diagonal
broken_states = list("diagonal_wood-broken", "diagonal_wood-broken2", "diagonal_wood-broken3")
/turf/open/floor/grass
name = "grass patch"
desc = "You can't tell if this is real grass or just cheap plastic imitation."
+6 -15
View File
@@ -646,23 +646,14 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!check_rights(R_ADMIN))
return
var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
if(heavy == null)
return
var/light = input("Range of light pulse.", text("Input")) as num|null
if(light == null)
var/range = input("Range.", text("Input")) as num|null
if(!range)
return
log_admin("[key_name(usr)] created an EM Pulse - log below") //because we'll just log the empulse itself
message_admins("[key_name_admin(usr)] created an EM Pulse at [AREACOORD(O)] with range [range]")
empulse_using_range(O, range, TRUE) //its details get shown too
if (heavy || light)
empulse(O, heavy, light)
log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]")
message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
else
return
SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
set category = "Special Verbs"
@@ -18,7 +18,7 @@
/datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag)
if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser")
empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it
empulse_using_range(B.loc, 5) //less than screen range, so you can stand out of range to avoid it
/datum/reagent/blob/electromagnetic_web
name = "Electromagnetic Web"
@@ -28,6 +28,6 @@
/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(prob(reac_volume*2))
M.emp_act(EMP_LIGHT)
M.emp_act(50)
if(M)
M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND)
@@ -204,7 +204,7 @@
if(severity > 0)
if(overmind)
overmind.blobstrain.emp_reaction(src, severity)
if(prob(100 - severity * 30))
if(prob(severity/1.5))
new /obj/effect/temp_visual/emp(get_turf(src))
/obj/structure/blob/zap_act(power)
@@ -48,6 +48,6 @@
for(var/obj/machinery/light/L in range(5, usr))
L.on = 1
L.break_light_tube()
empulse(get_turf(user), 2, 5, 1)
empulse_using_range(get_turf(user), 8, TRUE)
playsound(get_turf(user), 'sound/effects/lingempscreech.ogg', 75, TRUE, 5, soundenvwet = 0)
return TRUE
@@ -223,7 +223,7 @@
L.flash_act(1, 1)
if(issilicon(target))
var/mob/living/silicon/S = L
S.emp_act(EMP_HEAVY)
S.emp_act(80)
else //for Nar'sian weaklings
to_chat(L, "<span class='heavy_brass'>\"How does it feel to see the light, dog?\"</span>")
L.visible_message("<span class='warning'>[L]'s eyes flare with burning light!</span>", \
@@ -11,7 +11,7 @@
/obj/structure/destructible/clockwork/trap/power_nullifier/activate()
if(!activated)
activated = TRUE
empulse(get_turf(src),1,1,TRUE)
empulse_using_range(get_turf(src),1,TRUE)
/obj/structure/destructible/clockwork/trap/power_nullifier/emp_act(var/strength=1)
activate()
+3 -3
View File
@@ -165,7 +165,7 @@
/datum/action/innate/cult/blood_spell/emp/Activate()
owner.visible_message("<span class='warning'>[owner]'s hand flashes a bright blue!</span>", \
"<span class='cultitalic'>You speak the cursed words, emitting an EMP blast from your hand.</span>")
empulse(owner, 2, 5)
empulse_using_range(owner, 8)
owner.whisper(invocation, language = /datum/language/common)
charges--
if(charges<=0)
@@ -451,7 +451,7 @@
L.flash_act(1,1)
if(issilicon(target))
var/mob/living/silicon/S = L
S.emp_act(EMP_HEAVY)
S.emp_act(80)
else if(iscarbon(target))
var/mob/living/carbon/C = L
C.silent += clamp(12 - C.silent, 0, 6)
@@ -610,7 +610,7 @@
var/prev_color = candidate.color
candidate.color = "black"
if(do_after(user, 90, target = candidate))
candidate.emp_act(EMP_HEAVY)
candidate.emp_act(80)
var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
user.visible_message("<span class='danger'>The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!</span>")
switch(construct_class)
+1 -1
View File
@@ -982,7 +982,7 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message("<span class='warning'>A colossal shockwave of energy bursts from the rune, disintegrating it in the process!</span>")
for(var/mob/living/L in range(src, 3))
L.DefaultCombatKnockdown(30)
empulse(T, 0.42*(intensity), 1)
empulse_using_range(T, 0.65*(intensity))
var/list/images = list()
var/zmatch = T.z
var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
@@ -424,8 +424,7 @@
range = -1
include_user = TRUE
charge_max = 300
emp_heavy = 6
emp_light = 10
range = 14
sound = 'sound/effects/lingscreech.ogg'
/obj/effect/proc_holder/spell/aoe_turf/fire_cascade
@@ -300,7 +300,7 @@
continue
to_chat(human, "<span class='revenwarning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>")
new /obj/effect/temp_visual/revenant(human.loc)
human.emp_act(EMP_HEAVY)
human.emp_act(80)
for(var/obj/thing in T)
if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes)) //Doesn't work on SMES and APCs, to prevent kekkery
continue
@@ -310,12 +310,12 @@
thing.emag_act(null)
else
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
thing.emp_act(EMP_HEAVY)
thing.emp_act(80)
for(var/mob/living/silicon/robot/S in T) //Only works on cyborgs, not AI
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
new /obj/effect/temp_visual/revenant(S.loc)
S.spark_system.start()
S.emp_act(EMP_HEAVY)
S.emp_act(80)
//Blight: Infects nearby humans and in general messes living stuff up.
/obj/effect/proc_holder/spell/aoe_turf/revenant/blight
@@ -186,6 +186,20 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
moles_visible = MOLES_GAS_VISIBLE * 60
rarity = 250
/datum/gas/methane
id = "methane"
specific_heat = 30
name = "Methane"
rarity = 320
/datum/gas/methyl_bromide
id = "methyl_bromide"
specific_heat = 42
name = "Methyl Bromide"
dangerous = TRUE
rarity = 310
/obj/effect/overlay/gas
icon = 'icons/effects/atmospherics.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
@@ -97,7 +97,7 @@
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
/datum/gas/miasma = new/datum/tlv(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
@@ -106,7 +106,9 @@
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/server // No checks here.
@@ -125,7 +127,9 @@
/datum/gas/tritium = new/datum/tlv/no_checks,
/datum/gas/stimulum = new/datum/tlv/no_checks,
/datum/gas/nitryl = new/datum/tlv/no_checks,
/datum/gas/pluoxium = new/datum/tlv/no_checks
/datum/gas/pluoxium = new/datum/tlv/no_checks,
/datum/gas/methane = new/datum/tlv/no_checks,
/datum/gas/methyl_bromide = new/datum/tlv/no_checks
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
@@ -144,7 +148,9 @@
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/unlocked
@@ -542,7 +548,9 @@
/datum/gas/tritium,
/datum/gas/bz,
/datum/gas/stimulum,
/datum/gas/pluoxium
/datum/gas/pluoxium,
/datum/gas/methane,
/datum/gas/methyl_bromide
),
"scrubbing" = 1,
"widenet" = 1,
@@ -50,7 +50,9 @@
"stimulum" = /obj/machinery/portable_atmospherics/canister/stimulum,
"pluoxium" = /obj/machinery/portable_atmospherics/canister/pluoxium,
"caution" = /obj/machinery/portable_atmospherics/canister,
"miasma" = /obj/machinery/portable_atmospherics/canister/miasma
"miasma" = /obj/machinery/portable_atmospherics/canister/miasma,
"methane" = /obj/machinery/portable_atmospherics/canister/methane,
"methyl bromide" = /obj/machinery/portable_atmospherics/canister/methyl_bromide
)
/obj/machinery/portable_atmospherics/canister/interact(mob/user)
@@ -62,7 +64,7 @@
/obj/machinery/portable_atmospherics/canister/nitrogen
name = "n2 canister"
desc = "Nitrogen gas. Reportedly useful for something."
desc = "Nitrogen. Reportedly useful for something."
icon_state = "red"
gas_type = /datum/gas/nitrogen
@@ -80,19 +82,19 @@
/obj/machinery/portable_atmospherics/canister/toxins
name = "plasma canister"
desc = "Plasma gas. The reason YOU are here. Highly toxic."
desc = "Plasma. The reason YOU are here. Highly toxic."
icon_state = "orange"
gas_type = /datum/gas/plasma
/obj/machinery/portable_atmospherics/canister/bz
name = "\improper BZ canister"
desc = "BZ, a powerful hallucinogenic nerve agent."
desc = "BZ. A powerful hallucinogenic nerve agent."
icon_state = "purple"
gas_type = /datum/gas/bz
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "n2o canister"
desc = "Nitrous oxide gas. Known to cause drowsiness."
desc = "Nitrous oxide. Known to cause drowsiness."
icon_state = "redws"
gas_type = /datum/gas/nitrous_oxide
@@ -115,7 +117,7 @@
/obj/machinery/portable_atmospherics/canister/nitryl
name = "nitryl canister"
desc = "Nitryl gas. Feels great 'til the acid eats your lungs."
desc = "Nitryl. Feels great 'til the acid eats your lungs."
icon_state = "brown"
gas_type = /datum/gas/nitryl
@@ -133,7 +135,7 @@
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "water vapor canister"
desc = "Water Vapor. We get it, you vape."
desc = "Water vapor. We get it, you vape."
icon_state = "water_vapor"
gas_type = /datum/gas/water_vapor
filled = 1
@@ -145,6 +147,18 @@
gas_type = /datum/gas/miasma
filled = 1
/obj/machinery/portable_atmospherics/canister/methane
name = "methane canister"
desc = "Methane. The simplest of hydrocarbons. Non-toxic but highly flammable."
icon_state = "greyblackred"
gas_type = /datum/gas/methane
/obj/machinery/portable_atmospherics/canister/methyl_bromide
name = "methyl bromide canister"
desc = "Methyl bromide. A potent toxin to most, essential for the Kharmaan to live."
icon_state = "purplecyan"
gas_type = /datum/gas/methyl_bromide
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
if(timing)
. = round(max(0, valve_timer - world.time) / 10, 1)
@@ -63,9 +63,9 @@
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
if(prob(50 / severity))
if(prob(severity/2))
on = !on
if(prob(100 / severity))
if(prob(severity))
direction = PUMP_OUT
pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE)
update_icon()
@@ -80,7 +80,6 @@
else if(on && holding && direction == PUMP_OUT)
investigate_log("[key_name(user)] started a transfer into [holding].", INVESTIGATE_ATMOS)
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -58,7 +58,7 @@
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
if(prob(50 / severity))
if(prob(severity/3))
on = !on
update_icon()
+2 -1
View File
@@ -8,6 +8,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/client/parent
//doohickeys for savefiles
var/path
var/vr_path
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
var/max_save_slots = 16
@@ -544,7 +545,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(length(pref_species.allowed_limb_ids))
if(!chosen_limb_id || !(chosen_limb_id in pref_species.allowed_limb_ids))
chosen_limb_id = pref_species.id
chosen_limb_id = pref_species.limbs_id || pref_species.id
dat += "<h3>Body sprite</h3>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=bodysprite;task=input'>[chosen_limb_id]</a>"
+51 -14
View File
@@ -212,26 +212,31 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!ckey)
return
path = "data/player_saves/[ckey[1]]/[ckey]/[filename]"
vr_path = "data/player_saves/[ckey[1]]/[ckey]/vore"
/datum/preferences/proc/load_preferences()
if(!path)
return 0
return FALSE
if(world.time < loadprefcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your preferences a little too fast. Wait half a second, then try again.</span>")
return 0
return FALSE
loadprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!fexists(path))
return 0
return FALSE
var/savefile/S = new /savefile(path)
if(!S)
return 0
return FALSE
S.cd = "/"
var/needs_update = savefile_needs_update(S)
if(needs_update == -2) //fatal, can't load any data
return 0
var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup
if (fexists(bacpath))
fdel(bacpath) //only keep 1 version of backup
fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg.
return FALSE
. = TRUE
@@ -293,8 +298,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//try to fix any outdated data if necessary
if(needs_update >= 0)
var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup
if (fexists(bacpath))
fdel(bacpath) //only keep 1 version of backup
fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg.
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
//Sanitize
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
@@ -336,7 +347,25 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped
return 1
if(needs_update >= 0) //save the updated version
var/old_default_slot = default_slot
var/old_max_save_slots = max_save_slots
for (var/slot in S.dir) //but first, update all current character slots.
if (copytext(slot, 1, 10) != "character")
continue
var/slotnum = text2num(copytext(slot, 10))
if (!slotnum)
continue
max_save_slots = max(max_save_slots, slotnum) //so we can still update byond member slots after they lose memeber status
default_slot = slotnum
if (load_character()) // this updtates char slots
save_character()
default_slot = old_default_slot
max_save_slots = old_max_save_slots
save_preferences()
return TRUE
/datum/preferences/proc/verify_keybindings_valid()
// Sanitize the actual keybinds to make sure they exist.
@@ -426,17 +455,17 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
/datum/preferences/proc/load_character(slot)
if(!path)
return 0
return FALSE
if(world.time < loadcharcooldown) //This is before the check to see if the filepath exists to ensure that BYOND can't get hung up on read attempts when the hard drive is a little slow
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your character a little too fast. Wait half a second, then try again.</span>")
return "SLOW THE FUCK DOWN" //the reason this isn't null is to make sure that people don't have their character slots overridden by random chars if they accidentally double-click a slot
loadcharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!fexists(path))
return 0
return FALSE
var/savefile/S = new /savefile(path)
if(!S)
return 0
return FALSE
S.cd = "/"
if(!slot)
slot = default_slot
@@ -448,7 +477,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S.cd = "/character[slot]"
var/needs_update = savefile_needs_update(S)
if(needs_update == -2) //fatal, can't load any data
return 0
return FALSE
. = TRUE
@@ -466,7 +495,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pref_species = new newtype
scars_index = rand(1,5)
scars_index = rand(1,5) // WHY
//Character
S["real_name"] >> real_name
@@ -609,8 +638,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["vore_flags"] >> vore_flags
S["vore_taste"] >> vore_taste
S["belly_prefs"] >> belly_prefs
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
if(fexists(char_vr_path))
var/list/json_from_file = json_decode(file2text(char_vr_path))
if(json_from_file)
belly_prefs = json_from_file["belly_prefs"]
//gear loadout
var/text_to_load
S["loadout"] >> text_to_load
@@ -627,6 +659,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
gear_points -= init_cost
//try to fix any outdated data if necessary
//preference updating will handle saving the updated data for us.
if(needs_update >= 0)
update_character(needs_update, S) //needs_update == savefile_version if we need an update (positive integer)
@@ -877,7 +910,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["vore_flags"] , vore_flags)
WRITE_FILE(S["vore_taste"] , vore_taste)
WRITE_FILE(S["belly_prefs"] , belly_prefs)
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
var/belly_prefs_json = safe_json_encode(list("belly_prefs" = belly_prefs))
if(fexists(char_vr_path))
fdel(char_vr_path)
text2file(belly_prefs_json,char_vr_path)
WRITE_FILE(S["persistent_scars"] , persistent_scars)
WRITE_FILE(S["scars1"] , scars_list["1"])
@@ -62,13 +62,12 @@
if(. & EMP_PROTECT_SELF)
return
var/mob/living/carbon/human/user = src.loc
switch(severity)
if(1)
if(activated && user && ishuman(user) && (user.wear_suit == src))
to_chat(user, "<span class='danger'>E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD</span>")
to_chat(user, "<span class='userdanger'>An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!</span>")
user.emote("scream")
deactivate(1, 1)
if(severity >= 70)
if(activated && user && ishuman(user) && (user.wear_suit == src))
to_chat(user, "<span class='danger'>E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD</span>")
to_chat(user, "<span class='userdanger'>An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!</span>")
user.emote("scream")
deactivate(1, 1)
/obj/item/clothing/suit/space/chronos/proc/finish_chronowalk(mob/living/carbon/human/user, turf/to_turf)
if(!user)
@@ -525,7 +525,7 @@ Contains:
icon_state = "hunter"
item_state = "swat_suit"
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat)
armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wpound" = 25)
armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 25)
strip_delay = 130
resistance_flags = FIRE_PROOF | ACID_PROOF
+17
View File
@@ -102,3 +102,20 @@
/obj/item/clothing/neck/cloak/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, poly_colors, 3)
/obj/item/clothing/neck/cloak/alt
name = "cloak"
desc = "A ragged up white cloak. It reminds you of a place not far from here."
icon_state = "cloak"
item_state = "cloak"
/obj/item/clothing/neck/cloak/alt/polychromic
name = "polychromic cloak"
desc = "A ragged up cloak. It reminds you of a place not far from here."
icon_state = "cloak"
item_state = "cloak"
var/list/poly_colors = list("#FFFFFF", "#676767", "#4C4C4C")
/obj/item/clothing/neck/cloak/alt/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, poly_colors, 3)
@@ -41,6 +41,13 @@
fitted = FEMALE_UNIFORM_TOP
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/under/rank/cargo/tech/long
name = "cargo technician's jumpsuit (trousers)"
desc = "A variant of the cargo technician's uniform with proper trousers, suited for colder climates and modest workers."
icon_state = "cargo_long"
item_state = "lb_suit"
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/cargo/miner
name = "shaft miner's jumpsuit"
desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty."
@@ -23,4 +23,4 @@
/datum/round_event/communications_blackout/start()
for(var/obj/machinery/telecomms/T in GLOB.telecomms_list)
T.emp_act(EMP_HEAVY)
T.emp_act(80)
+1 -1
View File
@@ -141,7 +141,7 @@
for(var/obj/machinery/rnd/server/S in GLOB.machines)
if(S.stat & (NOPOWER|BROKEN))
continue
S.emp_act(1)
S.emp_act(80)
new /obj/effect/temp_visual/emp(get_turf(S))
/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
+1 -1
View File
@@ -36,4 +36,4 @@
// at all
P.ex_act(EXPLODE_DEVASTATE)
else
P.emp_act(EMP_HEAVY)
P.emp_act(80)
+2 -1
View File
@@ -893,7 +893,8 @@
if(issilicon(user)) //How does AI know what plant is?
return
if(harvest)
return myseed.harvest(user)
myseed.harvest(user)
return
else if(dead)
dead = 0
+14
View File
@@ -59,3 +59,17 @@
var/mob/living/silicon/robot/R = user.mob
R.uneq_active()
return TRUE
/datum/keybinding/robot/drone/can_use(client/user)
return isdrone(user.mob)
/datum/keybinding/robot/drone/quick_equip_drone // QOL: Drone quickequip
hotkey_keys = list("E")
name = "quick_equip_drone"
full_name = "Quick Equip (Drone)"
description = "Quickly puts an item in the best slot available"
/datum/keybinding/robot/drone/quick_equip_drone/down(client/user)
var/mob/living/simple_animal/drone/D = user.mob
D.quick_equip()
return TRUE
@@ -61,24 +61,18 @@
playsound(src,'sound/effects/sparks4.ogg',50,1)
qdel(src)
/obj/item/wormhole_jaunter/emp_act(power)
/obj/item/wormhole_jaunter/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
var/mob/M = loc
if(istype(M))
var/triggered = FALSE
if(M.get_item_by_slot(SLOT_BELT) == src)
if(power == 1)
triggered = TRUE
else if(power == 2 && prob(50))
triggered = TRUE
if(triggered)
M.visible_message("<span class='warning'>[src] overloads and activates!</span>")
SSblackbox.record_feedback("tally", "jaunter", 1, "EMP") // EMP accidental activation
activate(M)
if(prob(severity))
M.visible_message("<span class='warning'>[src] overloads and activates!</span>")
SSblackbox.record_feedback("tally", "jaunter", 1, "EMP") // EMP accidental activation
activate(M)
/obj/item/wormhole_jaunter/proc/chasm_react(mob/source, datum/component/chasm/C)
to_chat(source, "Your [name] activates, saving you from the chasm!</span>")
+1 -7
View File
@@ -169,13 +169,7 @@
if(!brainmob || iscyborg(loc))
return
else
switch(severity)
if(1)
brainmob.emp_damage = min(brainmob.emp_damage + rand(20,30), 30)
if(2)
brainmob.emp_damage = min(brainmob.emp_damage + rand(10,20), 30)
if(3)
brainmob.emp_damage = min(brainmob.emp_damage + rand(0,10), 30)
brainmob.emp_damage = min(brainmob.emp_damage + rand(-5,5) + severity/3, 30)
brainmob.emote("alarm")
/obj/item/mmi/Destroy()
@@ -412,13 +412,8 @@
if(!informed)
to_chat(src, "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>")
informed = TRUE
switch(severity)
if(1)
L.receive_damage(0,10)
Stun(200)
if(2)
L.receive_damage(0,5)
Stun(100)
L.receive_damage(0,severity/10)
Stun(severity*2)
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit)
var/list/damaged = list()
@@ -96,6 +96,8 @@
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else if(S.breathid == "n2")
throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)
else if(S.breathid == "ch3br")
throw_alert("not_enough_ch3br", /obj/screen/alert/not_enough_ch3br)
return FALSE
else
@@ -362,10 +362,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.client && has_field_of_vision && CONFIG_GET(flag/use_field_of_vision))
H.LoadComponent(/datum/component/field_of_vision, H.field_of_vision_type)
C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod)
update_species_slowdown(C)
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
/datum/species/proc/update_species_slowdown(mob/living/carbon/human/H)
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod)
// EDIT ENDS
@@ -141,4 +141,5 @@
H.setMovetype(H.movement_type & ~FLYING)
override_float = FALSE
H.pass_flags &= ~PASSTABLE
H.CloseWings()
H.CloseWings()
update_species_slowdown(H)
@@ -84,11 +84,7 @@
EMPeffect = TRUE
spec_updatehealth(H)
to_chat(H, "<span class='notice'>You feel the light of your body leave you.</span>")
switch(severity)
if(EMP_LIGHT)
addtimer(CALLBACK(src, .proc/stop_emp, H), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds
if(EMP_HEAVY)
addtimer(CALLBACK(src, .proc/stop_emp, H), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds
addtimer(CALLBACK(src, .proc/stop_emp, H), (severity/5) SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //lights out
/datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/H, mob/user)
if(emageffect)
@@ -249,6 +249,8 @@
var/mob/living/carbon/human/spare = new /mob/living/carbon/human(H.loc)
spare.underwear = "Nude"
spare.undershirt = "Nude"
spare.socks = "Nude"
H.dna.transfer_identity(spare, transfer_SE=1)
spare.dna.features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
spare.real_name = spare.dna.real_name
@@ -435,6 +437,8 @@
heatmod = 1
burnmod = 1
allowed_limb_ids = list("slime","stargazer","lum")
/datum/action/innate/slime_change
name = "Alter Form"
check_flags = AB_CHECK_CONSCIOUS
@@ -184,7 +184,7 @@
else if(isliving(AM))
var/mob/living/L = AM
if(isethereal(AM))
AM.emp_act(EMP_LIGHT)
AM.emp_act(50)
if(iscyborg(AM))
var/mob/living/silicon/robot/borg = AM
if(borg.lamp_intensity)
@@ -19,13 +19,14 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
disconnect_shell()
if (prob(30))
switch(pick(1,2))
if(1)
view_core()
if(2)
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
if(severity >= 60)
disconnect_shell()
if(prob(30))
switch(pick(1,2))
if(1)
view_core()
if(2)
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
/mob/living/silicon/ai/ex_act(severity, target)
switch(severity)
@@ -7,8 +7,8 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
take_holo_damage(50/severity)
DefaultCombatKnockdown(400/severity)
take_holo_damage(severity/2)
DefaultCombatKnockdown(severity*4)
silent = max(silent, (PAI_EMP_SILENCE_DURATION) / SSmobs.wait / severity)
if(holoform)
fold_in(force = TRUE)
@@ -85,12 +85,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
switch(severity)
if(1)
Paralyze(160)
if(2)
Paralyze(60)
Paralyze(10 + severity/1.2)
/mob/living/silicon/robot/emag_act(mob/user)
if(user == src)//To prevent syndieborgs from emagging themselves
@@ -105,14 +105,10 @@
to_chat(src, "<span class='danger'>Warning: Electromagnetic pulse detected.</span>")
if(. & EMP_PROTECT_SELF)
return
switch(severity)
if(1)
src.take_bodypart_damage(20)
if(2)
src.take_bodypart_damage(10)
src.take_bodypart_damage(severity/5)
to_chat(src, "<span class='userdanger'>*BZZZT*</span>")
for(var/mob/living/M in buckled_mobs)
if(prob(severity*50))
if(prob(severity/2))
unbuckle_mob(M)
M.DefaultCombatKnockdown(40)
M.visible_message("<span class='boldwarning'>[M] is thrown off of [src]!</span>",

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