Merge branch 'master' into spike-loot-differentces
This commit is contained in:
+8
-2
@@ -26,7 +26,6 @@
|
||||
var/list/atom_colours //used to store the different colors on an atom
|
||||
//its inherent color, the colored paint applied on it, special color effect etc...
|
||||
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
var/list/remove_overlays // a very temporary list of overlays to remove
|
||||
var/list/add_overlays // a very temporary list of overlays to add
|
||||
|
||||
@@ -145,7 +144,6 @@
|
||||
qdel(reagents)
|
||||
|
||||
LAZYCLEARLIST(overlays)
|
||||
LAZYCLEARLIST(priority_overlays)
|
||||
|
||||
for(var/i in targeted_by)
|
||||
var/mob/M = i
|
||||
@@ -1121,3 +1119,11 @@
|
||||
max_grav = max(G.setting,max_grav)
|
||||
return max_grav
|
||||
return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
|
||||
|
||||
/**
|
||||
* Causes effects when the atom gets hit by a rust effect from heretics
|
||||
*
|
||||
* Override this if you want custom behaviour in whatever gets hit by the rust
|
||||
*/
|
||||
/atom/proc/rust_heretic_act()
|
||||
return
|
||||
|
||||
@@ -646,3 +646,10 @@
|
||||
animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING)
|
||||
sleep(1)
|
||||
animate(I, alpha = 0, transform = matrix(), time = 1)
|
||||
|
||||
/atom/movable/proc/set_anchored(anchorvalue) //literally only for plumbing ran
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(anchored == anchorvalue)
|
||||
return
|
||||
. = anchored
|
||||
anchored = anchorvalue
|
||||
|
||||
@@ -224,8 +224,7 @@ Credit where due:
|
||||
qdel(S)
|
||||
if(S && !QDELETED(S))
|
||||
to_chat(L, "<span class='alloy'>[slot] is a <b>clockwork slab</b>, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \
|
||||
as a servant, you can find a concise tutorial in the Recollection category of its interface.</span>")
|
||||
to_chat(L, "<span class='alloy italics'>If you want more information, you can read <a href=\"https://tgstation13.org/wiki/Clockwork_Cult\">the wiki page</a> to learn more.</span>")
|
||||
as a servant, you can read <a href=\"https://citadel-station.net/wikimain/index.php?title=Clockwork_Cult\">the wiki page</a> to learn more.</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -191,6 +191,24 @@
|
||||
SSticker.mode_result = "loss - rev heads killed"
|
||||
SSticker.news_report = REVS_LOSE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// HERETIC SMUGGLER //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/heretic_smuggler
|
||||
name = "Heretic Smuggler"
|
||||
antag_datum = /datum/antagonist/heretic
|
||||
antag_flag = ROLE_HERETIC
|
||||
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
restricted_roles = list("AI","Cyborg")
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 10
|
||||
requirements = list(40,30,20,10,10,10,10,10,10,10)
|
||||
repeatable = TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// BLOODSUCKERS //
|
||||
|
||||
@@ -143,6 +143,46 @@
|
||||
changeling.add_antag_datum(new_antag)
|
||||
return TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// ELDRITCH CULT //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/heretics
|
||||
name = "Heretics"
|
||||
antag_flag = ROLE_HERETIC
|
||||
antag_datum = /datum/antagonist/heretic
|
||||
protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain")
|
||||
restricted_roles = list("AI", "Cyborg")
|
||||
required_candidates = 1
|
||||
weight = 3
|
||||
cost = 20
|
||||
scaling_cost = 15
|
||||
requirements = list(50,45,45,40,35,20,20,15,10,10)
|
||||
antag_cap = list(1,1,1,1,2,2,2,2,3,3)
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/heretics/pre_execute()
|
||||
. = ..()
|
||||
var/num_ecult = antag_cap[indice_pop] * (scaled_times + 1)
|
||||
|
||||
for (var/i = 1 to num_ecult)
|
||||
var/mob/picked_candidate = pick_n_take(candidates)
|
||||
assigned += picked_candidate.mind
|
||||
picked_candidate.mind.restricted_roles = restricted_roles
|
||||
picked_candidate.mind.special_role = ROLE_HERETIC
|
||||
return TRUE
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/heretics/execute()
|
||||
|
||||
for(var/c in assigned)
|
||||
var/datum/mind/cultie = c
|
||||
var/datum/antagonist/heretic/new_antag = new antag_datum()
|
||||
cultie.add_antag_datum(new_antag)
|
||||
|
||||
return TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// WIZARDS //
|
||||
|
||||
@@ -50,10 +50,6 @@ Property weights are:
|
||||
for(var/r in SSevents.running)
|
||||
var/datum/round_event/R = r
|
||||
threat += R.threat()
|
||||
for(var/mob/living/simple_animal/hostile/H in GLOB.mob_living_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(H.stat != DEAD && is_station_level(T.z) && !("Station" in H.faction))
|
||||
threat += H.threat()
|
||||
for(var/obj/item/phylactery/P in GLOB.poi_list)
|
||||
threat += 25 // can't be giving them too much of a break
|
||||
for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
@@ -91,6 +87,8 @@ Property weights are:
|
||||
mean += 2.5
|
||||
if(CHAOS_MAX)
|
||||
mean += 5
|
||||
else
|
||||
voters += 0.5
|
||||
if(voters)
|
||||
GLOB.dynamic_curve_centre += (mean/voters)
|
||||
if(flags & USE_PREV_ROUND_WEIGHTS)
|
||||
@@ -128,7 +126,8 @@ Property weights are:
|
||||
for(var/property in property_weights)
|
||||
if(property in rule.property_weights) // just treat it as 0 if it's not in there
|
||||
property_weight += rule.property_weights[property] * property_weights[property]
|
||||
drafted_rules[rule] = (rule.get_weight() * property_weight)*rule.weight_mult
|
||||
if(property_weight > 0)
|
||||
drafted_rules[rule] = rule.get_weight() * property_weight * rule.weight_mult
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/proc/midround_draft()
|
||||
@@ -140,25 +139,26 @@ Property weights are:
|
||||
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
|
||||
continue
|
||||
rule.trim_candidates()
|
||||
var/threat_weight = 1
|
||||
if(!(rule.flags & MINOR_RULESET)) // makes the traitor rulesets always possible anyway
|
||||
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
|
||||
/* Basically, the closer the cost is to the current threat-level-away-from-threat, the more likely it is to
|
||||
pick this particular ruleset.
|
||||
Let's use a toy example: there's 60 threat level and 10 threat spent.
|
||||
We want to pick a ruleset that's close to that, so we run the below equation, on two rulesets.
|
||||
Ruleset 1 has 30 cost, ruleset 2 has 5 cost.
|
||||
When we do the math, ruleset 1's threat_weight is 0.538, and ruleset 2's is 0.238, meaning ruleset 1
|
||||
is 2.26 times as likely to be picked, all other things considered.
|
||||
Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight.
|
||||
*/
|
||||
threat_weight = abs(1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
|
||||
if (rule.ready())
|
||||
var/property_weight = 0
|
||||
for(var/property in property_weights)
|
||||
if(property in rule.property_weights)
|
||||
if(property in rule.property_weights) // just treat it as 0 if it's not in there
|
||||
property_weight += rule.property_weights[property] * property_weights[property]
|
||||
drafted_rules[rule] = round(((rule.get_weight() * property_weight)*rule.weight_mult*threat_weight)*1000,1)
|
||||
if(property_weight > 0)
|
||||
var/threat_weight = 1
|
||||
if(!(rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)) // makes the traitor rulesets always possible anyway
|
||||
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
|
||||
/* Basically, the closer the cost is to the current threat-level-away-from-threat, the more likely it is to
|
||||
pick this particular ruleset.
|
||||
Let's use a toy example: there's 60 threat level and 10 threat spent.
|
||||
We want to pick a ruleset that's close to that, so we run the below equation, on two rulesets.
|
||||
Ruleset 1 has 30 cost, ruleset 2 has 5 cost.
|
||||
When we do the math, ruleset 1's threat_weight is 0.538, and ruleset 2's is 0.238, meaning ruleset 1
|
||||
is 2.26 times as likely to be picked, all other things considered.
|
||||
Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight.
|
||||
*/
|
||||
threat_weight = abs(1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
|
||||
drafted_rules[rule] = rule.get_weight() * property_weight * rule.weight_mult * threat_weight
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/proc/latejoin_draft(mob/living/carbon/human/newPlayer)
|
||||
@@ -175,28 +175,29 @@ Property weights are:
|
||||
|
||||
rule.candidates = list(newPlayer)
|
||||
rule.trim_candidates()
|
||||
var/threat_weight = 1
|
||||
if(!(rule.flags & MINOR_RULESET))
|
||||
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
|
||||
threat_weight = 1-abs(1-(LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
|
||||
if (rule.ready())
|
||||
var/property_weight = 0
|
||||
for(var/property in property_weights)
|
||||
if(property in rule.property_weights)
|
||||
property_weight += rule.property_weights[property] * property_weights[property]
|
||||
drafted_rules[rule] = round(((rule.get_weight() * property_weight)*rule.weight_mult*threat_weight)*1000,1)
|
||||
if(property_weight > 0)
|
||||
var/threat_weight = 1
|
||||
if(!(rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET))
|
||||
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
|
||||
threat_weight = 1-abs(1-(LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
|
||||
drafted_rules[rule] = rule.get_weight() * property_weight * rule.weight_mult * threat_weight
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/proc/event_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for(var/datum/dynamic_ruleset/event/rule in mode.events)
|
||||
if(rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && (mode.threat_level - mode.threat) >= rule.cost)
|
||||
if(rule.ready())
|
||||
var/property_weight = 0
|
||||
for(var/property in property_weights)
|
||||
if(property in rule.property_weights)
|
||||
property_weight += rule.property_weights[property] * property_weights[property]
|
||||
drafted_rules[rule] = (rule.get_weight() + property_weight)*rule.weight_mult
|
||||
if(rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && (mode.threat_level + 20 - mode.threat) >= rule.cost && rule.ready())
|
||||
var/property_weight = 0
|
||||
for(var/property in property_weights)
|
||||
if(property in rule.property_weights)
|
||||
property_weight += rule.property_weights[property] * property_weights[property]
|
||||
if(property_weight > 0)
|
||||
drafted_rules[rule] = rule.get_weight() + property_weight * rule.weight_mult
|
||||
return drafted_rules
|
||||
|
||||
|
||||
@@ -313,9 +314,8 @@ Property weights are:
|
||||
/datum/dynamic_storyteller/random/event_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for(var/datum/dynamic_ruleset/event/rule in mode.events)
|
||||
if(rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level))
|
||||
if(rule.ready())
|
||||
drafted_rules[rule] = 1
|
||||
if(rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && rule.ready())
|
||||
drafted_rules[rule] = 1
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/story
|
||||
@@ -330,7 +330,7 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/story/calculate_threat()
|
||||
var/current_time = (world.time / SSautotransfer.targettime)*180
|
||||
mode.threat_level = round(mode.initial_threat_level*(sin(current_time)+0.25),0.1)
|
||||
mode.threat_level = round((mode.initial_threat_level*(sin(current_time)/2)+0.75),0.1)
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_storyteller/classic
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/datum/game_mode/heretics
|
||||
name = "heresy"
|
||||
config_tag = "heresy"
|
||||
antag_flag = ROLE_HERETIC
|
||||
false_report_weight = 5
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to heretic role blacklist
|
||||
required_players = 15
|
||||
required_enemies = 1
|
||||
recommended_enemies = 4
|
||||
reroll_friendly = 1
|
||||
enemy_minimum_age = 0
|
||||
round_ends_with_antag_death = 0
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "Heretics have been spotted on the station!\n\
|
||||
<span class='danger'>Heretics</span>: Accomplish your objectives.\n\
|
||||
<span class='notice'>Crew</span>: Do not let the madman succeed!"
|
||||
|
||||
var/ecult_possible = 4 //hard limit on culties if scaling is turned off
|
||||
var/num_ecult = 1
|
||||
var/list/culties = list()
|
||||
|
||||
/datum/game_mode/heretics/pre_setup()
|
||||
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
restricted_jobs += protected_jobs
|
||||
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
restricted_jobs += "Assistant"
|
||||
|
||||
|
||||
var/esc = CONFIG_GET(number/ecult_scaling_coeff)
|
||||
if(esc)
|
||||
num_ecult = min(max(1, min(round(num_players() / (esc * 2)) + 2, round(num_players() / esc))),4)
|
||||
else
|
||||
num_ecult = max(1, min(num_players(), ecult_possible))
|
||||
|
||||
for(var/i in 1 to num_ecult)
|
||||
if(!antag_candidates.len)
|
||||
break
|
||||
var/datum/mind/cultie = antag_pick(antag_candidates)
|
||||
antag_candidates -= cultie
|
||||
cultie.special_role = ROLE_HERETIC
|
||||
cultie.restricted_roles = restricted_jobs
|
||||
culties += cultie
|
||||
|
||||
var/enough_heretics = culties.len > 0
|
||||
|
||||
if(!enough_heretics)
|
||||
setup_error = "Not enough heretic candidates"
|
||||
return FALSE
|
||||
else
|
||||
for(var/antag in culties)
|
||||
return TRUE
|
||||
|
||||
/datum/game_mode/heretics/post_setup()
|
||||
for(var/c in culties)
|
||||
var/datum/mind/cultie = c
|
||||
log_game("[key_name(cultie)] has been selected as a heretic!")
|
||||
var/datum/antagonist/heretic/new_antag = new()
|
||||
cultie.add_antag_datum(new_antag)
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/heretics/generate_report()
|
||||
return "Cybersun Industries has announced that they have successfully raided a high-security library. The library contained a very dangerous book that was \
|
||||
shown to posses anomalous properties. We suspect that the book has been copied over, Stay vigilant!"
|
||||
+59
-175
@@ -12,9 +12,9 @@
|
||||
density = FALSE
|
||||
state_open = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/sleeper
|
||||
req_access = list(ACCESS_CMO) //Used for reagent deletion and addition of non medicines
|
||||
|
||||
var/efficiency = 1
|
||||
var/min_health = 30
|
||||
var/min_health = -25
|
||||
var/list/available_chems
|
||||
var/controls_inside = FALSE
|
||||
var/list/possible_chems = list(
|
||||
@@ -31,32 +31,13 @@
|
||||
|
||||
/obj/machinery/sleeper/Initialize()
|
||||
. = ..()
|
||||
create_reagents(500, NO_REACT)
|
||||
// if(mapload)
|
||||
// component_parts -= circuit
|
||||
// QDEL_NULL(circuit)
|
||||
occupant_typecache = GLOB.typecache_living
|
||||
update_icon()
|
||||
reset_chem_buttons()
|
||||
RefreshParts()
|
||||
add_inital_chems()
|
||||
new_occupant_dir = dir
|
||||
|
||||
/obj/machinery/sleeper/setDir(newdir)
|
||||
. = ..()
|
||||
new_occupant_dir = dir
|
||||
|
||||
/obj/machinery/sleeper/on_deconstruction()
|
||||
var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc)
|
||||
buffer.volume = reagents.maximum_volume
|
||||
buffer.reagents.maximum_volume = reagents.maximum_volume
|
||||
reagents.trans_to(buffer.reagents, reagents.total_volume)
|
||||
|
||||
/obj/machinery/sleeper/proc/add_inital_chems()
|
||||
for(var/i in available_chems)
|
||||
var/datum/reagent/R = reagents.has_reagent(i)
|
||||
if(!R)
|
||||
reagents.add_reagent(i, (20))
|
||||
continue
|
||||
if(R.volume < 20)
|
||||
reagents.add_reagent(i, (20 - R.volume))
|
||||
|
||||
/obj/machinery/sleeper/RefreshParts()
|
||||
var/E
|
||||
@@ -73,15 +54,11 @@
|
||||
available_chems |= possible_chems[i]
|
||||
reset_chem_buttons()
|
||||
|
||||
//Total container size 500 - 2000u
|
||||
if(reagents)
|
||||
reagents.maximum_volume = (500*E)
|
||||
|
||||
|
||||
/obj/machinery/sleeper/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "-open"
|
||||
icon_state = "[initial(icon_state)]-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/sleeper/container_resist(mob/living/user)
|
||||
visible_message("<span class='notice'>[occupant] emerges from [src]!</span>",
|
||||
@@ -98,10 +75,12 @@
|
||||
|
||||
/obj/machinery/sleeper/open_machine()
|
||||
if(!state_open && !panel_open)
|
||||
// flick("[initial(icon_state)]-anim", src)
|
||||
..()
|
||||
|
||||
/obj/machinery/sleeper/close_machine(mob/user)
|
||||
if((isnull(user) || istype(user)) && state_open && !panel_open)
|
||||
// flick("[initial(icon_state)]-anim", src)
|
||||
..(user)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant && mob_occupant.stat != DEAD)
|
||||
@@ -112,46 +91,23 @@
|
||||
if (. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(is_operational() && occupant)
|
||||
var/datum/reagent/R = pick(reagents.reagent_list)
|
||||
var/datum/reagent/R = pick(reagents.reagent_list) //cit specific
|
||||
inject_chem(R.type, occupant)
|
||||
open_machine()
|
||||
//Is this too much?
|
||||
//Is this too much? Cit specific
|
||||
if(severity == EMP_HEAVY)
|
||||
var/chem = pick(available_chems)
|
||||
available_chems -= chem
|
||||
available_chems += get_random_reagent_id()
|
||||
reset_chem_buttons()
|
||||
|
||||
/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/reagent_containers/sleeper_buffer))
|
||||
var/obj/item/reagent_containers/sleeper_buffer/SB = I
|
||||
if((SB.reagents.total_volume + reagents.total_volume) < reagents.maximum_volume)
|
||||
SB.reagents.trans_to(reagents, SB.reagents.total_volume)
|
||||
visible_message("[user] places the [SB] into the [src].")
|
||||
qdel(SB)
|
||||
return
|
||||
else
|
||||
SB.reagents.trans_to(reagents, SB.reagents.total_volume)
|
||||
visible_message("[user] adds as much as they can to the [src] from the [SB].")
|
||||
return
|
||||
if(istype(I, /obj/item/reagent_containers))
|
||||
var/obj/item/reagent_containers/RC = I
|
||||
if(RC.reagents.total_volume == 0)
|
||||
to_chat(user, "<span class='notice'>The [I] is empty!</span>")
|
||||
for(var/datum/reagent/R in RC.reagents.reagent_list)
|
||||
if((obj_flags & EMAGGED) || (allowed(usr)))
|
||||
break
|
||||
if(!istype(R, /datum/reagent/medicine))
|
||||
visible_message("The [src] gives out a hearty boop and rejects the [I]. The Sleeper's screen flashes with a pompous \"Medicines only, please.\"")
|
||||
return
|
||||
RC.reagents.trans_to(reagents, 1000)
|
||||
visible_message("[user] adds as much as they can to the [src] from the [I].")
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
|
||||
if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(!(L.mobility_flags & MOBILITY_STAND))
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/sleeper/screwdriver_act(mob/living/user, obj/item/I)
|
||||
@@ -187,23 +143,9 @@
|
||||
visible_message("<span class='notice'>[usr] pries open [src].</span>", "<span class='notice'>You pry open [src].</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/sleeper/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
return
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/sleeper/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click [src] to [state_open ? "close" : "open"] it.</span>"
|
||||
|
||||
/obj/machinery/sleeper/ui_state(mob/user)
|
||||
if(controls_inside)
|
||||
return GLOB.notcontained_state
|
||||
return GLOB.contained_state
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/sleeper/ui_interact(mob/user, datum/tgui/ui)
|
||||
@@ -212,6 +154,18 @@
|
||||
ui = new(user, src, "Sleeper", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/sleeper/AltClick(mob/user)
|
||||
if(!user.canUseTopic(src, !issilicon(user)))
|
||||
return
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/sleeper/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click [src] to [state_open ? "close" : "open"] it.</span>"
|
||||
|
||||
/obj/machinery/sleeper/process()
|
||||
..()
|
||||
check_nap_violations()
|
||||
@@ -221,22 +175,13 @@
|
||||
|
||||
/obj/machinery/sleeper/ui_data()
|
||||
var/list/data = list()
|
||||
var/chemical_list = list()
|
||||
var/blood_percent = 0
|
||||
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
data["blood_levels"] = blood_percent
|
||||
data["blood_status"] = "Patient either has no blood, or does not require it to function."
|
||||
data["chemical_list"] = chemical_list
|
||||
|
||||
data["chems"] = list()
|
||||
for(var/chem in available_chems)
|
||||
var/datum/reagent/R = reagents.has_reagent(chem)
|
||||
R = GLOB.chemical_reagents_list[chem]
|
||||
data["synthchems"] += list(list("name" = R.name, "id" = R.type, "synth_allowed" = synth_allowed(chem)))
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
data["chems"] += list(list("name" = R.name, "id" = R.type, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.type)))
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
|
||||
data["chems"] += list(list("name" = R.name, "id" = R.type, "allowed" = chem_allowed(chem)))
|
||||
|
||||
data["occupant"] = list()
|
||||
var/mob/living/mob_occupant = occupant
|
||||
@@ -264,40 +209,10 @@
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
|
||||
if(mob_occupant.reagents.reagent_list.len)
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
chemical_list += list(list("name" = R.name, "volume" = R.volume))
|
||||
else
|
||||
chemical_list = "Patient has no reagents."
|
||||
|
||||
data["occupant"]["failing_organs"] = list()
|
||||
var/mob/living/carbon/C = mob_occupant
|
||||
if(C)
|
||||
for(var/obj/item/organ/Or in C.getFailingOrgans())
|
||||
if(istype(Or, /obj/item/organ/brain))
|
||||
continue
|
||||
data["occupant"]["failing_organs"] += list(list("name" = Or.name))
|
||||
|
||||
if(istype(C)) //Non-carbons shouldn't be able to enter sleepers, but this is to prevent runtimes if something ever breaks
|
||||
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
|
||||
blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
|
||||
var/blood_id = C.get_blood_id()
|
||||
var/blood_warning = ""
|
||||
if(blood_percent < 80)
|
||||
blood_warning = "Patient has low blood levels."
|
||||
if(blood_percent < 60)
|
||||
blood_warning = "Patient has DANGEROUSLY low blood levels."
|
||||
if(blood_id)
|
||||
var/blood_type = C.dna.blood_type
|
||||
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
|
||||
if(R)
|
||||
blood_type = R.name
|
||||
else
|
||||
blood_type = blood_id
|
||||
data["blood_status"] = "Patient has [blood_type] type blood. [blood_warning]"
|
||||
data["blood_levels"] = blood_percent
|
||||
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
|
||||
return data
|
||||
|
||||
/obj/machinery/sleeper/ui_act(action, params)
|
||||
@@ -314,37 +229,14 @@
|
||||
. = TRUE
|
||||
if("inject")
|
||||
var/chem = text2path(params["chem"])
|
||||
var/amount = text2num(params["volume"])
|
||||
if(!is_operational() || !mob_occupant || isnull(chem))
|
||||
return
|
||||
if(mob_occupant.health < min_health && chem != /datum/reagent/medicine/epinephrine)
|
||||
return
|
||||
if(inject_chem(chem, usr, amount))
|
||||
if(inject_chem(chem, usr))
|
||||
. = TRUE
|
||||
if(scrambled_chems && prob(5))
|
||||
to_chat(usr, "<span class='warning'>Chemical system re-route detected, results may not be as expected!</span>")
|
||||
if("synth")
|
||||
var/chem = text2path(params["chem"])
|
||||
if(!is_operational())
|
||||
return
|
||||
reagents.add_reagent(chem_buttons[chem], 10) //other_purity = 0.75 for when the mechanics are in
|
||||
if("purge")
|
||||
var/chem = text2path(params["chem"])
|
||||
if(allowed(usr))
|
||||
if(!is_operational())
|
||||
return
|
||||
reagents.remove_reagent(chem, 1000)
|
||||
return
|
||||
if(chem in available_chems)
|
||||
if(!is_operational())
|
||||
return
|
||||
/*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in
|
||||
if(R.purity < 0.8)*/
|
||||
reagents.remove_reagent(chem, 1000)
|
||||
else
|
||||
visible_message("<span class='warning'>Access Denied.</span>")
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
|
||||
|
||||
/obj/machinery/sleeper/emag_act(mob/user)
|
||||
. = ..()
|
||||
@@ -353,10 +245,9 @@
|
||||
to_chat(user, "<span class='warning'>You scramble the sleeper's user interface!</span>")
|
||||
return TRUE
|
||||
|
||||
//trans to
|
||||
/obj/machinery/sleeper/proc/inject_chem(chem, mob/user, volume = 10)
|
||||
if(chem_allowed(chem))
|
||||
reagents.trans_id_to(occupant, chem, volume)//emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU
|
||||
/obj/machinery/sleeper/proc/inject_chem(chem, mob/user)
|
||||
if((chem in available_chems) && chem_allowed(chem))
|
||||
occupant.reagents.add_reagent(chem_buttons[chem], 10) //emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU
|
||||
if(user)
|
||||
log_combat(user, occupant, "injected [chem] into", addition = "via [src]")
|
||||
return TRUE
|
||||
@@ -369,14 +260,6 @@
|
||||
var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine
|
||||
return amount && occ_health
|
||||
|
||||
/obj/machinery/sleeper/proc/synth_allowed(chem)
|
||||
var/datum/reagent/R = reagents.has_reagent(chem)
|
||||
if(!R)
|
||||
return TRUE
|
||||
if(R.volume < 50)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/sleeper/proc/reset_chem_buttons()
|
||||
scrambled_chems = FALSE
|
||||
LAZYINITLIST(chem_buttons)
|
||||
@@ -416,23 +299,6 @@
|
||||
component_parts += new /obj/item/stack/cable_coil(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/sleeper/clockwork
|
||||
name = "soothing sleeper"
|
||||
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
|
||||
icon_state = "sleeper_clockwork"
|
||||
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
|
||||
possible_chems = list(list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine,
|
||||
/datum/reagent/medicine/kelotane, /datum/reagent/medicine/oculine, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/mannitol))
|
||||
|
||||
/obj/machinery/sleeper/clockwork/process()
|
||||
if(occupant && isliving(occupant))
|
||||
var/mob/living/L = occupant
|
||||
if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing
|
||||
GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1)
|
||||
L.adjustBruteLoss(-1)
|
||||
L.adjustFireLoss(-1)
|
||||
L.adjustOxyLoss(-5)
|
||||
|
||||
/obj/machinery/sleeper/old
|
||||
icon_state = "oldpod"
|
||||
|
||||
@@ -443,8 +309,6 @@
|
||||
idle_power_usage = 3000
|
||||
circuit = /obj/item/circuitboard/machine/sleeper/party
|
||||
var/leddit = FALSE //Get it like reddit and lead alright fine
|
||||
ui_x = 310
|
||||
ui_y = 400
|
||||
|
||||
controls_inside = TRUE
|
||||
possible_chems = list(
|
||||
@@ -477,3 +341,23 @@
|
||||
/obj/machinery/sleeper/party/emag_act(mob/user)
|
||||
..()
|
||||
leddit = TRUE
|
||||
|
||||
/obj/machinery/sleeper/clockwork
|
||||
name = "soothing sleeper"
|
||||
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
|
||||
icon_state = "sleeper_clockwork"
|
||||
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
|
||||
possible_chems = list(
|
||||
list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane, /datum/reagent/medicine/oculine, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/mannitol)
|
||||
) //everything is available at start
|
||||
fair_market_price = 0 //it's free
|
||||
|
||||
/obj/machinery/sleeper/clockwork/process()
|
||||
..()
|
||||
if(occupant && isliving(occupant))
|
||||
var/mob/living/L = occupant
|
||||
if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing
|
||||
GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1)
|
||||
L.adjustBruteLoss(-1)
|
||||
L.adjustFireLoss(-1)
|
||||
L.adjustOxyLoss(-5)
|
||||
|
||||
@@ -117,6 +117,7 @@ Class Procs:
|
||||
var/new_occupant_dir = SOUTH //The direction the occupant will be set to look at when entering the machine.
|
||||
var/speed_process = FALSE // Process as fast as possible?
|
||||
var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created
|
||||
var/wire_compatible = FALSE
|
||||
// For storing and overriding ui id and dimensions
|
||||
var/tgui_id // ID of TGUI interface
|
||||
var/ui_style // ID of custom TGUI style (optional)
|
||||
@@ -433,6 +434,7 @@ Class Procs:
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "un" : ""]secure [src].</span>")
|
||||
setAnchored(!anchored)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
SEND_SIGNAL(src, COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH, anchored)
|
||||
return SUCCESSFUL_UNFASTEN
|
||||
return FAILED_UNFASTEN
|
||||
return CANT_UNFASTEN
|
||||
@@ -547,3 +549,6 @@ Class Procs:
|
||||
. = . % 9
|
||||
AM.pixel_x = -8 + ((.%3)*8)
|
||||
AM.pixel_y = -8 + (round( . / 3)*8)
|
||||
|
||||
/obj/machinery/rust_heretic_act()
|
||||
take_damage(500, BRUTE, "melee", 1)
|
||||
|
||||
@@ -310,6 +310,17 @@
|
||||
opacity = 0
|
||||
glass = TRUE
|
||||
|
||||
/obj/machinery/door/airlock/bronze
|
||||
name = "bronze airlock"
|
||||
icon = 'icons/obj/doors/airlocks/clockwork/pinion_airlock.dmi'
|
||||
overlays_file = 'icons/obj/doors/airlocks/clockwork/overlays.dmi'
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_bronze
|
||||
|
||||
/obj/machinery/door/airlock/bronze/seethru
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_bronze/seethru
|
||||
opacity = 0
|
||||
glass = TRUE
|
||||
|
||||
//////////////////////////////////
|
||||
/*
|
||||
Station2 Airlocks
|
||||
|
||||
@@ -153,6 +153,9 @@
|
||||
/obj/mecha/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/mecha/rust_heretic_act()
|
||||
take_damage(500, BRUTE)
|
||||
|
||||
/obj/mecha/Destroy()
|
||||
go_out()
|
||||
var/mob/living/silicon/ai/AI
|
||||
|
||||
@@ -63,3 +63,23 @@
|
||||
|
||||
/datum/effect_system/lightning_spread
|
||||
effect_type = /obj/effect/particle_effect/sparks/electricity
|
||||
|
||||
//fake sparks, not subtyped because we don't want light/heat, nor checks inside an often used proc for a rare subcase for saving like 10 lines of code
|
||||
/obj/effect/particle_effect/fake_sparks
|
||||
name = "lightning"
|
||||
icon_state = "electricity"
|
||||
|
||||
/obj/effect/particle_effect/fake_sparks/Initialize()
|
||||
. = ..()
|
||||
flick(icon_state, src) // replay the animation
|
||||
playsound(src, "sparks", 100, TRUE)
|
||||
QDEL_IN(src, 20)
|
||||
|
||||
/datum/effect_system/fake_spark_spread
|
||||
effect_type = /obj/effect/particle_effect/fake_sparks
|
||||
|
||||
/proc/do_fake_sparks(n, c, source)
|
||||
var/datum/effect_system/fake_spark_spread/sparks = new
|
||||
sparks.set_up(n, c, source)
|
||||
sparks.autocleanup = TRUE
|
||||
sparks.start()
|
||||
|
||||
@@ -168,3 +168,26 @@
|
||||
items = list(
|
||||
/obj/item/clothing/mask/gas/sexymime,
|
||||
/obj/item/clothing/under/rank/civilian/mime/sexy)
|
||||
|
||||
/obj/effect/spawner/bundle/crate/Initialize(mapload)
|
||||
if(items && items.len)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/closet/LC = locate(/obj/structure/closet) in T
|
||||
if(LC)
|
||||
for(var/path in items)
|
||||
new path(LC)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/spawner/bundle/crate/mosin
|
||||
name = "Mosin-Nagant spawner"
|
||||
items = list(
|
||||
/obj/item/gun/ballistic/shotgun/boltaction,
|
||||
/obj/item/ammo_box/a762
|
||||
)
|
||||
|
||||
/obj/effect/spawner/bundle/crate/surplusrifle
|
||||
name = "surplus rifle spawner"
|
||||
items = list(
|
||||
/obj/item/gun/ballistic/automatic/surplus,
|
||||
/obj/item/ammo_box/magazine/m10mm/rifle
|
||||
)
|
||||
|
||||
@@ -139,6 +139,23 @@
|
||||
/obj/effect/temp_visual/dir_setting/curse/hand
|
||||
icon_state = "cursehand"
|
||||
|
||||
/obj/effect/temp_visual/bsa_splash
|
||||
name = "\improper Bluespace energy wave"
|
||||
desc = "A massive, rippling wave of bluepace energy, all rapidly exhausting itself the moment it leaves the concentrated beam of light."
|
||||
icon = 'icons/effects/beam_splash.dmi'
|
||||
icon_state = "beam_splash_l"
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
pixel_y = -16
|
||||
duration = 50
|
||||
|
||||
/obj/effect/temp_visual/bsa_splash/Initialize(mapload, dir)
|
||||
. = ..()
|
||||
switch(dir)
|
||||
if(WEST)
|
||||
icon_state = "beam_splash_w"
|
||||
if(EAST)
|
||||
icon_state = "beam_splash_e"
|
||||
|
||||
/obj/effect/temp_visual/wizard
|
||||
name = "water"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
|
||||
@@ -135,6 +135,14 @@ RLD
|
||||
flick("[icon_state]_empty", src) //somewhat hacky thing to make RCDs with ammo counters actually have a blinking yellow light
|
||||
return .
|
||||
|
||||
|
||||
/obj/item/construction/proc/check_menu(mob/living/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/construction/proc/range_check(atom/A, mob/user)
|
||||
if(!(A in range(custom_range, get_turf(user))))
|
||||
to_chat(user, "<span class='warning'>The \'Out of Range\' light on [src] blinks red.</span>")
|
||||
@@ -276,13 +284,6 @@ RLD
|
||||
//Not scaling these down to button size because they look horrible then, instead just bumping up radius.
|
||||
return MA
|
||||
|
||||
/obj/item/construction/rcd/proc/check_menu(mob/living/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/construction/rcd/proc/change_computer_dir(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
@@ -856,6 +857,82 @@ RLD
|
||||
desc = "It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells."
|
||||
upgrade = RCD_UPGRADE_SIMPLE_CIRCUITS
|
||||
|
||||
/obj/item/construction/plumbing
|
||||
name = "Plumbing Constructor"
|
||||
desc = "An expertly modified RCD outfitted to construct plumbing machinery. Reload with compressed matter cartridges."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "arcd"
|
||||
item_state = "oldrcd"
|
||||
has_ammobar = FALSE
|
||||
matter = 200
|
||||
max_matter = 200
|
||||
|
||||
///type of the plumbing machine
|
||||
var/blueprint = null
|
||||
///index, used in the attack self to get the type. stored here since it doesnt change
|
||||
var/list/choices = list()
|
||||
///index, used in the attack self to get the type. stored here since it doesnt change
|
||||
var/list/name_to_type = list()
|
||||
///
|
||||
var/list/machinery_data = list("cost" = list(), "delay" = list())
|
||||
|
||||
/obj/item/construction/plumbing/attack_self(mob/user)
|
||||
..()
|
||||
if(!choices.len)
|
||||
for(var/A in subtypesof(/obj/machinery/plumbing))
|
||||
var/obj/machinery/plumbing/M = A
|
||||
if(initial(M.rcd_constructable))
|
||||
choices += list(initial(M.name) = image(icon = initial(M.icon), icon_state = initial(M.icon_state)))
|
||||
name_to_type[initial(M.name)] = M
|
||||
machinery_data["cost"][A] = initial(M.rcd_cost)
|
||||
machinery_data["delay"][A] = initial(M.rcd_delay)
|
||||
|
||||
var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
|
||||
if(!check_menu(user))
|
||||
return
|
||||
|
||||
blueprint = name_to_type[choice]
|
||||
playsound(src, 'sound/effects/pop.ogg', 50, FALSE)
|
||||
to_chat(user, "<span class='notice'>You change [name]s blueprint to '[choice]'.</span>")
|
||||
|
||||
///pretty much rcd_create, but named differently to make myself feel less bad for copypasting from a sibling-type
|
||||
/obj/item/construction/plumbing/proc/create_machine(atom/A, mob/user)
|
||||
if(!machinery_data || !isopenturf(A))
|
||||
return FALSE
|
||||
|
||||
if(checkResource(machinery_data["cost"][blueprint], user) && blueprint)
|
||||
if(do_after(user, machinery_data["delay"][blueprint], target = A))
|
||||
if(checkResource(machinery_data["cost"][blueprint], user) && canPlace(A))
|
||||
useResource(machinery_data["cost"][blueprint], user)
|
||||
activate()
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
|
||||
new blueprint (A, FALSE, FALSE)
|
||||
return TRUE
|
||||
|
||||
/obj/item/construction/plumbing/proc/canPlace(turf/T)
|
||||
if(!isopenturf(T))
|
||||
return FALSE
|
||||
. = TRUE
|
||||
for(var/obj/O in T.contents)
|
||||
if(O.density) //let's not built ontop of dense stuff, like big machines and other obstacles, it kills my immershion
|
||||
return FALSE
|
||||
|
||||
/obj/item/construction/plumbing/afterattack(atom/A, mob/user)
|
||||
. = ..()
|
||||
if(!range_check(A, user))
|
||||
return
|
||||
if(istype(A, /obj/machinery/plumbing))
|
||||
var/obj/machinery/plumbing/P = A
|
||||
if(P.anchored)
|
||||
to_chat(user, "<span class='warning'>The [P.name] needs to be unanchored!</span>")
|
||||
return
|
||||
if(do_after(user, 20, target = P))
|
||||
P.deconstruct() //Let's not substract matter
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE) //this is just such a great sound effect
|
||||
else
|
||||
create_machine(A, user)
|
||||
|
||||
|
||||
#undef GLOW_MODE
|
||||
#undef LIGHT_MODE
|
||||
#undef REMOVE_MODE
|
||||
|
||||
@@ -6,6 +6,7 @@ RPD
|
||||
#define ATMOS_CATEGORY 0
|
||||
#define DISPOSALS_CATEGORY 1
|
||||
#define TRANSIT_CATEGORY 2
|
||||
#define PLUMBING_CATEGORY 3
|
||||
|
||||
#define BUILD_MODE (1<<0)
|
||||
#define WRENCH_MODE (1<<1)
|
||||
@@ -75,6 +76,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
)
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(fluid_duct_recipes, list(
|
||||
"Fluid Ducts" = list(
|
||||
new /datum/pipe_info/plumbing("Duct", /obj/machinery/duct, PIPE_ONEDIR),
|
||||
new /datum/pipe_info/plumbing/multilayer("Duct Layer-Manifold",/obj/machinery/duct/multilayered, PIPE_STRAIGHT)
|
||||
)
|
||||
))
|
||||
|
||||
/datum/pipe_info
|
||||
var/name
|
||||
var/icon_state
|
||||
@@ -175,6 +183,15 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
if(dt == PIPE_UNARY_FLIPPABLE)
|
||||
icon_state = "[icon_state]_preview"
|
||||
|
||||
/datum/pipe_info/plumbing/New(label, obj/path, dt=PIPE_UNARY)
|
||||
name = label
|
||||
id = path
|
||||
icon_state = initial(path.icon_state)
|
||||
dirtype = dt
|
||||
|
||||
/datum/pipe_info/plumbing/multilayer //exists as identifier so we can see the difference between multi_layer and just ducts properly later on
|
||||
|
||||
|
||||
/obj/item/pipe_dispenser
|
||||
name = "Rapid Piping Device (RPD)"
|
||||
desc = "A device used to rapidly pipe things."
|
||||
@@ -200,15 +217,19 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
var/atmos_build_speed = 5 //deciseconds (500ms)
|
||||
var/disposal_build_speed = 5
|
||||
var/transit_build_speed = 5
|
||||
var/plumbing_build_speed = 5
|
||||
var/destroy_speed = 5
|
||||
var/paint_speed = 5
|
||||
var/category = ATMOS_CATEGORY
|
||||
var/piping_layer = PIPING_LAYER_DEFAULT
|
||||
var/ducting_layer = DUCT_LAYER_DEFAULT
|
||||
var/datum/pipe_info/recipe
|
||||
var/static/datum/pipe_info/first_atmos
|
||||
var/static/datum/pipe_info/first_disposal
|
||||
var/static/datum/pipe_info/first_transit
|
||||
var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE
|
||||
var/static/datum/pipe_info/first_plumbing
|
||||
var/locked = FALSE //wheter we can change categories. Useful for the plumber
|
||||
|
||||
/obj/item/pipe_dispenser/New()
|
||||
. = ..()
|
||||
@@ -253,12 +274,15 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
var/list/data = list(
|
||||
"category" = category,
|
||||
"piping_layer" = piping_layer,
|
||||
// "ducting_layer" = ducting_layer, //uhh is this for chem thing?
|
||||
|
||||
"ducting_layer" = ducting_layer,
|
||||
|
||||
"preview_rows" = recipe.get_preview(p_dir),
|
||||
"categories" = list(),
|
||||
"selected_color" = paint_color,
|
||||
"paint_colors" = GLOB.pipe_paint_colors,
|
||||
"mode" = mode
|
||||
"mode" = mode,
|
||||
"locked" = locked
|
||||
)
|
||||
|
||||
var/list/recipes
|
||||
@@ -269,6 +293,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
recipes = GLOB.disposal_pipe_recipes
|
||||
if(TRANSIT_CATEGORY)
|
||||
recipes = GLOB.transit_tube_recipes
|
||||
if(PLUMBING_CATEGORY)
|
||||
recipes = GLOB.fluid_duct_recipes
|
||||
for(var/c in recipes)
|
||||
var/list/cat = recipes[c]
|
||||
var/list/r = list()
|
||||
@@ -297,6 +323,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
recipe = first_atmos
|
||||
if(TRANSIT_CATEGORY)
|
||||
recipe = first_transit
|
||||
if(PLUMBING_CATEGORY)
|
||||
recipe = first_plumbing
|
||||
p_dir = NORTH
|
||||
playeffect = FALSE
|
||||
if("piping_layer")
|
||||
@@ -468,16 +496,56 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
if(mode & WRENCH_MODE)
|
||||
tube.wrench_act(user, src)
|
||||
return
|
||||
|
||||
if(PLUMBING_CATEGORY) //Plumbing.
|
||||
if(!can_make_pipe)
|
||||
return ..()
|
||||
A = get_turf(A)
|
||||
if(isclosedturf(A))
|
||||
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a fluid duct...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, plumbing_build_speed, target = A))
|
||||
var/obj/machinery/duct/D
|
||||
if(recipe.type == /datum/pipe_info/plumbing/multilayer)
|
||||
var/temp_connects = NORTH + SOUTH
|
||||
if(queued_p_dir == EAST)
|
||||
temp_connects = EAST + WEST
|
||||
D = new queued_p_type (A, TRUE, GLOB.pipe_paint_colors[paint_color], ducting_layer, temp_connects)
|
||||
else
|
||||
D = new queued_p_type (A, TRUE, GLOB.pipe_paint_colors[paint_color], ducting_layer)
|
||||
D.add_fingerprint(usr)
|
||||
if(mode & WRENCH_MODE)
|
||||
D.wrench_act(user, src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/pipe_dispenser/proc/activate()
|
||||
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
|
||||
/* unneeded, you can craft ducts from plastic
|
||||
/obj/item/pipe_dispenser/plumbing
|
||||
name = "Plumberinator"
|
||||
desc = "A crude device to rapidly plumb things."
|
||||
icon_state = "plumberer"
|
||||
category = PLUMBING_CATEGORY
|
||||
locked = TRUE
|
||||
|
||||
/obj/item/pipe_dispenser/plumbing/Initialize()
|
||||
. = ..()
|
||||
spark_system = new
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
if(!first_plumbing)
|
||||
first_plumbing = GLOB.fluid_duct_recipes[GLOB.fluid_duct_recipes[1]][1]
|
||||
|
||||
recipe = first_plumbing
|
||||
|
||||
*/
|
||||
|
||||
#undef ATMOS_CATEGORY
|
||||
#undef DISPOSALS_CATEGORY
|
||||
#undef TRANSIT_CATEGORY
|
||||
#undef PLUMBING_CATEGORY
|
||||
|
||||
#undef BUILD_MODE
|
||||
#undef DESTROY_MODE
|
||||
|
||||
@@ -48,6 +48,13 @@
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/medipen_refiller
|
||||
name = "Medipen Refiller (Machine Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/medipen_refiller
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/matter_bin = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/clonepod
|
||||
name = "Clone Pod (Machine Board)"
|
||||
build_path = /obj/machinery/clonepod
|
||||
@@ -512,6 +519,10 @@
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
needs_anchored = FALSE
|
||||
|
||||
/obj/item/circuitboard/machine/hydroponics/automagic
|
||||
name = "Automatic Hydroponics Tray (Machine Board)"
|
||||
build_path = /obj/machinery/hydroponics/constructable/automagic
|
||||
|
||||
/obj/item/circuitboard/machine/seed_extractor
|
||||
name = "Seed Extractor (Machine Board)"
|
||||
build_path = /obj/machinery/seed_extractor
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
block_projectile_mitigation = 75
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
)
|
||||
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 8
|
||||
@@ -65,14 +69,20 @@
|
||||
parry_imperfect_falloff_percent = 10
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 25 // VERY generous
|
||||
parry_efficiency_perfect = 90
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_MELEE
|
||||
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
)
|
||||
/obj/item/dualsaber/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER
|
||||
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
|
||||
return ..()
|
||||
|
||||
/obj/item/dualsaber/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
. = ..()
|
||||
if(parry_efficiency >= 90) // perfect parry
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER
|
||||
. |= BLOCK_SHOULD_REDIRECT
|
||||
|
||||
/obj/item/dualsaber/Initialize()
|
||||
. = ..()
|
||||
@@ -342,12 +352,30 @@
|
||||
name = "divine lightblade"
|
||||
desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
|
||||
force = 5
|
||||
block_chance = 50
|
||||
armour_penetration = 0
|
||||
block_parry_data = /datum/block_parry_data/chaplain
|
||||
var/chaplain_spawnable = TRUE
|
||||
can_reflect = FALSE
|
||||
obj_flags = UNIQUE_RENAME
|
||||
|
||||
/datum/block_parry_data/chaplain
|
||||
parry_stamina_cost = 12
|
||||
parry_time_windup = 2
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 3
|
||||
// parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK
|
||||
parry_time_perfect = 1
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 7.5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 80
|
||||
parry_efficiency_perfect = 120
|
||||
parry_efficiency_perfect_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 30,
|
||||
)
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = 2 SECONDS
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/chaplain/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=20, \
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
user.set_nutrition(NUTRITION_LEVEL_STARVING + 50)
|
||||
|
||||
/obj/item/book/granter/spell/blind
|
||||
spell = /obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
spell = /obj/effect/proc_holder/spell/pointed/trigger/blind
|
||||
spellname = "blind"
|
||||
icon_state ="bookblind"
|
||||
desc = "This book looks blurry, no matter how you look at it."
|
||||
@@ -265,7 +265,7 @@
|
||||
user.blind_eyes(10)
|
||||
|
||||
/obj/item/book/granter/spell/mindswap
|
||||
spell = /obj/effect/proc_holder/spell/targeted/mind_transfer
|
||||
spell = /obj/effect/proc_holder/spell/pointed/mind_transfer
|
||||
spellname = "mindswap"
|
||||
icon_state ="bookmindswap"
|
||||
desc = "This book's cover is pristine, though its pages look ragged and torn."
|
||||
@@ -289,7 +289,7 @@
|
||||
if(stored_swap == user)
|
||||
to_chat(user,"<span class='notice'>You stare at the book some more, but there doesn't seem to be anything else to learn...</span>")
|
||||
return
|
||||
var/obj/effect/proc_holder/spell/targeted/mind_transfer/swapper = new
|
||||
var/obj/effect/proc_holder/spell/pointed/mind_transfer/swapper = new
|
||||
if(swapper.cast(list(stored_swap), user, TRUE, TRUE))
|
||||
to_chat(user,"<span class='warning'>You're suddenly somewhere else... and someone else?!</span>")
|
||||
to_chat(stored_swap,"<span class='warning'>Suddenly you're staring at [src] again... where are you, who are you?!</span>")
|
||||
@@ -324,7 +324,7 @@
|
||||
user.DefaultCombatKnockdown(40)
|
||||
|
||||
/obj/item/book/granter/spell/barnyard
|
||||
spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse
|
||||
spell = /obj/effect/proc_holder/spell/pointed/barnyardcurse
|
||||
spellname = "barnyard"
|
||||
icon_state ="bookhorses"
|
||||
desc = "This book is more horse than your mind has room for."
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
if(target)
|
||||
if(!QDELETED(target))
|
||||
location = get_turf(target)
|
||||
target.cut_overlay(plastic_overlay, TRUE)
|
||||
target.cut_overlay(plastic_overlay)
|
||||
UnregisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/add_plastic_overlay)
|
||||
if(!ismob(target) || full_damage_on_mobs)
|
||||
target.ex_act(EXPLODE_HEAVY, target)
|
||||
else
|
||||
@@ -126,13 +127,17 @@
|
||||
I.embedding["embed_chance"] = 0
|
||||
I.updateEmbedding()
|
||||
|
||||
target.add_overlay(plastic_overlay, TRUE)
|
||||
RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/add_plastic_overlay)
|
||||
target.update_icon()
|
||||
if(!nadeassembly)
|
||||
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [det_time].</span>")
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time*10)
|
||||
else
|
||||
qdel(src) //How?
|
||||
|
||||
/obj/item/grenade/plastic/proc/add_plastic_overlay(atom/source, list/overlay_list)
|
||||
overlay_list += plastic_overlay
|
||||
|
||||
/obj/item/grenade/plastic/proc/shout_syndicate_crap(mob/M)
|
||||
if(!M)
|
||||
return
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/obj/item/implant/uplink/Initialize(mapload, _owner)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc, GLOB.not_incapacitated_state)
|
||||
AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc)
|
||||
|
||||
/obj/item/implanter/uplink
|
||||
name = "implanter (uplink)"
|
||||
|
||||
@@ -47,8 +47,11 @@
|
||||
spawn_option(stored_options[choice],M)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/proc/spawn_option(obj/choice,mob/living/M)
|
||||
var/obj/new_item = new choice()
|
||||
/obj/item/choice_beacon/proc/create_choice_atom(atom/choice, mob/owner)
|
||||
return new choice()
|
||||
|
||||
/obj/item/choice_beacon/proc/spawn_option(atom/choice,mob/living/M)
|
||||
var/obj/new_item = create_choice_atom(choice, M)
|
||||
var/obj/structure/closet/supplypod/bluespacepod/pod = new()
|
||||
pod.explosionSize = list(0,0,0,0)
|
||||
new_item.forceMove(pod)
|
||||
@@ -152,10 +155,50 @@
|
||||
augment_list[initial(A.name)] = A
|
||||
return augment_list
|
||||
|
||||
/obj/item/choice_beacon/augments/spawn_option(obj/choice,mob/living/M)
|
||||
/obj/item/choice_beacon/augments/spawn_option(atom/choice,mob/living/M)
|
||||
new choice(get_turf(M))
|
||||
to_chat(M, "<span class='hear'>You hear something crackle from the beacon for a moment before a voice speaks. \"Please stand by for a message from S.E.L.F. Message as follows: <b>Item request received. Your package has been transported, use the autosurgeon supplied to apply the upgrade.</b> Message ends.\"</span>")
|
||||
|
||||
/obj/item/choice_beacon/pet //donator beacon that summons a small friendly animal
|
||||
name = "pet beacon"
|
||||
desc = "Straight from the outerspace pet shop to your feet."
|
||||
var/static/list/pets = list("Crab" = /mob/living/simple_animal/crab,
|
||||
"Cat" = /mob/living/simple_animal/pet/cat,
|
||||
"Space cat" = /mob/living/simple_animal/pet/cat/space,
|
||||
"Kitten" = /mob/living/simple_animal/pet/cat/kitten,
|
||||
"Dog" = /mob/living/simple_animal/pet/dog,
|
||||
"Corgi" = /mob/living/simple_animal/pet/dog/corgi,
|
||||
"Pug" = /mob/living/simple_animal/pet/dog/pug,
|
||||
"Exotic Corgi" = /mob/living/simple_animal/pet/dog/corgi/exoticcorgi,
|
||||
"Fox" = /mob/living/simple_animal/pet/fox,
|
||||
"Red Panda" = /mob/living/simple_animal/pet/redpanda,
|
||||
"Possum" = /mob/living/simple_animal/opossum)
|
||||
var/pet_name
|
||||
|
||||
/obj/item/choice_beacon/pet/generate_display_names()
|
||||
return pets
|
||||
|
||||
/obj/item/choice_beacon/pet/create_choice_atom(atom/choice, mob/owner)
|
||||
var/mob/living/simple_animal/new_choice = new choice()
|
||||
new_choice.butcher_results = null //please don't eat your pet, chef
|
||||
var/obj/item/pet_carrier/donator/carrier = new() //a donator pet carrier is just a carrier that can't be shoved in an autolathe for metal
|
||||
carrier.add_occupant(new_choice)
|
||||
new_choice.mob_size = MOB_SIZE_TINY //yeah we're not letting you use this roundstart pet to hurt people / knock them down
|
||||
new_choice.pass_flags = PASSTABLE | PASSMOB //your pet is not a bullet/person shield
|
||||
new_choice.density = FALSE
|
||||
new_choice.blood_volume = 0 //your pet cannot be used to drain blood from for a bloodsucker
|
||||
new_choice.desc = "A pet [initial(choice.name)], owned by [owner]!"
|
||||
new_choice.can_have_ai = FALSE //no it cant be sentient damnit
|
||||
if(pet_name)
|
||||
new_choice.name = pet_name
|
||||
new_choice.unique_name = TRUE
|
||||
return carrier
|
||||
|
||||
/obj/item/choice_beacon/pet/spawn_option(atom/choice,mob/living/M)
|
||||
pet_name = input(M, "What would you like to name the pet? (leave blank for default name)", "Pet Name")
|
||||
..()
|
||||
|
||||
//choice boxes (they just open in your hand instead of making a pod)
|
||||
/obj/item/choice_beacon/box
|
||||
name = "choice box (default)"
|
||||
desc = "Think really hard about what you want, and then rip it open!"
|
||||
@@ -163,21 +206,17 @@
|
||||
icon_state = "deliverypackage3"
|
||||
item_state = "deliverypackage3"
|
||||
|
||||
/obj/item/choice_beacon/box/spawn_option(obj/choice,mob/living/M)
|
||||
to_chat(M, "<span class='hear'>The box opens, revealing the [choice]!</span>")
|
||||
/obj/item/choice_beacon/box/spawn_option(atom/choice,mob/living/M)
|
||||
var/choice_text = choice
|
||||
if(ispath(choice_text))
|
||||
choice_text = initial(choice.name)
|
||||
to_chat(M, "<span class='hear'>The box opens, revealing the [choice_text]!</span>")
|
||||
playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1)
|
||||
M.temporarilyRemoveItemFromInventory(src, TRUE)
|
||||
M.put_in_hands(new choice)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/box/plushie
|
||||
name = "choice box (plushie)"
|
||||
desc = "Using the power of quantum entanglement, this box contains every plush, until the moment it is opened!"
|
||||
icon = 'icons/obj/plushes.dmi'
|
||||
icon_state = "box"
|
||||
item_state = "box"
|
||||
|
||||
/obj/item/choice_beacon/box/spawn_option(choice,mob/living/M)
|
||||
/obj/item/choice_beacon/box/plushie/spawn_option(choice,mob/living/M)
|
||||
if(ispath(choice, /obj/item/toy/plush))
|
||||
..() //regular plush, spawn it naturally
|
||||
else
|
||||
@@ -188,6 +227,31 @@
|
||||
M.put_in_hands(new choice)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/box/carpet //donator carpet beacon
|
||||
name = "choice box (carpet)"
|
||||
desc = "Contains 50 of a selected carpet inside!"
|
||||
var/static/list/carpet_list = list(/obj/item/stack/tile/carpet/black/fifty = "Black Carpet",
|
||||
"Black & Red Carpet" = /obj/item/stack/tile/carpet/blackred/fifty,
|
||||
"Monochrome Carpet" = /obj/item/stack/tile/carpet/monochrome/fifty,
|
||||
"Blue Carpet" = /obj/item/stack/tile/carpet/blue/fifty,
|
||||
"Cyan Carpet" = /obj/item/stack/tile/carpet/cyan/fifty,
|
||||
"Green Carpet" = /obj/item/stack/tile/carpet/green/fifty,
|
||||
"Orange Carpet" = /obj/item/stack/tile/carpet/orange/fifty,
|
||||
"Purple Carpet" = /obj/item/stack/tile/carpet/purple/fifty,
|
||||
"Red Carpet" = /obj/item/stack/tile/carpet/red/fifty,
|
||||
"Royal Black Carpet" = /obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
"Royal Blue Carpet" = /obj/item/stack/tile/carpet/royalblue/fifty)
|
||||
|
||||
/obj/item/choice_beacon/box/carpet/generate_display_names()
|
||||
return carpet_list
|
||||
|
||||
/obj/item/choice_beacon/box/plushie
|
||||
name = "choice box (plushie)"
|
||||
desc = "Using the power of quantum entanglement, this box contains every plush, until the moment it is opened!"
|
||||
icon = 'icons/obj/plushes.dmi'
|
||||
icon_state = "box"
|
||||
item_state = "box"
|
||||
|
||||
/obj/item/choice_beacon/box/plushie/generate_display_names()
|
||||
var/list/plushie_list = list()
|
||||
//plushie set 1: just subtypes of /obj/item/toy/plush
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
var/has_lock_sprites = TRUE //whether to load the lock overlays or not
|
||||
var/allows_hostiles = FALSE //does the pet carrier allow hostile entities to be held within it?
|
||||
|
||||
/obj/item/pet_carrier/donator
|
||||
custom_materials = null //you cant just use the loadout item to get free metal!
|
||||
|
||||
/obj/item/pet_carrier/Destroy()
|
||||
if(occupants.len)
|
||||
for(var/V in occupants)
|
||||
@@ -240,7 +243,31 @@
|
||||
custom_materials = list(/datum/material/glass = 1000, /datum/material/bluespace = 600)
|
||||
escape_time = 200 //equal to the time of a bluespace bodybag
|
||||
alternate_escape_time = 100
|
||||
|
||||
///gas supply for simplemobs so they don't die
|
||||
var/datum/gas_mixture/occupant_gas_supply
|
||||
///level until the reagent gets INGEST ed instead of TOUCH
|
||||
var/sipping_level = 150
|
||||
///prob50 level of sipping
|
||||
var/sipping_probably = 99
|
||||
///chem transfer rate / second
|
||||
var/transfer_rate = 5
|
||||
|
||||
/obj/item/pet_carrier/bluespace/Initialize()
|
||||
. = ..()
|
||||
create_reagents(300, OPENCONTAINER, DEFAULT_REAGENTS_VALUE) //equivalent of bsbeakers
|
||||
|
||||
/obj/item/pet_carrier/bluespace/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/pet_carrier/bluespace/attack_self(mob/living/user)
|
||||
..()
|
||||
if(reagents)
|
||||
if(open)
|
||||
reagents.reagents_holder_flags = OPENCONTAINER
|
||||
else
|
||||
reagents.reagents_holder_flags = NONE
|
||||
|
||||
/obj/item/pet_carrier/bluespace/update_icon_state()
|
||||
if(open)
|
||||
@@ -248,11 +275,28 @@
|
||||
else
|
||||
icon_state = "bluespace_jar"
|
||||
|
||||
/obj/item/pet_carrier/bluespace/throw_impact()
|
||||
/obj/item/pet_carrier/bluespace/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
. = ..()
|
||||
//delete the item upon impact, releasing the creature inside (this is handled by its deletion)
|
||||
if(occupants.len)
|
||||
loc.visible_message("<span class='warning'>The bluespace jar smashes, releasing [occupants[1]]!</span>")
|
||||
|
||||
if(reagents?.total_volume && ismob(hit_atom) && hit_atom.reagents)
|
||||
reagents.total_volume *= rand(5,10) * 0.1 //Not all of it makes contact with the target
|
||||
var/mob/M = hit_atom
|
||||
var/R = reagents.log_list()
|
||||
hit_atom.visible_message("<span class='danger'>[M] has been splashed with something!</span>", \
|
||||
"<span class='userdanger'>[M] has been splashed with something!</span>")
|
||||
var/turf/TT = get_turf(hit_atom)
|
||||
var/throwerstring
|
||||
if(thrownby)
|
||||
log_combat(thrownby, M, "splashed", R)
|
||||
var/turf/AT = get_turf(thrownby)
|
||||
throwerstring = " THROWN BY [key_name(thrownby)] at [AT] (AREACOORD(AT)]"
|
||||
log_reagent("SPLASH: [src] mob throw_impact() onto [key_name(hit_atom)] at [TT] ([AREACOORD(TT)])[throwerstring] - [R]")
|
||||
reagents.reaction(hit_atom, TOUCH)
|
||||
reagents.clear_reagents()
|
||||
|
||||
playsound(src, "shatter", 70, 1)
|
||||
qdel(src)
|
||||
|
||||
@@ -260,21 +304,24 @@
|
||||
. = ..()
|
||||
if(!occupant_gas_supply)
|
||||
occupant_gas_supply = new
|
||||
|
||||
if(isanimal(occupant))
|
||||
var/mob/living/simple_animal/animal = occupant
|
||||
occupant_gas_supply[/datum/gas/oxygen] = 0.0064 //make sure it has some gas in so it isn't depressurized
|
||||
occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature/pressure when their turf isnt a location
|
||||
else
|
||||
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
|
||||
ADD_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
|
||||
|
||||
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
|
||||
START_PROCESSING(SSobj, src)
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
|
||||
ADD_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
|
||||
|
||||
/obj/item/pet_carrier/bluespace/remove_occupant(mob/living/occupant)
|
||||
. = ..()
|
||||
if(ishuman(occupant))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
|
||||
REMOVE_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
|
||||
@@ -287,6 +334,18 @@
|
||||
occupant_gas_supply = new
|
||||
return occupant_gas_supply
|
||||
|
||||
/obj/item/pet_carrier/bluespace/process()
|
||||
if(!reagents)
|
||||
return
|
||||
for(var/mob/living/L in occupants)
|
||||
if(!ishuman(L))
|
||||
continue
|
||||
if((reagents.total_volume >= sipping_level) || ((reagents.total_volume >= sipping_probably) && prob(50))) //sipp
|
||||
reagents.reaction(L, INGEST) //consume
|
||||
reagents.trans_to(L, transfer_rate)
|
||||
else
|
||||
reagents.reaction(L, TOUCH, show_message = FALSE)
|
||||
|
||||
/obj/item/pet_carrier/bluespace/load_occupant(mob/living/user, mob/living/target)
|
||||
if(..())
|
||||
name = "[initial(name)] ([target])"
|
||||
|
||||
@@ -688,6 +688,18 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
icon_state = "scrubpuppy"
|
||||
item_state = "scrubpuppy"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/meddrake
|
||||
name = "MediDrake Plushie"
|
||||
desc = "An adorable stuffed toy of a Medidrake."
|
||||
icon_state = "meddrake"
|
||||
item_state = "meddrake"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/secdrake
|
||||
name = "SecDrake Plushie"
|
||||
desc = "An adorable stuffed toy of a Secdrake."
|
||||
icon_state = "secdrake"
|
||||
item_state = "secdrake"
|
||||
|
||||
/obj/item/toy/plush/aiplush
|
||||
name = "AI plushie"
|
||||
desc = "A little stuffed toy AI core... it appears to be malfunctioning."
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
absorption_capacity = 5
|
||||
splint_factor = 0.35
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
grind_results = list(/datum/reagent/cellulose = 2)
|
||||
|
||||
// gauze is only relevant for wounds, which are handled in the wounds themselves
|
||||
/obj/item/stack/medical/gauze/try_heal(mob/living/M, mob/user, silent)
|
||||
|
||||
@@ -412,6 +412,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
force = 0
|
||||
throwforce = 0
|
||||
merge_type = /obj/item/stack/sheet/cloth
|
||||
grind_results = list(/datum/reagent/cellulose = 2)
|
||||
|
||||
/obj/item/stack/sheet/cloth/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -672,6 +673,10 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
new/datum/stack_recipe("wall gear", /obj/structure/girder/bronze, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null,
|
||||
new/datum/stack_recipe("directional bronze window", /obj/structure/window/bronze/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("fulltile bronze window", /obj/structure/window/bronze/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("pinion airlock assembly", /obj/structure/door_assembly/door_assembly_bronze, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze pinion airlock assembly", /obj/structure/door_assembly/door_assembly_bronze/seethru, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze hat", /obj/item/clothing/head/bronze), \
|
||||
new/datum/stack_recipe("bronze suit", /obj/item/clothing/suit/bronze), \
|
||||
new/datum/stack_recipe("bronze boots", /obj/item/clothing/shoes/bronze), \
|
||||
@@ -679,9 +684,10 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \
|
||||
))
|
||||
|
||||
/obj/item/stack/tile/bronze
|
||||
/obj/item/stack/sheet/bronze
|
||||
name = "brass"
|
||||
desc = "On closer inspection, what appears to be wholly-unsuitable-for-building brass is actually more structurally stable bronze."
|
||||
singular_name = "bronze sheet"
|
||||
@@ -690,27 +696,21 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/bronze = MINERAL_MATERIAL_AMOUNT)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
throwforce = 10
|
||||
max_amount = 50
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
turf_type = /turf/open/floor/bronze
|
||||
novariants = FALSE
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/copper = 3) //we have no "tin" reagent so this is the closest thing
|
||||
merge_type = /obj/item/stack/tile/bronze
|
||||
merge_type = /obj/item/stack/sheet/bronze
|
||||
tableVariant = /obj/structure/table/bronze
|
||||
material_type = /datum/material/bronze
|
||||
|
||||
/obj/item/stack/tile/bronze/attack_self(mob/living/user)
|
||||
/obj/item/stack/sheet/bronze/attack_self(mob/living/user)
|
||||
if(is_servant_of_ratvar(user)) //still lets them build with it, just gives a message
|
||||
to_chat(user, "<span class='danger'>Wha... what is this cheap imitation crap? This isn't brass at all!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/stack/tile/bronze/get_main_recipes()
|
||||
/obj/item/stack/sheet/bronze/get_main_recipes()
|
||||
. = ..()
|
||||
. += GLOB.bronze_recipes
|
||||
|
||||
/obj/item/stack/tile/bronze/thirty
|
||||
/obj/item/stack/sheet/bronze/thirty
|
||||
amount = 30
|
||||
|
||||
/*
|
||||
@@ -774,6 +774,7 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
|
||||
new /datum/stack_recipe("water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/empty), \
|
||||
new /datum/stack_recipe("large water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/large/empty,3), \
|
||||
new /datum/stack_recipe("shower curtain", /obj/structure/curtain, 10, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("duct", /obj/item/stack/ducts,1), \
|
||||
new /datum/stack_recipe("laser pointer case", /obj/item/glasswork/glass_base/laserpointer_shell, 30), \
|
||||
new /datum/stack_recipe("wet floor sign", /obj/item/caution, 2)))
|
||||
|
||||
@@ -842,6 +843,7 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
merge_type = /obj/item/stack/sheet/cotton
|
||||
var/pull_effort = 30
|
||||
var/loom_result = /obj/item/stack/sheet/cloth
|
||||
grind_results = list(/datum/reagent/cellulose = 5)
|
||||
|
||||
/obj/item/stack/sheet/cotton/ten
|
||||
amount = 10
|
||||
@@ -857,6 +859,7 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
merge_type = /obj/item/stack/sheet/cotton/durathread
|
||||
pull_effort = 70
|
||||
loom_result = /obj/item/stack/sheet/durathread
|
||||
grind_results = list(/datum/reagent/cellulose = 10)
|
||||
|
||||
/obj/item/stack/sheet/meat
|
||||
name = "meat sheets"
|
||||
|
||||
@@ -513,3 +513,12 @@
|
||||
icon_state = "material_tile"
|
||||
turf_type = /turf/open/floor/material
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
|
||||
/obj/item/stack/tile/bronze
|
||||
name = "bronze tile"
|
||||
singular_name = "bronze floor tile"
|
||||
desc = "A tile made out of bronze. Looks like clockwork."
|
||||
icon_state = "material_tile"
|
||||
color = "#92661A"
|
||||
turf_type = /turf/open/floor/bronze
|
||||
custom_materials = list(/datum/material/bronze = 250)
|
||||
|
||||
@@ -478,7 +478,7 @@
|
||||
/obj/item/assembly/signaler,
|
||||
/obj/item/lightreplacer,
|
||||
/obj/item/rcd_ammo,
|
||||
/obj/item/construction/rcd,
|
||||
/obj/item/construction,
|
||||
/obj/item/pipe_dispenser,
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/tile/plasteel,
|
||||
@@ -492,7 +492,7 @@
|
||||
icon_state = "grenadebeltnew"
|
||||
item_state = "security"
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
|
||||
|
||||
/obj/item/storage/belt/grenade/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
|
||||
@@ -47,41 +47,58 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
user.visible_message("<span class='suicide'>[user] is offering [user.p_them()]self to [deity_name]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/storage/book/bible/attack_self(mob/living/carbon/human/H)
|
||||
if(!istype(H))
|
||||
/obj/item/storage/book/bible/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
// If H is the Chaplain, we can set the icon_state of the bible (but only once!)
|
||||
if(!GLOB.bible_icon_state && H.job == "Chaplain")
|
||||
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Pick Bible Style</title></head><body><center><h2>Pick a bible style</h2></center><table>"
|
||||
for(var/i in 1 to GLOB.biblestates.len)
|
||||
var/icon/bibleicon = icon('icons/obj/storage.dmi', GLOB.biblestates[i])
|
||||
var/nicename = GLOB.biblenames[i]
|
||||
H << browse_rsc(bibleicon, nicename)
|
||||
dat += {"<tr><td><img src="[nicename]"></td><td><a href="?src=[REF(src)];seticon=[i]">[nicename]</a></td></tr>"}
|
||||
dat += "</table></body></html>"
|
||||
H << browse(dat, "window=editicon;can_close=0;can_minimize=0;size=250x650")
|
||||
if(GLOB.bible_icon_state) // if there is already a bible icon return FALSE
|
||||
return FALSE
|
||||
if(user.job != "Chaplain") // if the user is not the chaplain, return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/item/storage/book/bible/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(src))
|
||||
return
|
||||
if(href_list["seticon"] && GLOB && !GLOB.bible_icon_state)
|
||||
var/iconi = text2num(href_list["seticon"])
|
||||
var/biblename = GLOB.biblenames[iconi]
|
||||
var/obj/item/storage/book/bible/B = locate(href_list["src"])
|
||||
B.icon_state = GLOB.biblestates[iconi]
|
||||
B.item_state = GLOB.bibleitemstates[iconi]
|
||||
var/list/skins = list()
|
||||
for(var/i in 1 to GLOB.biblestates.len)
|
||||
var/image/bible_image = image(icon = 'icons/obj/storage.dmi', icon_state = GLOB.biblestates[i])
|
||||
skins += list("[GLOB.biblenames[i]]" = bible_image)
|
||||
|
||||
if(B.icon_state == "honk1" || B.icon_state == "honk2")
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.dna.add_mutation(CLOWNMUT)
|
||||
H.dna.add_mutation(SMILE)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), SLOT_WEAR_MASK)
|
||||
var/choice = show_radial_menu(user, src, skins, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 40, require_near = TRUE)
|
||||
if(!choice)
|
||||
return FALSE
|
||||
var/bible_index = GLOB.biblenames.Find(choice)
|
||||
if(!bible_index)
|
||||
return FALSE
|
||||
icon_state = GLOB.biblestates[bible_index]
|
||||
item_state = GLOB.bibleitemstates[bible_index]
|
||||
|
||||
GLOB.bible_icon_state = B.icon_state
|
||||
GLOB.bible_item_state = B.item_state
|
||||
if(icon_state == "honk1" || icon_state == "honk2")
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.dna.add_mutation(CLOWNMUT)
|
||||
H.dna.add_mutation(SMILE)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), SLOT_WEAR_MASK)
|
||||
|
||||
SSblackbox.record_feedback("text", "religion_book", 1, "[biblename]")
|
||||
usr << browse(null, "window=editicon")
|
||||
GLOB.bible_icon_state = icon_state
|
||||
GLOB.bibleitemstates = item_state
|
||||
SSblackbox.record_feedback("text", "religion_book", 1, "[choice]")
|
||||
|
||||
/**
|
||||
* Checks if we are allowed to interact with the radial
|
||||
*
|
||||
* Arguements: user The mob interacting with the menu
|
||||
*/
|
||||
|
||||
/obj/item/storage/book/bible/proc/check_menu(mob/living/carbon/human/user)
|
||||
if(GLOB.bible_icon_state)
|
||||
return FALSE
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(!user.is_holding(src))
|
||||
return FALSE
|
||||
if(!user.can_read(src))
|
||||
return FALSE
|
||||
if(user.incapacitated())
|
||||
return FALSE
|
||||
if(user.job != "Chaplain")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/storage/book/bible/proc/bless(mob/living/carbon/human/H, mob/living/user)
|
||||
for(var/X in H.bodyparts)
|
||||
|
||||
@@ -245,19 +245,20 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
new /obj/item/stack/cable_coil/white(src)
|
||||
|
||||
/obj/item/storage/toolbox/ammo
|
||||
name = "ammo box"
|
||||
desc = "It contains a few clips."
|
||||
name = "ammunition case (7.62mm stripper clips)"
|
||||
desc = "It contains a few 7.62 stripper clips."
|
||||
icon_state = "ammobox"
|
||||
item_state = "ammobox"
|
||||
var/ammotype = /obj/item/ammo_box/a762 // make sure this is a typepath thanks
|
||||
|
||||
/obj/item/storage/toolbox/ammo/PopulateContents()
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
for (var/i = 0, i < 7, i++)
|
||||
new ammotype(src)
|
||||
|
||||
/obj/item/storage/toolbox/ammo/surplus
|
||||
name = "ammunition case (10mm rifle magazines)"
|
||||
desc = "It contains a few 10mm rifle magazines."
|
||||
ammotype = /obj/item/ammo_box/magazine/m10mm/rifle
|
||||
|
||||
/obj/item/storage/toolbox/infiltrator
|
||||
name = "insidious case"
|
||||
@@ -280,6 +281,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
/obj/item/clothing/suit/armor/vest/infiltrator,
|
||||
/obj/item/clothing/under/syndicate/bloodred,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile/infiltrator,
|
||||
/obj/item/clothing/gloves/tackler/combat/insulated/infiltrator,
|
||||
/obj/item/clothing/mask/infiltrator,
|
||||
/obj/item/clothing/shoes/combat/sneakboots,
|
||||
/obj/item/gun/ballistic/automatic/pistol,
|
||||
@@ -291,7 +293,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
new /obj/item/clothing/head/helmet/infiltrator(src)
|
||||
new /obj/item/clothing/suit/armor/vest/infiltrator(src)
|
||||
new /obj/item/clothing/under/syndicate/bloodred(src)
|
||||
new /obj/item/clothing/gloves/color/latex/nitrile/infiltrator(src)
|
||||
new /obj/item/clothing/gloves/tackler/combat/insulated/infiltrator(src)
|
||||
new /obj/item/clothing/mask/infiltrator(src)
|
||||
new /obj/item/clothing/shoes/combat/sneakboots(src)
|
||||
|
||||
|
||||
@@ -257,6 +257,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/katana/timestop
|
||||
name = "temporal katana"
|
||||
desc = "Delicately balanced, this finely-crafted blade hums with barely-restrained potential."
|
||||
icon_state = "temporalkatana"
|
||||
item_state = "temporalkatana"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
block_chance = 0 // oops
|
||||
force = 27.5 // oops
|
||||
item_flags = ITEM_CAN_PARRY
|
||||
@@ -268,6 +272,21 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
flynn.emote("smirk")
|
||||
new /obj/effect/timestop/magic(get_turf(owner), 1, 50, list(owner)) // null roddies counter
|
||||
|
||||
/obj/item/katana/timestop/suicide_act(mob/living/user) // stolen from hierophant staff
|
||||
new /obj/effect/timestop/magic(get_turf(user), 1, 50, list(user)) // free usage for dying
|
||||
user.visible_message("<span class='suicide'>[user] poses menacingly with the [src]! It looks like [user.p_theyre()] trying to teleport behind someone!</span>")
|
||||
user.say("Heh.. Nothing personnel, kid..", forced = "temporal katana suicide")
|
||||
sleep(20)
|
||||
if(!user)
|
||||
return
|
||||
user.visible_message("<span class='hierophant_warning'>[user] vanishes into a cloud of falling dust and burning embers, likely off to style on some poor sod in the distance!</span>")
|
||||
playsound(user,'sound/magic/blink.ogg', 75, TRUE)
|
||||
for(var/obj/item/I in user)
|
||||
if(I != src)
|
||||
user.dropItemToGround(I)
|
||||
user.dropItemToGround(src) //Drop us last, so it goes on top of their stuff
|
||||
qdel(user)
|
||||
|
||||
/obj/item/melee/bokken // parrying stick
|
||||
name = "bokken"
|
||||
desc = "A space-Japanese training sword made of wood and shaped like a katana."
|
||||
@@ -302,7 +321,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
parry_time_perfect = 1.5
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 7.5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_to_counterattack = 120
|
||||
parry_efficiency_considered_successful = 65 // VERY generous
|
||||
parry_efficiency_perfect = 120
|
||||
parry_efficiency_perfect_override = list(
|
||||
@@ -311,13 +330,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_data = list(
|
||||
PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 2.5, // 7*2.5 = 17.5, 8*2.5 = 20, 9*2.5 = 22.5, 10*2.5 = 25
|
||||
)
|
||||
)
|
||||
|
||||
/datum/block_parry_data/bokken/quick_parry // emphasizing REALLY SHORT PARRIES
|
||||
parry_stamina_cost = 6 // still more costly than most parries, but less than a full bokken parry
|
||||
parry_time_active = 5 // REALLY small parry window
|
||||
parry_time_perfect = 2.5 // however...
|
||||
parry_time_perfect_leeway = 2.5 // the entire time, the parry is perfect
|
||||
parry_time_perfect_leeway = 2 // the entire time, the parry is perfect
|
||||
parry_failed_stagger_duration = 1 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS // more forgiving punishments for missed parries
|
||||
// still, don't fucking miss your parries or you're down stamina and staggered to shit
|
||||
|
||||
@@ -186,7 +186,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
if(!acid_level)
|
||||
SSacid.processing[src] = src
|
||||
add_overlay(GLOB.acid_overlay, TRUE)
|
||||
update_icon()
|
||||
var/acid_cap = acidpwr * 300 //so we cannot use huge amounts of weak acids to do as well as strong acids.
|
||||
if(acid_level < acid_cap)
|
||||
acid_level = min(acid_level + acidpwr * acid_volume, acid_cap)
|
||||
@@ -224,7 +224,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE))
|
||||
resistance_flags |= ON_FIRE
|
||||
SSfire_burning.processing[src] = src
|
||||
add_overlay(GLOB.fire_overlay, TRUE)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
//called when the obj is destroyed by fire
|
||||
@@ -236,7 +236,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
/obj/proc/extinguish()
|
||||
if(resistance_flags & ON_FIRE)
|
||||
resistance_flags &= ~ON_FIRE
|
||||
cut_overlay(GLOB.fire_overlay, TRUE)
|
||||
update_icon()
|
||||
SSfire_burning.processing -= src
|
||||
|
||||
/obj/zap_act(power, zap_flags, shocked_targets)
|
||||
|
||||
@@ -317,6 +317,13 @@
|
||||
icon_state = unique_reskin[choice]
|
||||
to_chat(M, "[src] is now skinned as '[choice]'.")
|
||||
|
||||
/obj/update_overlays()
|
||||
. = ..()
|
||||
if(acid_level)
|
||||
. += GLOB.acid_overlay
|
||||
if(resistance_flags & ON_FIRE)
|
||||
. += GLOB.fire_overlay
|
||||
|
||||
//Called when the object is constructed by an autolathe
|
||||
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
|
||||
/obj/proc/autolathe_crafted(obj/machinery/autolathe/A)
|
||||
@@ -329,3 +336,6 @@
|
||||
. = ..()
|
||||
if(. && ricochet_damage_mod)
|
||||
take_damage(P.damage * ricochet_damage_mod, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration) // pass along ricochet_damage_mod damage to the structure for the ricochet
|
||||
|
||||
/obj/proc/plunger_act(obj/item/plunger/P, mob/living/user, reinforced)
|
||||
return
|
||||
|
||||
@@ -112,3 +112,6 @@
|
||||
if(0 to 25)
|
||||
if(!broken)
|
||||
return "<span class='warning'>It's falling apart!</span>"
|
||||
|
||||
/obj/structure/rust_heretic_act()
|
||||
take_damage(500, BRUTE, "melee", 1)
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
desc = "A bronze bar stool with red silk for a pillow."
|
||||
icon_state = "barbrass"
|
||||
item_chair = /obj/item/chair/stool/bar/bronze
|
||||
buildstacktype = /obj/item/stack/tile/bronze
|
||||
buildstacktype = /obj/item/stack/sheet/bronze
|
||||
buildstackamount = 1
|
||||
|
||||
/obj/structure/chair/stool/brass
|
||||
@@ -503,7 +503,7 @@
|
||||
desc = "A bronze stool with a silk top for comfort."
|
||||
icon_state = "stoolbrass"
|
||||
item_chair = /obj/item/chair/stool/bronze
|
||||
buildstacktype = /obj/item/stack/tile/bronze
|
||||
buildstacktype = /obj/item/stack/sheet/bronze
|
||||
buildstackamount = 1
|
||||
|
||||
/obj/item/chair/stool/brass
|
||||
@@ -569,7 +569,6 @@
|
||||
buildstacktype = /obj/item/stack/tile/brass
|
||||
buildstackamount = 1
|
||||
item_chair = null
|
||||
var/turns = 0
|
||||
|
||||
/obj/structure/chair/brass/ComponentInitialize()
|
||||
return //it spins with the power of ratvar, not components.
|
||||
@@ -581,16 +580,12 @@
|
||||
/obj/structure/chair/brass/process()
|
||||
setDir(turn(dir,-90))
|
||||
playsound(src, 'sound/effects/servostep.ogg', 50, FALSE)
|
||||
turns++
|
||||
if(turns >= 8)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/structure/chair/brass/ratvar_act()
|
||||
return
|
||||
|
||||
/obj/structure/chair/brass/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
turns = 0
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
if(!(datum_flags & DF_ISPROCESSING))
|
||||
@@ -608,7 +603,7 @@
|
||||
desc = "A spinny chair made of bronze. It has little cogs for wheels!"
|
||||
anchored = FALSE
|
||||
icon_state = "brass_chair"
|
||||
buildstacktype = /obj/item/stack/tile/bronze
|
||||
buildstacktype = /obj/item/stack/sheet/bronze
|
||||
buildstackamount = 1
|
||||
item_chair = null
|
||||
|
||||
|
||||
@@ -243,10 +243,24 @@ LINEN BINS
|
||||
|
||||
/obj/item/bedsheet/random/Initialize()
|
||||
..()
|
||||
var/type = pick(typesof(/obj/item/bedsheet) - /obj/item/bedsheet/random)
|
||||
var/type = pick(typesof(/obj/item/bedsheet) - list(/obj/item/bedsheet/random, /obj/item/bedsheet/chameleon))
|
||||
new type(loc)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/item/bedsheet/chameleon //donator chameleon bedsheet
|
||||
name = "chameleon bedsheet"
|
||||
desc = "Bedsheet technology has truly gone too far."
|
||||
var/datum/action/item_action/chameleon/change/chameleon_action
|
||||
|
||||
/obj/item/bedsheet/chameleon/New()
|
||||
..()
|
||||
chameleon_action = new(src)
|
||||
chameleon_action.chameleon_type = /obj/item/bedsheet
|
||||
chameleon_action.chameleon_name = "Bedsheet"
|
||||
chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/bedsheet/chameleon, /obj/item/bedsheet/random), only_root_path = TRUE)
|
||||
chameleon_action.initialize_disguises()
|
||||
|
||||
//bedsheet bin
|
||||
/obj/structure/bedsheetbin
|
||||
name = "linen bin"
|
||||
desc = "It looks rather cosy."
|
||||
|
||||
@@ -111,6 +111,9 @@
|
||||
var/mob/living/L = user
|
||||
if(HAS_TRAIT(L, TRAIT_SKITTISH))
|
||||
. += "<span class='notice'>Ctrl-Shift-click [src] to jump inside.</span>"
|
||||
if(isobserver(user))
|
||||
. += "<span class='info'>It contains: [english_list(contents)].</span>"
|
||||
investigate_log("had its contents examined by [user] as a ghost.", INVESTIGATE_GHOST)
|
||||
|
||||
/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
|
||||
if(wall_mounted)
|
||||
|
||||
@@ -240,3 +240,14 @@
|
||||
airlock_type = /obj/machinery/door/airlock/wood
|
||||
mineral = "wood"
|
||||
glass_type = /obj/machinery/door/airlock/wood/glass
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_bronze
|
||||
name = "bronze airlock assembly"
|
||||
icon = 'icons/obj/doors/airlocks/clockwork/pinion_airlock.dmi'
|
||||
base_name = "bronze airlock"
|
||||
airlock_type = /obj/machinery/door/airlock/bronze
|
||||
noglass = TRUE
|
||||
material_type = /obj/item/stack/tile/bronze
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_bronze/seethru
|
||||
airlock_type = /obj/machinery/door/airlock/bronze/seethru
|
||||
|
||||
@@ -442,19 +442,19 @@
|
||||
to_chat(user, "<span class='notice'>You start slicing apart [src]...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
to_chat(user, "<span class='notice'>You slice apart [src].</span>")
|
||||
var/obj/item/stack/tile/bronze/B = new(drop_location(), 2)
|
||||
var/obj/item/stack/sheet/bronze/B = new(drop_location(), 2)
|
||||
transfer_fingerprints_to(B)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/pickaxe/drill/jackhammer))
|
||||
to_chat(user, "<span class='notice'>Your jackhammer smashes through the girder!</span>")
|
||||
var/obj/item/stack/tile/bronze/B = new(drop_location(), 2)
|
||||
var/obj/item/stack/sheet/bronze/B = new(drop_location(), 2)
|
||||
transfer_fingerprints_to(B)
|
||||
W.play_tool_sound(src)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/stack/tile/bronze))
|
||||
var/obj/item/stack/tile/bronze/B = W
|
||||
else if(istype(W, /obj/item/stack/sheet/bronze))
|
||||
var/obj/item/stack/sheet/bronze/B = W
|
||||
if(B.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two bronze sheets to build a bronze wall!</span>")
|
||||
return 0
|
||||
|
||||
@@ -86,6 +86,10 @@
|
||||
|
||||
/obj/structure/grille/attack_animal(mob/user)
|
||||
. = ..()
|
||||
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
user.DelayNextAction(flush = TRUE)
|
||||
user.do_attack_animation(src)
|
||||
if(!shock(user, 70) && !QDELETED(src)) //Last hit still shocks but shouldn't deal damage to the grille)
|
||||
take_damage(rand(5,10), BRUTE, "melee", 1)
|
||||
|
||||
@@ -114,12 +118,12 @@
|
||||
/obj/structure/grille/attack_alien(mob/living/user)
|
||||
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
user.DelayNextAction(flush = TRUE)
|
||||
user.do_attack_animation(src)
|
||||
user.visible_message("<span class='warning'>[user] mangles [src].</span>", null, null, COMBAT_MESSAGE_RANGE)
|
||||
if(!shock(user, 70))
|
||||
take_damage(20, BRUTE, "melee", 1)
|
||||
|
||||
|
||||
/obj/structure/grille/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover) && (mover.pass_flags & PASSGRILLE))
|
||||
return TRUE
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
var/erupting_state = null //set to null to get it greyscaled from "[icon_state]_soup". Not very usable with the whole random thing, but more types can be added if you change the spawn prob
|
||||
var/activated = FALSE //whether we are active and generating chems
|
||||
var/reagent_id = /datum/reagent/fuel/oil
|
||||
var/reagent_id = /datum/reagent/oil
|
||||
var/potency = 2 //how much reagents we add every process (2 seconds)
|
||||
var/max_volume = 500
|
||||
var/start_volume = 50
|
||||
@@ -77,10 +77,10 @@
|
||||
|
||||
/obj/item/plunger/reinforced
|
||||
name = "reinforced plunger"
|
||||
desc = "It's an M. 7 Reinforced Plunger© for heavy duty plunging."
|
||||
desc = "It's an M. 7 Reinforced Plunger� for heavy duty plunging."
|
||||
icon_state = "reinforced_plunger"
|
||||
|
||||
reinforced = TRUE
|
||||
plunge_mod = 0.8
|
||||
|
||||
custom_premium_price = 1200
|
||||
custom_premium_price = 600
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define STAIR_TERMINATOR_YES 2
|
||||
|
||||
// dir determines the direction of travel to go upwards (due to lack of sprites, currently only 1 and 2 make sense)
|
||||
// stairs require /turf/open/openspace as the tile above them to work
|
||||
// stairs require /turf/open/transparent/openspace as the tile above them to work
|
||||
// multiple stair objects can be chained together; the Z level transition will happen on the final stair object in the chain
|
||||
|
||||
/obj/structure/stairs
|
||||
@@ -12,7 +12,7 @@
|
||||
icon_state = "stairs"
|
||||
anchored = TRUE
|
||||
|
||||
var/force_open_above = FALSE // replaces the turf above this stair obj with /turf/open/openspace
|
||||
var/force_open_above = FALSE // replaces the turf above this stair obj with /turf/open/transparent/openspace
|
||||
var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC
|
||||
var/turf/listeningTo
|
||||
|
||||
@@ -95,20 +95,20 @@
|
||||
/obj/structure/stairs/proc/build_signal_listener()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_TURF_MULTIZ_NEW)
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
RegisterSignal(T, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_new)
|
||||
listeningTo = T
|
||||
|
||||
/obj/structure/stairs/proc/force_open_above()
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
if(T && !istype(T))
|
||||
T.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
T.ChangeTurf(/turf/open/transparent/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
/obj/structure/stairs/proc/on_multiz_new(turf/source, dir)
|
||||
if(dir == UP)
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
if(T && !istype(T))
|
||||
T.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
T.ChangeTurf(/turf/open/transparent/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
/obj/structure/stairs/intercept_zImpact(atom/movable/AM, levels = 1)
|
||||
. = ..()
|
||||
|
||||
@@ -597,7 +597,7 @@
|
||||
icon = 'icons/obj/smooth_structures/brass_table.dmi'
|
||||
icon_state = "brass_table"
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
buildstack = /obj/item/stack/tile/bronze
|
||||
buildstack = /obj/item/stack/sheet/bronze
|
||||
canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze)
|
||||
|
||||
/obj/structure/table/bronze/tablelimbsmash(mob/living/user, mob/living/pushed_mob)
|
||||
|
||||
@@ -875,3 +875,26 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
return
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/window/bronze
|
||||
name = "brass window"
|
||||
desc = "A paper-thin pane of translucent yet reinforced brass. Nevermind, this is just weak bronze!"
|
||||
icon = 'icons/obj/smooth_structures/clockwork_window.dmi'
|
||||
icon_state = "clockwork_window_single"
|
||||
glass_type = /obj/item/stack/tile/bronze
|
||||
|
||||
/obj/structure/window/bronze/unanchored
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/window/bronze/fulltile
|
||||
icon_state = "clockwork_window"
|
||||
canSmoothWith = null
|
||||
smooth = SMOOTH_TRUE
|
||||
fulltile = TRUE
|
||||
flags_1 = PREVENT_CLICK_UNDER_1
|
||||
dir = FULLTILE_WINDOW_DIR
|
||||
max_integrity = 50
|
||||
glass_amount = 2
|
||||
|
||||
/obj/structure/window/bronze/fulltile/unanchored
|
||||
anchored = FALSE
|
||||
|
||||
@@ -226,5 +226,9 @@
|
||||
soundin = pick('sound/effects/clangsmall1.ogg', 'sound/effects/clangsmall2.ogg')
|
||||
if("slosh")
|
||||
soundin = pick('sound/effects/slosh1.ogg', 'sound/effects/slosh2.ogg')
|
||||
if("smcalm")
|
||||
soundin = pick('sound/machines/sm/accent/normal/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg')
|
||||
if("smdelam")
|
||||
soundin = pick('sound/machines/sm/accent/delam/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg')
|
||||
//END OF CIT CHANGES
|
||||
return soundin
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
explosion_block = 50
|
||||
|
||||
/turf/closed/indestructible/rust_heretic_act()
|
||||
return
|
||||
|
||||
/turf/closed/indestructible/TerraformTurf(path, new_baseturf, flags, defer_change = FALSE, ignore_air = FALSE)
|
||||
return
|
||||
|
||||
@@ -198,13 +201,13 @@
|
||||
|
||||
/turf/closed/indestructible/rock/glacierrock
|
||||
name = "unaturally hard ice wall"
|
||||
desc = "Ice, hardened over thousands of years, you're not breaking through this."
|
||||
desc = "Ice, hardened over thousands of years, you're not breaking through this."
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
icon_state = "snow_rock"
|
||||
|
||||
/turf/closed/indestructible/rock/glacierrock/blue
|
||||
name = "blue ice wall"
|
||||
desc = "The incredible compressive forces that formed this sturdy ice wall gave it a blue color."
|
||||
desc = "The incredible compressive forces that formed this sturdy ice wall gave it a blue color."
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
icon_state = "ice"
|
||||
canSmoothWith = list(/turf/closed/indestructible/rock/glacierrock/blue)
|
||||
|
||||
@@ -11,66 +11,47 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
layer = SPLASHSCREEN_LAYER
|
||||
|
||||
/turf/open/openspace
|
||||
/turf/open/transparent/openspace
|
||||
name = "open space"
|
||||
desc = "Watch your step!"
|
||||
icon_state = "transparent"
|
||||
baseturfs = /turf/open/openspace
|
||||
baseturfs = /turf/open/transparent/openspace
|
||||
CanAtmosPassVertical = ATMOS_PASS_YES
|
||||
//mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/can_cover_up = TRUE
|
||||
var/can_build_on = TRUE
|
||||
|
||||
/turf/open/openspace/debug/update_multiz()
|
||||
/turf/open/transparent/openspace/airless
|
||||
initial_gas_mix = AIRLESS_ATMOS
|
||||
|
||||
/turf/open/transparent/openspace/debug/update_multiz()
|
||||
..()
|
||||
return TRUE
|
||||
|
||||
/turf/open/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
///No bottom level for openspace.
|
||||
/turf/open/transparent/openspace/show_bottom_level()
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
plane = OPENSPACE_PLANE
|
||||
layer = OPENSPACE_LAYER
|
||||
|
||||
vis_contents += GLOB.openspace_backdrop_one_for_all //Special grey square for projecting backdrop darkness filter on it.
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/openspace/LateInitialize()
|
||||
update_multiz(TRUE, TRUE)
|
||||
/turf/open/transparent/openspace/can_have_cabling()
|
||||
if(locate(/obj/structure/lattice/catwalk, src))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/openspace/Destroy()
|
||||
vis_contents.len = 0
|
||||
return ..()
|
||||
|
||||
/turf/open/openspace/update_multiz(prune_on_fail = FALSE, init = FALSE)
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
if(!T)
|
||||
vis_contents.len = 0
|
||||
if(prune_on_fail)
|
||||
ChangeTurf(/turf/open/floor/plating)
|
||||
return FALSE
|
||||
if(init)
|
||||
vis_contents += T
|
||||
/turf/open/transparent/openspace/zAirIn()
|
||||
return TRUE
|
||||
|
||||
/turf/open/openspace/multiz_turf_del(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
/turf/open/openspace/multiz_turf_new(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
/turf/open/openspace/zAirIn()
|
||||
/turf/open/transparent/openspace/zAirOut()
|
||||
return TRUE
|
||||
|
||||
/turf/open/openspace/zAirOut()
|
||||
/turf/open/transparent/openspace/zPassIn(atom/movable/A, direction, turf/source)
|
||||
return TRUE
|
||||
|
||||
/turf/open/openspace/zPassIn(atom/movable/A, direction, turf/source)
|
||||
return TRUE
|
||||
|
||||
/turf/open/openspace/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
/turf/open/transparent/openspace/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
if(A.anchored)
|
||||
return FALSE
|
||||
for(var/obj/O in contents)
|
||||
@@ -78,13 +59,13 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/turf/open/openspace/proc/CanCoverUp()
|
||||
/turf/open/transparent/openspace/proc/CanCoverUp()
|
||||
return can_cover_up
|
||||
|
||||
/turf/open/openspace/proc/CanBuildHere()
|
||||
/turf/open/transparent/openspace/proc/CanBuildHere()
|
||||
return can_build_on
|
||||
|
||||
/turf/open/openspace/attackby(obj/item/C, mob/user, params)
|
||||
/turf/open/transparent/openspace/attackby(obj/item/C, mob/user, params)
|
||||
..()
|
||||
if(!CanBuildHere())
|
||||
return
|
||||
@@ -98,14 +79,14 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
if(L)
|
||||
if(R.use(1))
|
||||
to_chat(user, "<span class='notice'>You construct a catwalk.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
new/obj/structure/lattice/catwalk(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need two rods to build a catwalk!</span>")
|
||||
return
|
||||
if(R.use(1))
|
||||
to_chat(user, "<span class='notice'>You construct a lattice.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
ReplaceWithLattice()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one rod to build a lattice.</span>")
|
||||
@@ -118,7 +99,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
var/obj/item/stack/tile/plasteel/S = C
|
||||
if(S.use(1))
|
||||
qdel(L)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
to_chat(user, "<span class='notice'>You build a floor.</span>")
|
||||
PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
@@ -126,7 +107,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
|
||||
|
||||
/turf/open/openspace/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
/turf/open/transparent/openspace/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
if(!CanBuildHere())
|
||||
return FALSE
|
||||
|
||||
@@ -139,7 +120,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3)
|
||||
return FALSE
|
||||
|
||||
/turf/open/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
/turf/open/transparent/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_FLOORWALL)
|
||||
to_chat(user, "<span class='notice'>You build a floor.</span>")
|
||||
@@ -147,12 +128,12 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/openspace/icemoon
|
||||
/turf/open/transparent/openspace/icemoon
|
||||
name = "ice chasm"
|
||||
baseturfs = /turf/open/openspace/icemoon
|
||||
can_cover_up = FALSE
|
||||
can_build_on = FALSE
|
||||
baseturfs = /turf/open/transparent/openspace/icemoon
|
||||
can_cover_up = TRUE
|
||||
can_build_on = TRUE
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/openspace/icemoon/can_zFall(atom/movable/A, levels = 1, turf/target)
|
||||
/turf/open/transparent/openspace/icemoon/can_zFall(atom/movable/A, levels = 1, turf/target)
|
||||
return TRUE
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/turf/open/transparent
|
||||
baseturfs = /turf/open/transparent/openspace
|
||||
intact = FALSE //this means wires go on top
|
||||
|
||||
/turf/open/transparent/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
plane = OPENSPACE_PLANE
|
||||
layer = OPENSPACE_LAYER
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/transparent/LateInitialize()
|
||||
update_multiz(TRUE, TRUE)
|
||||
|
||||
/turf/open/transparent/Destroy()
|
||||
vis_contents.len = 0
|
||||
return ..()
|
||||
|
||||
/turf/open/transparent/update_multiz(prune_on_fail = FALSE, init = FALSE)
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
if(!T)
|
||||
vis_contents.len = 0
|
||||
if(!show_bottom_level() && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
|
||||
ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
return FALSE
|
||||
if(init)
|
||||
vis_contents += T
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/multiz_turf_del(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
/turf/open/transparent/multiz_turf_new(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
///Called when there is no real turf below this turf
|
||||
/turf/open/transparent/proc/show_bottom_level()
|
||||
var/turf/path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
|
||||
if(!ispath(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
|
||||
path = /turf/open/space
|
||||
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER, plane = PLANE_SPACE)
|
||||
underlays += underlay_appearance
|
||||
return TRUE
|
||||
|
||||
|
||||
/turf/open/transparent/glass
|
||||
name = "Glass floor"
|
||||
desc = "Dont jump on it, or do, I'm not your mom."
|
||||
icon = 'icons/turf/floors/glass.dmi'
|
||||
icon_state = "floor_glass"
|
||||
smooth = SMOOTH_MORE
|
||||
var/floor_tile = /obj/item/stack/sheet/glass
|
||||
canSmoothWith = list(/turf/open/transparent/glass, /turf/open/transparent/glass/reinforced)
|
||||
footstep = FOOTSTEP_PLATING
|
||||
barefootstep = FOOTSTEP_HARD_BAREFOOT
|
||||
clawfootstep = FOOTSTEP_HARD_CLAW
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
|
||||
/turf/open/transparent/glass/Initialize()
|
||||
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
|
||||
return ..()
|
||||
|
||||
/turf/open/transparent/glass/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing glass...</span>")
|
||||
if(I.use_tool(src, user, 30, volume=80))
|
||||
if(!istype(src, /turf/open/transparent/glass))
|
||||
return TRUE
|
||||
if(floor_tile)
|
||||
new floor_tile(src, 2)
|
||||
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/glass/reinforced
|
||||
name = "Reinforced glass floor"
|
||||
desc = "Do jump on it, it can take it."
|
||||
icon = 'icons/turf/floors/reinf_glass.dmi'
|
||||
floor_tile = /obj/item/stack/sheet/rglass
|
||||
|
||||
/turf/open/transparent/glass/reinforced/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing reinforced glass...</span>")
|
||||
if(I.use_tool(src, user, 30, volume=80))
|
||||
if(!istype(src, /turf/open/transparent/glass/reinforced))
|
||||
return TRUE
|
||||
if(floor_tile)
|
||||
new floor_tile(src, 2)
|
||||
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
@@ -63,6 +63,11 @@
|
||||
to_chat(user, "<span class='notice'>You forcefully pry off the planks, destroying them in the process.</span>")
|
||||
return make_plating()
|
||||
|
||||
/turf/open/floor/wood/rust_heretic_act()
|
||||
if(prob(70))
|
||||
new /obj/effect/temp_visual/glowing_rune(src)
|
||||
ChangeTurf(/turf/open/floor/plating/rust)
|
||||
|
||||
/turf/open/floor/wood/cold
|
||||
temperature = 255.37
|
||||
|
||||
|
||||
@@ -58,6 +58,12 @@
|
||||
if(exposed_temperature > 300)
|
||||
PlasmaBurn(exposed_temperature)
|
||||
|
||||
// Plasma floor that can't be removed, for disco
|
||||
|
||||
/turf/open/floor/mineral/plasma/disco
|
||||
name = "disco floor"
|
||||
/turf/open/floor/mineral/plasma/disco/crowbar_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
//GOLD
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
desc = "Some heavy bronze tiles."
|
||||
icon = 'icons/obj/clockwork_objects.dmi'
|
||||
icon_state = "clockwork_floor"
|
||||
floor_tile = /obj/item/stack/tile/bronze
|
||||
floor_tile = /obj/item/stack/sheet/bronze
|
||||
|
||||
/turf/open/floor/padded
|
||||
name = "padded floor"
|
||||
@@ -267,3 +267,15 @@
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "floor_padded"
|
||||
floor_tile = /obj/item/stack/tile/padded
|
||||
|
||||
/turf/open/floor/plating/rust
|
||||
name = "rusted plating"
|
||||
desc = "Corrupted steel."
|
||||
icon_state = "plating_rust"
|
||||
footstep = FOOTSTEP_RUST
|
||||
barefootstep = FOOTSTEP_RUST
|
||||
clawfootstep = FOOTSTEP_RUST
|
||||
heavyfootstep = FOOTSTEP_RUST
|
||||
|
||||
/turf/open/floor/plating/rust/rust_heretic_act()
|
||||
return
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
. = ..()
|
||||
. += "<span class='notice'>There's a <b>small crack</b> on the edge of it.</span>"
|
||||
|
||||
/turf/open/floor/plasteel/rust_heretic_act()
|
||||
if(prob(70))
|
||||
new /obj/effect/temp_visual/glowing_rune(src)
|
||||
ChangeTurf(/turf/open/floor/plating/rust)
|
||||
|
||||
/turf/open/floor/plasteel/update_icon()
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
@@ -66,6 +66,40 @@
|
||||
R.use(2)
|
||||
to_chat(user, "<span class='notice'>You reinforce the floor.</span>")
|
||||
return
|
||||
if(istype(C, /obj/item/stack/sheet/glass))
|
||||
if(broken || burnt)
|
||||
to_chat(user, "<span class='warning'>Repair the plating first!</span>")
|
||||
return
|
||||
var/obj/item/stack/sheet/glass/G = C
|
||||
if (G.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need two glass sheets to make a glass floor!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin adding glass to the floor...</span>")
|
||||
if(do_after(user, 5, target = src))
|
||||
if (G.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass))
|
||||
PlaceOnTop(/turf/open/transparent/glass, flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
|
||||
G.use(2)
|
||||
to_chat(user, "<span class='notice'>You add glass to the floor.</span>")
|
||||
return
|
||||
if(istype(C, /obj/item/stack/sheet/rglass))
|
||||
if(broken || burnt)
|
||||
to_chat(user, "<span class='warning'>Repair the plating first!</span>")
|
||||
return
|
||||
var/obj/item/stack/sheet/rglass/RG = C
|
||||
if (RG.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need two reinforced glass sheets to make a reinforced glass floor!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin adding reinforced glass to the floor...</span>")
|
||||
if(do_after(user, 10, target = src))
|
||||
if (RG.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass/reinforced))
|
||||
PlaceOnTop(/turf/open/transparent/glass/reinforced, flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
|
||||
RG.use(2)
|
||||
to_chat(user, "<span class='notice'>You add reinforced glass to the floor.</span>")
|
||||
return
|
||||
else if(istype(C, /obj/item/stack/tile))
|
||||
if(!broken && !burnt)
|
||||
for(var/obj/O in src)
|
||||
@@ -98,6 +132,11 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/plating/rust_heretic_act()
|
||||
if(prob(70))
|
||||
new /obj/effect/temp_visual/glowing_rune(src)
|
||||
ChangeTurf(/turf/open/floor/plating/rust)
|
||||
|
||||
/turf/open/floor/plating/make_plating()
|
||||
return
|
||||
|
||||
|
||||
@@ -149,6 +149,8 @@
|
||||
var/list/megafauna_spawn_list
|
||||
/// Flora that can spawn in the tunnel, weighted list
|
||||
var/list/flora_spawn_list
|
||||
//terrain to spawn weighted list
|
||||
var/list/terrain_spawn_list
|
||||
/// Turf type to choose when spawning in tunnel at 1% chance, weighted list
|
||||
var/list/choose_turf_type
|
||||
/// if the tunnel should keep being created
|
||||
@@ -230,7 +232,8 @@
|
||||
megafauna_spawn_list = list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = SPAWN_BUBBLEGUM)
|
||||
if (!flora_spawn_list)
|
||||
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
|
||||
|
||||
if(!terrain_spawn_list)
|
||||
terrain_spawn_list = list(/obj/structure/geyser/random = 1)
|
||||
. = ..()
|
||||
if(!has_data)
|
||||
produce_tunnel_from_data()
|
||||
@@ -334,8 +337,19 @@
|
||||
spawned_flora = SpawnFlora(T)
|
||||
if(!spawned_flora) // no rocks beneath mob spawners / mobs.
|
||||
SpawnMonster(T)
|
||||
SpawnTerrain(T)
|
||||
T.ChangeTurf(turf_type, null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnTerrain(turf/T)
|
||||
if(prob(1))
|
||||
if(istype(loc, /area/mine/explored) || istype(loc, /area/lavaland/surface/outdoors/explored))
|
||||
return
|
||||
var/randumb = pickweight(terrain_spawn_list)
|
||||
for(var/obj/structure/geyser/F in range(7, T))
|
||||
if(istype(F, randumb))
|
||||
return
|
||||
new randumb(T)
|
||||
|
||||
/// Spawns a random mob or megafauna in the tunnel
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnMonster(turf/T)
|
||||
if(!isarea(loc))
|
||||
|
||||
@@ -188,17 +188,25 @@
|
||||
icon = 'icons/turf/walls/rusty_wall.dmi'
|
||||
hardness = 45
|
||||
|
||||
/turf/closed/wall/rust/rust_heretic_act()
|
||||
ScrapeAway()
|
||||
|
||||
/turf/closed/wall/r_wall/rust
|
||||
name = "rusted reinforced wall"
|
||||
desc = "A huge chunk of rusted reinforced metal."
|
||||
icon = 'icons/turf/walls/rusty_reinforced_wall.dmi'
|
||||
hardness = 15
|
||||
|
||||
/turf/closed/wall/r_wall/rust/rust_heretic_act()
|
||||
if(prob(50))
|
||||
return
|
||||
ScrapeAway()
|
||||
|
||||
/turf/closed/wall/mineral/bronze
|
||||
name = "clockwork wall"
|
||||
desc = "A huge chunk of bronze, decorated like gears and cogs."
|
||||
icon = 'icons/turf/walls/clockwork_wall.dmi'
|
||||
icon_state = "clockwork_wall"
|
||||
sheet_type = /obj/item/stack/tile/bronze
|
||||
sheet_type = /obj/item/stack/sheet/bronze
|
||||
sheet_amount = 2
|
||||
girder_type = /obj/structure/girder/bronze
|
||||
|
||||
@@ -235,6 +235,13 @@
|
||||
if(the_rcd.canRturf)
|
||||
return ..()
|
||||
|
||||
/turf/closed/wall/r_wall/rust_heretic_act()
|
||||
if(prob(50))
|
||||
return
|
||||
if(prob(70))
|
||||
new /obj/effect/temp_visual/glowing_rune(src)
|
||||
ChangeTurf(/turf/closed/wall/r_wall/rust)
|
||||
|
||||
/turf/closed/wall/r_wall/syndicate
|
||||
name = "hull"
|
||||
desc = "The armored hull of an ominous looking ship."
|
||||
|
||||
@@ -325,4 +325,9 @@
|
||||
|
||||
add_overlay(dent_decals)
|
||||
|
||||
/turf/closed/wall/rust_heretic_act()
|
||||
if(prob(70))
|
||||
new /obj/effect/temp_visual/glowing_rune(src)
|
||||
ChangeTurf(/turf/closed/wall/rust)
|
||||
|
||||
#undef MAX_DENT_DECALS
|
||||
|
||||
@@ -12,6 +12,9 @@ GLOBAL_LIST(topic_status_cache)
|
||||
if (fexists(EXTOOLS))
|
||||
call(EXTOOLS, "maptick_initialize")()
|
||||
enable_debugger()
|
||||
#ifdef REFERENCE_TRACKING
|
||||
enable_reference_tracking()
|
||||
#endif
|
||||
|
||||
world.Profile(PROFILE_START)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user