Merge branch 'master' into cool-ipcs

This commit is contained in:
Timothy Teakettle
2020-10-01 21:06:16 +01:00
committed by GitHub
522 changed files with 181605 additions and 92979 deletions
+2 -1
View File
@@ -43,6 +43,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
considered_hull_exterior = TRUE
/area/space/nearstation
icon_state = "space_near"
@@ -1592,4 +1593,4 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
valid_territory = FALSE
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE //While part of the station, what good will it do you?
blob_allowed = FALSE //While part of the station, what good will it do you?
+3
View File
@@ -34,6 +34,9 @@
/// If megafauna can be spawned by natural random generation
var/megafauna_spawn_allowed = FALSE
/// Considered space for hull shielding
var/considered_hull_exterior = FALSE
var/fire = null
var/atmos = TRUE
var/atmosalm = FALSE
+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
+19 -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)
@@ -1127,3 +1127,21 @@
*/
/atom/proc/rust_heretic_act()
return
///Passes Stat Browser Panel clicks to the game and calls client click on an atom
/atom/Topic(href, list/href_list)
. = ..()
if(!usr?.client)
return
var/client/usr_client = usr.client
var/list/paramslist = list()
if(href_list["statpanel_item_shiftclick"])
paramslist["shift"] = "1"
if(href_list["statpanel_item_ctrlclick"])
paramslist["ctrl"] = "1"
if(href_list["statpanel_item_altclick"])
paramslist["alt"] = "1"
if(href_list["statpanel_item_click"])
// first of all make sure we valid
var/mouseparams = list2params(paramslist)
usr_client.Click(src, loc, null, mouseparams)
+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()
+2 -2
View File
@@ -56,7 +56,7 @@
<li>There are many other ways; be creative!</li>\
</ul>"
/datum/sabotage_objective/processing/supermatter
/*/datum/sabotage_objective/processing/supermatter
name = "Sabotage the supermatter so that it goes under 50% integrity. If it is delaminated, you will fail."
sabotage_type = "supermatter"
special_equipment = list(/obj/item/paper/guides/antag/supermatter_sabotage)
@@ -77,7 +77,7 @@
/datum/sabotage_objective/processing/supermatter/can_run()
return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines)
/*
/datum/sabotage_objective/station_integrity
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
sabotage_type = "integrity"
+2 -1
View File
@@ -8,7 +8,8 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE)
sandbox.owner = src.ckey
if(src.client.holder)
sandbox.admin = 1
verbs += new/mob/proc/sandbox_panel
add_verb(src, /mob/proc/sandbox_panel)
/mob/proc/sandbox_panel()
set name = "Sandbox Panel"
if(sandbox)
+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()
+3 -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)
@@ -381,6 +381,7 @@ Class Procs:
/obj/machinery/obj_break(damage_flag)
if(!(flags_1 & NODECONSTRUCT_1))
stat |= BROKEN
return TRUE
/obj/machinery/contents_explosion(severity, target)
if(occupant)
@@ -534,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
+13 -13
View File
@@ -355,23 +355,23 @@
cryo_items -= I
//Update any existing objectives involving this mob.
for(var/datum/objective/O in GLOB.objectives)
for(var/i in GLOB.objectives)
var/datum/objective/O = i
// We don't want revs to get objectives that aren't for heads of staff. Letting
// them win or lose based on cryo is silly so we remove the objective.
if(istype(O,/datum/objective/mutiny) && O.target == mob_occupant.mind)
qdel(O)
else if(O.target && istype(O.target, /datum/mind))
if(O.target == mob_occupant.mind)
if(O.owner && O.owner.current)
to_chat(O.owner.current, "<BR><span class='userdanger'>You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!</span>")
O.target = null
spawn(10) //This should ideally fire after the occupant is deleted.
if(!O)
return
O.find_target()
O.update_explanation_text()
if(!(O.target))
qdel(O)
else if(O.target && istype(O.target, /datum/mind) && !O.check_completion())
if(O.target == mob_occupant.mind && O.owner?.current)
to_chat(O.owner.current, "<BR><span class='userdanger'>You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!</span>")
O.target = null
spawn(10) //This should ideally fire after the occupant is deleted.
if(!O)
return
O.find_target()
O.update_explanation_text()
if(!(O.target))
qdel(O)
if(mob_occupant.mind)
//Handle job slot/tater cleanup.
+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)
@@ -300,6 +300,7 @@
else
to_chat(user, "<span class='notice'>You remove the turret but did not manage to salvage anything.</span>")
qdel(src)
return
else if((istype(I, /obj/item/wrench)) && (!on))
if(raised)
@@ -718,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
@@ -151,6 +151,7 @@
turret.installation = installed_gun.type
turret.setup(installed_gun)
qdel(src)
return
else if(istype(I, /obj/item/crowbar))
I.play_tool_sound(src, 75)
@@ -0,0 +1,100 @@
/obj/machinery/fan_assembly
name = "fan assembly"
desc = "A basic microfan assembly."
icon = 'icons/obj/poweredfans.dmi'
icon_state = "mfan_assembly"
max_integrity = 150
use_power = NO_POWER_USE
power_channel = ENVIRON
idle_power_usage = 0
active_power_usage = 0
layer = ABOVE_NORMAL_TURF_LAYER
anchored = FALSE
density = FALSE
CanAtmosPass = ATMOS_PASS_YES
stat = 1
var/buildstacktype = /obj/item/stack/sheet/plasteel
var/buildstackamount = 5
/*
1 = Wrenched in place
2 = Welded in place
3 = Wires attached to it, this makes it change to the full thing.
*/
/obj/machinery/fan_assembly/attackby(obj/item/W, mob/living/user, params)
switch(stat)
if(1)
// Stat 1
if(istype(W, /obj/item/weldingtool))
if(weld(W, user))
to_chat(user, "<span class='notice'>You weld the fan assembly securely into place.</span>")
setAnchored(TRUE)
stat = 2
update_icon_state()
return
if(2)
// Stat 2
if(istype(W, /obj/item/stack/cable_coil))
if(!W.tool_start_check(user, amount=2))
to_chat(user, "<span class='warning'>You need two lengths of cable to wire the fan assembly!</span>")
return
to_chat(user, "<span class='notice'>You start to add wires to the assembly...</span>")
if(W.use_tool(src, user, 30, volume=50, amount=2))
to_chat(user, "<span class='notice'>You add wires to the fan assembly.</span>")
stat = 3
var/obj/machinery/poweredfans/F = new(loc, src)
forceMove(F)
F.setDir(src.dir)
return
else if(istype(W, /obj/item/weldingtool))
if(weld(W, user))
to_chat(user, "<span class='notice'>You unweld the fan assembly from its place.</span>")
stat = 1
update_icon_state()
setAnchored(FALSE)
return
return ..()
/obj/machinery/fan_assembly/wrench_act(mob/user, obj/item/I)
if(stat != 1)
return FALSE
user.visible_message("<span class='warning'>[user] disassembles [src].</span>",
"<span class='notice'>You start to disassemble [src]...</span>", "You hear wrenching noises.")
if(I.use_tool(src, user, 30, volume=50))
deconstruct()
return TRUE
/obj/machinery/fan_assembly/proc/weld(obj/item/weldingtool/W, mob/living/user)
if(!W.tool_start_check(user, amount=0))
return FALSE
switch(stat)
if(1)
to_chat(user, "<span class='notice'>You start to weld \the [src]...</span>")
if(2)
to_chat(user, "<span class='notice'>You start to unweld \the [src]...</span>")
if(W.use_tool(src, user, 30, volume=50))
return TRUE
return FALSE
/obj/machinery/fan_assembly/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new buildstacktype(loc,buildstackamount)
qdel(src)
/obj/machinery/fan_assembly/examine(mob/user)
. = ..()
switch(stat)
if(1)
to_chat(user, "<span class='notice'>The fan assembly seems to be <b>unwelded</b> and loose.</span>")
if(2)
to_chat(user, "<span class='notice'>The fan assembly seems to be welded, but missing <b>wires</b>.</span>")
if(3)
to_chat(user, "<span class='notice'>The outer plating is <b>wired</b> firmly in place.</span>")
/obj/machinery/fan_assembly/update_icon_state()
. = ..()
switch(stat)
if(1)
icon_state = "mfan_assembly"
if(2)
icon_state = "mfan_welded"
@@ -0,0 +1,56 @@
/obj/machinery/poweredfans
icon = 'icons/obj/poweredfans.dmi'
icon_state = "mfan_powered"
name = "micro powered fan"
desc = "A handmade fan, releasing a thin gust of air."
use_power = ACTIVE_POWER_USE
power_channel = ENVIRON
idle_power_usage = 5
active_power_usage = 10
max_integrity = 150
layer = ABOVE_NORMAL_TURF_LAYER
anchored = TRUE
density = FALSE
CanAtmosPass = ATMOS_PASS_NO
var/obj/machinery/fan_assembly/assembly
/obj/machinery/poweredfans/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(!assembly)
assembly = new()
assembly.forceMove(drop_location())
assembly.stat = 2
assembly.setAnchored(TRUE)
assembly.setDir(dir)
assembly = null
new /obj/item/stack/cable_coil(loc, 2)
qdel(src)
/obj/machinery/poweredfans/wirecutter_act(mob/living/user, obj/item/I)
user.visible_message("<span class='warning'>[user] removes the wires from the [src].</span>",
"<span class='notice'>You start to remove the wires from the [src]...</span>", "You hear clanking and banging noises.")
if(I.use_tool(src, user, 30, volume=50))
deconstruct()
return TRUE
/obj/machinery/poweredfans/Initialize(mapload, obj/machinery/fan_assembly/FA)
. = ..()
if(FA)
assembly = FA
else
assembly = new(src)
assembly.stat = 3
air_update_turf(1)
/obj/machinery/poweredfans/power_change()
..()
if(powered())
icon_state = "mfan_powered"
CanAtmosPass = ATMOS_PASS_NO
air_update_turf(1)
else
icon_state = "mfan_unpowered"
CanAtmosPass = ATMOS_PASS_YES
air_update_turf(1)
update_icon_state()
+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
@@ -100,7 +100,7 @@
// So he can't jump out the gate right away.
R.SetLockdown()
if(masterAI)
R.connected_ai = masterAI
R.set_connected_ai(masterAI)
R.lawsync()
R.lawupdate = 1
addtimer(CALLBACK(src, .proc/unlock_new_robot, R), 50)
+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
@@ -113,8 +113,7 @@
if (loc != user)
return ..()
if(SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
ui_interact(user)
return
INVOKE_ASYNC(src, /datum.proc/ui_interact, user)
/obj/item/storage/portable_chem_mixer/attack_self(mob/user)
if(loc == user)
+3 -2
View File
@@ -718,8 +718,9 @@ GENETICS SCANNER
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.01)] kPa</span>")
for(var/id in air_contents.get_gases())
var/gas_concentration = air_contents.get_moles(id)/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)</span>")
if(air_contents.get_moles(id) >= 0.005)
var/gas_concentration = air_contents.get_moles(id)/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] &deg;C ([round(temperature, 0.01)] K)</span>")
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)
@@ -7,7 +7,8 @@
activated = 1
var/toggled = FALSE
icon_state = "hijack"
var/eye_color
var/left_eye_color
var/right_eye_color
var/stealthmode = FALSE
var/stealthcooldown = 0
var/hijacking = FALSE
@@ -25,8 +26,10 @@
return
var/on = toggled && !stealthmode
var/mob/living/carbon/human/H = imp_in
H.eye_color = on ? "ff0" : eye_color
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.left_eye_color = on ? "ff0" : left_eye_color
H.right_eye_color = on ? "ff0" : right_eye_color
H.dna.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK)
H.dna.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK)
H.update_body()
/obj/item/implant/hijack/implant(mob/living/target, mob/user, silent = FALSE)
@@ -34,7 +37,8 @@
ADD_TRAIT(target, TRAIT_HIJACKER, "implant")
if (ishuman(target))
var/mob/living/carbon/human/H = target
eye_color = H.eye_color
left_eye_color = H.left_eye_color
right_eye_color = H.right_eye_color
return TRUE
/obj/item/implant/hijack/removed(mob/living/source, silent = FALSE, special = 0)
@@ -49,7 +53,8 @@
apc.update_icon()
if (ishuman(source))
var/mob/living/carbon/human/H = source
H.eye_color = eye_color
H.left_eye_color = left_eye_color
H.right_eye_color = left_eye_color
return TRUE
/obj/item/implant/hijack/proc/InterceptClickOn(mob/living/user,params,atom/object)
@@ -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
@@ -272,4 +272,3 @@
icon_state = "skub"
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("skubbed")
+5 -5
View File
@@ -281,12 +281,12 @@
O.custom_name = created_name
O.locked = panel_locked
if(!aisync)
lawsync = 0
O.connected_ai = null
lawsync = FALSE
O.set_connected_ai(null)
else
O.notify_ai(NEW_BORG)
if(forced_ai)
O.connected_ai = forced_ai
O.set_connected_ai(forced_ai)
if(!lawsync)
O.lawupdate = 0
if(M.laws.id == DEFAULT_AI_LAWID)
@@ -337,10 +337,10 @@
if(!aisync)
lawsync = FALSE
O.connected_ai = null
O.set_connected_ai(null)
else
if(forced_ai)
O.connected_ai = forced_ai
O.set_connected_ai(forced_ai)
O.notify_ai(AI_SHELL)
if(!lawsync)
O.lawupdate = FALSE
+2 -2
View File
@@ -269,8 +269,8 @@
to_chat(user, "<span class='notice'>[M] is at full health.</span>")
return FALSE
user.visible_message("<span class='green'>[user] applies \the [src] on [M].</span>", "<span class='green'>You apply \the [src] on [M].</span>")
return heal_carbon(M, user, heal_brute, heal_burn)
M.heal_bodypart_damage(heal_brute)
return TRUE
to_chat(user, "<span class='warning'>You can't heal [M] with \the [src]!</span>")
/obj/item/stack/medical/ointment
+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
@@ -179,6 +179,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
new/datum/stack_recipe("micro powered fan assembly", /obj/machinery/fan_assembly, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new /datum/stack_recipe_list("crates", list( \
new /datum/stack_recipe("gray crate", /obj/structure/closet/crate, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("internals crate", /obj/structure/closet/crate/internals, 5, time = 50, one_per_turf = 1, on_floor = 1), \
@@ -232,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
-3
View File
@@ -204,9 +204,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
/obj/proc/acid_processing()
. = 1
if(!(resistance_flags & ACID_PROOF))
for(var/armour_value in armor)
if(armour_value != "acid" && armour_value != "fire")
armor = armor.modifyAllRatings(0 - round(sqrt(acid_level)*0.1))
if(prob(33))
playsound(loc, 'sound/items/welder.ogg', 150, 1)
take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, "acid", 0)
-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)
+1
View File
@@ -9,6 +9,7 @@
armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20)
var/obj/item/holosign_creator/projector
var/init_vis_overlay = TRUE
rad_flags = RAD_NO_CONTAMINATE
/obj/structure/holosign/Initialize(mapload, source_projector)
. = ..()
+26 -11
View File
@@ -229,17 +229,32 @@
H.update_hair()
if(BODY_ZONE_PRECISE_EYES)
var/new_eye_color = input(H, "Choose your eye color", "Eye Color","#"+H.eye_color) as color|null
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(new_eye_color)
var/n_color = sanitize_hexcolor(new_eye_color)
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
if(eyes)
eyes.eye_color = n_color
H.eye_color = n_color
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.dna.species.handle_body()
var/eye_type = input(H, "Choose the eye you want to color", "Eye Color") as null|anything in list("Both Eyes", "Left Eye", "Right Eye")
if(eye_type)
var/input_color = H.left_eye_color
if(eye_type == "Right Eye")
input_color = H.right_eye_color
var/new_eye_color = input(H, "Choose your eye color", "Eye Color","#"+input_color) as color|null
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(new_eye_color)
var/n_color = sanitize_hexcolor(new_eye_color)
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
var/left_color = n_color
var/right_color = n_color
if(eye_type == "Left Eye")
right_color = H.right_eye_color
else
if(eye_type == "Right Eye")
left_color = H.left_eye_color
if(eyes)
eyes.left_eye_color = left_color
eyes.right_eye_color = right_color
H.left_eye_color = left_color
H.right_eye_color = right_color
H.dna.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK)
H.dna.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK)
H.dna.species.handle_body()
if(choice)
curse(user)
+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))
+1 -1
View File
@@ -210,7 +210,7 @@
if(!get_excited() && air.compare(enemy_air))
//testing("Active turf found. Return value of compare(): [is_active]")
set_excited(TRUE)
SSair.active_turfs |= src
SSair.add_to_active_extools(src)
/turf/open/proc/GetHeatCapacity()
. = air.heat_capacity()
@@ -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."
+1 -1
View File
@@ -138,7 +138,7 @@
if(prob(hardness))
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
hulk_recoil(arm, user)
//hulk_recoil(arm, user) // citadel edit - no, hulks are already subject to stamina combat
dismantle_wall(1)
else
-6
View File
@@ -273,12 +273,6 @@ GLOBAL_LIST(topic_status_cache)
..()
/world/Del()
// memory leaks bad
var/num_deleted = 0
for(var/datum/gas_mixture/GM)
GM.__gasmixture_unregister()
num_deleted++
log_world("Deallocated [num_deleted] gas mixtures")
shutdown_logging() // makes sure the thread is closed before end, else we terminate
..()