Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into explosionport
This commit is contained in:
+2
-2
@@ -47,7 +47,7 @@
|
||||
/atom/New(loc, ...)
|
||||
//atom creation method that preloads variables at creation
|
||||
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
GLOB._preloader.load(src)
|
||||
world.preloader_load(src)
|
||||
|
||||
if(datum_flags & DF_USE_TAG)
|
||||
GenerateTag()
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
|
||||
if(does_attack_animation)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
@@ -515,10 +515,10 @@
|
||||
step(src, AM.dir)
|
||||
..()
|
||||
|
||||
/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback)
|
||||
return throw_at(target, range, speed, thrower, spin, diagonals_first, callback)
|
||||
/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE)
|
||||
return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, messy_throw)
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback) //If this returns FALSE then callback will not be called.
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) //If this returns FALSE then callback will not be called.
|
||||
. = FALSE
|
||||
if (!target || speed <= 0)
|
||||
return
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \
|
||||
/datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee)
|
||||
// The antags you're allowed to be if turning Vassal.
|
||||
/proc/isvamp(mob/living/M)
|
||||
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/bloodsucker)
|
||||
|
||||
/datum/game_mode/bloodsucker
|
||||
name = "bloodsucker"
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
H.dna.add_mutation(CLOWNMUT)
|
||||
H.dna.add_mutation(SMILE)
|
||||
|
||||
/datum/outfit/syndicate/clownop/leader
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
spray_range = 1
|
||||
stream_range = 1
|
||||
volume = 30
|
||||
list_reagents = list("lube" = 30)
|
||||
list_reagents = list(/datum/reagent/lube = 30)
|
||||
|
||||
//COMBAT CLOWN SHOES
|
||||
//Clown shoes with combat stats and noslip. Of course they still squeak.
|
||||
@@ -165,7 +165,7 @@
|
||||
customfoodfilling = FALSE
|
||||
seed = null
|
||||
tastes = list("explosives" = 10)
|
||||
list_reagents = list("vitamin" = 1)
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 1)
|
||||
|
||||
/obj/item/grown/bananapeel/bombanana
|
||||
desc = "A peel from a banana. Why is it beeping?"
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
#define CURRENT_LIVING_PLAYERS 1
|
||||
#define CURRENT_LIVING_ANTAGS 2
|
||||
#define CURRENT_DEAD_PLAYERS 3
|
||||
#define CURRENT_OBSERVERS 4
|
||||
|
||||
#define ONLY_RULESET 1
|
||||
#define HIGHLANDER_RULESET 2
|
||||
#define TRAITOR_RULESET 4
|
||||
#define MINOR_RULESET 8
|
||||
|
||||
#define RULESET_STOP_PROCESSING 1
|
||||
|
||||
// -- Injection delays
|
||||
GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (10 MINUTES))
|
||||
@@ -52,6 +41,8 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset)
|
||||
// Forced threat level, setting this to zero or higher forces the roundstart threat to the value.
|
||||
GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
|
||||
GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
|
||||
|
||||
/datum/game_mode/dynamic
|
||||
name = "dynamic mode"
|
||||
config_tag = "dynamic"
|
||||
@@ -60,7 +51,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
announce_text = "Dynamic mode!" // This needs to be changed maybe
|
||||
|
||||
reroll_friendly = FALSE;
|
||||
|
||||
// Current storyteller
|
||||
var/datum/dynamic_storyteller/storyteller = null
|
||||
// Threat logging vars
|
||||
/// The "threat cap", threat shouldn't normally go above this and is used in ruleset calculations
|
||||
var/threat_level = 0
|
||||
@@ -164,6 +156,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
|
||||
dat += "Threat to Spend: <b>[threat]</b> <a href='?src=\ref[src];[HrefToken()];adjustthreat=1'>\[Adjust\]</A> <a href='?src=\ref[src];[HrefToken()];threatlog=1'>\[View Log\]</a><br/>"
|
||||
dat += "<br/>"
|
||||
dat += "Storyteller: <b>[storyteller.name]</b><br/>"
|
||||
dat += "Parameters: centre = [GLOB.dynamic_curve_centre] ; width = [GLOB.dynamic_curve_width].<br/>"
|
||||
dat += "<i>On average, <b>[peaceful_percentage]</b>% of the rounds are more peaceful.</i><br/>"
|
||||
dat += "Forced extended: <a href='?src=\ref[src];[HrefToken()];forced_extended=1'><b>[GLOB.dynamic_forced_extended ? "On" : "Off"]</b></a><br/>"
|
||||
@@ -178,7 +171,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
dat += "[DR.ruletype] - <b>[DR.name]</b><br>"
|
||||
else
|
||||
dat += "none.<br>"
|
||||
dat += "<br>Injection Timers: (<b>[get_injection_chance(TRUE)]%</b> chance)<BR>"
|
||||
dat += "<br>Injection Timers: (<b>[storyteller.get_injection_chance(TRUE)]%</b> chance)<BR>"
|
||||
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
|
||||
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
|
||||
dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
|
||||
@@ -336,6 +329,9 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",peaceful_percentage,"Percent of same-vote rounds that are more peaceful")
|
||||
|
||||
/datum/game_mode/dynamic/can_start()
|
||||
storyteller = new GLOB.dynamic_storyteller_type // this is where all the initialization happens
|
||||
storyteller.on_start()
|
||||
SSblackbox.record_feedback("text","dynamic_storyteller",1,storyteller.name)
|
||||
message_admins("Dynamic mode parameters for the round:")
|
||||
message_admins("Centre is [GLOB.dynamic_curve_centre], Width is [GLOB.dynamic_curve_width], Forced extended is [GLOB.dynamic_forced_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].")
|
||||
message_admins("Stacking limit is [GLOB.dynamic_stacking_limit], Classic secret is [GLOB.dynamic_classic_secret ? "Enabled" : "Disabled"], High population limit is [GLOB.dynamic_high_pop_limit].")
|
||||
@@ -345,19 +341,12 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
if(GLOB.dynamic_forced_threat_level >= 0)
|
||||
threat_level = round(GLOB.dynamic_forced_threat_level, 0.1)
|
||||
threat = threat_level
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Threat level (forced by admins)")
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Threat level (forced)")
|
||||
else
|
||||
generate_threat()
|
||||
|
||||
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_latejoin_delay_max + GLOB.dynamic_first_latejoin_delay_min)
|
||||
latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_first_latejoin_delay_min, GLOB.dynamic_first_latejoin_delay_max)) + world.time
|
||||
storyteller.start_injection_cooldowns()
|
||||
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max)
|
||||
midround_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time
|
||||
|
||||
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
|
||||
event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time)
|
||||
|
||||
log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!")
|
||||
initial_threat_level = threat_level
|
||||
return TRUE
|
||||
@@ -391,7 +380,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
log_game("DYNAMIC: [roundstart_rules.len] rules.")
|
||||
return TRUE
|
||||
SSblackbox.record_feedback("tally","dynamic",roundstart_rules.len,"Roundstart rules considered")
|
||||
SSblackbox.record_feedback("tally","dynamic",roundstart_rules.len,"Players readied up")
|
||||
SSblackbox.record_feedback("tally","dynamic",roundstart_pop_ready,"Players readied up")
|
||||
if(GLOB.dynamic_forced_roundstart_ruleset.len > 0)
|
||||
rigged_roundstart()
|
||||
else
|
||||
@@ -429,13 +418,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
if (GLOB.dynamic_forced_extended)
|
||||
log_game("DYNAMIC: Starting a round of forced extended.")
|
||||
return TRUE
|
||||
var/list/drafted_rules = list()
|
||||
for (var/datum/dynamic_ruleset/roundstart/rule in roundstart_rules)
|
||||
if (rule.acceptable(roundstart_pop_ready, threat_level) && threat >= rule.cost) // If we got the population and threat required
|
||||
rule.candidates = candidates.Copy()
|
||||
rule.trim_candidates()
|
||||
if (rule.ready() && rule.candidates.len > 0)
|
||||
drafted_rules[rule] = rule.weight
|
||||
var/list/drafted_rules = storyteller.roundstart_draft()
|
||||
if(!drafted_rules.len)
|
||||
message_admins("Not enough threat level for roundstart antags!")
|
||||
log_game("DYNAMIC: Not enough threat level for roundstart antags!")
|
||||
@@ -653,7 +636,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
if (rule.persistent)
|
||||
current_rules += rule
|
||||
return TRUE
|
||||
rule.clean_up()
|
||||
stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.")
|
||||
return FALSE
|
||||
|
||||
@@ -667,62 +649,41 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
current_rules -= rule
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Rulesets finished")
|
||||
SSblackbox.record_feedback("associative","dynamic_rulesets_finished",1,rule.get_blackbox_info())
|
||||
|
||||
|
||||
storyteller.do_process()
|
||||
|
||||
if (midround_injection_cooldown < world.time)
|
||||
if (GLOB.dynamic_forced_extended)
|
||||
return
|
||||
|
||||
// Somehow it managed to trigger midround multiple times so this was moved here.
|
||||
// There is no way this should be able to trigger an injection twice now.
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min)
|
||||
midround_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max)) + world.time)
|
||||
midround_injection_cooldown = storyteller.get_midround_cooldown() + world.time
|
||||
|
||||
// Time to inject some threat into the round
|
||||
if(EMERGENCY_ESCAPED_OR_ENDGAMED) // Unless the shuttle is gone
|
||||
return
|
||||
if((world.realtime - SSshuttle.realtimeofstart) > SSshuttle.auto_call) // no rules after shuttle is auto-called
|
||||
return
|
||||
message_admins("DYNAMIC: Checking for midround injection.")
|
||||
log_game("DYNAMIC: Checking for midround injection.")
|
||||
|
||||
update_playercounts()
|
||||
if (get_injection_chance())
|
||||
if (prob(storyteller.get_injection_chance()))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Attempted midround injections")
|
||||
var/cur_threat_frac = threat/threat_level
|
||||
var/list/drafted_rules = list()
|
||||
var/antag_num = current_players[CURRENT_LIVING_ANTAGS].len
|
||||
for (var/datum/dynamic_ruleset/midround/rule in midround_rules)
|
||||
// if there are antags OR the rule is an antag rule, antag_acceptable will be true.
|
||||
if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost)
|
||||
// Classic secret : only autotraitor/minor roles
|
||||
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
|
||||
continue
|
||||
rule.trim_candidates()
|
||||
if (rule.ready())
|
||||
if(!antag_num)
|
||||
drafted_rules[rule] = round(rule.get_weight() + (rule.cost * cur_threat_frac))
|
||||
else
|
||||
drafted_rules[rule] = rule.get_weight()
|
||||
else if(threat < rule.cost)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat to spend")
|
||||
var/list/drafted_rules = storyteller.midround_draft()
|
||||
if (drafted_rules.len > 0)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
|
||||
picking_midround_latejoin_rule(drafted_rules)
|
||||
else
|
||||
midround_injection_cooldown = (midround_injection_cooldown + world.time)/2
|
||||
// get_injection_chance can do things on fail
|
||||
|
||||
if(event_injection_cooldown < world.time)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Attempted event injections")
|
||||
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
|
||||
event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time)
|
||||
event_injection_cooldown = storyteller.get_event_cooldown() + world.time
|
||||
message_admins("DYNAMIC: Doing event injection.")
|
||||
log_game("DYNAMIC: Doing event injection.")
|
||||
update_playercounts()
|
||||
var/list/drafted_rules = list()
|
||||
for(var/datum/dynamic_ruleset/event/rule in events)
|
||||
if(rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost)
|
||||
if(rule.ready())
|
||||
drafted_rules[rule] = rule.get_weight()
|
||||
else if(threat < rule.cost)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat to spend")
|
||||
var/list/drafted_rules = storyteller.event_draft()
|
||||
if(drafted_rules.len > 0)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Successful event injections")
|
||||
picking_midround_latejoin_rule(drafted_rules)
|
||||
@@ -741,38 +702,13 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
if (M.mind && (M.mind.special_role || M.mind.antag_datums?.len > 0))
|
||||
current_players[CURRENT_LIVING_ANTAGS].Add(M)
|
||||
else
|
||||
if (istype(M,/mob/dead/observer))
|
||||
if (isobserver(M))
|
||||
var/mob/dead/observer/O = M
|
||||
if (O.started_as_observer) // Observers
|
||||
current_players[CURRENT_OBSERVERS].Add(M)
|
||||
continue
|
||||
current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
|
||||
|
||||
/// Gets the chance for latejoin and midround injection, the dry_run argument is only used for forced injection.
|
||||
/datum/game_mode/dynamic/proc/get_injection_chance(dry_run = FALSE)
|
||||
if(forced_injection)
|
||||
forced_injection = !dry_run
|
||||
return 100
|
||||
var/chance = 0
|
||||
// If the high pop override is in effect, we reduce the impact of population on the antag injection chance
|
||||
var/high_pop_factor = (current_players[CURRENT_LIVING_PLAYERS].len >= GLOB.dynamic_high_pop_limit)
|
||||
var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(current_players[CURRENT_LIVING_PLAYERS].len/(high_pop_factor ? 10 : 5)))
|
||||
if (!current_players[CURRENT_LIVING_ANTAGS].len)
|
||||
chance += 80 // No antags at all? let's boost those odds!
|
||||
else
|
||||
var/current_pop_per_antag = current_players[CURRENT_LIVING_PLAYERS].len / current_players[CURRENT_LIVING_ANTAGS].len
|
||||
if (current_pop_per_antag > max_pop_per_antag)
|
||||
chance += min(50, 25+10*(current_pop_per_antag-max_pop_per_antag))
|
||||
else
|
||||
chance += 25-10*(max_pop_per_antag-current_pop_per_antag)
|
||||
if (current_players[CURRENT_DEAD_PLAYERS].len > current_players[CURRENT_LIVING_PLAYERS].len)
|
||||
chance -= 30 // More than half the crew died? ew, let's calm down on antags
|
||||
if (threat > 70)
|
||||
chance += 15
|
||||
if (threat < 30)
|
||||
chance -= 15
|
||||
return round(max(0,chance))
|
||||
|
||||
/// Removes type from the list
|
||||
/datum/game_mode/dynamic/proc/remove_from_list(list/type_list, type)
|
||||
for(var/I in type_list)
|
||||
@@ -803,7 +739,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
return
|
||||
if(EMERGENCY_ESCAPED_OR_ENDGAMED) // No more rules after the shuttle has left
|
||||
return
|
||||
|
||||
if((world.realtime - SSshuttle.realtimeofstart) > SSshuttle.auto_call) // no rules after shuttle is auto-called
|
||||
return
|
||||
update_playercounts()
|
||||
|
||||
if (forced_latejoin_rule)
|
||||
@@ -814,28 +751,12 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
picking_midround_latejoin_rule(list(forced_latejoin_rule), forced = TRUE)
|
||||
forced_latejoin_rule = null
|
||||
|
||||
else if (latejoin_injection_cooldown < world.time && prob(get_injection_chance()))
|
||||
else if (latejoin_injection_cooldown < world.time && prob(storyteller.get_injection_chance()))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Attempted latejoin injections")
|
||||
var/list/drafted_rules = list()
|
||||
for (var/datum/dynamic_ruleset/latejoin/rule in latejoin_rules)
|
||||
if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost)
|
||||
// Classic secret : only autotraitor/minor roles
|
||||
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
|
||||
continue
|
||||
// No stacking : only one round-ender, unless threat level > stacking_limit.
|
||||
if (threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
|
||||
if(rule.flags & HIGHLANDER_RULESET && highlander_executed)
|
||||
continue
|
||||
|
||||
rule.candidates = list(newPlayer)
|
||||
rule.trim_candidates()
|
||||
if (rule.ready())
|
||||
drafted_rules[rule] = rule.get_weight()
|
||||
|
||||
var/list/drafted_rules = storyteller.latejoin_draft(newPlayer)
|
||||
if (drafted_rules.len > 0 && picking_midround_latejoin_rule(drafted_rules))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Successful latejoin injections")
|
||||
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_latejoin_delay_max + GLOB.dynamic_latejoin_delay_min)
|
||||
latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_latejoin_delay_min, GLOB.dynamic_latejoin_delay_max)) + world.time
|
||||
latejoin_injection_cooldown = storyteller.get_latejoin_cooldown() + world.time
|
||||
|
||||
/// Refund threat, but no more than threat_level.
|
||||
/datum/game_mode/dynamic/proc/refund_threat(regain)
|
||||
|
||||
@@ -80,9 +80,13 @@
|
||||
/// Delay for when execute will get called from the time of post_setup (roundstart) or process (midround/latejoin).
|
||||
/// Make sure your ruleset works with execute being called during the game when using this, and that the clean_up proc reverts it properly in case of faliure.
|
||||
var/delay = 0
|
||||
/// List of tags for use in storytellers.
|
||||
var/list/property_weights = list()
|
||||
/// Whether or not recent-round weight values are taken into account for this ruleset.
|
||||
/// Weight reduction uses the same values as secret's recent-round mode weight reduction.
|
||||
var/always_max_weight = FALSE
|
||||
/// Weight reduction by recent-rounds. Saved on new.
|
||||
var/weight_mult = 1
|
||||
|
||||
/datum/dynamic_ruleset/New()
|
||||
..()
|
||||
@@ -96,13 +100,11 @@
|
||||
var/high_population_requirements = CONFIG_GET(keyed_list/dynamic_high_population_requirement)
|
||||
var/list/repeated_mode_adjust = CONFIG_GET(number_list/repeated_mode_adjust)
|
||||
if(config_tag in weights)
|
||||
var/weight_mult = 1
|
||||
if(!always_max_weight && SSpersistence.saved_dynamic_rules.len == 3 && repeated_mode_adjust.len == 3)
|
||||
var/saved_dynamic_rules = SSpersistence.saved_dynamic_rules
|
||||
for(var/i in 1 to 3)
|
||||
if(config_tag in saved_dynamic_rules[i])
|
||||
weight_mult -= (repeated_mode_adjust[i]/100)
|
||||
weight = weights[config_tag] * weight_mult
|
||||
if(config_tag in costs)
|
||||
cost = costs[config_tag]
|
||||
if(config_tag in requirementses)
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
cost = 10
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear)
|
||||
requirements = list(70,60,50,50,40,40,40,30,20,15)
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "chaos" = 1)
|
||||
high_population_requirement = 15
|
||||
|
||||
/datum/dynamic_ruleset/event/pirates/ready(forced = FALSE)
|
||||
@@ -81,6 +82,7 @@
|
||||
cost = 10
|
||||
requirements = list(70,60,50,50,40,40,40,30,20,15)
|
||||
high_population_requirement = 15
|
||||
property_weights = list("chaos" = 1, "valid" = 1)
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
@@ -100,6 +102,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("chaos" = 1, "extended" = 2)
|
||||
|
||||
/datum/dynamic_ruleset/event/ventclog/ready()
|
||||
if(mode.threat_level > 30 && mode.threat >= 5 && prob(20))
|
||||
@@ -133,10 +136,11 @@
|
||||
required_enemies = list(1,1,0,0,0,0,0,0,0,0)
|
||||
weight = 4
|
||||
// no repeatable weight decrease. too variable to be unfun multiple times in one round
|
||||
cost = 3
|
||||
cost = 1
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = 1, "extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
@@ -156,6 +160,7 @@
|
||||
repeatable_weight_decrease = 2
|
||||
requirements = list(60,50,40,30,30,30,30,30,30,30)
|
||||
high_population_requirement = 30
|
||||
property_weights = list("extended" = -2)
|
||||
|
||||
/datum/dynamic_ruleset/event/meteor_wave/ready()
|
||||
if(mode.threat_level > 40 && mode.threat >= 25 && prob(20))
|
||||
@@ -190,6 +195,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_flux
|
||||
name = "Anomaly: Hyper-Energetic Flux"
|
||||
@@ -203,6 +209,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_gravitational
|
||||
name = "Anomaly: Gravitational"
|
||||
@@ -214,6 +221,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_pyroclastic
|
||||
name = "Anomaly: Pyroclastic"
|
||||
@@ -227,6 +235,7 @@
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_vortex
|
||||
name = "Anomaly: Vortex"
|
||||
@@ -240,6 +249,7 @@
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
@@ -259,6 +269,7 @@
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = -1, "chaos" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/carp_migration
|
||||
name = "Carp Migration"
|
||||
@@ -270,6 +281,7 @@
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/communications_blackout
|
||||
name = "Communications Blackout"
|
||||
@@ -283,6 +295,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1, "chaos" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/processor_overload
|
||||
name = "Processor Overload"
|
||||
@@ -296,6 +309,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1, "chaos" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/event/space_dust
|
||||
@@ -310,6 +324,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/event/major_dust
|
||||
@@ -324,6 +339,7 @@
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/electrical_storm
|
||||
name = "Electrical Storm"
|
||||
@@ -337,6 +353,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/heart_attack
|
||||
name = "Random Heart Attack"
|
||||
@@ -350,6 +367,7 @@
|
||||
requirements = list(101,101,101,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/event/radiation_storm
|
||||
@@ -362,3 +380,4 @@
|
||||
required_enemies = list(1,1,1,1,1,1,1,1,1,1)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = 1,"chaos" = 1)
|
||||
|
||||
@@ -69,8 +69,15 @@
|
||||
high_population_requirement = 15
|
||||
repeatable = TRUE
|
||||
flags = TRAITOR_RULESET
|
||||
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/infiltrator/execute()
|
||||
. = ..()
|
||||
for(var/datum/mind/M in assigned)
|
||||
log_admin("[M.name] was made into a traitor by dynamic.")
|
||||
message_admins("[M.name] was made into a traitor by dynamic.")
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// REVOLUTIONARY PROVOCATEUR //
|
||||
@@ -94,6 +101,7 @@
|
||||
requirements = list(101,101,70,40,40,40,40,40,40,40)
|
||||
high_population_requirement = 40
|
||||
flags = HIGHLANDER_RULESET
|
||||
property_weights = list("trust" = -2, "chaos" = 2, "extended" = -2, "valid" = 2, "conversion" = 1)
|
||||
var/required_heads_of_staff = 3
|
||||
var/finished = FALSE
|
||||
var/datum/team/revolution/revolution
|
||||
@@ -123,6 +131,8 @@
|
||||
revolution.update_objectives()
|
||||
revolution.update_heads()
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
log_admin("[M.name] was made into a revolutionary by dynamic.")
|
||||
message_admins("[M.name] was made into a revolutionary by dynamic.")
|
||||
return TRUE
|
||||
else
|
||||
log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.")
|
||||
@@ -187,30 +197,31 @@
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// VAMPIRE //
|
||||
// BLOODSUCKERS //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
/datum/dynamic_ruleset/latejoin/vampire
|
||||
name = "vampire"
|
||||
config_tag = "vampire_latejoin"
|
||||
antag_flag = ROLE_VAMPIRE
|
||||
antag_datum = ANTAG_DATUM_VAMPIRE
|
||||
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
|
||||
/datum/dynamic_ruleset/latejoin/bloodsucker
|
||||
name = "Bloodsucker Infiltrator"
|
||||
config_tag = "latejoin_bloodsucker"
|
||||
antag_datum = ANTAG_DATUM_BLOODSUCKER
|
||||
antag_flag = ROLE_TRAITOR
|
||||
restricted_roles = list("AI", "Cyborg")
|
||||
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_candidates = 1
|
||||
weight = 5
|
||||
cost = 15
|
||||
requirements = list(80,70,60,50,40,20,20,15,15,15)
|
||||
weight = 3
|
||||
cost = 10
|
||||
property_weights = list("story_potential" = 2, "extended" = 2, "trust" = -2, "valid" = 1)
|
||||
requirements = list(70,65,60,55,50,45,40,35,30,30)
|
||||
high_population_requirement = 30
|
||||
repeatable = TRUE
|
||||
high_population_requirement = 15
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/vampire/pre_execute()
|
||||
/datum/dynamic_ruleset/latejoin/bloodsucker/execute()
|
||||
var/mob/M = pick(candidates)
|
||||
candidates -= M
|
||||
assigned += M.mind
|
||||
M.mind.restricted_roles = restricted_roles
|
||||
M.mind.special_role = ROLE_VAMPIRE
|
||||
M.mind.special_role = antag_flag
|
||||
if(mode.make_bloodsucker(M.mind))
|
||||
mode.bloodsuckers += M
|
||||
log_admin("[M.name] was made into a bloodsucker by dynamic.")
|
||||
message_admins("[M.name] was made into a bloodsucker by dynamic.")
|
||||
return TRUE
|
||||
*/
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
var/list/living_antags = list()
|
||||
var/list/dead_players = list()
|
||||
var/list/list_observers = list()
|
||||
var/list/ghost_eligible = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts
|
||||
weight = 0
|
||||
required_type = /mob/dead/observer
|
||||
/// Whether the ruleset should call generate_ruleset_body or not.
|
||||
var/makeBody = TRUE
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
|
||||
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
|
||||
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
|
||||
ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
|
||||
|
||||
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
|
||||
var/list/trimmed_list = L.Copy()
|
||||
@@ -70,6 +72,25 @@
|
||||
continue
|
||||
return trimmed_list
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/trim_list(list/L = list())
|
||||
var/list/trimmed_list = L.Copy()
|
||||
for(var/mob/M in trimmed_list)
|
||||
if (!M.client) // Are they connected?
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(!mode.check_age(M.client, minimum_required_age))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(antag_flag_override)
|
||||
if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
else
|
||||
if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
return trimmed_list
|
||||
|
||||
// You can then for example prompt dead players in execute() to join as strike teams or whatever
|
||||
// Or autotator someone
|
||||
|
||||
@@ -91,11 +112,15 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE)
|
||||
if (required_candidates > ghost_eligible.len)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/execute()
|
||||
var/list/possible_candidates = list()
|
||||
possible_candidates.Add(dead_players)
|
||||
possible_candidates.Add(list_observers)
|
||||
var/application_successful = send_applications(possible_candidates)
|
||||
var/application_successful = send_applications(ghost_eligible)
|
||||
return assigned.len > 0 && application_successful
|
||||
|
||||
/// This sends a poll to ghosts if they want to be a ghost spawn from a ruleset.
|
||||
@@ -108,8 +133,12 @@
|
||||
|
||||
candidates = pollGhostCandidates("The mode is looking for volunteers to become a [name]", antag_flag, SSticker.mode, antag_flag, poll_time = 300)
|
||||
|
||||
if(!candidates || candidates.len <= required_candidates)
|
||||
if(!candidates || candidates.len < required_candidates)
|
||||
message_admins("The ruleset [name] did not receive enough applications.")
|
||||
if(candidates)
|
||||
message_admins("Only received [candidates.len], needed [required_candidates].")
|
||||
else
|
||||
message_admins("There were no candidates.")
|
||||
log_game("DYNAMIC: The ruleset [name] did not receive enough applications.")
|
||||
return FALSE
|
||||
|
||||
@@ -180,6 +209,7 @@
|
||||
repeatable = TRUE
|
||||
high_population_requirement = 15
|
||||
flags = TRAITOR_RULESET
|
||||
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/autotraitor/acceptable(population = 0, threat = 0)
|
||||
@@ -214,6 +244,8 @@
|
||||
living_players -= M
|
||||
var/datum/antagonist/traitor/newTraitor = new
|
||||
M.mind.add_antag_datum(newTraitor)
|
||||
log_admin("[M] was made into a traitor by dynamic.")
|
||||
message_admins("[M] was made into a traitor by dynamic.")
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -237,6 +269,7 @@
|
||||
requirements = list(101,101,70,50,50,50,40,30,30,30)
|
||||
high_population_requirement = 30
|
||||
required_type = /mob/living/silicon/ai
|
||||
property_weights = list("story_potential" = 2, "trust" = 1, "chaos" = 2)
|
||||
var/ion_announce = 33
|
||||
var/removeDontImproveChance = 10
|
||||
|
||||
@@ -261,6 +294,8 @@
|
||||
var/datum/antagonist/traitor/AI = new
|
||||
M.mind.special_role = antag_flag
|
||||
M.mind.add_antag_datum(AI)
|
||||
log_admin("[M] was made into a malf AI by dynamic.")
|
||||
message_admins("[M] was made into a malf AI by dynamic.")
|
||||
if(prob(ion_announce))
|
||||
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm")
|
||||
if(prob(removeDontImproveChance))
|
||||
@@ -289,12 +324,10 @@
|
||||
requirements = list(90,90,70,50,50,50,50,40,30,30)
|
||||
high_population_requirement = 30
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = 2, "trust" = 1, "chaos" = 2, "extended" = -2)
|
||||
var/datum/mind/wizard
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
if(GLOB.wizardstart.len == 0)
|
||||
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
@@ -337,6 +370,7 @@
|
||||
cost = 35
|
||||
requirements = list(90,90,90,80,70,60,50,40,40,40)
|
||||
high_population_requirement = 40
|
||||
property_weights = list("story_potential" = 2, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
var/operative_cap = list(2,2,3,3,4,5,5,5,5,5)
|
||||
var/datum/team/nuclear/nuke_team
|
||||
flags = HIGHLANDER_RULESET
|
||||
@@ -354,12 +388,6 @@
|
||||
required_candidates = operative_cap[indice_pop]
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/finish_setup(mob/new_character, index)
|
||||
new_character.mind.special_role = "Nuclear Operative"
|
||||
new_character.mind.assigned_role = "Nuclear Operative"
|
||||
@@ -390,12 +418,7 @@
|
||||
requirements = list(101,101,101,80,60,50,50,50,50,50)
|
||||
high_population_requirement = 50
|
||||
repeatable = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/blob/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
property_weights = list("story_potential" = -1, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant)
|
||||
var/body = applicant.become_overmind()
|
||||
@@ -421,14 +444,9 @@
|
||||
high_population_requirement = 50
|
||||
repeatable_weight_decrease = 2
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = -1, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
var/list/vents = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
|
||||
// 50% chance of being incremented by one
|
||||
required_candidates += prob(50)
|
||||
@@ -476,6 +494,7 @@
|
||||
high_population_requirement = 50
|
||||
repeatable_weight_decrease = 2
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "extended" = 1, "valid" = 2, "integrity" = 2)
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nightmare/execute()
|
||||
@@ -521,14 +540,9 @@
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
|
||||
property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
|
||||
high_population_requirement = 5
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/ready(forced = FALSE)
|
||||
if (required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
|
||||
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
|
||||
applicant.transfer_ckey(virus, FALSE)
|
||||
@@ -555,17 +569,18 @@
|
||||
cost = 5
|
||||
requirements = list(30,30,30,30,20,15,15,15,15,15)
|
||||
high_population_requirement = 15
|
||||
property_weights = list("story_potential" = -2, "extended" = -1)
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready(forced = FALSE)
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population = 0,threat = 0)
|
||||
var/deadMobs = 0
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
deadMobs++
|
||||
if(deadMobs < REVENANT_SPAWN_THRESHOLD)
|
||||
return FALSE
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready(forced = FALSE)
|
||||
for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies
|
||||
var/turf/T = get_turf(L)
|
||||
if(T && is_station_level(T.z))
|
||||
@@ -607,13 +622,11 @@
|
||||
weight = 4
|
||||
cost = 15
|
||||
requirements = list(101,101,101,90,80,70,60,50,40,30)
|
||||
property_weights = list("story_potential" = -2, "extended" = -2, "integrity" = 2, "valid" = 2, "trust" = 2)
|
||||
high_population_requirement = 30
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
@@ -659,13 +672,11 @@
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear)
|
||||
high_population_requirement = 15
|
||||
var/datum/team/abductor_team/team
|
||||
property_weights = list("story_potential" = 1, "extended" = -2, "valid" = 1, "trust" = -1, "chaos" = 2)
|
||||
repeatable_weight_decrease = 4
|
||||
repeatable = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
team = new /datum/team/abductor_team
|
||||
if(team.team_number > ABDUCTOR_MAX_TEAMS)
|
||||
return FALSE
|
||||
@@ -699,13 +710,11 @@
|
||||
cost = 15
|
||||
requirements = list(101,101,101,90,80,70,60,50,40,30)
|
||||
high_population_requirement = 30
|
||||
property_weights = list("story_potential" = 1, "extended" = -2, "valid" = 2)
|
||||
var/list/spawn_locs = list()
|
||||
var/spawn_loc
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE)
|
||||
if(required_candidates > (dead_players.len + list_observers.len))
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
|
||||
return FALSE
|
||||
if(!spawn_loc)
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
@@ -745,31 +754,3 @@
|
||||
|
||||
#undef ABDUCTOR_MAX_TEAMS
|
||||
#undef REVENANT_SPAWN_THRESHOLD
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// BLOODSUCKERS //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/bloodsucker
|
||||
name = "Bloodsucker Infiltrator"
|
||||
config_tag = "latejoin_bloodsucker"
|
||||
antag_datum = ANTAG_DATUM_BLOODSUCKER
|
||||
antag_flag = ROLE_TRAITOR
|
||||
restricted_roles = list("AI", "Cyborg")
|
||||
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_candidates = 1
|
||||
weight = 3
|
||||
cost = 10
|
||||
requirements = list(90,80,70,60,55,50,45,40,35,30)
|
||||
high_population_requirement = 30
|
||||
repeatable = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/bloodsucker/execute()
|
||||
var/mob/M = pick(candidates)
|
||||
assigned += M.mind
|
||||
M.mind.special_role = antag_flag
|
||||
if(mode.make_bloodsucker(M.mind))
|
||||
mode.bloodsuckers += M
|
||||
return TRUE
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
requirements = list(50,50,50,50,50,50,50,50,50,50)
|
||||
high_population_requirement = 40
|
||||
antag_cap = list(1,1,1,1,2,2,2,2,3,3)
|
||||
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1, "valid" = 1)
|
||||
always_max_weight = TRUE
|
||||
var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec)
|
||||
|
||||
@@ -61,6 +62,7 @@
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 101
|
||||
antag_cap = list(2,2,2,2,2,2,2,2,2,2) // Can pick 3 per team, but rare enough it doesn't matter.
|
||||
property_weights = list("story_potential" = 1, "trust" = -1, "extended" = 1, "valid" = 1)
|
||||
var/list/datum/team/brother_team/pre_brother_teams = list()
|
||||
var/const/min_team_size = 2
|
||||
|
||||
@@ -108,6 +110,7 @@
|
||||
cost = 15
|
||||
scaling_cost = 15
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
property_weights = list("trust" = -2, "valid" = 2)
|
||||
high_population_requirement = 10
|
||||
antag_cap = list(1,1,1,1,1,2,2,2,2,3)
|
||||
var/team_mode_probability = 30
|
||||
@@ -160,6 +163,7 @@
|
||||
cost = 30
|
||||
requirements = list(101,101,101,60,50,50,50,50,50,50)
|
||||
high_population_requirement = 50
|
||||
property_weights = list("story_potential" = 2, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
var/list/roundstart_wizards = list()
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/wizard/acceptable(population=0, threat=0)
|
||||
@@ -222,6 +226,7 @@
|
||||
weight = 3
|
||||
cost = 30
|
||||
requirements = list(101,101,101,80,70,60,50,50,50,50)
|
||||
property_weights = list("story_potential" = -1, "trust" = -1, "chaos" = 1, "conversion" = 1, "extended" = -2, "valid" = 2)
|
||||
high_population_requirement = 50
|
||||
flags = HIGHLANDER_RULESET
|
||||
antag_cap = list(2,2,2,3,3,4,4,4,4,4)
|
||||
@@ -283,6 +288,7 @@
|
||||
high_population_requirement = 50
|
||||
flags = HIGHLANDER_RULESET
|
||||
antag_cap = list(1,1,2,3,4,5,5,5,5,5)
|
||||
property_weights = list("story_potential" = 2, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
var/datum/team/nuclear/nuke_team
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/nuclear/ready(forced = FALSE)
|
||||
@@ -373,6 +379,7 @@
|
||||
flags = HIGHLANDER_RULESET
|
||||
// I give up, just there should be enough heads with 35 players...
|
||||
minimum_players = 35
|
||||
property_weights = list("trust" = -2, "chaos" = 2, "extended" = -2, "valid" = 2, "conversion" = 1)
|
||||
var/datum/team/revolution/revolution
|
||||
var/finished = FALSE
|
||||
|
||||
@@ -490,6 +497,7 @@
|
||||
weight = 3
|
||||
cost = 0
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
property_weights = list("extended" = 2)
|
||||
high_population_requirement = 101
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/extended/pre_execute()
|
||||
@@ -517,6 +525,7 @@
|
||||
high_population_requirement = 50
|
||||
flags = HIGHLANDER_RULESET
|
||||
antag_cap = list(2,3,3,4,4,4,4,4,4,4)
|
||||
property_weights = list("trust" = 2, "chaos" = 2, "extended" = -2, "conversion" = 1, "valid" = 2)
|
||||
var/ark_time
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/clockcult/pre_execute()
|
||||
@@ -616,6 +625,8 @@
|
||||
antag_leader_datum = /datum/antagonist/nukeop/leader/clownop
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 101
|
||||
property_weights = list("trust" = 2, "chaos" = 2, "extended" = -2, "story_potential" = 2, "valid" = 2)
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/nuclear/clown_ops/pre_execute()
|
||||
. = ..()
|
||||
@@ -647,6 +658,7 @@
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 101
|
||||
antag_cap = list(1,1,1,2,2,2,3,3,3,4)
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/devil/pre_execute()
|
||||
var/num_devils = antag_cap[indice_pop]
|
||||
@@ -698,6 +710,7 @@
|
||||
cost = 0
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 101
|
||||
property_weights = list("extended" = -2, "chaos" = 2, "conversion" = 1, "valid" = 2)
|
||||
var/players_per_carrier = 30
|
||||
var/monkeys_to_win = 1
|
||||
var/escaped_monkeys = 0
|
||||
@@ -759,6 +772,7 @@
|
||||
cost = 0
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 101
|
||||
property_weights = list("extended" = -2, "chaos" = 2, "trust" = 2)
|
||||
var/meteordelay = 2000
|
||||
var/nometeors = 0
|
||||
var/rampupdelta = 5
|
||||
@@ -799,7 +813,8 @@
|
||||
weight = 2
|
||||
cost = 15
|
||||
scaling_cost = 10
|
||||
requirements = list(90,80,70,60,50,50,50,50,50,50)
|
||||
property_weights = list("story_potential" = 1, "extended" = 1, "trust" = -2, "valid" = 1)
|
||||
requirements = list(70,65,60,55,50,50,50,50,50,50)
|
||||
high_population_requirement = 50
|
||||
antag_cap = list(1,1,1,1,1,2,2,2,2,2)
|
||||
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/datum/dynamic_storyteller
|
||||
var/name = "none"
|
||||
var/desc = "A coder's idiocy."
|
||||
var/list/property_weights = list()
|
||||
var/curve_centre = 0
|
||||
var/curve_width = 1.8
|
||||
var/forced_threat_level = -1
|
||||
var/flags = 0
|
||||
var/weight = 3 // how many rounds need to have been recently played for this storyteller to be left out of the vote
|
||||
var/datum/game_mode/dynamic/mode = null
|
||||
|
||||
/**
|
||||
Property weights are:
|
||||
"story_potential" -- essentially how many different ways the antag can be played.
|
||||
"trust" -- How much it makes the crew trust each other. Negative values means they're suspicious. Team antags are like this.
|
||||
"chaos" -- How chaotic it makes the round. Has some overlap with "valid" and somewhat contradicts "extended".
|
||||
"valid" -- How likely the non-antag-enemy crew are to get involved, e.g. nukies encouraging the warden to
|
||||
let everyone into the armory, wizard moving around and being a nuisance, nightmare busting lights.
|
||||
"extended" -- How much the antag is conducive to a long round. Nukies and cults are bad for this; Wizard is less bad; and so on.
|
||||
"conversion" -- Basically a bool. Conversion antags, well, convert. It's its own class for a good reason.
|
||||
*/
|
||||
|
||||
/datum/dynamic_storyteller/New()
|
||||
..()
|
||||
if (istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
mode = SSticker.mode
|
||||
GLOB.dynamic_curve_centre = curve_centre
|
||||
GLOB.dynamic_curve_width = curve_width
|
||||
GLOB.dynamic_forced_threat_level = forced_threat_level
|
||||
|
||||
/datum/dynamic_storyteller/proc/start_injection_cooldowns()
|
||||
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_latejoin_delay_max + GLOB.dynamic_first_latejoin_delay_min)
|
||||
mode.latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_first_latejoin_delay_min, GLOB.dynamic_first_latejoin_delay_max)) + world.time
|
||||
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max)
|
||||
mode.midround_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time
|
||||
|
||||
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
|
||||
mode.event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time)
|
||||
|
||||
/datum/dynamic_storyteller/proc/do_process()
|
||||
return
|
||||
|
||||
/datum/dynamic_storyteller/proc/on_start()
|
||||
return
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_midround_cooldown()
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min)
|
||||
return round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max))
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_event_cooldown()
|
||||
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
|
||||
return round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max))
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_latejoin_cooldown()
|
||||
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_latejoin_delay_max + GLOB.dynamic_latejoin_delay_min)
|
||||
return round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_latejoin_delay_min, GLOB.dynamic_latejoin_delay_max))
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_injection_chance(dry_run = FALSE)
|
||||
if(mode.forced_injection)
|
||||
mode.forced_injection = !dry_run
|
||||
return 100
|
||||
var/chance = 0
|
||||
// If the high pop override is in effect, we reduce the impact of population on the antag injection chance
|
||||
var/high_pop_factor = (mode.current_players[CURRENT_LIVING_PLAYERS].len >= GLOB.dynamic_high_pop_limit)
|
||||
var/max_pop_per_antag = max(5,15 - round(mode.threat_level/10) - round(mode.current_players[CURRENT_LIVING_PLAYERS].len/(high_pop_factor ? 10 : 5)))
|
||||
if (!mode.current_players[CURRENT_LIVING_ANTAGS].len)
|
||||
chance += 80 // No antags at all? let's boost those odds!
|
||||
else
|
||||
var/current_pop_per_antag = mode.current_players[CURRENT_LIVING_PLAYERS].len / mode.current_players[CURRENT_LIVING_ANTAGS].len
|
||||
if (current_pop_per_antag > max_pop_per_antag)
|
||||
chance += min(50, 25+10*(current_pop_per_antag-max_pop_per_antag))
|
||||
else
|
||||
chance += 25-10*(max_pop_per_antag-current_pop_per_antag)
|
||||
if (mode.current_players[CURRENT_DEAD_PLAYERS].len > mode.current_players[CURRENT_LIVING_PLAYERS].len)
|
||||
chance -= 30 // More than half the crew died? ew, let's calm down on antags
|
||||
if (mode.threat > 70)
|
||||
chance += 15
|
||||
if (mode.threat < 30)
|
||||
chance -= 15
|
||||
return round(max(0,chance))
|
||||
|
||||
/datum/dynamic_storyteller/proc/roundstart_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for (var/datum/dynamic_ruleset/roundstart/rule in mode.roundstart_rules)
|
||||
if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level) && mode.threat >= rule.cost) // If we got the population and threat required
|
||||
rule.candidates = mode.candidates.Copy()
|
||||
rule.trim_candidates()
|
||||
if (rule.ready() && rule.candidates.len > 0)
|
||||
var/property_weight = 0
|
||||
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
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/proc/midround_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for (var/datum/dynamic_ruleset/midround/rule in mode.midround_rules)
|
||||
// if there are antags OR the rule is an antag rule, antag_acceptable will be true.
|
||||
if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && mode.threat >= rule.cost)
|
||||
// Classic secret : only autotraitor/minor roles
|
||||
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
|
||||
continue
|
||||
rule.trim_candidates()
|
||||
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
|
||||
else if(mode.threat < rule.cost)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat to spend")
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/proc/latejoin_draft(mob/living/carbon/human/newPlayer)
|
||||
var/list/drafted_rules = list()
|
||||
for (var/datum/dynamic_ruleset/latejoin/rule in mode.latejoin_rules)
|
||||
if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && mode.threat >= rule.cost)
|
||||
// Classic secret : only autotraitor/minor roles
|
||||
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
|
||||
continue
|
||||
// No stacking : only one round-ender, unless threat level > stacking_limit.
|
||||
if (mode.threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
|
||||
if(rule.flags & HIGHLANDER_RULESET && mode.highlander_executed)
|
||||
continue
|
||||
|
||||
rule.candidates = list(newPlayer)
|
||||
rule.trim_candidates()
|
||||
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
|
||||
else if(mode.threat < rule.cost)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat to spend")
|
||||
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 >= 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
|
||||
else if(mode.threat < rule.cost)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat to spend")
|
||||
return drafted_rules
|
||||
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga
|
||||
name = "Chaotic"
|
||||
curve_centre = 10
|
||||
desc = "Chaos: high. Variation: high. Likely antags: clock cult, revs, wizard."
|
||||
property_weights = list("extended" = -1, "chaos" = 10)
|
||||
weight = 2
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
var/refund_cooldown
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/get_midround_cooldown()
|
||||
return ..() / 4
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/get_latejoin_cooldown()
|
||||
return ..() / 4
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/do_process()
|
||||
if(refund_cooldown < world.time)
|
||||
mode.refund_threat(10)
|
||||
mode.log_threat("Cowabunga it is. Refunded 10 threat. Threat is now [mode.threat].")
|
||||
refund_cooldown = world.time + 300 SECONDS
|
||||
|
||||
/datum/dynamic_storyteller/team
|
||||
name = "Teamwork"
|
||||
desc = "Chaos: high. Variation: low. Likely antags: nukies, clockwork cult, wizard, blob, xenomorph."
|
||||
curve_centre = 2
|
||||
curve_width = 1.5
|
||||
weight = 2
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
property_weights = list("valid" = 3, "trust" = 5)
|
||||
|
||||
/datum/dynamic_storyteller/team/get_injection_chance(dry_run = FALSE)
|
||||
return (mode.current_players[CURRENT_LIVING_ANTAGS].len ? 0 : ..())
|
||||
|
||||
/datum/dynamic_storyteller/conversion
|
||||
name = "Conversion"
|
||||
desc = "Chaos: high. Variation: medium. Likely antags: cults, bloodsuckers, revs."
|
||||
curve_centre = 3
|
||||
curve_width = 1
|
||||
weight = 2
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
property_weights = list("valid" = 1, "conversion" = 20)
|
||||
|
||||
/datum/dynamic_storyteller/classic
|
||||
name = "Random"
|
||||
desc = "Chaos: varies. Variation: highest. No special weights attached."
|
||||
weight = 6
|
||||
curve_width = 4
|
||||
|
||||
/datum/dynamic_storyteller/memes
|
||||
name = "Story"
|
||||
desc = "Chaos: varies. Variation: high. Likely antags: abductors, nukies, wizard, traitor."
|
||||
curve_width = 4
|
||||
property_weights = list("story_potential" = 10)
|
||||
|
||||
/datum/dynamic_storyteller/suspicion
|
||||
name = "Intrigue"
|
||||
desc = "Chaos: low. Variation: high. Likely antags: traitor, bloodsucker. Rare: revs, blood cult."
|
||||
curve_width = 4
|
||||
property_weights = list("trust" = -5)
|
||||
|
||||
/datum/dynamic_storyteller/liteextended
|
||||
name = "Calm"
|
||||
desc = "Chaos: low. Variation: medium. Likely antags: bloodsuckers, traitors, sentient disease, revenant."
|
||||
curve_centre = -5
|
||||
curve_width = 0.5
|
||||
flags = NO_ASSASSIN
|
||||
weight = 2
|
||||
property_weights = list("extended" = 1, "chaos" = -1, "valid" = -1, "story_potential" = 1, "conversion" = -10)
|
||||
|
||||
/datum/dynamic_storyteller/liteextended/get_injection_chance(dry_run = FALSE)
|
||||
return ..()/2
|
||||
|
||||
/datum/dynamic_storyteller/extended
|
||||
name = "Extended"
|
||||
desc = "Chaos: none. Variation: none. Likely antags: none."
|
||||
curve_centre = -20
|
||||
weight = 2
|
||||
curve_width = 0.5
|
||||
|
||||
/datum/dynamic_storyteller/extended/on_start()
|
||||
GLOB.dynamic_forced_extended = TRUE
|
||||
@@ -14,14 +14,14 @@
|
||||
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 = -25
|
||||
var/min_health = 30
|
||||
var/list/available_chems
|
||||
var/controls_inside = FALSE
|
||||
var/list/possible_chems = list(
|
||||
list("epinephrine", "morphine", "salbutamol", "bicaridine", "kelotane"),
|
||||
list("oculine","inacusiate"),
|
||||
list("antitoxin", "mutadone", "mannitol", "pen_acid"),
|
||||
list("omnizine")
|
||||
list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/morphine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane),
|
||||
list(/datum/reagent/medicine/oculine,/datum/reagent/medicine/inacusiate),
|
||||
list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/mutadone, /datum/reagent/medicine/mannitol, /datum/reagent/medicine/pen_acid),
|
||||
list(/datum/reagent/medicine/omnizine)
|
||||
)
|
||||
var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: antitoxin -> morphine
|
||||
var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning
|
||||
@@ -106,7 +106,7 @@
|
||||
return
|
||||
if(is_operational() && occupant)
|
||||
var/datum/reagent/R = pick(reagents.reagent_list)
|
||||
inject_chem(R.id, occupant)
|
||||
inject_chem(R.type, occupant)
|
||||
open_machine()
|
||||
//Is this too much?
|
||||
if(severity == EMP_HEAVY)
|
||||
@@ -217,9 +217,9 @@
|
||||
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.id, "synth_allowed" = synth_allowed(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.id, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.id)))
|
||||
data["chems"] += list(list("name" = R.name, "id" = R.type, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.type)))
|
||||
|
||||
data["occupant"] = list()
|
||||
var/mob/living/mob_occupant = occupant
|
||||
@@ -289,23 +289,23 @@
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("inject")
|
||||
var/chem = params["chem"]
|
||||
var/chem = text2path(params["chem"])
|
||||
var/amount = text2num(params["volume"])
|
||||
if(!is_operational() || !mob_occupant)
|
||||
if(!is_operational() || !mob_occupant || isnull(chem))
|
||||
return
|
||||
if(mob_occupant.health < min_health && chem != "epinephrine")
|
||||
if(mob_occupant.health < min_health && chem != /datum/reagent/medicine/epinephrine)
|
||||
return
|
||||
if(inject_chem(chem, usr, amount))
|
||||
. = 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 = params["chem"]
|
||||
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 = params["chem"]
|
||||
var/chem = text2path(params["chem"])
|
||||
if(allowed(usr))
|
||||
if(!is_operational())
|
||||
return
|
||||
@@ -342,7 +342,7 @@
|
||||
if(!mob_occupant || !mob_occupant.reagents)
|
||||
return
|
||||
var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency
|
||||
var/occ_health = mob_occupant.health > min_health || chem == "epinephrine"
|
||||
var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine
|
||||
return amount && occ_health
|
||||
|
||||
/obj/machinery/sleeper/proc/synth_allowed(chem)
|
||||
|
||||
@@ -123,15 +123,15 @@
|
||||
if(reagents.total_volume >= reagents.maximum_volume || !bag || !bag.reagents.total_volume)
|
||||
beep_stop_pumping()
|
||||
return
|
||||
var/blood_amount = bag.reagents.get_reagent_amount("blood")
|
||||
var/blood_amount = bag.reagents.get_reagent_amount(/datum/reagent/blood)
|
||||
//monitor the machine and blood bag's reagents storage.
|
||||
var/amount = min(blood_amount, min(transfer_amount, reagents.maximum_volume - reagents.total_volume))
|
||||
if(!amount)
|
||||
beep_stop_pumping()
|
||||
return
|
||||
var/bonus = bag.blood_type == "SY" ? 0 : 5 * efficiency //no infinite loops using synthetics.
|
||||
reagents.add_reagent("syntheticblood", amount + bonus)
|
||||
bag.reagents.remove_reagent("blood", amount)
|
||||
reagents.add_reagent(/datum/reagent/blood/synthetics, amount + bonus)
|
||||
bag.reagents.remove_reagent(/datum/reagent/blood, amount)
|
||||
update_icon()
|
||||
|
||||
if(filling)
|
||||
|
||||
@@ -155,6 +155,8 @@
|
||||
mess = TRUE
|
||||
update_icon()
|
||||
return FALSE
|
||||
if(isvamp(clonemind)) //If the mind is a bloodsucker
|
||||
return FALSE
|
||||
|
||||
attempting = TRUE //One at a time!!
|
||||
countdown.start()
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
occupant_status += "</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [viable_occupant.health]%;' class='progressFill good'></div></div><div class='statusValue'>[viable_occupant.health] %</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Radiation Level:</div><div class='progressBar'><div style='width: [viable_occupant.radiation/(RAD_MOB_SAFE/100)]%;' class='progressFill bad'></div></div><div class='statusValue'>[viable_occupant.radiation/(RAD_MOB_SAFE/100)] %</div></div>"
|
||||
var/rejuvenators = viable_occupant.reagents.get_reagent_amount("potass_iodide")
|
||||
var/rejuvenators = viable_occupant.reagents.get_reagent_amount(/datum/reagent/medicine/potass_iodide)
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Rejuvenators:</div><div class='progressBar'><div style='width: [round((rejuvenators / REJUVENATORS_MAX) * 100)]%;' class='progressFill highlight'></div></div><div class='statusValue'>[rejuvenators] units</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Unique Enzymes :</div><div class='statusValue'><span class='highlight'>[viable_occupant.dna.unique_enzymes]</span></div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Last Operation:</div><div class='statusValue'>[last_change ? last_change : "----"]</div></div>"
|
||||
@@ -342,9 +342,9 @@
|
||||
current_screen = href_list["text"]
|
||||
if("rejuv")
|
||||
if(viable_occupant && viable_occupant.reagents)
|
||||
var/potassiodide_amount = viable_occupant.reagents.get_reagent_amount("potass_iodide")
|
||||
var/potassiodide_amount = viable_occupant.reagents.get_reagent_amount(/datum/reagent/medicine/potass_iodide)
|
||||
var/can_add = max(min(REJUVENATORS_MAX - potassiodide_amount, REJUVENATORS_INJECT), 0)
|
||||
viable_occupant.reagents.add_reagent("potass_iodide", can_add)
|
||||
viable_occupant.reagents.add_reagent(/datum/reagent/medicine/potass_iodide, can_add)
|
||||
if("setbufferlabel")
|
||||
var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null)
|
||||
if(num && text)
|
||||
|
||||
@@ -491,4 +491,4 @@
|
||||
|
||||
//Attacks/effects.
|
||||
/obj/machinery/cryopod/blob_act()
|
||||
return //Sorta gamey, but we don't really want these to be destroyed.
|
||||
return //Sorta gamey, but we don't really want these to be destroyed.
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
limit--
|
||||
while(!FoundDoor && limit)
|
||||
if (!FoundDoor)
|
||||
log_world("### MAP WARNING, [src] at [AREACOORD(src)] failed to find a valid airlock to cyclelink with!")
|
||||
log_mapping("[src] at [AREACOORD(src)] failed to find a valid airlock to cyclelink with!")
|
||||
return
|
||||
FoundDoor.cyclelinkedairlock = src
|
||||
cyclelinkedairlock = FoundDoor
|
||||
|
||||
@@ -7,26 +7,51 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
icon_state = "tdoppler"
|
||||
density = TRUE
|
||||
var/integrated = FALSE
|
||||
var/list_limit = 100
|
||||
var/cooldown = 10
|
||||
var/next_announce = 0
|
||||
var/max_dist = 150
|
||||
verb_say = "states coldly"
|
||||
var/list/message_log = list()
|
||||
|
||||
/obj/machinery/doppler_array/Initialize()
|
||||
. = ..()
|
||||
GLOB.doppler_arrays += src
|
||||
|
||||
/obj/machinery/doppler_array/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE,null,null,CALLBACK(src,.proc/rot_message))
|
||||
|
||||
/obj/machinery/doppler_array/Destroy()
|
||||
GLOB.doppler_arrays -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/doppler_array/examine(mob/user)
|
||||
/obj/machinery/doppler_array/ui_interact(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Its dish is facing to the [dir2text(dir)].</span>"
|
||||
if(stat)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/doppler_array/process()
|
||||
return PROCESS_KILL
|
||||
var/list/dat = list()
|
||||
for(var/i in 1 to LAZYLEN(message_log))
|
||||
dat += "Log recording #[i]: [message_log[i]]<br/><br>"
|
||||
dat += "<A href='?src=[REF(src)];delete_log=1'>Delete logs</A><br>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=[REF(src)];refresh=1'>(Refresh)</A><br>"
|
||||
dat += "</body></html>"
|
||||
var/datum/browser/popup = new(user, "computer", name, 400, 500)
|
||||
popup.set_content(dat.Join(" "))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/doppler_array/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["delete_log"])
|
||||
LAZYCLEARLIST(message_log)
|
||||
if(href_list["refresh"])
|
||||
updateUsrDialog()
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/doppler_array/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/wrench))
|
||||
@@ -46,15 +71,18 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
to_chat(user, "<span class='notice'>You adjust [src]'s dish to face to the [dir2text(dir)].</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
|
||||
/obj/machinery/doppler_array/proc/sense_explosion(turf/epicenter,devastation_range,heavy_impact_range,light_impact_range,
|
||||
took,orig_dev_range,orig_heavy_range,orig_light_range)
|
||||
/obj/machinery/doppler_array/proc/sense_explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range,
|
||||
took, orig_dev_range, orig_heavy_range, orig_light_range)
|
||||
if(stat & NOPOWER)
|
||||
return FALSE
|
||||
var/turf/zone = get_turf(src)
|
||||
|
||||
if(zone.z != epicenter.z)
|
||||
return FALSE
|
||||
|
||||
if(next_announce > world.time)
|
||||
return FALSE
|
||||
next_announce = world.time + cooldown
|
||||
|
||||
var/distance = get_dist(epicenter, zone)
|
||||
var/direct = get_dir(zone, epicenter)
|
||||
|
||||
@@ -80,8 +108,19 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
else
|
||||
for(var/message in messages)
|
||||
say(message)
|
||||
if(LAZYLEN(message_log) > list_limit)
|
||||
say("Storage buffer is full! Clearing buffers...")
|
||||
LAZYCLEARLIST(message_log)
|
||||
LAZYADD(message_log, messages.Join(" "))
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/doppler_array/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Its dish is facing to the [dir2text(dir)].</span>"
|
||||
|
||||
/obj/machinery/doppler_array/process()
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/machinery/doppler_array/power_change()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
|
||||
@@ -256,7 +256,6 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/firealarm/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
. = ..()
|
||||
if(.) //damage received
|
||||
|
||||
@@ -500,7 +500,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf)
|
||||
/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf, direction)
|
||||
if(LAZYLEN(masters) && masters[user])
|
||||
var/obj/effect/overlay/holo_pad_hologram/holo = masters[user]
|
||||
var/transfered = FALSE
|
||||
@@ -512,6 +512,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
transfered = TRUE
|
||||
//All is good.
|
||||
holo.forceMove(new_turf)
|
||||
if(direction)
|
||||
holo.setDir(direction)
|
||||
if(!transfered)
|
||||
update_holoray(user,new_turf)
|
||||
return TRUE
|
||||
|
||||
@@ -222,5 +222,21 @@
|
||||
|
||||
. += "\t<span class='notice'>[attached ? attached : "No one"] is attached.</span>"
|
||||
|
||||
/obj/machinery/iv_drip/telescopic
|
||||
name = "telescopic IV drip"
|
||||
desc = "An IV drip with an advanced infusion pump that can both drain blood into and inject liquids from attached containers. Blood packs are processed at an accelerated rate. This one is telescopic, and can be picked up and put down."
|
||||
icon_state = "iv_drip"
|
||||
|
||||
/obj/machinery/iv_drip/telescopic/update_icon()
|
||||
..()
|
||||
icon_state = icon_state + "_tele"
|
||||
|
||||
/obj/machinery/iv_drip/telescopic/AltClick(mob/user)
|
||||
if (attached || beaker || !user.canUseTopic(src, BE_CLOSE))
|
||||
return ..()
|
||||
new /obj/item/tele_iv(get_turf(src))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
#undef IV_TAKING
|
||||
#undef IV_INJECTING
|
||||
#undef IV_INJECTING
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
selected_category = href_list["category"]
|
||||
|
||||
if(href_list["disposeI"]) //Get rid of a reagent incase you add the wrong one by mistake
|
||||
reagents.del_reagent(href_list["disposeI"])
|
||||
reagents.del_reagent(text2path(href_list["disposeI"]))
|
||||
|
||||
if(href_list["make"])
|
||||
|
||||
@@ -100,10 +100,10 @@
|
||||
return
|
||||
|
||||
|
||||
var/synth_cost = being_built.reagents_list["synthflesh"]*prod_coeff
|
||||
var/synth_cost = being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff
|
||||
var/power = max(2000, synth_cost/5)
|
||||
|
||||
if(reagents.has_reagent("synthflesh", being_built.reagents_list["synthflesh"]*prod_coeff))
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff))
|
||||
busy = TRUE
|
||||
use_power(power)
|
||||
flick("limbgrower_fill",src)
|
||||
@@ -117,8 +117,8 @@
|
||||
return
|
||||
|
||||
/obj/machinery/limbgrower/proc/build_item()
|
||||
if(reagents.has_reagent("synthflesh", being_built.reagents_list["synthflesh"]*prod_coeff)) //sanity check, if this happens we are in big trouble
|
||||
reagents.remove_reagent("synthflesh",being_built.reagents_list["synthflesh"]*prod_coeff)
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //sanity check, if this happens we are in big trouble
|
||||
reagents.remove_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)
|
||||
var/buildpath = being_built.build_path
|
||||
if(ispath(buildpath, /obj/item/bodypart)) //This feels like spatgheti code, but i need to initilise a limb somehow
|
||||
build_limb(buildpath)
|
||||
@@ -198,7 +198,7 @@
|
||||
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
dat += "[R.name]: [R.volume]"
|
||||
dat += "<A href='?src=[REF(src)];disposeI=[R.id]'>Purge</A><BR>"
|
||||
dat += "<A href='?src=[REF(src)];disposeI=[R]'>Purge</A><BR>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
@@ -208,12 +208,12 @@
|
||||
return dat
|
||||
|
||||
/obj/machinery/limbgrower/proc/can_build(datum/design/D)
|
||||
return (reagents.has_reagent("synthflesh", D.reagents_list["synthflesh"]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design
|
||||
return (reagents.has_reagent(/datum/reagent/medicine/synthflesh, D.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design
|
||||
|
||||
/obj/machinery/limbgrower/proc/get_design_cost(datum/design/D)
|
||||
var/dat
|
||||
if(D.reagents_list["synthflesh"])
|
||||
dat += "[D.reagents_list["synthflesh"] * prod_coeff] Synthetic flesh "
|
||||
dat += "[D.reagents_list[/datum/reagent/medicine/synthflesh] * prod_coeff] Synthetic flesh "
|
||||
return dat
|
||||
|
||||
/obj/machinery/limbgrower/emag_act(mob/user)
|
||||
|
||||
@@ -18,6 +18,28 @@
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/recharge_station/upgraded
|
||||
|
||||
/obj/machinery/recharge_station/upgraded/Initialize()
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/machine/cyborgrecharger(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor/super(null)
|
||||
component_parts += new /obj/item/stock_parts/manipulator/pico(null)
|
||||
component_parts += new /obj/item/stock_parts/cell/hyper(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/recharge_station/fullupgrade
|
||||
|
||||
/obj/machinery/recharge_station/fullupgrade/Initialize()
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/machine/cyborgrecharger(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor/quadratic(null)
|
||||
component_parts += new /obj/item/stock_parts/manipulator/femto(null)
|
||||
component_parts += new /obj/item/stock_parts/cell/bluespace(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/recharge_station/RefreshParts()
|
||||
recharge_speed = 0
|
||||
repairs = 0
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
#define AUTOYLATHE_MAIN_MENU 1
|
||||
#define AUTOYLATHE_CATEGORY_MENU 2
|
||||
#define AUTOYLATHE_SEARCH_MENU 3
|
||||
|
||||
/obj/machinery/autoylathe
|
||||
name = "autoylathe"
|
||||
desc = "It produces toys using plastic, metal and glass."
|
||||
icon_state = "autolathe"
|
||||
density = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/circuitboard/machine/autoylathe
|
||||
layer = BELOW_OBJ_LAYER
|
||||
|
||||
var/operating = FALSE
|
||||
var/list/L = list()
|
||||
var/list/LL = list()
|
||||
var/hacked = FALSE
|
||||
var/disabled = 0
|
||||
var/shocked = FALSE
|
||||
var/hack_wire
|
||||
var/disable_wire
|
||||
var/shock_wire
|
||||
|
||||
var/busy = FALSE
|
||||
var/prod_coeff = 1
|
||||
|
||||
var/datum/design/being_built
|
||||
var/datum/techweb/stored_research
|
||||
var/list/datum/design/matching_designs
|
||||
var/selected_category
|
||||
var/screen = 1
|
||||
|
||||
var/list/categories = list(
|
||||
"Toys",
|
||||
"Figurines",
|
||||
"Pistols",
|
||||
"Rifles",
|
||||
"Heavy",
|
||||
"Melee",
|
||||
"Armor",
|
||||
"Adult",
|
||||
"Misc",
|
||||
"Imported"
|
||||
)
|
||||
|
||||
/obj/machinery/autoylathe/Initialize()
|
||||
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASTIC), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
. = ..()
|
||||
|
||||
wires = new /datum/wires/autoylathe(src)
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/autoylathe
|
||||
matching_designs = list()
|
||||
|
||||
/obj/machinery/autoylathe/Destroy()
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autoylathe/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if(!is_operational())
|
||||
return
|
||||
|
||||
if(shocked && !(stat & NOPOWER))
|
||||
shock(user,50)
|
||||
|
||||
var/dat
|
||||
|
||||
switch(screen)
|
||||
if(AUTOYLATHE_MAIN_MENU)
|
||||
dat = main_win(user)
|
||||
if(AUTOYLATHE_CATEGORY_MENU)
|
||||
dat = category_win(user,selected_category)
|
||||
if(AUTOYLATHE_SEARCH_MENU)
|
||||
dat = search_win(user)
|
||||
|
||||
var/datum/browser/popup = new(user, "Autoylathe", name, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/autoylathe/on_deconstruction()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.retrieve_all()
|
||||
|
||||
/obj/machinery/autoylathe/attackby(obj/item/O, mob/user, params)
|
||||
if (busy)
|
||||
to_chat(user, "<span class=\"alert\">The autoylathe is busy. Please wait for completion of previous operation.</span>")
|
||||
return TRUE
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O))
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return TRUE
|
||||
|
||||
if(panel_open && is_wire_tool(O))
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
|
||||
if(user.a_intent == INTENT_HARM) //so we can hit the machine
|
||||
return ..()
|
||||
|
||||
if(stat)
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message("[user] begins to load \the [O] in \the [src]...",
|
||||
"You begin to load a design from \the [O]...",
|
||||
"You hear the chatter of a floppy drive.")
|
||||
busy = TRUE
|
||||
var/obj/item/disk/design_disk/D = O
|
||||
if(do_after(user, 14.4, target = src))
|
||||
for(var/B in D.blueprints)
|
||||
if(B)
|
||||
stored_research.add_design(B)
|
||||
busy = FALSE
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autoylathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
|
||||
if(ispath(type_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
use_power(amount_inserted / 10)
|
||||
else
|
||||
switch(id_inserted)
|
||||
if (MAT_METAL)
|
||||
flick("autolathe_o",src)//plays metal insertion animation
|
||||
if (MAT_GLASS)
|
||||
flick("autolathe_r",src)//plays glass insertion animation
|
||||
if (MAT_PLASTIC)
|
||||
flick("autolathe_o",src)//plays metal insertion animation
|
||||
use_power(amount_inserted / 10)
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/autoylathe/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if (!busy)
|
||||
if(href_list["menu"])
|
||||
screen = text2num(href_list["menu"])
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["category"])
|
||||
selected_category = href_list["category"]
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["make"])
|
||||
|
||||
/////////////////
|
||||
//href protection
|
||||
being_built = stored_research.isDesignResearchedID(href_list["make"])
|
||||
if(!being_built)
|
||||
return
|
||||
|
||||
var/multiplier = text2num(href_list["multiplier"])
|
||||
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
|
||||
multiplier = CLAMP(multiplier,1,50)
|
||||
|
||||
/////////////////
|
||||
|
||||
var/coeff = (is_stack ? 1 : prod_coeff) //stacks are unaffected by production coefficient
|
||||
var/metal_cost = being_built.materials[MAT_METAL]
|
||||
var/glass_cost = being_built.materials[MAT_GLASS]
|
||||
var/plastic_cost = being_built.materials[MAT_PLASTIC]
|
||||
var/power = max(2000, (metal_cost+glass_cost+plastic_cost)*multiplier/5)
|
||||
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff) && (materials.amount(MAT_PLASTIC) >= plastic_cost*multiplier*coeff))
|
||||
busy = TRUE
|
||||
use_power(power)
|
||||
icon_state = "autolathe_n"
|
||||
var/time = is_stack ? 32 : 32*coeff*multiplier
|
||||
addtimer(CALLBACK(src, .proc/make_item, power, metal_cost, glass_cost, plastic_cost, multiplier, coeff, is_stack), time)
|
||||
|
||||
if(href_list["search"])
|
||||
matching_designs.Cut()
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(findtext(D.name,href_list["to_search"]))
|
||||
matching_designs.Add(D)
|
||||
updateUsrDialog()
|
||||
else
|
||||
to_chat(usr, "<span class=\"alert\">The autoylathe is busy. Please wait for completion of previous operation.</span>")
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/autoylathe/proc/make_item(power, metal_cost, glass_cost, plastic_cost, multiplier, coeff, is_stack)
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/atom/A = drop_location()
|
||||
use_power(power)
|
||||
var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier, MAT_PLASTIC=plastic_cost*coeff*multiplier)
|
||||
materials.use_amount(materials_used)
|
||||
|
||||
if(is_stack)
|
||||
var/obj/item/stack/N = new being_built.build_path(A, multiplier)
|
||||
N.update_icon()
|
||||
N.autoylathe_crafted(src)
|
||||
else
|
||||
for(var/i=1, i<=multiplier, i++)
|
||||
var/obj/item/new_item = new being_built.build_path(A)
|
||||
new_item.materials = new_item.materials.Copy()
|
||||
for(var/mat in materials_used)
|
||||
new_item.materials[mat] = materials_used[mat] / multiplier
|
||||
new_item.autoylathe_crafted(src)
|
||||
icon_state = "autolathe"
|
||||
busy = FALSE
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/autoylathe/RefreshParts()
|
||||
var/T = 0
|
||||
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
|
||||
T += MB.rating*75000
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.max_amount = T
|
||||
T=1.2
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
T -= M.rating*0.2
|
||||
prod_coeff = CLAMP(T,1,0) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
|
||||
|
||||
/obj/machinery/autoylathe/proc/main_win(mob/user)
|
||||
var/dat = "<div class='statusDisplay'><h3>Autoylathe Menu:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
dat += "<form name='search' action='?src=[REF(src)]'>\
|
||||
<input type='hidden' name='src' value='[REF(src)]'>\
|
||||
<input type='hidden' name='search' value='to_search'>\
|
||||
<input type='hidden' name='menu' value='[AUTOYLATHE_SEARCH_MENU]'>\
|
||||
<input type='text' name='to_search'>\
|
||||
<input type='submit' value='Search'>\
|
||||
</form><hr>"
|
||||
|
||||
var/line_length = 1
|
||||
dat += "<table style='width:100%' align='center'><tr>"
|
||||
|
||||
for(var/C in categories)
|
||||
if(line_length > 2)
|
||||
dat += "</tr><tr>"
|
||||
line_length = 1
|
||||
|
||||
dat += "<td><A href='?src=[REF(src)];category=[C];menu=[AUTOYLATHE_CATEGORY_MENU]'>[C]</A></td>"
|
||||
line_length++
|
||||
|
||||
dat += "</tr></table></div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autoylathe/proc/category_win(mob/user,selected_category)
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[AUTOYLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(!(selected_category in D.category))
|
||||
continue
|
||||
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS] ?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY,D.materials[MAT_PLASTIC] ?round(materials.amount(MAT_PLASTIC)/D.materials[MAT_PLASTIC]):INFINITY)
|
||||
if (max_multiplier>10 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
if (max_multiplier>25 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=25'>x25</a>"
|
||||
if(max_multiplier > 0 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
else
|
||||
if(!disabled && can_build(D, 5))
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=5'>x5</a>"
|
||||
if(!disabled && can_build(D, 10))
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autoylathe/proc/search_win(mob/user)
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[AUTOYLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Search results:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
for(var/v in matching_designs)
|
||||
var/datum/design/D = v
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS] ?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY,D.materials[MAT_PLASTIC] ?round(materials.amount(MAT_PLASTIC)/D.materials[MAT_PLASTIC]):INFINITY)
|
||||
if (max_multiplier>10 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
if (max_multiplier>25 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=25'>x25</a>"
|
||||
if(max_multiplier > 0 && !disabled)
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autoylathe/proc/materials_printout()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/dat = "<b>Total amount:</b> [materials.total_amount] / [materials.max_amount] cm<sup>3</sup><br>"
|
||||
for(var/mat_id in materials.materials)
|
||||
var/datum/material/M = materials.materials[mat_id]
|
||||
dat += "<b>[M.name] amount:</b> [M.amount] cm<sup>3</sup><br>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autoylathe/proc/can_build(datum/design/D, amount = 1)
|
||||
if(D.make_reagents.len)
|
||||
return FALSE
|
||||
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
|
||||
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount)))
|
||||
return FALSE
|
||||
if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount)))
|
||||
return FALSE
|
||||
if(D.materials[MAT_PLASTIC] && (materials.amount(MAT_PLASTIC) < (D.materials[MAT_PLASTIC] * coeff * amount)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/autoylathe/proc/get_design_cost(datum/design/D)
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
|
||||
var/dat
|
||||
if(D.materials[MAT_METAL])
|
||||
dat += "[D.materials[MAT_METAL] * coeff] metal "
|
||||
if(D.materials[MAT_GLASS])
|
||||
dat += "[D.materials[MAT_GLASS] * coeff] glass "
|
||||
if(D.materials[MAT_PLASTIC])
|
||||
dat += "[D.materials[MAT_PLASTIC] * coeff] plastic"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autoylathe/proc/reset(wire)
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
if(!wires.is_cut(wire))
|
||||
adjust_hacked(FALSE)
|
||||
if(WIRE_SHOCK)
|
||||
if(!wires.is_cut(wire))
|
||||
shocked = FALSE
|
||||
if(WIRE_DISABLE)
|
||||
if(!wires.is_cut(wire))
|
||||
disabled = FALSE
|
||||
|
||||
/obj/machinery/autoylathe/proc/shock(mob/user, prb)
|
||||
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
return FALSE
|
||||
if(!prob(prb))
|
||||
return FALSE
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if (electrocute_mob(user, get_area(src), src, 0.7, TRUE))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/autoylathe/proc/adjust_hacked(state)
|
||||
hacked = state
|
||||
for(var/id in SSresearch.techweb_designs)
|
||||
var/datum/design/D = SSresearch.techweb_designs[id]
|
||||
if((D.build_type & AUTOYLATHE) && ("hacked" in D.category))
|
||||
if(hacked)
|
||||
stored_research.add_design(D)
|
||||
else
|
||||
stored_research.remove_design(D)
|
||||
|
||||
/obj/machinery/autoylathe/hacked/Initialize()
|
||||
. = ..()
|
||||
adjust_hacked(TRUE)
|
||||
|
||||
//Called when the object is constructed by an autoylathe
|
||||
//Has a reference to the autoylathe so you can do !!FUN!! things with hacked lathes
|
||||
/obj/item/proc/autoylathe_crafted(obj/machinery/autoylathe/A)
|
||||
return
|
||||
@@ -191,11 +191,11 @@
|
||||
if(!R || !patient || !SG || !(SG in chassis.equipment))
|
||||
return 0
|
||||
var/to_inject = min(R.volume, inject_amount)
|
||||
if(to_inject && patient.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2)
|
||||
if(to_inject && patient.reagents.get_reagent_amount(R.type) + to_inject <= inject_amount*2)
|
||||
occupant_message("Injecting [patient] with [to_inject] units of [R.name].")
|
||||
log_message("Injecting [patient] with [to_inject] units of [R.name].")
|
||||
log_combat(chassis.occupant, patient, "injected", "[name] ([R] - [to_inject] units)")
|
||||
SG.reagents.trans_id_to(patient,R.id,to_inject)
|
||||
SG.reagents.trans_id_to(patient,R.type,to_inject)
|
||||
update_equip_info()
|
||||
return
|
||||
|
||||
@@ -228,8 +228,8 @@
|
||||
M.AdjustStun(-80)
|
||||
M.AdjustKnockdown(-80)
|
||||
M.AdjustUnconscious(-80)
|
||||
if(M.reagents.get_reagent_amount("epinephrine") < 5)
|
||||
M.reagents.add_reagent("epinephrine", 5)
|
||||
if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5)
|
||||
M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5)
|
||||
chassis.use_power(energy_drain)
|
||||
update_equip_info()
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
. = ..()
|
||||
create_reagents(max_volume, NO_REACT)
|
||||
syringes = new
|
||||
known_reagents = list("epinephrine"="Epinephrine","charcoal"="Charcoal")
|
||||
known_reagents = list(/datum/reagent/medicine/epinephrine = "Epinephrine", /datum/reagent/medicine/charcoal = "Charcoal")
|
||||
processed_reagents = new
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach()
|
||||
@@ -330,8 +330,7 @@
|
||||
if(M.can_inject(null, 1))
|
||||
if(mechsyringe.reagents)
|
||||
for(var/datum/reagent/A in mechsyringe.reagents.reagent_list)
|
||||
R += A.id + " ("
|
||||
R += num2text(A.volume) + "),"
|
||||
R += "[A.name] ([num2text(A.volume)]"
|
||||
mechsyringe.icon_state = initial(mechsyringe.icon_state)
|
||||
mechsyringe.icon = initial(mechsyringe.icon)
|
||||
mechsyringe.reagents.reaction(M, INJECT)
|
||||
@@ -445,7 +444,7 @@
|
||||
var/output
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.volume > 0)
|
||||
output += "[R]: [round(R.volume,0.001)] - <a href=\"?src=[REF(src)];purge_reagent=[R.id]\">Purge Reagent</a><br />"
|
||||
output += "[R]: [round(R.volume,0.001)] - <a href=\"?src=[REF(src)];purge_reagent=[R.type]\">Purge Reagent</a><br />"
|
||||
if(output)
|
||||
output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - <a href=\"?src=[REF(src)];purge_all=1\">Purge All</a>"
|
||||
return output || "None"
|
||||
@@ -481,7 +480,7 @@
|
||||
return 0
|
||||
occupant_message("Analyzing reagents...")
|
||||
for(var/datum/reagent/R in A.reagents.reagent_list)
|
||||
if(R.can_synth && add_known_reagent(R.id,R.name))
|
||||
if(R.can_synth && add_known_reagent(R.type,R.name))
|
||||
occupant_message("Reagent analyzed, identified as [R.name] and added to database.")
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
occupant_message("Analyzis complete.")
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize()
|
||||
. = ..()
|
||||
create_reagents(1000)
|
||||
reagents.add_reagent("water", 1000)
|
||||
reagents.add_reagent(/datum/reagent/water, 1000)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch.
|
||||
if(!action_checks(target) || get_dist(chassis, target)>3)
|
||||
@@ -262,14 +262,14 @@
|
||||
occupant_message("Deconstructing [W]...")
|
||||
if(do_after_cooldown(W))
|
||||
chassis.spark_system.start()
|
||||
W.ScrapeAway()
|
||||
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(W, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
else if(isfloorturf(target))
|
||||
var/turf/open/floor/F = target
|
||||
occupant_message("Deconstructing [F]...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
F.ScrapeAway()
|
||||
F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(F, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
else if (istype(target, /obj/machinery/door/airlock))
|
||||
occupant_message("Deconstructing [target]...")
|
||||
@@ -282,7 +282,7 @@
|
||||
var/turf/open/space/S = target
|
||||
occupant_message("Building Floor...")
|
||||
if(do_after_cooldown(S))
|
||||
S.PlaceOnTop(/turf/open/floor/plating)
|
||||
S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(S, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
else if(isfloorturf(target))
|
||||
|
||||
@@ -286,10 +286,10 @@
|
||||
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
|
||||
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
|
||||
if(target.reagents)
|
||||
if(target.reagents.get_reagent_amount("cryptobiolin") + force < force*2)
|
||||
target.reagents.add_reagent("cryptobiolin", force/2)
|
||||
if(target.reagents.get_reagent_amount("toxin") + force < force*2)
|
||||
target.reagents.add_reagent("toxin", force/2.5)
|
||||
if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2)
|
||||
target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2)
|
||||
if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2)
|
||||
target.reagents.add_reagent(/datum/reagent/toxin, force/2.5)
|
||||
|
||||
|
||||
/obj/mecha/mech_melee_attack(obj/mecha/M)
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
|
||||
//Wrapper procs that handle sanity and user feedback
|
||||
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
|
||||
if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored)
|
||||
if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored || !user.can_buckle_others(M, src))
|
||||
return FALSE
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/xeno
|
||||
color = BLOOD_COLOR_XENO
|
||||
gibs_reagent_id = "liquidxenogibs"
|
||||
gibs_reagent_id = /datum/reagent/liquidgibs/xeno
|
||||
gibs_bloodtype = "X*"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/xeno/Initialize(mapload, list/datum/disease/diseases)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
|
||||
mergeable_decal = FALSE
|
||||
var/body_colors = "#e3ba84" //a default color just in case.
|
||||
var/gibs_reagent_id = "liquidgibs"
|
||||
var/gibs_reagent_id = /datum/reagent/liquidgibs
|
||||
var/gibs_bloodtype = "A+"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
|
||||
@@ -120,7 +120,6 @@
|
||||
//Lizards
|
||||
/obj/effect/decal/cleanable/blood/gibs/human/lizard
|
||||
body_colors = "117720"
|
||||
gibs_reagent_id = "liquidgibs"
|
||||
gibs_bloodtype = "L"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/human/lizard/Initialize(mapload, list/datum/disease/diseases)
|
||||
@@ -148,7 +147,7 @@
|
||||
// Slime Gibs
|
||||
/obj/effect/decal/cleanable/blood/gibs/slime
|
||||
desc = "They look gooey and gruesome."
|
||||
gibs_reagent_id = "liquidslimegibs"
|
||||
gibs_reagent_id = /datum/reagent/liquidgibs/slime
|
||||
gibs_bloodtype = "GEL"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/slime/Initialize(mapload, list/datum/disease/diseases)
|
||||
@@ -187,7 +186,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/synth
|
||||
desc = "They look sludgy and disgusting."
|
||||
gibs_reagent_id = "liquidsyntheticgibs"
|
||||
gibs_reagent_id = /datum/reagent/liquidgibs/synth
|
||||
gibs_bloodtype = "SY"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/synth/Initialize(mapload, list/datum/disease/diseases)
|
||||
@@ -198,7 +197,7 @@
|
||||
/obj/effect/decal/cleanable/blood/gibs/ipc
|
||||
desc = "They look sharp yet oozing."
|
||||
body_colors = "00ff00"
|
||||
gibs_reagent_id = "liquidoilgibs"
|
||||
gibs_reagent_id = /datum/reagent/liquidgibs/oil
|
||||
gibs_bloodtype = "HF"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/ipc/Initialize(mapload, list/datum/disease/diseases)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/ash/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("ash", 30)
|
||||
reagents.add_reagent(/datum/reagent/ash, 30)
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/ash/large/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("ash", 30) //double the amount of ash.
|
||||
reagents.add_reagent(/datum/reagent/ash, 30) //double the amount of ash.
|
||||
|
||||
/obj/effect/decal/cleanable/glass
|
||||
name = "tiny shards"
|
||||
@@ -131,12 +131,10 @@
|
||||
playsound(get_turf(src), 'sound/items/drink.ogg', 50, 1) //slurp
|
||||
H.visible_message("<span class='alert'>[H] extends a small proboscis into the vomit pool, sucking it with a slurping sound.</span>")
|
||||
if(reagents)
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if (istype(R, /datum/reagent/consumable))
|
||||
var/datum/reagent/consumable/nutri_check = R
|
||||
if(nutri_check.nutriment_factor >0)
|
||||
H.nutrition += nutri_check.nutriment_factor * nutri_check.volume
|
||||
reagents.remove_reagent(nutri_check.id,nutri_check.volume)
|
||||
for(var/datum/reagent/consumable/R in reagents.reagent_list)
|
||||
if(R.nutriment_factor > 0)
|
||||
H.nutrition += R.nutriment_factor * R.volume
|
||||
reagents.del_reagent(R.type)
|
||||
reagents.trans_to(H, reagents.total_volume)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
|
||||
. = ..()
|
||||
reagents.add_reagent("liquidoilgibs", 5)
|
||||
reagents.add_reagent(/datum/reagent/liquidgibs, 5)
|
||||
|
||||
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
|
||||
set waitfor = 0
|
||||
@@ -53,8 +53,8 @@
|
||||
|
||||
/obj/effect/decal/cleanable/oil/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("oil", 30)
|
||||
reagents.add_reagent("liquidoilgibs", 5)
|
||||
reagents.add_reagent(/datum/reagent/oil, 30)
|
||||
reagents.add_reagent(/datum/reagent/liquidgibs/oil, 5)
|
||||
|
||||
/obj/effect/decal/cleanable/oil/streak
|
||||
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src))
|
||||
if(!P)
|
||||
P = new(loc)
|
||||
P.reagents.add_reagent("stable_plasma", absorbed_plasma)
|
||||
P.reagents.add_reagent(/datum/reagent/stable_plasma, absorbed_plasma)
|
||||
|
||||
flick("[icon_state]-disolve", src)
|
||||
QDEL_IN(src, 5)
|
||||
@@ -123,7 +123,7 @@
|
||||
if(metal)
|
||||
var/turf/T = get_turf(src)
|
||||
if(isspaceturf(T)) //Block up any exposed space
|
||||
T.PlaceOnTop(/turf/open/floor/plating/foam)
|
||||
T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR)
|
||||
for(var/direction in GLOB.cardinals)
|
||||
var/turf/cardinal_turf = get_step(T, direction)
|
||||
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
|
||||
|
||||
@@ -435,7 +435,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
|
||||
//------Station Rooms Landmarks------------//
|
||||
/obj/effect/landmark/stationroom
|
||||
var/list/template_names = list()
|
||||
var/list/templates = list()
|
||||
layer = BULLET_HOLE_LAYER
|
||||
|
||||
/obj/effect/landmark/stationroom/New()
|
||||
@@ -452,11 +452,11 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
if(!T)
|
||||
return FALSE
|
||||
if(!template_name)
|
||||
for(var/t in template_names)
|
||||
for(var/t in templates)
|
||||
if(!SSmapping.station_room_templates[t])
|
||||
log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list")
|
||||
template_names -= t
|
||||
template_name = safepick(template_names)
|
||||
templates -= t
|
||||
template_name = pickweight(templates)
|
||||
if(!template_name)
|
||||
GLOB.stationroom_landmarks -= src
|
||||
qdel(src)
|
||||
@@ -474,10 +474,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
// The landmark for the Engine on Box
|
||||
|
||||
/obj/effect/landmark/stationroom/box/engine
|
||||
template_names = list("Engine SM", "Engine Singulo", "Engine Tesla")
|
||||
templates = list("Engine SM" = 3, "Engine Singulo" = 3, "Engine Tesla" = 3)
|
||||
icon = 'icons/rooms/box/engine.dmi'
|
||||
|
||||
|
||||
/obj/effect/landmark/stationroom/box/engine/New()
|
||||
. = ..()
|
||||
template_names = CONFIG_GET(keyed_list/box_random_engine)
|
||||
templates = CONFIG_GET(keyed_list/box_random_engine)
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
victim.put_in_hands(chainsaw, forced = TRUE)
|
||||
chainsaw.attack_self(victim)
|
||||
chainsaw.wield(victim)
|
||||
victim.reagents.add_reagent("adminordrazine",25)
|
||||
victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
|
||||
to_chat(victim, "<span class='warning'>KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!</span>")
|
||||
|
||||
victim.client.color = pure_red
|
||||
|
||||
@@ -52,7 +52,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
var/interaction_flags_item = INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
//Citadel Edit for digitigrade stuff
|
||||
var/mutantrace_variation = NO_MUTANTRACE_VARIATION //Are there special sprites for specific situations? Don't use this unless you need to.
|
||||
var/mutantrace_variation = NONE //Are there special sprites for specific situations? Don't use this unless you need to.
|
||||
|
||||
var/item_color = null //this needs deprecating, soonish
|
||||
|
||||
@@ -578,21 +578,22 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
itempush = 0 //too light to push anything
|
||||
return A.hitby(src, 0, itempush)
|
||||
|
||||
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, messy_throw = TRUE)
|
||||
thrownby = thrower
|
||||
callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own
|
||||
callback = CALLBACK(src, .proc/after_throw, callback, (spin && messy_throw)) //replace their callback with our own
|
||||
. = ..(target, range, speed, thrower, spin, diagonals_first, callback)
|
||||
|
||||
/obj/item/proc/after_throw(datum/callback/callback)
|
||||
/obj/item/proc/after_throw(datum/callback/callback, messy_throw)
|
||||
if (callback) //call the original callback
|
||||
. = callback.Invoke()
|
||||
throw_speed = initial(throw_speed) //explosions change this.
|
||||
item_flags &= ~IN_INVENTORY
|
||||
var/matrix/M = matrix(transform)
|
||||
M.Turn(rand(-170, 170))
|
||||
transform = M
|
||||
pixel_x = rand(-8, 8)
|
||||
pixel_y = rand(-8, 8)
|
||||
if(messy_throw)
|
||||
var/matrix/M = matrix(transform)
|
||||
M.Turn(rand(-170, 170))
|
||||
transform = M
|
||||
pixel_x = rand(-8, 8)
|
||||
pixel_y = rand(-8, 8)
|
||||
|
||||
/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/storage
|
||||
if(!newLoc)
|
||||
|
||||
@@ -182,7 +182,7 @@ RSF
|
||||
to_chat(user, "Fabricating Cookie..")
|
||||
var/obj/item/reagent_containers/food/snacks/cookie/S = new /obj/item/reagent_containers/food/snacks/cookie(T)
|
||||
if(toxin)
|
||||
S.reagents.add_reagent("chloralhydrate", 10)
|
||||
S.reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 10)
|
||||
if (iscyborg(user))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
R.cell.charge -= 100
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
// make some colorful reagent, and apply it to the lungs
|
||||
L.create_reagents(10)
|
||||
L.reagents.add_reagent("colorful_reagent", 10)
|
||||
L.reagents.add_reagent(/datum/reagent/colorful_reagent, 10)
|
||||
L.reagents.reaction(L, TOUCH, 1)
|
||||
|
||||
// TODO maybe add some colorful vomit?
|
||||
@@ -81,7 +81,7 @@
|
||||
return (TOXLOSS|OXYLOSS)
|
||||
else if(can_use(user) && !L)
|
||||
user.visible_message("<span class='suicide'>[user] is spraying toner on [user.p_them()]self from [src]! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
user.reagents.add_reagent("colorful_reagent", 1)
|
||||
user.reagents.add_reagent(/datum/reagent/colorful_reagent, 1)
|
||||
user.reagents.reaction(user, TOUCH, 1)
|
||||
return TOXLOSS
|
||||
|
||||
|
||||
@@ -120,4 +120,4 @@
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=50)
|
||||
grind_results = list("iron" = 10, "silicon" = 10)
|
||||
grind_results = list(/datum/reagent/iron = 10, /datum/reagent/silicon = 10)
|
||||
|
||||
@@ -25,7 +25,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
var/smoketime = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
heat = 1000
|
||||
grind_results = list("phosphorus" = 2)
|
||||
grind_results = list(/datum/reagent/phosphorus = 2)
|
||||
|
||||
/obj/item/match/process()
|
||||
smoketime--
|
||||
@@ -113,7 +113,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
var/lastHolder = null
|
||||
var/smoketime = 300
|
||||
var/chem_volume = 30
|
||||
var/list/list_reagents = list("nicotine" = 15)
|
||||
var/list/list_reagents = list(/datum/reagent/drug/nicotine = 15)
|
||||
heat = 1000
|
||||
|
||||
/obj/item/clothing/mask/cigarette/suicide_act(mob/user)
|
||||
@@ -169,15 +169,15 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
hitsound = 'sound/items/welder.ogg'
|
||||
damtype = "fire"
|
||||
force = 4
|
||||
if(reagents.get_reagent_amount("plasma")) // the plasma explodes when exposed to fire
|
||||
if(reagents.get_reagent_amount(/datum/reagent/toxin/plasma)) // the plasma explodes when exposed to fire
|
||||
var/datum/effect_system/reagents_explosion/e = new()
|
||||
e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0)
|
||||
e.set_up(round(reagents.get_reagent_amount(/datum/reagent/toxin/plasma) / 2.5, 1), get_turf(src), 0, 0)
|
||||
e.start()
|
||||
qdel(src)
|
||||
return
|
||||
if(reagents.get_reagent_amount("welding_fuel")) // the fuel explodes, too, but much less violently
|
||||
if(reagents.get_reagent_amount(/datum/reagent/fuel)) // the fuel explodes, too, but much less violently
|
||||
var/datum/effect_system/reagents_explosion/e = new()
|
||||
e.set_up(round(reagents.get_reagent_amount("welding_fuel") / 5, 1), get_turf(src), 0, 0)
|
||||
e.set_up(round(reagents.get_reagent_amount(/datum/reagent/fuel) / 5, 1), get_turf(src), 0, 0)
|
||||
e.start()
|
||||
qdel(src)
|
||||
return
|
||||
@@ -268,29 +268,29 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
|
||||
/obj/item/clothing/mask/cigarette/uplift
|
||||
desc = "An Uplift Smooth brand cigarette."
|
||||
list_reagents = list("nicotine" = 7.5, "menthol" = 7.5)
|
||||
list_reagents = list(/datum/reagent/drug/nicotine = 7.5, /datum/reagent/consumable/menthol = 7.5)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/robust
|
||||
desc = "A Robust brand cigarette."
|
||||
|
||||
/obj/item/clothing/mask/cigarette/robustgold
|
||||
desc = "A Robust Gold brand cigarette."
|
||||
list_reagents = list("nicotine" = 15, "gold" = 1)
|
||||
list_reagents = list(/datum/reagent/drug/nicotine = 15, /datum/reagent/gold = 1)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/carp
|
||||
desc = "A Carp Classic brand cigarette."
|
||||
|
||||
/obj/item/clothing/mask/cigarette/syndicate
|
||||
desc = "An unknown brand cigarette."
|
||||
list_reagents = list("nicotine" = 15, "omnizine" = 15)
|
||||
list_reagents = list(/datum/reagent/drug/nicotine = 15, /datum/reagent/medicine/omnizine = 15)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/shadyjims
|
||||
desc = "A Shady Jim's Super Slims cigarette."
|
||||
list_reagents = list("nicotine" = 15, "lipolicide" = 4, "ammonia" = 2, "plantbgone" = 1, "toxin" = 1.5)
|
||||
list_reagents = list(/datum/reagent/drug/nicotine = 15, /datum/reagent/toxin/lipolicide = 4, /datum/reagent/ammonia = 2, /datum/reagent/toxin/plantbgone = 1, /datum/reagent/toxin = 1.5)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/xeno
|
||||
desc = "A Xeno Filtered brand cigarette."
|
||||
list_reagents = list ("nicotine" = 20, "regen_jelly" = 15, "krokodil" = 4)
|
||||
list_reagents = list (/datum/reagent/drug/nicotine = 20, /datum/reagent/medicine/regen_jelly = 15, /datum/reagent/drug/krokodil = 4)
|
||||
|
||||
// Rollies.
|
||||
|
||||
@@ -313,17 +313,17 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
src.pixel_y = rand(-5, 5)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/rollie/nicotine
|
||||
list_reagents = list("nicotine" = 15)
|
||||
list_reagents = list(/datum/reagent/drug/nicotine = 15)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/rollie/trippy
|
||||
list_reagents = list("nicotine" = 15, "mushroomhallucinogen" = 35)
|
||||
list_reagents = list(/datum/reagent/drug/nicotine = 15, /datum/reagent/drug/mushroomhallucinogen = 35)
|
||||
starts_lit = TRUE
|
||||
|
||||
/obj/item/clothing/mask/cigarette/rollie/cannabis
|
||||
list_reagents = list("space_drugs" = 15, "lipolicide" = 35)
|
||||
list_reagents = list(/datum/reagent/drug/space_drugs = 15, /datum/reagent/toxin/lipolicide = 35)
|
||||
|
||||
/obj/item/clothing/mask/cigarette/rollie/mindbreaker
|
||||
list_reagents = list("mindbreaker" = 35, "lipolicide" = 15)
|
||||
list_reagents = list(/datum/reagent/toxin/mindbreaker = 35, /datum/reagent/toxin/lipolicide = 15)
|
||||
|
||||
/obj/item/cigbutt/roach
|
||||
name = "roach"
|
||||
@@ -377,7 +377,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
icon_state = "cigbutt"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throwforce = 0
|
||||
grind_results = list("carbon" = 2)
|
||||
grind_results = list(/datum/reagent/carbon = 2)
|
||||
|
||||
/obj/item/cigbutt/cigarbutt
|
||||
name = "cigar butt"
|
||||
@@ -506,7 +506,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
heat = 1500
|
||||
resistance_flags = FIRE_PROOF
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
grind_results = list("iron" = 1, "welding_fuel" = 5, "oil" = 5)
|
||||
grind_results = list(/datum/reagent/iron = 1, /datum/reagent/fuel = 5, /datum/reagent/oil = 5)
|
||||
|
||||
/obj/item/lighter/Initialize()
|
||||
. = ..()
|
||||
@@ -665,7 +665,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
heat = 3000 //Blue flame!
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
overlay_state = "slime"
|
||||
grind_results = list("iron" = 1, "welding_fuel" = 5, "pyroxadone" = 5)
|
||||
grind_results = list(/datum/reagent/iron = 1, /datum/reagent/fuel = 5, /datum/reagent/medicine/pyroxadone = 5)
|
||||
|
||||
|
||||
///////////
|
||||
@@ -719,7 +719,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
|
||||
. = ..()
|
||||
create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
|
||||
reagents.add_reagent("nicotine", 50)
|
||||
reagents.add_reagent(/datum/reagent/drug/nicotine, 50)
|
||||
if(!icon_state)
|
||||
if(!param_color)
|
||||
param_color = pick("red","blue","black","white","green","purple","yellow","orange")
|
||||
@@ -810,14 +810,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
reagents.reaction(C, INGEST, fraction)
|
||||
if(!reagents.trans_to(C, REAGENTS_METABOLISM))
|
||||
reagents.remove_any(REAGENTS_METABOLISM)
|
||||
if(reagents.get_reagent_amount("welding_fuel"))
|
||||
if(reagents.get_reagent_amount(/datum/reagent/fuel))
|
||||
//HOT STUFF
|
||||
C.fire_stacks = 2
|
||||
C.IgniteMob()
|
||||
|
||||
if(reagents.get_reagent_amount("plasma")) // the plasma explodes when exposed to fire
|
||||
if(reagents.get_reagent_amount(/datum/reagent/toxin/plasma)) // the plasma explodes when exposed to fire
|
||||
var/datum/effect_system/reagents_explosion/e = new()
|
||||
e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0)
|
||||
e.set_up(round(reagents.get_reagent_amount(/datum/reagent/toxin/plasma) / 2.5, 1), get_turf(src), 0, 0)
|
||||
e.start()
|
||||
qdel(src)
|
||||
return
|
||||
@@ -863,3 +863,205 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
|
||||
if(reagents && reagents.total_volume)
|
||||
hand_reagents()
|
||||
|
||||
///////////////
|
||||
/////BONGS/////
|
||||
///////////////
|
||||
|
||||
/obj/item/bong
|
||||
name = "bong"
|
||||
desc = "A water bong used for smoking dried plants."
|
||||
icon = 'icons/obj/bongs.dmi'
|
||||
icon_state = null
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
light_color = "#FFCC66"
|
||||
var/icon_off = "bong"
|
||||
var/icon_on = "bong_lit"
|
||||
var/chem_volume = 100
|
||||
var/last_used_time //for cooldown
|
||||
var/firecharges = 0 //used for counting how many hits can be taken before the flame goes out
|
||||
var/list/list_reagents = list() //For the base reagents bongs could get
|
||||
|
||||
|
||||
/obj/item/bong/Initialize()
|
||||
. = ..()
|
||||
create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
|
||||
reagents.add_reagent_list(list_reagents)
|
||||
icon_state = icon_off
|
||||
|
||||
/obj/item/bong/attackby(obj/item/O, mob/user, params)
|
||||
. = ..()
|
||||
//If we're using a dried plant..
|
||||
if(istype(O,/obj/item/reagent_containers/food/snacks))
|
||||
var/obj/item/reagent_containers/food/snacks/DP = O
|
||||
if (DP.dry)
|
||||
//Nothing if our bong is full
|
||||
if (reagents.holder_full())
|
||||
user.show_message("<span class='notice'>The bowl is full!</span>", MSG_VISUAL)
|
||||
return
|
||||
|
||||
//Transfer reagents and remove the plant
|
||||
user.show_message("<span class='notice'>You stuff the [DP] into the [src]'s bowl.</span>", MSG_VISUAL)
|
||||
DP.reagents.trans_to(src, 100)
|
||||
qdel(DP)
|
||||
return
|
||||
else
|
||||
user.show_message("<span class='warning'>[DP] must be dried first!</span>", MSG_VISUAL)
|
||||
return
|
||||
|
||||
if (O.get_temperature() <= 500)
|
||||
return
|
||||
if (reagents && reagents.total_volume) //if there's stuff in the bong
|
||||
var/lighting_text = O.ignition_effect(src, user)
|
||||
if(lighting_text)
|
||||
//Logic regarding igniting it on
|
||||
if (firecharges == 0)
|
||||
user.show_message("<span class='notice'>You light the [src] with the [O]!</span>", MSG_VISUAL)
|
||||
bongturnon()
|
||||
else
|
||||
user.show_message("<span class='notice'>You rekindle [src]'s flame with the [O]!</span>", MSG_VISUAL)
|
||||
|
||||
firecharges = 1
|
||||
return
|
||||
else
|
||||
user.show_message("<span warning='notice'>There's nothing to light up in the bowl.</span>", MSG_VISUAL)
|
||||
return
|
||||
|
||||
/obj/item/bong/CtrlShiftClick(mob/user) //empty reagents on alt click
|
||||
..()
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
|
||||
if (reagents && reagents.total_volume)
|
||||
user.show_message("<span class='notice'>You empty the [src].</span>", MSG_VISUAL)
|
||||
reagents.clear_reagents()
|
||||
if(firecharges)
|
||||
firecharges = 0
|
||||
bongturnoff()
|
||||
else
|
||||
user.show_message("<span class='notice'>The [src] is already empty.</span>", MSG_VISUAL)
|
||||
|
||||
/obj/item/bong/AltClick(mob/user)
|
||||
..()
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
|
||||
if(firecharges)
|
||||
firecharges = 0
|
||||
bongturnoff()
|
||||
user.show_message("<span class='notice'>You quench the flame.</span>", MSG_VISUAL)
|
||||
return TRUE
|
||||
|
||||
/obj/item/bong/examine(mob/user)
|
||||
. = ..()
|
||||
if(!reagents.total_volume)
|
||||
. += "<span class='notice'>The bowl is empty.</span>"
|
||||
else if (reagents.total_volume > 80)
|
||||
. += "<span class='notice'>The bowl is filled to the brim.</span>"
|
||||
else if (reagents.total_volume > 40)
|
||||
. += "<span class='notice'>The bowl has plenty weed in it.</span>"
|
||||
else
|
||||
. += "<span class='notice'>The bowl has some weed in it.</span>"
|
||||
|
||||
. += "<span class='notice'>Ctrl+Shift-click to empty.</span>"
|
||||
. += "<span class='notice'>Alt-click to extinguish.</span>"
|
||||
|
||||
/obj/item/bong/ignition_effect(atom/A, mob/user)
|
||||
if(firecharges)
|
||||
. = "<span class='notice'>[user] lights [A] off of the [src].</span>"
|
||||
else
|
||||
. = ""
|
||||
|
||||
/obj/item/bong/attack(mob/living/carbon/M, mob/living/carbon/user, obj/target)
|
||||
//if it's lit up, some stuff in the bowl and the user is a target, and we're not on cooldown
|
||||
|
||||
if (M != user)
|
||||
return ..()
|
||||
|
||||
if(user.is_mouth_covered(head_only = 1))
|
||||
to_chat(user, "<span class='warning'>Remove your headgear first.</span>")
|
||||
return ..()
|
||||
|
||||
if(user.is_mouth_covered(mask_only = 1))
|
||||
to_chat(user, "<span class='warning'>Remove your mask first.</span>")
|
||||
return ..()
|
||||
|
||||
if (!reagents.total_volume)
|
||||
to_chat(user, "<span class='warning'>There's nothing in the bowl.</span>")
|
||||
return ..()
|
||||
|
||||
if (!firecharges)
|
||||
to_chat(user, "<span class='warning'>You have to light it up first.</span>")
|
||||
return ..()
|
||||
|
||||
if (last_used_time + 30 >= world.time)
|
||||
return ..()
|
||||
var/hit_strength
|
||||
var/noise
|
||||
var/hittext = ""
|
||||
//if the intent is help then you take a small hit, else a big one
|
||||
if (user.a_intent == INTENT_HARM)
|
||||
hit_strength = 2
|
||||
noise = 100
|
||||
hittext = "big hit"
|
||||
else
|
||||
hit_strength = 1
|
||||
noise = 70
|
||||
hittext = "hit"
|
||||
//bubbling sound
|
||||
playsound(user.loc,'sound/effects/bonghit.ogg', noise, 1)
|
||||
|
||||
last_used_time = world.time
|
||||
|
||||
//message
|
||||
user.visible_message("<span class='notice'>[user] begins to take a [hittext] from the [src]!</span>", \
|
||||
"<span class='notice'>You begin to take a [hittext] from [src].</span>")
|
||||
|
||||
//we take a hit here, after an uninterrupted delay
|
||||
if(!do_after(user, 25, target = user))
|
||||
return
|
||||
if (!(reagents && reagents.total_volume))
|
||||
return
|
||||
|
||||
var/fraction = 12 * hit_strength
|
||||
|
||||
var/datum/effect_system/smoke_spread/chem/smoke_machine/s = new
|
||||
s.set_up(reagents, hit_strength, 18, user.loc)
|
||||
s.start()
|
||||
|
||||
reagents.reaction(user, INGEST, fraction)
|
||||
if(!reagents.trans_to(user, fraction))
|
||||
reagents.remove_any(fraction)
|
||||
|
||||
if (hit_strength == 2 && prob(15))
|
||||
user.emote("cough")
|
||||
user.adjustOxyLoss(15)
|
||||
|
||||
user.visible_message("<span class='notice'>[user] takes a [hittext] from the [src]!</span>", \
|
||||
"<span class='notice'>You take a [hittext] from [src].</span>")
|
||||
|
||||
firecharges = firecharges - 1
|
||||
if (!firecharges)
|
||||
bongturnoff()
|
||||
if (!reagents.total_volume)
|
||||
firecharges = 0
|
||||
bongturnoff()
|
||||
|
||||
|
||||
|
||||
/obj/item/bong/proc/bongturnon()
|
||||
icon_state = icon_on
|
||||
set_light(3, 0.8)
|
||||
|
||||
/obj/item/bong/proc/bongturnoff()
|
||||
icon_state = icon_off
|
||||
set_light(0, 0.0)
|
||||
|
||||
|
||||
|
||||
/obj/item/bong/coconut
|
||||
name = "coconut bong"
|
||||
icon_off = "coconut_bong"
|
||||
icon_on = "coconut_bong_lit"
|
||||
desc = "A water bong used for smoking dried plants. This one's made out of a coconut and some bamboo."
|
||||
@@ -12,7 +12,7 @@
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
materials = list(MAT_GLASS=1000)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
grind_results = list("silicon" = 20)
|
||||
grind_results = list(/datum/reagent/silicon = 20)
|
||||
var/build_path = null
|
||||
|
||||
/obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M)
|
||||
|
||||
@@ -260,9 +260,8 @@
|
||||
var/position = vending_names_paths.Find(build_path)
|
||||
position = (position == vending_names_paths.len) ? 1 : (position + 1)
|
||||
var/typepath = vending_names_paths[position]
|
||||
|
||||
to_chat(user, "<span class='notice'>You set the board to \"[vending_names_paths[typepath]]\".</span>")
|
||||
set_type(typepath)
|
||||
to_chat(user, "<span class='notice'>You set the board to \"[vending_names_paths[typepath]]\".</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -1001,3 +1000,16 @@
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/reagent_containers/glass/beaker = 6) //So it can hold lots of chems
|
||||
|
||||
/obj/item/circuitboard/machine/kinkmate
|
||||
name = "Kinkmate Vendor (Machine Board)"
|
||||
build_path = /obj/machinery/vending/kink
|
||||
req_components = list(/obj/item/vending_refill/kink = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/autoylathe
|
||||
name = "Autoylathe (Machine Board)"
|
||||
build_path = /obj/machinery/autoylathe
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/matter_bin = 3,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
grind_results = list("lye" = 10)
|
||||
grind_results = list(/datum/reagent/lye = 10)
|
||||
var/cleanspeed = 50 //slower than mop
|
||||
force_string = "robust... against germs"
|
||||
|
||||
@@ -180,4 +180,4 @@
|
||||
name = "Canned Laughter"
|
||||
desc = "Just looking at this makes you want to giggle."
|
||||
icon_state = "laughter"
|
||||
list_reagents = list("laughter" = 50)
|
||||
list_reagents = list(/datum/reagent/consumable/laughter = 50)
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
var/edible = TRUE // That doesn't mean eating it is a good idea
|
||||
|
||||
var/list/reagent_contents = list("nutriment" = 1)
|
||||
var/list/reagent_contents = list(/datum/reagent/consumable/nutriment = 1)
|
||||
// If the user can toggle the colour, a la vanilla spraycan
|
||||
var/can_change_colour = FALSE
|
||||
|
||||
@@ -485,63 +485,63 @@
|
||||
icon_state = "crayonred"
|
||||
paint_color = "#DA0000"
|
||||
item_color = "red"
|
||||
reagent_contents = list("nutriment" = 1, "redcrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/red = 1)
|
||||
|
||||
/obj/item/toy/crayon/orange
|
||||
icon_state = "crayonorange"
|
||||
paint_color = "#FF9300"
|
||||
item_color = "orange"
|
||||
reagent_contents = list("nutriment" = 1, "orangecrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/orange = 1)
|
||||
|
||||
/obj/item/toy/crayon/yellow
|
||||
icon_state = "crayonyellow"
|
||||
paint_color = "#FFF200"
|
||||
item_color = "yellow"
|
||||
reagent_contents = list("nutriment" = 1, "yellowcrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/yellow = 1)
|
||||
|
||||
/obj/item/toy/crayon/green
|
||||
icon_state = "crayongreen"
|
||||
paint_color = "#A8E61D"
|
||||
item_color = "green"
|
||||
reagent_contents = list("nutriment" = 1, "greencrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/green = 1)
|
||||
|
||||
/obj/item/toy/crayon/blue
|
||||
icon_state = "crayonblue"
|
||||
paint_color = "#00B7EF"
|
||||
item_color = "blue"
|
||||
reagent_contents = list("nutriment" = 1, "bluecrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/blue = 1)
|
||||
|
||||
/obj/item/toy/crayon/purple
|
||||
icon_state = "crayonpurple"
|
||||
paint_color = "#DA00FF"
|
||||
item_color = "purple"
|
||||
reagent_contents = list("nutriment" = 1, "purplecrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/purple = 1)
|
||||
|
||||
/obj/item/toy/crayon/black
|
||||
icon_state = "crayonblack"
|
||||
paint_color = "#1C1C1C" //Not completely black because total black looks bad. So Mostly Black.
|
||||
item_color = "black"
|
||||
reagent_contents = list("nutriment" = 1, "blackcrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/black = 1)
|
||||
|
||||
/obj/item/toy/crayon/white
|
||||
icon_state = "crayonwhite"
|
||||
paint_color = "#FFFFFF"
|
||||
item_color = "white"
|
||||
reagent_contents = list("nutriment" = 1, "whitecrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/white = 1)
|
||||
|
||||
/obj/item/toy/crayon/mime
|
||||
icon_state = "crayonmime"
|
||||
desc = "A very sad-looking crayon."
|
||||
paint_color = "#FFFFFF"
|
||||
item_color = "mime"
|
||||
reagent_contents = list("nutriment" = 1, "invisiblecrayonpowder" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/invisible = 1)
|
||||
charges = -1
|
||||
|
||||
/obj/item/toy/crayon/rainbow
|
||||
icon_state = "crayonrainbow"
|
||||
paint_color = "#FFF000"
|
||||
item_color = "rainbow"
|
||||
reagent_contents = list("nutriment" = 1, "colorful_reagent" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent = 1)
|
||||
drawtype = RANDOM_ANY // just the default starter.
|
||||
|
||||
charges = -1
|
||||
@@ -621,7 +621,7 @@
|
||||
can_change_colour = TRUE
|
||||
gang = TRUE //Gang check is true for all things upon the honored hierarchy of spraycans, except those that are FALSE.
|
||||
|
||||
reagent_contents = list("welding_fuel" = 1, "ethanol" = 1)
|
||||
reagent_contents = list(/datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol = 1)
|
||||
|
||||
pre_noise = TRUE
|
||||
post_noise = FALSE
|
||||
@@ -778,7 +778,7 @@
|
||||
|
||||
volume_multiplier = 25
|
||||
charges = 100
|
||||
reagent_contents = list("clf3" = 1)
|
||||
reagent_contents = list(/datum/reagent/clf3 = 1)
|
||||
actually_paints = FALSE
|
||||
paint_color = "#000000"
|
||||
|
||||
@@ -791,7 +791,7 @@
|
||||
use_overlays = FALSE
|
||||
gang = FALSE
|
||||
|
||||
reagent_contents = list("lube" = 1, "banana" = 1)
|
||||
reagent_contents = list(/datum/reagent/lube = 1, /datum/reagent/consumable/banana = 1)
|
||||
volume_multiplier = 5
|
||||
|
||||
/obj/item/toy/crayon/spraycan/lubecan/isValidSurface(surface)
|
||||
@@ -811,7 +811,7 @@
|
||||
|
||||
pre_noise = FALSE
|
||||
post_noise = FALSE
|
||||
reagent_contents = list("nothing" = 1, "mutetoxin" = 1)
|
||||
reagent_contents = list(/datum/reagent/consumable/nothing = 1, /datum/reagent/toxin/mutetoxin = 1)
|
||||
|
||||
/obj/item/toy/crayon/spraycan/gang
|
||||
charges = 20 // Charges back to 20, which is the default value for them.
|
||||
|
||||
@@ -700,10 +700,10 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
U << browse(null, "window=pda")
|
||||
return
|
||||
|
||||
/obj/item/pda/proc/remove_id()
|
||||
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
/obj/item/pda/proc/remove_id(mob/user)
|
||||
if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
do_remove_id(usr)
|
||||
do_remove_id(user)
|
||||
|
||||
/obj/item/pda/proc/do_remove_id(mob/user)
|
||||
if(!id)
|
||||
@@ -827,23 +827,23 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
/obj/item/pda/proc/create_message(mob/living/U, obj/item/pda/P)
|
||||
send_message(U,list(P))
|
||||
|
||||
/obj/item/pda/AltClick()
|
||||
/obj/item/pda/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(id)
|
||||
remove_id()
|
||||
remove_id(user)
|
||||
playsound(src, 'sound/machines/terminal_eject_disc.ogg', 50, 1)
|
||||
else
|
||||
remove_pen()
|
||||
remove_pen(user)
|
||||
playsound(src, 'sound/machines/button4.ogg', 50, 1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/pda/CtrlClick()
|
||||
/obj/item/pda/CtrlClick(mob/user)
|
||||
..()
|
||||
|
||||
if(isturf(loc)) //stops the user from dragging the PDA by ctrl-clicking it.
|
||||
return
|
||||
|
||||
remove_pen()
|
||||
remove_pen(user)
|
||||
|
||||
/obj/item/pda/verb/verb_toggle_light()
|
||||
set category = "Object"
|
||||
@@ -857,7 +857,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
set src in usr
|
||||
|
||||
if(id)
|
||||
remove_id()
|
||||
remove_id(usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This PDA does not have an ID in it!</span>")
|
||||
|
||||
@@ -896,7 +896,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
/obj/item/pda/proc/id_check(mob/user, obj/item/card/id/I)
|
||||
if(!I)
|
||||
if(id && (src in user.contents))
|
||||
remove_id()
|
||||
remove_id(user)
|
||||
return TRUE
|
||||
else
|
||||
var/obj/item/card/id/C = user.get_active_held_item()
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
var/cleaning = FALSE
|
||||
var/cleaning_cycles = 10
|
||||
var/patient_laststat = null
|
||||
var/list/injection_chems = list("antitoxin", "epinephrine", "salbutamol", "bicaridine", "kelotane")
|
||||
var/list/injection_chems = list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/epinephrine,
|
||||
/datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane)
|
||||
var/eject_port = "ingestion"
|
||||
var/escape_in_progress = FALSE
|
||||
var/message_cooldown
|
||||
@@ -183,7 +184,7 @@
|
||||
data["chem"] = list()
|
||||
for(var/chem in injection_chems)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
|
||||
data["chem"] += list(list("name" = R.name, "id" = R.id))
|
||||
data["chem"] += list(list("name" = R.name, "id" = R.type))
|
||||
|
||||
data["occupant"] = list()
|
||||
var/mob/living/mob_occupant = patient
|
||||
@@ -227,8 +228,8 @@
|
||||
go_out(null, usr)
|
||||
. = TRUE
|
||||
if("inject")
|
||||
var/chem = params["chem"]
|
||||
if(!patient)
|
||||
var/chem = text2path(params["chem"])
|
||||
if(!patient || !chem)
|
||||
return
|
||||
inject_chem(chem, usr)
|
||||
. = TRUE
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
var/produce_heat = 1500
|
||||
heat = 1000
|
||||
light_color = LIGHT_COLOR_FLARE
|
||||
grind_results = list("sulfur" = 15)
|
||||
grind_results = list(/datum/reagent/sulfur = 15)
|
||||
|
||||
/obj/item/flashlight/flare/New()
|
||||
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
|
||||
@@ -430,7 +430,7 @@
|
||||
color = LIGHT_COLOR_GREEN
|
||||
icon_state = "glowstick"
|
||||
item_state = "glowstick"
|
||||
grind_results = list("phenol" = 15, "hydrogen" = 10, "oxygen" = 5) //Meth-in-a-stick
|
||||
grind_results = list(/datum/reagent/phenol = 15, /datum/reagent/hydrogen = 10, /datum/reagent/oxygen = 5) //Meth-in-a-stick
|
||||
rad_flags = RAD_NO_CONTAMINATE
|
||||
var/fuel = 0
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "forcefield projector"
|
||||
desc = "An experimental device that can create several forcefields at a distance."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "signmaker_engi"
|
||||
icon_state = "signmaker_forcefield"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = NOBLUDGEON
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
var/mob/living/silicon/pai/pai
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
max_integrity = 200
|
||||
|
||||
/obj/item/paicard/suicide_act(mob/living/user)
|
||||
user.visible_message("<span class='suicide'>[user] is staring sadly at [src]! [user.p_they()] can't keep living without real human intimacy!</span>")
|
||||
@@ -45,6 +46,8 @@
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "Transmit: <A href='byond://?src=[REF(src)];wires=[WIRE_TX]'>[(pai.radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
|
||||
dat += "Receive: <A href='byond://?src=[REF(src)];wires=[WIRE_RX]'>[(pai.radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
|
||||
if(pai.radio_short)
|
||||
dat += "<font color='red'>Reset radio short: <a href='byond://?src=[REF(src)];reset_radio_short=1'>\[RESET\]</a><br>"
|
||||
else
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
|
||||
@@ -82,7 +85,6 @@
|
||||
pai.master = M.real_name
|
||||
pai.master_dna = M.dna.unique_enzymes
|
||||
to_chat(pai, "<span class='notice'>You have been bound to a new master.</span>")
|
||||
pai.emittersemicd = FALSE
|
||||
if(href_list["wipe"])
|
||||
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
@@ -96,6 +98,8 @@
|
||||
var/wire = text2num(href_list["wires"])
|
||||
if(pai.radio)
|
||||
pai.radio.wires.cut(wire)
|
||||
if(href_list["reset_radio_short"])
|
||||
pai.unshort_radio()
|
||||
if(href_list["setlaws"])
|
||||
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
|
||||
if(newlaws && pai)
|
||||
|
||||
@@ -262,7 +262,7 @@ SLIME SCANNER
|
||||
temp_message += " <span class='info'>Subject has abnormal brain fuctions.</span>"
|
||||
|
||||
//Astrogen shenanigans
|
||||
if(H.reagents.has_reagent("astral"))
|
||||
if(H.reagents.has_reagent(/datum/reagent/fermi/astral))
|
||||
if(H.mind)
|
||||
temp_message += " <span class='danger'>Warning: subject may be possesed.</span>"
|
||||
else
|
||||
@@ -465,19 +465,18 @@ SLIME SCANNER
|
||||
else
|
||||
msg += "<span class='notice'>Subject is not addicted to any reagents.</span>\n"
|
||||
|
||||
if(M.reagents.has_reagent("fermiTox"))
|
||||
var/datum/reagent/fermiTox = M.reagents.has_reagent("fermiTox")
|
||||
switch(fermiTox.volume)
|
||||
if(5 to 10)
|
||||
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
|
||||
if(10 to 25)
|
||||
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
|
||||
if(25 to 50)
|
||||
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
|
||||
if(50 to 95)
|
||||
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
|
||||
if(95 to INFINITY)
|
||||
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
|
||||
var/datum/reagent/impure/fermiTox/F = M.reagents.has_reagent(/datum/reagent/impure/fermiTox)
|
||||
switch(F?.volume)
|
||||
if(5 to 10)
|
||||
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
|
||||
if(10 to 25)
|
||||
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
|
||||
if(25 to 50)
|
||||
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
|
||||
if(50 to 95)
|
||||
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
|
||||
if(95 to INFINITY)
|
||||
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
to_chat(user, msg)
|
||||
@@ -519,7 +518,7 @@ SLIME SCANNER
|
||||
throw_range = 7
|
||||
tool_behaviour = TOOL_ANALYZER
|
||||
materials = list(MAT_METAL=30, MAT_GLASS=20)
|
||||
grind_results = list("mercury" = 5, "iron" = 5, "silicon" = 5)
|
||||
grind_results = list(/datum/reagent/mercury = 5, /datum/reagent/iron = 5, /datum/reagent/silicon = 5)
|
||||
var/cooldown = FALSE
|
||||
var/cooldown_time = 250
|
||||
var/accuracy // 0 is the best accuracy.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/max_water = 50
|
||||
var/last_use = 1
|
||||
var/chem = "water"
|
||||
var/chem = /datum/reagent/water
|
||||
var/safety = TRUE
|
||||
var/refilling = FALSE
|
||||
var/tanktype = /obj/structure/reagent_dispensers/watertank
|
||||
|
||||
@@ -332,9 +332,9 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("aluminium", 30)
|
||||
B2.reagents.add_reagent("foaming_agent", 10)
|
||||
B2.reagents.add_reagent("facid", 10)
|
||||
B1.reagents.add_reagent(/datum/reagent/aluminium, 30)
|
||||
B2.reagents.add_reagent(/datum/reagent/foaming_agent, 10)
|
||||
B2.reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 10)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -350,9 +350,9 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("aluminium", 75)
|
||||
B2.reagents.add_reagent("smart_foaming_agent", 25)
|
||||
B2.reagents.add_reagent("facid", 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/aluminium, 75)
|
||||
B2.reagents.add_reagent(/datum/reagent/smart_foaming_agent, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 25)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -368,9 +368,9 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("phosphorus", 25)
|
||||
B2.reagents.add_reagent("stable_plasma", 25)
|
||||
B2.reagents.add_reagent("sacid", 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/phosphorus, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/stable_plasma, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/toxin/acid, 25)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -386,10 +386,10 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("plantbgone", 25)
|
||||
B1.reagents.add_reagent("potassium", 25)
|
||||
B2.reagents.add_reagent("phosphorus", 25)
|
||||
B2.reagents.add_reagent("sugar", 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/toxin/plantbgone, 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/phosphorus, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/consumable/sugar, 25)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -405,9 +405,9 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("fluorosurfactant", 40)
|
||||
B2.reagents.add_reagent("water", 40)
|
||||
B2.reagents.add_reagent("cleaner", 10)
|
||||
B1.reagents.add_reagent(/datum/reagent/fluorosurfactant, 40)
|
||||
B2.reagents.add_reagent(/datum/reagent/water, 40)
|
||||
B2.reagents.add_reagent(/datum/reagent/space_cleaner, 10)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -423,9 +423,9 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("fluorosurfactant", 40)
|
||||
B2.reagents.add_reagent("water", 40)
|
||||
B2.reagents.add_reagent("ez_clean", 60) //ensures a t h i c c distribution
|
||||
B1.reagents.add_reagent(/datum/reagent/fluorosurfactant, 40)
|
||||
B2.reagents.add_reagent(/datum/reagent/water, 40)
|
||||
B2.reagents.add_reagent(/datum/reagent/space_cleaner/ez_clean, 60) //ensures a t h i c c distribution
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -442,10 +442,10 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("condensedcapsaicin", 60)
|
||||
B1.reagents.add_reagent("potassium", 40)
|
||||
B2.reagents.add_reagent("phosphorus", 40)
|
||||
B2.reagents.add_reagent("sugar", 40)
|
||||
B1.reagents.add_reagent(/datum/reagent/consumable/condensedcapsaicin, 60)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 40)
|
||||
B2.reagents.add_reagent(/datum/reagent/phosphorus, 40)
|
||||
B2.reagents.add_reagent(/datum/reagent/consumable/sugar, 40)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -461,11 +461,11 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("facid", 290)
|
||||
B1.reagents.add_reagent("potassium", 10)
|
||||
B2.reagents.add_reagent("phosphorus", 10)
|
||||
B2.reagents.add_reagent("sugar", 10)
|
||||
B2.reagents.add_reagent("facid", 280)
|
||||
B1.reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 290)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 10)
|
||||
B2.reagents.add_reagent(/datum/reagent/phosphorus, 10)
|
||||
B2.reagents.add_reagent(/datum/reagent/consumable/sugar, 10)
|
||||
B2.reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 280)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -481,10 +481,10 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("colorful_reagent", 25)
|
||||
B1.reagents.add_reagent("potassium", 25)
|
||||
B2.reagents.add_reagent("phosphorus", 25)
|
||||
B2.reagents.add_reagent("sugar", 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/colorful_reagent, 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/phosphorus, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/consumable/sugar, 25)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -493,7 +493,7 @@
|
||||
name = "generic glitter grenade"
|
||||
desc = "You shouldn't see this description."
|
||||
stage = READY
|
||||
var/glitter_type = "glitter"
|
||||
var/glitter_type = /datum/reagent/glitter
|
||||
|
||||
/obj/item/grenade/chem_grenade/glitter/Initialize()
|
||||
. = ..()
|
||||
@@ -501,9 +501,9 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent(glitter_type, 25)
|
||||
B1.reagents.add_reagent("potassium", 25)
|
||||
B2.reagents.add_reagent("phosphorus", 25)
|
||||
B2.reagents.add_reagent("sugar", 25)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/phosphorus, 25)
|
||||
B2.reagents.add_reagent(/datum/reagent/consumable/sugar, 25)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -511,17 +511,17 @@
|
||||
/obj/item/grenade/chem_grenade/glitter/pink
|
||||
name = "pink glitter bomb"
|
||||
desc = "For that HOT glittery look."
|
||||
glitter_type = "pink_glitter"
|
||||
glitter_type = /datum/reagent/glitter/pink
|
||||
|
||||
/obj/item/grenade/chem_grenade/glitter/blue
|
||||
name = "blue glitter bomb"
|
||||
desc = "For that COOL glittery look."
|
||||
glitter_type = "blue_glitter"
|
||||
glitter_type = /datum/reagent/glitter/blue
|
||||
|
||||
/obj/item/grenade/chem_grenade/glitter/white
|
||||
name = "white glitter bomb"
|
||||
desc = "For that somnolent glittery look."
|
||||
glitter_type = "white_glitter"
|
||||
glitter_type = /datum/reagent/glitter/white
|
||||
|
||||
/obj/item/grenade/chem_grenade/clf3
|
||||
name = "clf3 grenade"
|
||||
@@ -533,10 +533,10 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("fluorosurfactant", 250)
|
||||
B1.reagents.add_reagent("clf3", 50)
|
||||
B2.reagents.add_reagent("water", 250)
|
||||
B2.reagents.add_reagent("clf3", 50)
|
||||
B1.reagents.add_reagent(/datum/reagent/fluorosurfactant, 250)
|
||||
B1.reagents.add_reagent(/datum/reagent/clf3, 50)
|
||||
B2.reagents.add_reagent(/datum/reagent/water, 250)
|
||||
B2.reagents.add_reagent(/datum/reagent/clf3, 50)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -551,13 +551,13 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("cryptobiolin", 75)
|
||||
B1.reagents.add_reagent("water", 50)
|
||||
B1.reagents.add_reagent("mutetoxin", 50)
|
||||
B1.reagents.add_reagent("spore", 75)
|
||||
B1.reagents.add_reagent("itching_powder", 50)
|
||||
B2.reagents.add_reagent("fluorosurfactant", 150)
|
||||
B2.reagents.add_reagent("mutagen", 150)
|
||||
B1.reagents.add_reagent(/datum/reagent/cryptobiolin, 75)
|
||||
B1.reagents.add_reagent(/datum/reagent/water, 50)
|
||||
B1.reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 50)
|
||||
B1.reagents.add_reagent(/datum/reagent/toxin/spore, 75)
|
||||
B1.reagents.add_reagent(/datum/reagent/toxin/itching_powder, 50)
|
||||
B2.reagents.add_reagent(/datum/reagent/fluorosurfactant, 150)
|
||||
B2.reagents.add_reagent(/datum/reagent/toxin/mutagen, 150)
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
@@ -571,11 +571,11 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("potassium", 50)
|
||||
B1.reagents.add_reagent("phosphorus", 50)
|
||||
B1.reagents.add_reagent("fungalspores", 200)
|
||||
B2.reagents.add_reagent("blood", 250)
|
||||
B2.reagents.add_reagent("sugar", 50)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 50)
|
||||
B1.reagents.add_reagent(/datum/reagent/phosphorus, 50)
|
||||
B1.reagents.add_reagent(/datum/reagent/fungalspores, 200)
|
||||
B2.reagents.add_reagent(/datum/reagent/blood, 250)
|
||||
B2.reagents.add_reagent(/datum/reagent/consumable/sugar, 50)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
@@ -591,8 +591,8 @@
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
|
||||
|
||||
B1.reagents.add_reagent("potassium", 100)
|
||||
B2.reagents.add_reagent("holywater", 100)
|
||||
B1.reagents.add_reagent(/datum/reagent/potassium, 100)
|
||||
B2.reagents.add_reagent(/datum/reagent/water/holywater, 100)
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
@@ -94,11 +94,11 @@
|
||||
var/chem = pick(slime_chems)
|
||||
var/amount = 5
|
||||
if(chem == "lesser plasma") //In the rare case we get another rainbow.
|
||||
chem = "plasma"
|
||||
chem = /datum/reagent/toxin/plasma
|
||||
amount = 4
|
||||
if(chem == "holy water and uranium")
|
||||
chem = "uranium"
|
||||
reagents.add_reagent("holywater")
|
||||
chem = /datum/reagent/uranium
|
||||
reagents.add_reagent(/datum/reagent/water/holywater)
|
||||
reagents.add_reagent(chem,amount)
|
||||
|
||||
/obj/effect/payload_spawner/random_slime/spawn_payload(type, numspawned)
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
/obj/item/grenade/flashbang/proc/flashbang_mobs(turf/source, range)
|
||||
var/list/banged = get_hearers_in_view(range, source)
|
||||
var/list/flashed = viewers(range, source)
|
||||
for(var/i in banged)
|
||||
bang(i, source)
|
||||
for(var/i in flashed)
|
||||
flash(i, source)
|
||||
for(var/mob/living/l in banged)
|
||||
bang(l, source)
|
||||
for(var/mob/living/l in flashed)
|
||||
flash(l, source)
|
||||
|
||||
/obj/item/grenade/flashbang/proc/bang(mob/living/M, turf/source)
|
||||
if(M.stat == DEAD) //They're dead!
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
/obj/item/holosign_creator/atmos
|
||||
name = "ATMOS holofan projector"
|
||||
desc = "A holographic projector that creates holographic barriers that prevent changes in atmosphere conditions."
|
||||
icon_state = "signmaker_engi"
|
||||
icon_state = "signmaker_atmos"
|
||||
holosign_type = /obj/structure/holosign/barrier/atmos
|
||||
creation_time = 0
|
||||
max_signs = 3
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
block_chance = 50
|
||||
var/shield_icon = "shield-red"
|
||||
|
||||
/obj/item/nullrod/staff/worn_overlays(isinhands)
|
||||
/obj/item/nullrod/staff/worn_overlays(isinhands, icon_file, style_flags = NONE)
|
||||
. = list()
|
||||
if(isinhands)
|
||||
. += mutable_appearance('icons/effects/effects.dmi', shield_icon, MOB_LAYER + 0.01)
|
||||
@@ -479,10 +479,10 @@
|
||||
|
||||
possessed = TRUE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
|
||||
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
var/mob/C = pick(candidates)
|
||||
var/mob/living/simple_animal/shade/S = new(src)
|
||||
S.real_name = name
|
||||
S.name = name
|
||||
@@ -789,7 +789,7 @@
|
||||
|
||||
praying = TRUE
|
||||
if(do_after(user, 20, target = M))
|
||||
M.reagents?.add_reagent("holywater", 5)
|
||||
M.reagents?.add_reagent(/datum/reagent/water/holywater, 5)
|
||||
to_chat(M, "<span class='notice'>[user]'s prayer to [deity_name] has eased your pain!</span>")
|
||||
M.adjustToxLoss(-5, TRUE, TRUE)
|
||||
M.adjustOxyLoss(-5)
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
L.SetKnockdown(0)
|
||||
L.SetSleeping(0)
|
||||
L.SetUnconscious(0)
|
||||
L.reagents.add_reagent("muscle_stimulant", CLAMP(5 - L.reagents.get_reagent_amount("muscle_stimulant"), 0, 5)) //If you don't have legs or get bola'd, tough luck!
|
||||
L.reagents.add_reagent(/datum/reagent/medicine/muscle_stimulant, CLAMP(5 - L.reagents.get_reagent_amount(/datum/reagent/medicine/muscle_stimulant), 0, 5)) //If you don't have legs or get bola'd, tough luck!
|
||||
colorize(L)
|
||||
|
||||
/obj/item/hot_potato/examine(mob/user)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/obj/item/implant/adrenalin/activate()
|
||||
. = ..()
|
||||
uses--
|
||||
imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10), "<span class='boldnotice'>You feel a sudden surge of energy!</span>")
|
||||
imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list(/datum/reagent/medicine/inaprovaline = 3, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/regen_jelly = 10, /datum/reagent/medicine/stimulants = 10), "<span class='boldnotice'>You feel a sudden surge of energy!</span>")
|
||||
to_chat(imp_in, "<span class='notice'>You feel a sudden surge of energy!</span>")
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
if(forkload)
|
||||
if(M == user)
|
||||
M.visible_message("<span class='notice'>[user] eats a delicious forkful of omelette!</span>")
|
||||
M.reagents.add_reagent(forkload.id, 1)
|
||||
M.reagents.add_reagent(forkload.type, 1)
|
||||
else
|
||||
M.visible_message("<span class='notice'>[user] feeds [M] a delicious forkful of omelette!</span>")
|
||||
M.reagents.add_reagent(forkload.id, 1)
|
||||
M.reagents.add_reagent(forkload.type, 1)
|
||||
icon_state = "fork"
|
||||
forkload = null
|
||||
|
||||
|
||||
@@ -339,7 +339,7 @@
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click to recolor it.</span>"
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
|
||||
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(isinhands)
|
||||
@@ -374,7 +374,7 @@
|
||||
It appears to have a wooden grip and a shaved down guard."
|
||||
icon_state = "cxsword_hilt_traitor"
|
||||
force_on = 30
|
||||
armour_penetration = 50
|
||||
armour_penetration = 35
|
||||
embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10)
|
||||
block_chance = 50
|
||||
hitsound_on = 'sound/weapons/blade1.ogg'
|
||||
|
||||
@@ -216,10 +216,11 @@
|
||||
return
|
||||
else
|
||||
if(last_hit < world.time)
|
||||
if(target.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
|
||||
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if (H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
|
||||
return
|
||||
if(check_martial_counter(H, user))
|
||||
return
|
||||
playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
/obj/item/mop/proc/clean(turf/A)
|
||||
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
|
||||
if(reagents.has_reagent(/datum/reagent/water, 1) || reagents.has_reagent(/datum/reagent/water/holywater, 1) || reagents.has_reagent(/datum/reagent/consumable/ethanol/vodka, 1) || reagents.has_reagent(/datum/reagent/space_cleaner, 1))
|
||||
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
A.clean_blood()
|
||||
for(var/obj/effect/O in A)
|
||||
@@ -98,7 +98,7 @@
|
||||
stamusage = 1
|
||||
var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water.
|
||||
var/refill_rate = 1 //Rate per process() tick mop refills itself
|
||||
var/refill_reagent = "water" //Determins what reagent to use for refilling, just in case someone wanted to make a HOLY MOP OF PURGING
|
||||
var/refill_reagent = /datum/reagent/water //Determins what reagent to use for refilling, just in case someone wanted to make a HOLY MOP OF PURGING
|
||||
|
||||
/obj/item/mop/advanced/New()
|
||||
..()
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
if(tank)
|
||||
updateTank(tank, 1, user)
|
||||
|
||||
|
||||
/obj/item/melee/powerfist/proc/updateTank(obj/item/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
|
||||
if(removing)
|
||||
if(!tank)
|
||||
@@ -71,26 +70,42 @@
|
||||
|
||||
|
||||
/obj/item/melee/powerfist/attack(mob/living/target, mob/living/user)
|
||||
if(!tank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
|
||||
return
|
||||
if(tank && !tank.air_contents.remove(gasperfist * fisto_setting))
|
||||
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
|
||||
playsound(loc, 'sound/effects/refill.ogg', 50, 1)
|
||||
return
|
||||
target.apply_damage(force * fisto_setting, BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
|
||||
new /obj/effect/temp_visual/kinetic_blast(target.loc)
|
||||
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
|
||||
if(!tank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
|
||||
return
|
||||
var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
T.assume_air(gasused)
|
||||
T.air_update_turf()
|
||||
if(!gasused)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s tank is empty!</span>")
|
||||
target.apply_damage((force / 5), BRUTE)
|
||||
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>[user]'s punches you!</span>")
|
||||
return
|
||||
if(gasused.total_moles() < gasperfist * fisto_setting)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
|
||||
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
target.apply_damage((force / 2), BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>[user]'s punch strikes with force!</span>")
|
||||
return
|
||||
target.apply_damage(force * fisto_setting, BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
|
||||
new /obj/effect/temp_visual/kinetic_blast(target.loc)
|
||||
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
|
||||
|
||||
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
|
||||
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
|
||||
|
||||
target.throw_at(throw_target, 5 * fisto_setting, 0.2)
|
||||
target.throw_at(throw_target, 5 * fisto_setting, 0.5 + (fisto_setting / 2))
|
||||
|
||||
log_combat(user, target, "power fisted", src)
|
||||
log_combat(user, target, "power fisted", src)
|
||||
|
||||
user.changeNext_move(CLICK_CD_MELEE * click_delay)
|
||||
user.changeNext_move(CLICK_CD_MELEE * click_delay)
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
|
||||
H.adjustToxLoss(-15)
|
||||
H.setOxyLoss(0)
|
||||
H.reagents.add_reagent("inaprovaline", 5)
|
||||
H.reagents.add_reagent(/datum/reagent/medicine/inaprovaline, 5)
|
||||
|
||||
/obj/item/banner/science
|
||||
name = "sciencia banner"
|
||||
|
||||
@@ -11,11 +11,9 @@
|
||||
var/charge_cost = 30
|
||||
|
||||
/obj/item/borg/stun/attack(mob/living/M, mob/living/user)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.check_shields(src, 0, "[M]'s [name]", MELEE_ATTACK))
|
||||
playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(M.check_shields(src, 0, "[M]'s [name]", MELEE_ATTACK))
|
||||
playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(iscyborg(user))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(!R.cell.use(charge_cost))
|
||||
@@ -816,3 +814,93 @@
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Your gripper cannot hold \the [target].</span>")
|
||||
|
||||
/obj/item/weapon/gripper/mining
|
||||
name = "shelter capsule deployer"
|
||||
desc = "A simple grasping tool for carrying and deploying shelter capsules."
|
||||
icon_state = "gripper_mining"
|
||||
can_hold = list(
|
||||
/obj/item/survivalcapsule
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/mining/attack_self()
|
||||
if(wrapped)
|
||||
wrapped.forceMove(get_turf(wrapped))
|
||||
wrapped.attack_self()
|
||||
wrapped = null
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/plasmacutter/cyborg
|
||||
name = "cyborg plasma cutter"
|
||||
desc = "A basic variation of the plasma cutter, compressed into a cyborg chassis. Less effective than normal plasma cutters."
|
||||
force = 15
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/plasma/weak)
|
||||
can_charge = FALSE
|
||||
selfcharge = EGUN_SELFCHARGE_BORG
|
||||
cell_type = /obj/item/stock_parts/cell/secborg
|
||||
charge_delay = 5
|
||||
|
||||
/obj/item/cyborg_clamp
|
||||
name = "cyborg loading clamp"
|
||||
desc = "Equipment for supply cyborgs. Lifts objects and loads them into cargo. Will not carry living beings."
|
||||
icon = 'icons/mecha/mecha_equipment.dmi'
|
||||
icon_state = "mecha_clamp"
|
||||
tool_behaviour = TOOL_RETRACTOR
|
||||
item_flags = NOBLUDGEON
|
||||
flags_1 = NONE
|
||||
var/cargo_capacity = 8
|
||||
var/cargo = list()
|
||||
|
||||
/obj/item/cyborg_clamp/attack(mob/M, mob/user, def_zone)
|
||||
return
|
||||
|
||||
/obj/item/cyborg_clamp/afterattack(atom/movable/target, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return FALSE
|
||||
if(isobj(target))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(contents.len < cargo_capacity)
|
||||
user.visible_message("[user] lifts [target] and starts to load it into its cargo compartment.")
|
||||
O.anchored = TRUE
|
||||
if(do_mob(user, O, 20))
|
||||
for(var/mob/chump in target.GetAllContents())
|
||||
to_chat(user, "<span class='warning'>Error: Living entity detected in [target]. Cannot load.</span>")
|
||||
O.anchored = initial(O.anchored)
|
||||
return
|
||||
for(var/obj/item/disk/nuclear/diskie in target.GetAllContents())
|
||||
to_chat(user, "<span class='warning'>Error: Nuclear class authorization device detected in [target]. Cannot load.</span>")
|
||||
O.anchored = initial(O.anchored)
|
||||
return
|
||||
if(contents.len < cargo_capacity) //check both before and after
|
||||
cargo += O
|
||||
O.forceMove(src)
|
||||
O.anchored = FALSE
|
||||
to_chat(user, "<span class='notice'>[target] successfully loaded.</span>")
|
||||
playsound(loc, 'sound/effects/bin_close.ogg', 50, 0)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Not enough room in cargo compartment! Maximum of [cargo_capacity] objects!</span>")
|
||||
O.anchored = initial(O.anchored)
|
||||
return
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Not enough room in cargo compartment! Maximum of eight objects!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] is firmly secured!</span>")
|
||||
|
||||
/obj/item/cyborg_clamp/attack_self(mob/user)
|
||||
var/obj/chosen_cargo = input(user, "Drop what?") as null|anything in cargo
|
||||
if(!chosen_cargo)
|
||||
return
|
||||
chosen_cargo.forceMove(get_turf(chosen_cargo))
|
||||
cargo -= chosen_cargo
|
||||
user.visible_message("[user] unloads [chosen_cargo] from its cargo.")
|
||||
playsound(loc, 'sound/effects/bin_close.ogg', 50, 0)
|
||||
|
||||
/obj/item/card/id/miningborg
|
||||
name = "mining point card"
|
||||
desc = "A robotic ID strip used for claiming and transferring mining points. Must be held in an active slot to transfer points."
|
||||
access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
|
||||
icon_state = "data_1"
|
||||
@@ -173,32 +173,64 @@
|
||||
R.module.basic_modules += S
|
||||
R.module.add_module(S, FALSE, TRUE)
|
||||
|
||||
/obj/item/borg/upgrade/soh
|
||||
name = "mining cyborg satchel of holding"
|
||||
desc = "A satchel of holding replacement for mining cyborg's ore satchel module."
|
||||
/obj/item/borg/upgrade/premiumka
|
||||
name = "mining cyborg premium KA"
|
||||
desc = "A premium kinetic accelerator replacement for the mining module's standard kinetic accelerator."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/miner)
|
||||
|
||||
/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R)
|
||||
/obj/item/borg/upgrade/premiumka/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if(.)
|
||||
for(var/obj/item/storage/bag/ore/cyborg/S in R.module)
|
||||
R.module.remove_module(S, TRUE)
|
||||
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module)
|
||||
for(var/obj/item/borg/upgrade/modkit/M in KA.modkits)
|
||||
M.uninstall(src)
|
||||
R.module.remove_module(KA, TRUE)
|
||||
|
||||
var/obj/item/storage/bag/ore/holding/H = new /obj/item/storage/bag/ore/holding(R.module)
|
||||
R.module.basic_modules += H
|
||||
R.module.add_module(H, FALSE, TRUE)
|
||||
var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA = new /obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg(R.module)
|
||||
R.module.basic_modules += PKA
|
||||
R.module.add_module(PKA, FALSE, TRUE)
|
||||
|
||||
/obj/item/borg/upgrade/soh/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
/obj/item/borg/upgrade/premiumka/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
for(var/obj/item/storage/bag/ore/holding/H in R.module)
|
||||
R.module.remove_module(H, TRUE)
|
||||
for(var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA in R.module)
|
||||
for(var/obj/item/borg/upgrade/modkit/M in PKA.modkits)
|
||||
M.uninstall(src)
|
||||
R.module.remove_module(PKA, TRUE)
|
||||
|
||||
var/obj/item/storage/bag/ore/cyborg/S = new (R.module)
|
||||
R.module.basic_modules += S
|
||||
R.module.add_module(S, FALSE, TRUE)
|
||||
var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA = new (R.module)
|
||||
R.module.basic_modules += KA
|
||||
R.module.add_module(KA, FALSE, TRUE)
|
||||
|
||||
|
||||
/obj/item/borg/upgrade/advcutter
|
||||
name = "mining cyborg advanced plasma cutter"
|
||||
desc = "An upgrade for the mining cyborgs plasma cutter, bringing it to advanced operation."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/miner)
|
||||
|
||||
/obj/item/borg/upgrade/advcutter/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if(.)
|
||||
for(var/obj/item/gun/energy/plasmacutter/cyborg/C in R.module)
|
||||
C.name = "advanced cyborg plasma cutter"
|
||||
C.desc = "An improved version of the cyborg plasma cutter. Baring functionality identical to the standard hand held version."
|
||||
C.icon_state = "adv_plasmacutter"
|
||||
for(var/obj/item/ammo_casing/energy/plasma/weak/L in C.ammo_type)
|
||||
L.projectile_type = /obj/item/projectile/plasma/adv
|
||||
|
||||
/obj/item/borg/upgrade/advcutter/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
for(var/obj/item/gun/energy/plasmacutter/cyborg/C in R.module)
|
||||
C.name = initial(name)
|
||||
C.desc = initial(desc)
|
||||
C.icon_state = initial(icon_state)
|
||||
for(var/obj/item/ammo_casing/energy/plasma/weak/L in C.ammo_type)
|
||||
L.projectile_type = initial(L.projectile_type)
|
||||
|
||||
/obj/item/borg/upgrade/tboh
|
||||
name = "janitor cyborg trash bag of holding"
|
||||
@@ -434,15 +466,15 @@
|
||||
name = "medical cyborg expanded hypospray"
|
||||
desc = "An upgrade to the Medical module's hypospray, allowing it \
|
||||
to treat a wider range of conditions and problems."
|
||||
additional_reagents = list("mannitol", "oculine", "inacusiate",
|
||||
"mutadone", "haloperidol")
|
||||
additional_reagents = list(/datum/reagent/medicine/mannitol, /datum/reagent/medicine/oculine, /datum/reagent/medicine/inacusiate,
|
||||
/datum/reagent/medicine/mutadone, /datum/reagent/medicine/haloperidol)
|
||||
|
||||
/obj/item/borg/upgrade/hypospray/high_strength
|
||||
name = "medical cyborg high-strength hypospray"
|
||||
desc = "An upgrade to the Medical module's hypospray, containing \
|
||||
stronger versions of existing chemicals."
|
||||
additional_reagents = list("oxandrolone", "sal_acid", "rezadone",
|
||||
"pen_acid")
|
||||
additional_reagents = list(/datum/reagent/medicine/oxandrolone, /datum/reagent/medicine/sal_acid,
|
||||
/datum/reagent/medicine/rezadone, /datum/reagent/medicine/pen_acid)
|
||||
|
||||
/obj/item/borg/upgrade/piercing_hypospray
|
||||
name = "cyborg piercing hypospray"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
points = 50
|
||||
var/blink_range = 8 // The teleport range when crushed/thrown at someone.
|
||||
refined_type = /obj/item/stack/sheet/bluespace_crystal
|
||||
grind_results = list("bluespace" = 20)
|
||||
grind_results = list(/datum/reagent/bluespace = 20)
|
||||
|
||||
/obj/item/stack/ore/bluespace_crystal/refined
|
||||
name = "refined bluespace crystal"
|
||||
@@ -53,7 +53,7 @@
|
||||
blink_range = 4 // Not as good as the organic stuff!
|
||||
points = 0 //nice try
|
||||
refined_type = null
|
||||
grind_results = list("bluespace" = 10, "silicon" = 20)
|
||||
grind_results = list(/datum/reagent/bluespace = 10, /datum/reagent/silicon = 20)
|
||||
|
||||
//Polycrystals, aka stacks
|
||||
/obj/item/stack/sheet/bluespace_crystal
|
||||
@@ -66,7 +66,7 @@
|
||||
materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT)
|
||||
attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed")
|
||||
novariants = TRUE
|
||||
grind_results = list("bluespace" = 20)
|
||||
grind_results = list(/datum/reagent/bluespace = 20)
|
||||
point_value = 30
|
||||
var/crystal_type = /obj/item/stack/ore/bluespace_crystal/refined
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
var/heal_brute = 20
|
||||
self_delay = 20
|
||||
grind_results = list("styptic_powder" = 10)
|
||||
grind_results = list(/datum/reagent/medicine/styptic_powder = 10)
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/heal(mob/living/M, mob/user)
|
||||
if(M.stat == DEAD)
|
||||
@@ -140,7 +140,7 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
var/heal_burn = 20
|
||||
self_delay = 20
|
||||
grind_results = list("silver_sulfadiazine" = 10)
|
||||
grind_results = list(/datum/reagent/medicine/silver_sulfadiazine = 10)
|
||||
|
||||
/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user)
|
||||
if(M.stat == DEAD)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
throw_range = 7
|
||||
flags_1 = CONDUCT_1
|
||||
max_amount = 60
|
||||
grind_results = list("silicon" = 20, "copper" = 5)
|
||||
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/copper = 5)
|
||||
|
||||
/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, /obj/item/stack/sheet/metal))
|
||||
|
||||
@@ -108,7 +108,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
|
||||
sheettype = "diamond"
|
||||
materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)
|
||||
novariants = TRUE
|
||||
grind_results = list("carbon" = 20)
|
||||
grind_results = list(/datum/reagent/carbon = 20)
|
||||
point_value = 25
|
||||
merge_type = /obj/item/stack/sheet/mineral/diamond
|
||||
|
||||
@@ -135,7 +135,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
sheettype = "uranium"
|
||||
materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
novariants = TRUE
|
||||
grind_results = list("uranium" = 20)
|
||||
grind_results = list(/datum/reagent/uranium = 20)
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/uranium
|
||||
|
||||
@@ -162,7 +162,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
|
||||
grind_results = list("plasma" = 20)
|
||||
grind_results = list(/datum/reagent/toxin/plasma = 20)
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/plasma
|
||||
|
||||
@@ -203,7 +203,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
singular_name = "gold bar"
|
||||
sheettype = "gold"
|
||||
materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT)
|
||||
grind_results = list("gold" = 20)
|
||||
grind_results = list(/datum/reagent/gold = 20)
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/gold
|
||||
|
||||
@@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
singular_name = "silver bar"
|
||||
sheettype = "silver"
|
||||
materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT)
|
||||
grind_results = list("silver" = 20)
|
||||
grind_results = list(/datum/reagent/silver = 20)
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/silver
|
||||
tableVariant = /obj/structure/table/optable
|
||||
@@ -262,7 +262,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
sheettype = "bananium"
|
||||
materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
novariants = TRUE
|
||||
grind_results = list("banana" = 20)
|
||||
grind_results = list(/datum/reagent/consumable/banana = 20)
|
||||
point_value = 50
|
||||
merge_type = /obj/item/stack/sheet/mineral/bananium
|
||||
|
||||
@@ -342,7 +342,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
|
||||
singular_name = "snow block"
|
||||
force = 1
|
||||
throwforce = 2
|
||||
grind_results = list("ice" = 20)
|
||||
grind_results = list(/datum/reagent/consumable/ice = 20)
|
||||
merge_type = /obj/item/stack/sheet/mineral/snow
|
||||
|
||||
GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
@@ -422,7 +422,7 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \
|
||||
icon_state = "slag"
|
||||
singular_name = "coal lump"
|
||||
merge_type = /obj/item/stack/sheet/mineral/coal
|
||||
grind_results = list("carbon" = 20)
|
||||
grind_results = list(/datum/reagent/carbon = 20)
|
||||
|
||||
/obj/item/stack/sheet/mineral/coal/attackby(obj/item/W, mob/user, params)
|
||||
if(W.get_temperature() > 300)//If the temperature of the object is over 300, then ignite
|
||||
|
||||
@@ -106,7 +106,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
|
||||
flags_1 = CONDUCT_1
|
||||
resistance_flags = FIRE_PROOF
|
||||
merge_type = /obj/item/stack/sheet/metal
|
||||
grind_results = list("iron" = 20)
|
||||
grind_results = list(/datum/reagent/iron = 20)
|
||||
point_value = 2
|
||||
tableVariant = /obj/structure/table
|
||||
|
||||
@@ -168,7 +168,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80)
|
||||
resistance_flags = FIRE_PROOF
|
||||
merge_type = /obj/item/stack/sheet/plasteel
|
||||
grind_results = list("iron" = 20, "plasma" = 20)
|
||||
grind_results = list(/datum/reagent/iron = 20, /datum/reagent/toxin/plasma = 20)
|
||||
point_value = 23
|
||||
tableVariant = /obj/structure/table/reinforced
|
||||
|
||||
@@ -238,7 +238,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/mineral/wood
|
||||
novariants = TRUE
|
||||
grind_results = list("carbon" = 20)
|
||||
grind_results = list(/datum/reagent/carbon = 20)
|
||||
|
||||
|
||||
/obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there.
|
||||
@@ -296,7 +296,7 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/mineral/bamboo
|
||||
grind_results = list("carbon" = 5)
|
||||
grind_results = list(/datum/reagent/carbon = 5)
|
||||
|
||||
/obj/item/stack/sheet/mineral/bamboo/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.bamboo_recipes
|
||||
@@ -398,39 +398,64 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
* Cardboard
|
||||
*/
|
||||
GLOBAL_LIST_INIT(cardboard_recipes, list ( \
|
||||
new/datum/stack_recipe("box", /obj/item/storage/box), \
|
||||
new/datum/stack_recipe("sec box", /obj/item/storage/box/seclooking), \
|
||||
new/datum/stack_recipe("light tubes", /obj/item/storage/box/lights/tubes), \
|
||||
new/datum/stack_recipe("light bulbs", /obj/item/storage/box/lights/bulbs), \
|
||||
new/datum/stack_recipe("mouse traps", /obj/item/storage/box/mousetraps), \
|
||||
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
|
||||
new/datum/stack_recipe("power cell", /obj/item/storage/box/cells), \
|
||||
new/datum/stack_recipe("02", /obj/item/storage/box/otwo), \
|
||||
null, \
|
||||
new/datum/stack_recipe("lethal ammo box", /obj/item/storage/box/lethalshot), \
|
||||
new/datum/stack_recipe("rubber shot ammo box", /obj/item/storage/box/rubbershot), \
|
||||
new/datum/stack_recipe("bean bag ammo box", /obj/item/storage/box/beanbag), \
|
||||
new/datum/stack_recipe("12g ammo box", /obj/item/storage/box/lethalslugs), \
|
||||
new/datum/stack_recipe("stun slug ammo box", /obj/item/storage/box/stunslug), \
|
||||
new/datum/stack_recipe("tech shell ammo box", /obj/item/storage/box/techsslug), \
|
||||
new/datum/stack_recipe("incendiary ammo box", /obj/item/storage/box/fireshot), \
|
||||
new/datum/stack_recipe("firing pins", /obj/item/storage/box/firingpins), \
|
||||
new/datum/stack_recipe("loose ammo", /obj/item/storage/box/ammoshells), \
|
||||
null, \
|
||||
new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \
|
||||
new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \
|
||||
new/datum/stack_recipe("folder", /obj/item/folder), \
|
||||
new/datum/stack_recipe("large box", /obj/structure/closet/cardboard, 4), \
|
||||
new/datum/stack_recipe("cardboard cutout", /obj/item/cardboard_cutout, 5), \
|
||||
null, \
|
||||
new/datum/stack_recipe("colored brown", /obj/item/storage/box/brown), \
|
||||
new/datum/stack_recipe("colored green", /obj/item/storage/box/green), \
|
||||
new/datum/stack_recipe("colored red", /obj/item/storage/box/blue), \
|
||||
new/datum/stack_recipe("colored blue", /obj/item/storage/box/red), \
|
||||
new/datum/stack_recipe("colored yellow", /obj/item/storage/box/yellow), \
|
||||
new/datum/stack_recipe("colored pink", /obj/item/storage/box/pink), \
|
||||
new/datum/stack_recipe("colored purple", /obj/item/storage/box/purple), \
|
||||
))
|
||||
new/datum/stack_recipe("box", /obj/item/storage/box), \
|
||||
new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \
|
||||
new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \
|
||||
new/datum/stack_recipe("large box", /obj/structure/closet/cardboard, 4), \
|
||||
new/datum/stack_recipe("cardboard cutout", /obj/item/cardboard_cutout, 5), \
|
||||
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
|
||||
new/datum/stack_recipe("folder", /obj/item/folder), \
|
||||
// holy fuck why are there so many boxes
|
||||
new/datum/stack_recipe_list("fancy boxes", list ( \
|
||||
new /datum/stack_recipe("donut box", /obj/item/storage/fancy/donut_box), \
|
||||
new /datum/stack_recipe("egg box", /obj/item/storage/fancy/egg_box), \
|
||||
new /datum/stack_recipe("donk-pockets box", /obj/item/storage/box/donkpockets), \
|
||||
new /datum/stack_recipe("monkey cube box", /obj/item/storage/box/monkeycubes), \
|
||||
new /datum/stack_recipe("box (internals)", /obj/item/storage/box/otwo), \
|
||||
null, \
|
||||
new /datum/stack_recipe("security-styled box", /obj/item/storage/box/seclooking), \
|
||||
new /datum/stack_recipe("buckshot shell box", /obj/item/storage/box/lethalshot), \
|
||||
new /datum/stack_recipe("rubber shot shell box", /obj/item/storage/box/rubbershot), \
|
||||
new /datum/stack_recipe("beanbag shell box", /obj/item/storage/box/beanbag), \
|
||||
new /datum/stack_recipe("slug shell box", /obj/item/storage/box/lethalslugs), \
|
||||
new /datum/stack_recipe("stunslug shell box", /obj/item/storage/box/stunslug), \
|
||||
new /datum/stack_recipe("tech shell box", /obj/item/storage/box/techsslug), \
|
||||
new /datum/stack_recipe("incendiary ammo box", /obj/item/storage/box/fireshot), \
|
||||
new /datum/stack_recipe("loose ammo box", /obj/item/storage/box/ammoshells), \
|
||||
new /datum/stack_recipe("firing pins box", /obj/item/storage/box/firingpins), \
|
||||
null, \
|
||||
new /datum/stack_recipe("flashbang box", /obj/item/storage/box/flashbangs), \
|
||||
new /datum/stack_recipe("flashes box", /obj/item/storage/box/flashes), \
|
||||
new /datum/stack_recipe("handcuffs box", /obj/item/storage/box/handcuffs), \
|
||||
new /datum/stack_recipe("ID card box", /obj/item/storage/box/ids), \
|
||||
new /datum/stack_recipe("PDA box", /obj/item/storage/box/PDAs), \
|
||||
null, \
|
||||
new /datum/stack_recipe("pill bottle box", /obj/item/storage/box/pillbottles), \
|
||||
new /datum/stack_recipe("beaker box", /obj/item/storage/box/beakers), \
|
||||
new /datum/stack_recipe("syringe box", /obj/item/storage/box/syringes), \
|
||||
new /datum/stack_recipe("latex gloves box", /obj/item/storage/box/gloves), \
|
||||
new /datum/stack_recipe("sterile masks box", /obj/item/storage/box/masks), \
|
||||
new /datum/stack_recipe("body bag box", /obj/item/storage/box/bodybags), \
|
||||
new /datum/stack_recipe("prescription glasses box", /obj/item/storage/box/rxglasses), \
|
||||
null, \
|
||||
new /datum/stack_recipe("disk box", /obj/item/storage/box/disks), \
|
||||
new /datum/stack_recipe("light tubes box", /obj/item/storage/box/lights/tubes), \
|
||||
new /datum/stack_recipe("light bulbs box", /obj/item/storage/box/lights/bulbs), \
|
||||
new /datum/stack_recipe("mixed lights box", /obj/item/storage/box/lights/mixed), \
|
||||
new /datum/stack_recipe("power cell box", /obj/item/storage/box/cells), \
|
||||
new /datum/stack_recipe("mouse traps box", /obj/item/storage/box/mousetraps), \
|
||||
new /datum/stack_recipe("candle box", /obj/item/storage/fancy/candle_box), \
|
||||
null, \
|
||||
new /datum/stack_recipe("box (brown)", /obj/item/storage/box/brown), \
|
||||
new /datum/stack_recipe("box (green)", /obj/item/storage/box/green), \
|
||||
new /datum/stack_recipe("box (blue)", /obj/item/storage/box/blue), \
|
||||
new /datum/stack_recipe("box (red)", /obj/item/storage/box/red), \
|
||||
new /datum/stack_recipe("box (yellow)", /obj/item/storage/box/yellow), \
|
||||
new /datum/stack_recipe("box (pink)", /obj/item/storage/box/pink), \
|
||||
new /datum/stack_recipe("box (purple)", /obj/item/storage/box/purple), \
|
||||
)),
|
||||
null, \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/cardboard //BubbleWrap //it's cardboard you fuck
|
||||
name = "cardboard"
|
||||
@@ -456,7 +481,7 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
|
||||
var/atom/droploc = drop_location()
|
||||
if(use(1))
|
||||
playsound(I, 'sound/items/bikehorn.ogg', 50, 1, -1)
|
||||
to_chat(user, "<span class='notice'>You stamp the cardboard! Its a clown box! Honk!</span>")
|
||||
to_chat(user, "<span class='notice'>You stamp the cardboard! It's a clown box! Honk!</span>")
|
||||
if (amount >= 0)
|
||||
new/obj/item/storage/box/clown(droploc) //bugfix
|
||||
else
|
||||
@@ -486,7 +511,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
sheettype = "runed"
|
||||
merge_type = /obj/item/stack/sheet/runed_metal
|
||||
novariants = TRUE
|
||||
grind_results = list("iron" = 5, "blood" = 15)
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/blood = 15)
|
||||
|
||||
/obj/item/stack/sheet/runed_metal/ratvar_act()
|
||||
new /obj/item/stack/tile/brass(loc, amount)
|
||||
@@ -521,31 +546,30 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
*/
|
||||
GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null,
|
||||
null, \
|
||||
new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass pinion airlock - windowed", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \
|
||||
null,
|
||||
null, \
|
||||
new/datum/stack_recipe("brass reflector", /obj/structure/destructible/clockwork/reflector, 10, time = 100, one_per_turf = TRUE, on_floor = TRUE, window_checks = TRUE), \
|
||||
null,
|
||||
null, \
|
||||
new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null,
|
||||
null, \
|
||||
new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("sender - mech sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("sender - lever", /obj/structure/destructible/clockwork/trap/trigger/lever, 1, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("sender - repeater", /obj/structure/destructible/clockwork/trap/trigger/repeater, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null,
|
||||
null, \
|
||||
new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_ADJACENT), \
|
||||
new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
|
||||
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
|
||||
null,
|
||||
null, \
|
||||
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \
|
||||
|
||||
))
|
||||
|
||||
/obj/item/stack/tile/brass
|
||||
@@ -562,7 +586,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
throw_range = 3
|
||||
turf_type = /turf/open/floor/clockwork
|
||||
novariants = FALSE
|
||||
grind_results = list("iron" = 5, "teslium" = 15, "holyoil" = 1)
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/teslium = 15, /datum/reagent/fuel/holyoil = 1)
|
||||
merge_type = /obj/item/stack/tile/brass
|
||||
tableVariant = /obj/structure/table/reinforced/brass
|
||||
|
||||
@@ -615,7 +639,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
throw_range = 3
|
||||
turf_type = /turf/open/floor/bronze
|
||||
novariants = FALSE
|
||||
grind_results = list("iron" = 5, "copper" = 3) //we have no "tin" reagent so this is the closest thing
|
||||
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
|
||||
tableVariant = /obj/structure/table/bronze
|
||||
|
||||
@@ -669,11 +693,12 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
grind_results = list("carbon" = 10)
|
||||
grind_results = list(/datum/reagent/carbon = 10)
|
||||
merge_type = /obj/item/stack/sheet/bone
|
||||
|
||||
GLOBAL_LIST_INIT(plastic_recipes, list(
|
||||
new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
|
||||
new /datum/stack_recipe("see-through plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
|
||||
new /datum/stack_recipe("opaque plastic flaps", /obj/structure/plasticflaps/opaque, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
|
||||
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("large trash cart", /obj/structure/closet/crate/bin,50),\
|
||||
|
||||
@@ -192,9 +192,15 @@
|
||||
var/obj/O
|
||||
if(R.max_res_amount > 1) //Is it a stack?
|
||||
O = new R.result_type(usr.drop_location(), R.res_amount * multiplier)
|
||||
else if(ispath(R.result_type, /turf))
|
||||
var/turf/T = usr.drop_location()
|
||||
if(!isturf(T))
|
||||
return
|
||||
T.PlaceOnTop(R.result_type, flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
O = new R.result_type(usr.drop_location())
|
||||
O.setDir(usr.dir)
|
||||
if(O)
|
||||
O.setDir(usr.dir)
|
||||
use(R.req_amount * multiplier)
|
||||
|
||||
//START: oh fuck i'm so sorry
|
||||
@@ -439,4 +445,4 @@
|
||||
|
||||
/datum/stack_recipe_list/New(title, recipes)
|
||||
src.title = title
|
||||
src.recipes = recipes
|
||||
src.recipes = recipes
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it
|
||||
var/mob/listeningTo
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
var/range = null
|
||||
|
||||
/obj/item/storage/bag/ore/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -130,7 +131,8 @@
|
||||
|
||||
/obj/item/storage/bag/ore/dropped()
|
||||
. = ..()
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
|
||||
/obj/item/storage/bag/ore/proc/Pickup_ores(mob/living/user)
|
||||
@@ -141,12 +143,21 @@
|
||||
return
|
||||
if (istype(user.pulling, /obj/structure/ore_box))
|
||||
box = user.pulling
|
||||
if(issilicon(user))
|
||||
var/mob/living/silicon/robot/borgo = user
|
||||
for(var/obj/item/cyborg_clamp/C in borgo.module.modules)
|
||||
for(var/obj/structure/ore_box/B in C)
|
||||
box = B
|
||||
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
if(STR)
|
||||
for(var/A in tile)
|
||||
if (!is_type_in_typecache(A, STR.can_hold))
|
||||
continue
|
||||
if (box)
|
||||
if(range)
|
||||
for(var/obj/item/stack/ore/ore in range(range, user))
|
||||
user.transferItemToLoc(ore, box)
|
||||
user.transferItemToLoc(A, box)
|
||||
show_message = TRUE
|
||||
else if(SEND_SIGNAL(src, COMSIG_TRY_STORAGE_INSERT, A, user, TRUE))
|
||||
@@ -168,6 +179,7 @@
|
||||
|
||||
/obj/item/storage/bag/ore/cyborg
|
||||
name = "cyborg mining satchel"
|
||||
range = 1
|
||||
|
||||
/obj/item/storage/bag/ore/cyborg/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
add_overlay(M)
|
||||
..()
|
||||
|
||||
/obj/item/storage/belt/worn_overlays(isinhands, icon_file)
|
||||
/obj/item/storage/belt/worn_overlays(isinhands, icon_file, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands && worn_overlays)
|
||||
for(var/obj/item/I in contents)
|
||||
@@ -61,6 +61,7 @@
|
||||
/obj/item/radio,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/holosign_creator,
|
||||
/obj/item/forcefield_projector,
|
||||
/obj/item/assembly/signaler
|
||||
))
|
||||
STR.can_hold = can_hold
|
||||
@@ -458,8 +459,7 @@
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/radio,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/holosign_creator/atmos,
|
||||
/obj/item/holosign_creator/engineering,
|
||||
/obj/item/holosign_creator,
|
||||
/obj/item/forcefield_projector,
|
||||
/obj/item/assembly/signaler,
|
||||
/obj/item/lightreplacer,
|
||||
@@ -571,6 +571,7 @@
|
||||
/obj/item/reagent_containers/spray,
|
||||
/obj/item/soap,
|
||||
/obj/item/holosign_creator,
|
||||
/obj/item/forcefield_projector,
|
||||
/obj/item/key/janitor,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/melee/flyswatter,
|
||||
@@ -582,7 +583,7 @@
|
||||
|
||||
/obj/item/storage/belt/bandolier
|
||||
name = "bandolier"
|
||||
desc = "A bandolier for holding shotgun ammunition."
|
||||
desc = "A bandolier for holding ammunition."
|
||||
icon_state = "bandolier"
|
||||
item_state = "bandolier"
|
||||
|
||||
@@ -592,7 +593,7 @@
|
||||
STR.max_items = 18
|
||||
STR.display_numerical_stacking = TRUE
|
||||
STR.can_hold = typecacheof(list(
|
||||
/obj/item/ammo_casing/shotgun
|
||||
/obj/item/ammo_casing
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/bandolier/durathread
|
||||
|
||||
@@ -163,16 +163,16 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
for(var/obj/effect/rune/R in orange(2,user))
|
||||
R.invisibility = 0
|
||||
if(user.mind && (user.mind.isholy))
|
||||
if(A.reagents && A.reagents.has_reagent("water")) // blesses all the water in the holder
|
||||
if(A.reagents && A.reagents.has_reagent(/datum/reagent/water)) // blesses all the water in the holder
|
||||
to_chat(user, "<span class='notice'>You bless [A].</span>")
|
||||
var/water2holy = A.reagents.get_reagent_amount("water")
|
||||
A.reagents.del_reagent("water")
|
||||
A.reagents.add_reagent("holywater",water2holy)
|
||||
if(A.reagents && A.reagents.has_reagent("unholywater")) // yeah yeah, copy pasted code - sue me
|
||||
var/water2holy = A.reagents.get_reagent_amount(/datum/reagent/water)
|
||||
A.reagents.del_reagent(/datum/reagent/water)
|
||||
A.reagents.add_reagent(/datum/reagent/water/holywater,water2holy)
|
||||
if(A.reagents && A.reagents.has_reagent(/datum/reagent/fuel/unholywater)) // yeah yeah, copy pasted code - sue me
|
||||
to_chat(user, "<span class='notice'>You purify [A].</span>")
|
||||
var/unholy2clean = A.reagents.get_reagent_amount("unholywater")
|
||||
A.reagents.del_reagent("unholywater")
|
||||
A.reagents.add_reagent("holywater",unholy2clean)
|
||||
var/unholy2clean = A.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
|
||||
A.reagents.del_reagent(/datum/reagent/fuel/unholywater)
|
||||
A.reagents.add_reagent(/datum/reagent/water/holywater,unholy2clean)
|
||||
if(istype(A, /obj/item/twohanded/required/cult_bastard) && !iscultist(user))
|
||||
var/obj/item/twohanded/required/cult_bastard/sword = A
|
||||
to_chat(user, "<span class='notice'>You begin to exorcise [sword].</span>")
|
||||
|
||||
@@ -1259,3 +1259,12 @@
|
||||
var/obj/item/stack/sheet/cardboard/I = new(user.drop_location())
|
||||
qdel(src)
|
||||
user.put_in_hands(I)
|
||||
|
||||
/obj/item/storage/box/marshmallow
|
||||
name = "box of marshmallows"
|
||||
desc = "A box of marshmallows."
|
||||
illustration = "marshmallow"
|
||||
|
||||
/obj/item/storage/box/marshmallow/PopulateContents()
|
||||
for (var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/food/snacks/marshmallow(src)
|
||||
@@ -205,7 +205,7 @@
|
||||
new /obj/item/healthanalyzer/advanced(src)
|
||||
new /obj/item/reagent_containers/syringe/lethal/choral(src) // what the fuck does anyone use this piece of shit for
|
||||
new /obj/item/clothing/glasses/hud/health/night(src)
|
||||
|
||||
|
||||
/*
|
||||
* Pill Bottles
|
||||
*/
|
||||
@@ -439,8 +439,8 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/tricord(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/tricord(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/tricord(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/tricord(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/tricord(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/fire
|
||||
name = "burn treatment hypospray kit"
|
||||
@@ -452,8 +452,8 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/burn(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/kelotane(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/kelotane(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/kelotane(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/kelotane(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/toxin
|
||||
name = "toxin treatment hypospray kit"
|
||||
@@ -464,8 +464,8 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/toxin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/antitoxin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/antitoxin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/antitoxin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/antitoxin(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/o2
|
||||
name = "oxygen deprivation hypospray kit"
|
||||
@@ -476,8 +476,8 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/oxygen(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/dexalin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/dexalin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/dexalin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/dexalin(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/enlarge
|
||||
name = "organomegaly trauma hypospray kit"
|
||||
@@ -488,12 +488,12 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/enlarge(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/breastreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/penisreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/brute
|
||||
name = "brute trauma hypospray kit"
|
||||
@@ -504,8 +504,8 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/brute(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/bicaridine(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/bicaridine(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/tactical
|
||||
name = "combat hypospray kit"
|
||||
@@ -517,8 +517,8 @@
|
||||
return
|
||||
new /obj/item/defibrillator/compact/combat/loaded(src)
|
||||
new /obj/item/hypospray/mkii/CMO/combat(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/combat(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/combat(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/combat(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/combat(src)
|
||||
|
||||
/obj/item/storage/hypospraykit/cmo
|
||||
name = "deluxe hypospray kit"
|
||||
@@ -537,11 +537,11 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/hypospray/mkii/CMO(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/tricord(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/charcoal(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/salglu(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/dexalin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/synthflesh(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/tricord(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/charcoal(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/salglu(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/dexalin(src)
|
||||
new /obj/item/reagent_containers/glass/bottle/vial/large/synthflesh(src)
|
||||
|
||||
/obj/item/storage/box/vials
|
||||
name = "box of hypovials"
|
||||
|
||||
@@ -225,16 +225,31 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
STR.max_items = 10
|
||||
|
||||
/obj/item/storage/toolbox/artistic/PopulateContents()
|
||||
new/obj/item/storage/crayons(src)
|
||||
new/obj/item/crowbar(src)
|
||||
new/obj/item/stack/cable_coil/red(src)
|
||||
new/obj/item/stack/cable_coil/yellow(src)
|
||||
new/obj/item/stack/cable_coil/blue(src)
|
||||
new/obj/item/stack/cable_coil/green(src)
|
||||
new/obj/item/stack/cable_coil/pink(src)
|
||||
new/obj/item/stack/cable_coil/orange(src)
|
||||
new/obj/item/stack/cable_coil/cyan(src)
|
||||
new/obj/item/stack/cable_coil/white(src)
|
||||
new /obj/item/storage/crayons(src)
|
||||
new /obj/item/crowbar(src)
|
||||
new /obj/item/stack/cable_coil/red(src)
|
||||
new /obj/item/stack/cable_coil/yellow(src)
|
||||
new /obj/item/stack/cable_coil/blue(src)
|
||||
new /obj/item/stack/cable_coil/green(src)
|
||||
new /obj/item/stack/cable_coil/pink(src)
|
||||
new /obj/item/stack/cable_coil/orange(src)
|
||||
new /obj/item/stack/cable_coil/cyan(src)
|
||||
new /obj/item/stack/cable_coil/white(src)
|
||||
|
||||
/obj/item/storage/toolbox/ammo
|
||||
name = "ammo box"
|
||||
desc = "It contains a few clips."
|
||||
icon_state = "ammobox"
|
||||
item_state = "ammobox"
|
||||
|
||||
/obj/item/storage/toolbox/ammo/PopulateContents()
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
|
||||
/obj/item/storage/toolbox/gold_real
|
||||
name = "golden toolbox"
|
||||
@@ -314,4 +329,4 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
generate_rubber_toolbox_icon()
|
||||
icon = GLOB.rubber_toolbox_icons[icon_state]
|
||||
. = ..()
|
||||
AddComponent(/datum/component/bouncy)
|
||||
AddComponent(/datum/component/bouncy)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
. = ..()
|
||||
if(preload_cell_type)
|
||||
if(!ispath(preload_cell_type,/obj/item/stock_parts/cell))
|
||||
log_world("### MAP WARNING, [src] at [AREACOORD(src)] had an invalid preload_cell_type: [preload_cell_type].")
|
||||
log_mapping("[src] at [AREACOORD(src)] had an invalid preload_cell_type: [preload_cell_type].")
|
||||
else
|
||||
cell = new preload_cell_type(src)
|
||||
update_icon()
|
||||
@@ -168,11 +168,9 @@
|
||||
|
||||
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user)
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(L.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
var/stunpwr = stunforce
|
||||
var/obj/item/stock_parts/cell/our_cell = get_cell()
|
||||
if(!our_cell)
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
|
||||
/obj/item/watertank/janitor/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("cleaner", 500)
|
||||
reagents.add_reagent(/datum/reagent/space_cleaner, 500)
|
||||
|
||||
/obj/item/reagent_containers/spray/mister/janitor
|
||||
name = "janitor spray nozzle"
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
/obj/item/watertank/atmos/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("water", 200)
|
||||
reagents.add_reagent(/datum/reagent/water, 200)
|
||||
|
||||
/obj/item/watertank/atmos/make_noz()
|
||||
return new /obj/item/extinguisher/mini/nozzle(src)
|
||||
@@ -376,7 +376,7 @@
|
||||
filling.color = mix_color_from_reagents(reagents.reagent_list)
|
||||
add_overlay(filling)
|
||||
|
||||
/obj/item/reagent_containers/chemtank/worn_overlays(var/isinhands = FALSE) //apply chemcolor and level
|
||||
/obj/item/reagent_containers/chemtank/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE) //apply chemcolor and level
|
||||
. = list()
|
||||
//inhands + reagent_filling
|
||||
if(!isinhands && reagents.total_volume)
|
||||
@@ -436,13 +436,13 @@
|
||||
|
||||
/obj/item/watertank/op/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("mutagen",350)
|
||||
reagents.add_reagent("napalm",125)
|
||||
reagents.add_reagent("welding_fuel",125)
|
||||
reagents.add_reagent("clf3",300)
|
||||
reagents.add_reagent("cryptobiolin",350)
|
||||
reagents.add_reagent("plasma",250)
|
||||
reagents.add_reagent("condensedcapsaicin",500)
|
||||
reagents.add_reagent(/datum/reagent/toxin/mutagen,350)
|
||||
reagents.add_reagent(/datum/reagent/napalm,125)
|
||||
reagents.add_reagent(/datum/reagent/fuel,125)
|
||||
reagents.add_reagent(/datum/reagent/clf3,300)
|
||||
reagents.add_reagent(/datum/reagent/cryptobiolin,350)
|
||||
reagents.add_reagent(/datum/reagent/toxin/plasma,250)
|
||||
reagents.add_reagent(/datum/reagent/consumable/condensedcapsaicin,500)
|
||||
|
||||
/obj/item/reagent_containers/spray/mister/op
|
||||
desc = "A mister nozzle attached to several extended water tanks. It suspiciously has a compressor in the system and is labelled entirely in New Cyrillic."
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/obj/item/tele_iv
|
||||
name = "telescopic IV drip"
|
||||
desc = "An IV drip with an advanced infusion pump that can both drain blood into and inject liquids from attached containers. Blood packs are processed at an accelerated rate. This one is telescopic, and can be picked up and put down."
|
||||
icon = 'icons/obj/iv_drip.dmi'
|
||||
icon_state = "tele_iv"
|
||||
|
||||
/obj/item/tele_iv/attack_self(mob/user)
|
||||
deploy_iv(user, user.loc)
|
||||
|
||||
/obj/item/tele_iv/afterattack(atom/target, mob/user, proximity)
|
||||
. = ..()
|
||||
if(proximity && isopenturf(target) && user.CanReach(target))
|
||||
deploy_iv(user, target)
|
||||
|
||||
/obj/item/tele_iv/proc/deploy_iv(mob/user, atom/location)
|
||||
new /obj/machinery/iv_drip/telescopic(location)
|
||||
qdel(src)
|
||||
@@ -53,7 +53,7 @@
|
||||
base_overlay.appearance_flags = RESET_COLOR
|
||||
add_overlay(base_overlay)
|
||||
|
||||
/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file)
|
||||
/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
|
||||
. = list()
|
||||
if(isinhands && random_color)
|
||||
var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head")
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
/obj/item/weldingtool/Initialize()
|
||||
. = ..()
|
||||
create_reagents(max_fuel)
|
||||
reagents.add_reagent("welding_fuel", max_fuel)
|
||||
reagents.add_reagent(/datum/reagent/fuel, max_fuel)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
/obj/item/weldingtool/proc/explode()
|
||||
var/turf/T = get_turf(loc)
|
||||
var/plasmaAmount = reagents.get_reagent_amount("plasma")
|
||||
var/plasmaAmount = reagents.get_reagent_amount(/datum/reagent/toxin/plasma)
|
||||
dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder
|
||||
qdel(src)
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
|
||||
/obj/item/weldingtool/attack_self(mob/user)
|
||||
if(src.reagents.has_reagent("plasma"))
|
||||
if(src.reagents.has_reagent(/datum/reagent/toxin/plasma))
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] activated a rigged welder at [AREACOORD(user)].")
|
||||
explode()
|
||||
switched_on(user)
|
||||
@@ -154,7 +154,7 @@
|
||||
|
||||
// Returns the amount of fuel in the welder
|
||||
/obj/item/weldingtool/proc/get_fuel()
|
||||
return reagents.get_reagent_amount("welding_fuel")
|
||||
return reagents.get_reagent_amount(/datum/reagent/fuel)
|
||||
|
||||
|
||||
// Uses fuel from the welding tool.
|
||||
@@ -165,7 +165,7 @@
|
||||
if(used)
|
||||
burned_fuel_for = 0
|
||||
if(get_fuel() >= used)
|
||||
reagents.remove_reagent("welding_fuel", used)
|
||||
reagents.remove_reagent(/datum/reagent/fuel, used)
|
||||
check_fuel()
|
||||
return TRUE
|
||||
else
|
||||
@@ -333,7 +333,7 @@
|
||||
|
||||
/obj/item/weldingtool/abductor/process()
|
||||
if(get_fuel() <= max_fuel)
|
||||
reagents.add_reagent("welding_fuel", 1)
|
||||
reagents.add_reagent(/datum/reagent/fuel, 1)
|
||||
..()
|
||||
|
||||
/obj/item/weldingtool/hugetank
|
||||
@@ -377,7 +377,7 @@
|
||||
..()
|
||||
if(get_fuel() < max_fuel && nextrefueltick < world.time)
|
||||
nextrefueltick = world.time + 10
|
||||
reagents.add_reagent("welding_fuel", 1)
|
||||
reagents.add_reagent(/datum/reagent/fuel, 1)
|
||||
|
||||
/obj/item/weldingtool/advanced
|
||||
name = "advanced welding tool"
|
||||
@@ -390,7 +390,7 @@
|
||||
|
||||
/obj/item/weldingtool/advanced/process()
|
||||
if(get_fuel() <= max_fuel)
|
||||
reagents.add_reagent("welding_fuel", 1)
|
||||
reagents.add_reagent(/datum/reagent/fuel, 1)
|
||||
..()
|
||||
|
||||
#undef WELDER_FUEL_BURN_INTERVAL
|
||||
|
||||
@@ -353,7 +353,7 @@
|
||||
update_light()
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
|
||||
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(isinhands)
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
name = "crushed can"
|
||||
icon_state = "cola"
|
||||
resistance_flags = NONE
|
||||
grind_results = list("aluminium" = 10)
|
||||
grind_results = list(/datum/reagent/aluminium = 10)
|
||||
|
||||
/obj/item/trash/boritos
|
||||
name = "boritos bag"
|
||||
icon_state = "boritos"
|
||||
grind_results = list("aluminium" = 1) //from the mylar bag
|
||||
grind_results = list(/datum/reagent/aluminium = 1) //from the mylar bag
|
||||
|
||||
/obj/item/trash/attack(mob/M, mob/living/user)
|
||||
return
|
||||
|
||||
@@ -556,7 +556,7 @@
|
||||
update_light()
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file)
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, style_flags = NONE)
|
||||
. = ..()
|
||||
if(isinhands)
|
||||
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
|
||||
@@ -872,7 +872,7 @@
|
||||
user.visible_message("<span class='danger'>[user] blasts \the [target] with \the [src]!</span>")
|
||||
playsound(target, 'sound/magic/disintegrate.ogg', 100, 1)
|
||||
W.break_wall()
|
||||
W.ScrapeAway()
|
||||
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return
|
||||
|
||||
//HF blade
|
||||
|
||||
@@ -80,13 +80,12 @@
|
||||
SEND_SIGNAL(src, COMSIG_OBJ_SETANCHORED, anchorvalue)
|
||||
anchored = anchorvalue
|
||||
|
||||
/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
..()
|
||||
/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, messy_throw)
|
||||
. = ..()
|
||||
if(obj_flags & FROZEN)
|
||||
visible_message("<span class='danger'>[src] shatters into a million pieces!</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/assume_air(datum/gas_mixture/giver)
|
||||
if(loc)
|
||||
return loc.assume_air(giver)
|
||||
|
||||
@@ -88,6 +88,28 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/chair/alt_attack_hand(mob/living/user)
|
||||
if(Adjacent(user) && istype(user))
|
||||
if(!item_chair || !user.can_hold_items() || !has_buckled_mobs() || buckled_mobs.len > 1 || dir != user.dir || flags_1 & NODECONSTRUCT_1)
|
||||
return TRUE
|
||||
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return TRUE
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
|
||||
return TRUE
|
||||
var/mob/living/poordude = buckled_mobs[1]
|
||||
if(!istype(poordude))
|
||||
return TRUE
|
||||
user.visible_message("<span class='notice'>[user] pulls [src] out from under [poordude].</span>", "<span class='notice'>You pull [src] out from under [poordude].</span>")
|
||||
var/C = new item_chair(loc)
|
||||
user.put_in_hands(C)
|
||||
poordude.Knockdown(20)//rip in peace
|
||||
user.adjustStaminaLoss(5)
|
||||
unbuckle_all_mobs(TRUE)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/chair/attack_tk(mob/user)
|
||||
if(!anchored || has_buckled_mobs() || !isturf(user.loc))
|
||||
..()
|
||||
|
||||
@@ -252,7 +252,7 @@ LINEN BINS
|
||||
add_overlay(g_mouth)
|
||||
add_overlay(g_eyes)
|
||||
|
||||
/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file)
|
||||
/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands)
|
||||
. += mutable_appearance(icon_file, g_mouth)
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
if(opened || move_delay || user.stat || user.IsStun() || user.IsKnockdown() || user.IsUnconscious() || !isturf(loc) || !has_gravity(loc))
|
||||
return
|
||||
move_delay = TRUE
|
||||
if(step(src, direction))
|
||||
var/oldloc = loc
|
||||
step(src, direction)
|
||||
if(oldloc != loc)
|
||||
addtimer(CALLBACK(src, .proc/ResetMoveDelay), (use_mob_movespeed ? user.movement_delay() : CONFIG_GET(number/movedelay/walk_delay)) * move_speed_multiplier)
|
||||
else
|
||||
ResetMoveDelay()
|
||||
|
||||
@@ -12,18 +12,12 @@
|
||||
new /obj/item/clothing/head/hardhat/white(src)
|
||||
new /obj/item/clothing/head/hardhat/weldhat/white(src)
|
||||
new /obj/item/clothing/gloves/color/yellow(src)
|
||||
new /obj/item/clothing/shoes/sneakers/brown(src)
|
||||
new /obj/item/tank/jetpack/suit(src)
|
||||
new /obj/item/cartridge/ce(src)
|
||||
new /obj/item/radio/headset/heads/ce(src)
|
||||
new /obj/item/storage/toolbox/mechanical(src)
|
||||
new /obj/item/clothing/suit/hazardvest(src)
|
||||
new /obj/item/megaphone/command(src)
|
||||
new /obj/item/areaeditor/blueprints(src)
|
||||
new /obj/item/airlock_painter(src)
|
||||
new /obj/item/holosign_creator/engineering(src)
|
||||
new /obj/item/clothing/mask/gas(src)
|
||||
new /obj/item/multitool(src)
|
||||
new /obj/item/assembly/flash/handheld(src)
|
||||
new /obj/item/clothing/glasses/meson/engine(src)
|
||||
new /obj/item/door_remote/chief_engineer(src)
|
||||
@@ -67,7 +61,7 @@
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/head/welding(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/weldingtool(src)
|
||||
new /obj/item/weldingtool/largetank(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_personal
|
||||
name = "engineer's locker"
|
||||
@@ -84,7 +78,6 @@
|
||||
new /obj/item/clothing/glasses/meson/engine(src)
|
||||
new /obj/item/storage/box/emptysandbags(src)
|
||||
|
||||
|
||||
/obj/structure/closet/secure_closet/atmospherics
|
||||
name = "\proper atmospheric technician's locker"
|
||||
req_access = list(ACCESS_ATMOSPHERICS)
|
||||
@@ -103,3 +96,33 @@
|
||||
new /obj/item/clothing/head/hardhat/atmos(src)
|
||||
new /obj/item/clothing/glasses/meson/engine/tray(src)
|
||||
new /obj/item/extinguisher/advanced(src)
|
||||
|
||||
/*
|
||||
* Empty lockers
|
||||
* Some of the lockers are filled with junk, and sometimes its nice to just fill it with your own set-up for your own map gimmicks.
|
||||
*/
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_chief/empty
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_chief/empty/PopulateContents()
|
||||
return
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_electrical/empty
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_electrical/empty/PopulateContents()
|
||||
return
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_welding/empty
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_welding/empty/PopulateContents()
|
||||
return
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_personal/empty
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_personal/empty/PopulateContents()
|
||||
return
|
||||
|
||||
/obj/structure/closet/secure_closet/atmospherics/empty
|
||||
|
||||
/obj/structure/closet/secure_closet/atmospherics/empty/PopulateContents()
|
||||
return
|
||||
|
||||
@@ -237,6 +237,12 @@
|
||||
start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr
|
||||
req_access = list(ACCESS_RD)
|
||||
|
||||
/obj/structure/displaycase/clown
|
||||
desc = "In the event of clown, honk glass."
|
||||
alert = TRUE
|
||||
start_showpiece_type = /obj/item/bikehorn
|
||||
req_access = list(ACCESS_CENT_GENERAL)
|
||||
|
||||
/obj/structure/displaycase/trophy
|
||||
name = "trophy display case"
|
||||
desc = "Store your trophies of accomplishment in here, and they will stay forever."
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
return
|
||||
last_process = world.time
|
||||
to_chat(user, "<span class='notice'>The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.</span>")
|
||||
user.reagents.add_reagent("godblood",20)
|
||||
user.reagents.add_reagent(/datum/reagent/medicine/omnizine/godblood,20)
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src, /atom/.proc/update_icon), time_between_uses)
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
return
|
||||
|
||||
var/list/undergarment_choices = list("Underwear", "Underwear Color", "Undershirt", "Undershirt Color", "Socks", "Socks Color")
|
||||
if(!UNDIE_COLORABLE(GLOB.underwear_list[H.underwear]))
|
||||
if(!(GLOB.underwear_list[H.underwear]?.has_color))
|
||||
undergarment_choices -= "Underwear Color"
|
||||
if(!UNDIE_COLORABLE(GLOB.undershirt_list[H.undershirt]))
|
||||
if(!(GLOB.undershirt_list[H.undershirt]?.has_color))
|
||||
undergarment_choices -= "Undershirt Color"
|
||||
if(!UNDIE_COLORABLE(GLOB.socks_list[H.socks]))
|
||||
if(!(GLOB.socks_list[H.socks]?.has_color))
|
||||
undergarment_choices -= "Socks Color"
|
||||
|
||||
var/choice = input(H, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in undergarment_choices
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
new/obj/structure/fluff/empty_terrarium(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/carbon/human/new_spawn)
|
||||
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
|
||||
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker
|
||||
@@ -251,6 +253,9 @@
|
||||
new/obj/structure/fluff/empty_cryostasis_sleeper(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/hermit/special(mob/living/carbon/human/new_spawn)
|
||||
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
|
||||
|
||||
//Broken rejuvenation pod: Spawns in animal hospitals in lavaland. Ghosts become disoriented interns and are advised to search for help.
|
||||
/obj/effect/mob_spawn/human/doctor/alive/lavaland
|
||||
name = "broken rejuvenation pod"
|
||||
@@ -353,6 +358,9 @@
|
||||
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
|
||||
..()
|
||||
|
||||
/obj/effect/mob_spawn/human/hotel_staff/special(mob/living/carbon/human/new_spawn)
|
||||
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
|
||||
|
||||
/obj/effect/mob_spawn/human/demonic_friend
|
||||
name = "Essence of friendship"
|
||||
desc = "Oh boy! Oh boy! A friend!"
|
||||
@@ -597,7 +605,7 @@
|
||||
rank = "Gunner"
|
||||
|
||||
/obj/effect/mob_spawn/human/ghostcafe
|
||||
name = "ghost cafe sleeper"
|
||||
name = "Ghost Cafe Sleeper"
|
||||
uses = -1
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
@@ -618,12 +626,20 @@
|
||||
O.equip(new_spawn, FALSE, new_spawn.client)
|
||||
SSjob.equip_loadout(null, new_spawn, FALSE)
|
||||
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
|
||||
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
|
||||
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
|
||||
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
|
||||
to_chat(new_spawn,"<span class='boldwarning'>You maybe sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!</span>")
|
||||
to_chat(new_spawn,"<span class='boldwarning'>You can turn yourself into a ghost and freely reenter your body with the ghost action.</span>")
|
||||
var/datum/action/ghost/G = new(new_spawn)
|
||||
G.Grant(new_spawn)
|
||||
|
||||
/datum/outfit/ghostcafe
|
||||
name = "ID, jumpsuit and shoes"
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
id = /obj/item/card/id
|
||||
r_hand = /obj/item/storage/box/syndie_kit/chameleon/ghostcafe
|
||||
|
||||
|
||||
/datum/outfit/ghostcafe/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
|
||||
@@ -639,4 +655,18 @@
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
else
|
||||
uniform = /obj/item/clothing/under/skirt/color/random
|
||||
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chameleon/ghostcafe
|
||||
name = "ghost cafe costuming kit"
|
||||
desc = "Look just the way you did in life - or better!"
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chameleon/ghostcafe/PopulateContents() // Doesn't contain a PDA, for isolation reasons.
|
||||
new /obj/item/clothing/under/chameleon(src)
|
||||
new /obj/item/clothing/suit/chameleon(src)
|
||||
new /obj/item/clothing/gloves/chameleon(src)
|
||||
new /obj/item/clothing/shoes/chameleon(src)
|
||||
new /obj/item/clothing/glasses/chameleon(src)
|
||||
new /obj/item/clothing/head/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon(src)
|
||||
new /obj/item/storage/backpack/chameleon(src)
|
||||
new /obj/item/clothing/neck/cloak/chameleon(src)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
/obj/structure/grille/attack_animal(mob/user)
|
||||
. = ..()
|
||||
if(!shock(user, 70))
|
||||
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)
|
||||
|
||||
/obj/structure/grille/attack_paw(mob/user)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// flags = CONDUCT_1
|
||||
|
||||
/obj/structure/lattice/examine(mob/user)
|
||||
..()
|
||||
. = ..()
|
||||
. += deconstruction_hints(user)
|
||||
|
||||
/obj/structure/lattice/proc/deconstruction_hints(mob/user)
|
||||
@@ -60,7 +60,7 @@
|
||||
to_chat(user, "<span class='notice'>You build a floor.</span>")
|
||||
var/turf/T = src.loc
|
||||
if(isspaceturf(T))
|
||||
T.PlaceOnTop(/turf/open/floor/plating)
|
||||
T.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -102,13 +102,13 @@
|
||||
/obj/structure/stairs/proc/force_open_above()
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
if(T && !istype(T))
|
||||
T.ChangeTurf(/turf/open/openspace)
|
||||
T.ChangeTurf(/turf/open/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)
|
||||
if(T && !istype(T))
|
||||
T.ChangeTurf(/turf/open/openspace)
|
||||
T.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
/obj/structure/stairs/intercept_zImpact(atom/movable/AM, levels = 1)
|
||||
. = ..()
|
||||
|
||||
@@ -182,6 +182,17 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/alt_attack_hand(mob/user)
|
||||
if(user && Adjacent(user) && !user.incapacitated())
|
||||
user.setClickCooldown(4)
|
||||
if(istype(user) && user.a_intent == INTENT_HARM)
|
||||
user.visible_message("<span class='warning'>[user] slams [user.p_their()] palms down on [src].</span>", "<span class='warning'>You slam your palms down on [src].</span>")
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] slaps [user.p_their()] hands on [src].</span>", "<span class='notice'>You slap your hands on [src].</span>")
|
||||
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
|
||||
user.do_attack_animation(src)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user