This commit is contained in:
Ghommie
2020-04-01 00:49:13 +02:00
277 changed files with 3182 additions and 3104 deletions
+3 -1
View File
@@ -149,7 +149,9 @@
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
#define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat.
#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize)
#define COMPONENT_BLOCK_GHOSTING 1
#define COMPONENT_BLOCK_GHOSTING (1<<0)
#define COMPONENT_DO_NOT_PENALIZE_GHOSTING (1<<1)
#define COMPONENT_FREE_GHOSTING (1<<2)
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources)
#define COMPONENT_BLOCK_MAGIC 1
+28
View File
@@ -4,11 +4,16 @@
#define CLICKCATCHER_PLANE -99
#define PLANE_SPACE -95
#define PLANE_SPACE_RENDER_TARGET "PLANE_SPACE"
#define PLANE_SPACE_PARALLAX -90
#define PLANE_SPACE_PARALLAX_RENDER_TARGET "PLANE_SPACE_PARALLAX"
#define FLOOR_PLANE -2
#define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE"
#define GAME_PLANE -1
#define GAME_PLANE_RENDER_TARGET "GAME_PLANE"
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE"
#define SPACE_LAYER 1.8
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
@@ -78,20 +83,38 @@
#define MASSIVE_OBJ_LAYER 11
#define POINT_LAYER 12
#define EMISSIVE_BLOCKER_PLANE 12
#define EMISSIVE_BLOCKER_LAYER 12
#define EMISSIVE_BLOCKER_RENDER_TARGET "*EMISSIVE_BLOCKER_PLANE"
#define EMISSIVE_PLANE 13
#define EMISSIVE_LAYER 13
#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE"
#define EMISSIVE_UNBLOCKABLE_PLANE 14
#define EMISSIVE_UNBLOCKABLE_LAYER 14
#define EMISSIVE_UNBLOCKABLE_RENDER_TARGET "*EMISSIVE_UNBLOCKABLE_PLANE"
#define LIGHTING_PLANE 15
#define LIGHTING_LAYER 15
#define LIGHTING_RENDER_TARGET "LIGHT_PLANE"
#define ABOVE_LIGHTING_PLANE 16
#define ABOVE_LIGHTING_LAYER 16
#define ABOVE_LIGHTING_RENDER_TARGET "ABOVE_LIGHTING_PLANE"
#define FLOOR_OPENSPACE_PLANE 17
#define OPENSPACE_LAYER 17
#define OPENSPACE_RENDER_TARGET "OPENSPACE_PLANE"
#define BYOND_LIGHTING_PLANE 18
#define BYOND_LIGHTING_LAYER 18
#define BYOND_LIGHTING_RENDER_TARGET "BYOND_LIGHTING_PLANE"
#define CAMERA_STATIC_PLANE 19
#define CAMERA_STATIC_LAYER 19
#define CAMERA_STATIC_RENDER_TARGET "CAMERA_STATIC_PLANE"
//HUD layer defines
#define FULLSCREEN_PLANE 20
@@ -101,11 +124,16 @@
#define BLIND_LAYER 20.3
#define CRIT_LAYER 20.4
#define CURSE_LAYER 20.5
#define FULLSCREEN_RENDER_TARGET "FULLSCREEN_PLANE"
#define HUD_PLANE 21
#define HUD_LAYER 21
#define HUD_RENDER_TARGET "HUD_PLANE"
#define ABOVE_HUD_PLANE 22
#define ABOVE_HUD_LAYER 22
#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE"
#define SPLASHSCREEN_LAYER 23
#define SPLASHSCREEN_PLANE 23
#define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE"
+5
View File
@@ -83,3 +83,8 @@
#define FLASH_LIGHT_DURATION 2
#define FLASH_LIGHT_POWER 3
#define FLASH_LIGHT_RANGE 3.8
/// Uses vis_overlays to leverage caching so that very few new items need to be made for the overlay. For anything that doesn't change outline or opaque area much or at all.
#define EMISSIVE_BLOCK_GENERIC 1
/// Uses a dedicated render_target object to copy the entire appearance in real time to the blocking layer. For things that can change in appearance a lot from the base state, like humans.
#define EMISSIVE_BLOCK_UNIQUE 2
+1
View File
@@ -212,6 +212,7 @@
#define TRAIT_NO_TELEPORT "no-teleport" //you just can't
#define TRAIT_NO_INTERNALS "no-internals"
#define TRAIT_NO_ALCOHOL "alcohol_intolerance"
#define TRAIT_MUTATION_STASIS "mutation_stasis" //Prevents processed genetics mutations from processing.
// common trait sources
#define TRAIT_GENERIC "generic"
+51
View File
@@ -16,6 +16,7 @@
//Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong.
/obj/screen/plane_master/proc/backdrop(mob/mymob)
///Things rendered on "openspace"; holes in multi-z
/obj/screen/plane_master/openspace
name = "open space plane master"
plane = FLOOR_OPENSPACE_PLANE
@@ -38,12 +39,14 @@
/obj/screen/plane_master/proc/clear_filters()
filters = list()
///Contains just the floor
/obj/screen/plane_master/floor
name = "floor plane master"
plane = FLOOR_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_OVERLAY
///Contains most things in the game world
/obj/screen/plane_master/game_world
name = "game world plane master"
plane = GAME_PLANE
@@ -57,12 +60,60 @@
remove_filter("ambient_occlusion")
update_filters()
///Contains all lighting objects
/obj/screen/plane_master/lighting
name = "lighting plane master"
plane = LIGHTING_PLANE
blend_mode = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/plane_master/lighting/Initialize()
. = ..()
filters += filter(type="alpha", render_source=EMISSIVE_RENDER_TARGET, flags=MASK_INVERSE)
filters += filter(type="alpha", render_source=EMISSIVE_UNBLOCKABLE_RENDER_TARGET, flags=MASK_INVERSE)
/**
* Things placed on this mask the lighting plane. Doesn't render directly.
*
* Gets masked by blocking plane. Use for things that you want blocked by
* mobs, items, etc.
*/
/obj/screen/plane_master/emissive
name = "emissive plane master"
plane = EMISSIVE_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_target = EMISSIVE_RENDER_TARGET
/obj/screen/plane_master/emissive/Initialize()
. = ..()
filters += filter(type="alpha", render_source=EMISSIVE_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE)
/**
* Things placed on this always mask the lighting plane. Doesn't render directly.
*
* Always masks the light plane, isn't blocked by anything. Use for on mob glows,
* magic stuff, etc.
*/
/obj/screen/plane_master/emissive_unblockable
name = "unblockable emissive plane master"
plane = EMISSIVE_UNBLOCKABLE_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_target = EMISSIVE_UNBLOCKABLE_RENDER_TARGET
/**
* Things placed on this layer mask the emissive layer. Doesn't render directly
*
* You really shouldn't be directly using this, use atom helpers instead
*/
/obj/screen/plane_master/emissive_unblockable
name = "emissive mob plane master"
plane = EMISSIVE_BLOCKER_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_target = EMISSIVE_BLOCKER_RENDER_TARGET
///Contains space parallax
/obj/screen/plane_master/parallax
name = "parallax plane master"
plane = PLANE_SPACE_PARALLAX
@@ -368,12 +368,16 @@
var/list/datum/dynamic_storyteller/runnable_storytellers = new
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players)
for(var/T in storyteller_cache)
var/datum/dynamic_storyteller/S = T
var/config_tag = initial(S.config_tag)
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players)
if(probability <= 0)
continue
if(length(GLOB.player_list) < min_players)
continue
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
var/name = initial(S.name)
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
@@ -92,3 +92,7 @@
/datum/config_entry/keyed_list/storyteller_weight
key_mode = KEY_MODE_TEXT
value_mode = VALUE_MODE_NUM
/datum/config_entry/keyed_list/storyteller_min_players
key_mode = KEY_MODE_TEXT
value_mode = VALUE_MODE_NUM
+16 -2
View File
@@ -1,12 +1,17 @@
/datum/element/ghost_role_eligibility
element_flags = ELEMENT_DETACH
element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
id_arg_index = 3
var/list/timeouts = list()
var/list/mob/eligible_mobs = list()
var/penalizing = FALSE
var/free_ghost = FALSE
/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE)
/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE,free_ghosting = FALSE, penalize_on_ghost = FALSE)
. = ..()
if(!ismob(target))
return ELEMENT_INCOMPATIBLE
penalizing = penalize_on_ghost
free_ghost = free_ghosting
var/mob/M = target
if(!(M in eligible_mobs))
eligible_mobs += M
@@ -27,6 +32,7 @@
else if(timeouts[M.ckey] == CANT_REENTER_ROUND)
return
timeouts[M.ckey] = max(timeouts[M.ckey],penalty)
RegisterSignal(M,COMSIG_MOB_GHOSTIZE,.proc/get_ghost_flags)
/datum/element/ghost_role_eligibility/Detach(mob/M)
. = ..()
@@ -56,3 +62,11 @@
if(!silent && M.client)
to_chat(M, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
return FALSE
/datum/element/ghost_role_eligibility/proc/get_ghost_flags()
. = 0
if(!penalizing)
. |= COMPONENT_DO_NOT_PENALIZE_GHOSTING
if(free_ghost)
. |= COMPONENT_FREE_GHOSTING
return .
-1
View File
@@ -470,7 +470,6 @@
/datum/objective/steal,
/datum/objective/download,
/datum/objective/nuclear,
/datum/objective/capture,
/datum/objective/absorb,
/datum/objective/custom
)
+31
View File
@@ -39,6 +39,37 @@
var/zfalling = FALSE
/// Either FALSE, [EMISSIVE_BLOCK_GENERIC], or [EMISSIVE_BLOCK_UNIQUE]
var/blocks_emissive = FALSE
///Internal holder for emissive blocker object, do not use directly use blocks_emissive
var/atom/movable/emissive_blocker/em_block
/atom/movable/Initialize(mapload)
. = ..()
switch(blocks_emissive)
if(EMISSIVE_BLOCK_GENERIC)
update_emissive_block()
if(EMISSIVE_BLOCK_UNIQUE)
render_target = ref(src)
em_block = new(src, render_target)
vis_contents += em_block
/atom/movable/Destroy()
QDEL_NULL(em_block)
return ..()
/atom/movable/proc/update_emissive_block()
if(blocks_emissive != EMISSIVE_BLOCK_GENERIC)
return
if(length(managed_vis_overlays))
for(var/a in managed_vis_overlays)
var/obj/effect/overlay/vis/vs
if(vs.plane == EMISSIVE_BLOCKER_PLANE)
SSvis_overlays.remove_vis_overlay(src, list(vs))
break
SSvis_overlays.add_vis_overlay(src, icon, icon_state, EMISSIVE_BLOCKER_LAYER, EMISSIVE_BLOCKER_PLANE)
/atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction)
if(!direction)
direction = DOWN
+14 -13
View File
@@ -127,6 +127,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
var/only_ruleset_executed = FALSE
/// Antags rolled by rules so far, to keep track of and discourage scaling past a certain ratio of crew/antags especially on lowpop.
var/antags_rolled = 0
// Arbitrary threat addition, for fudging purposes.
var/added_threat = 50
/datum/game_mode/dynamic/New() // i have NO IDEA if this is the proper way to do this.
..()
@@ -172,9 +174,9 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
else
dat += "none.<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>"
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
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)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
/datum/game_mode/dynamic/Topic(href, href_list)
@@ -511,7 +513,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
starting_rule.trim_candidates()
starting_rule.scale_up(extra_rulesets_amount, threat)
if (starting_rule.pre_execute())
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> -[starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> [starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
if(starting_rule.flags & HIGHLANDER_RULESET)
highlander_executed = TRUE
else if(starting_rule.flags & ONLY_RULESET)
@@ -605,7 +607,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat)))
new_rule.trim_candidates()
if (new_rule.ready(forced))
log_threat("[new_rule.ruletype] - <b>[new_rule.name]</b> -[new_rule.cost] threat", verbose = TRUE)
log_threat("[new_rule.ruletype] - <b>[new_rule.name]</b> [new_rule.cost] threat", verbose = TRUE)
if (new_rule.execute()) // This should never fail since ready() returned 1
if(new_rule.flags & HIGHLANDER_RULESET)
highlander_executed = TRUE
@@ -625,7 +627,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
var/datum/dynamic_ruleset/rule = sent_rule
if (rule.execute())
log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].")
log_threat("[rule.ruletype] [rule.name] spent [rule.cost]", verbose = TRUE)
log_threat("[rule.ruletype] [rule.name] added [rule.cost]", verbose = TRUE)
if(rule.flags & HIGHLANDER_RULESET)
highlander_executed = TRUE
else if(rule.flags & ONLY_RULESET)
@@ -712,8 +714,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
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)
threat = storyteller.calculate_threat() + 50 // 50 is the centerpoint, so we want it to be around 50
threat = storyteller.calculate_threat() + added_threat
/// Removes type from the list
/datum/game_mode/dynamic/proc/remove_from_list(list/type_list, type)
for(var/I in type_list)
@@ -766,20 +767,20 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
/// Increase the threat level.
/datum/game_mode/dynamic/proc/create_threat(gain)
threat_level += gain
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat")
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat level")
log_threat("[gain] created. Threat level is now [threat_level].", verbose = TRUE)
/// Decrease the threat level.
/datum/game_mode/dynamic/proc/remove_threat(loss)
threat_level -= loss
SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat")
SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat level")
log_threat("[loss] removed. Threat level is now [threat_level].", verbose = TRUE)
/// Fill up more of the threat level.
/datum/game_mode/dynamic/proc/spend_threat(cost)
threat += cost
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat spent")
log_threat("[cost] spent. Threat is now [threat].", verbose = TRUE)
added_threat += cost
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat added")
log_threat("[cost] added. Threat is now [threat].", verbose = TRUE)
/// Turns the value generated by lorentz distribution to threat value between 0 and 100.
/datum/game_mode/dynamic/proc/lorentz_to_threat(x)
@@ -415,7 +415,7 @@
required_candidates = 1
blocking_rules = list(/datum/dynamic_ruleset/roundstart/clockcult)
weight = 4
cost = 10
cost = 20
requirements = list(101,101,101,80,60,50,50,50,50,50)
high_population_requirement = 50
repeatable = TRUE
@@ -17,6 +17,7 @@
var/weight = 3 // Weights for randomly picking storyteller. Multiplied by score after voting.
var/event_frequency_lower = 6 MINUTES // How rare events will be, at least.
var/event_frequency_upper = 20 MINUTES // How rare events will be, at most.
var/min_players = -1 // How many players are required for this one to start.
var/datum/game_mode/dynamic/mode = null // Cached as soon as it's made, by dynamic.
/**
@@ -114,7 +115,7 @@ Property weights are:
/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
if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level)) // If we got the population and threat required
rule.candidates = mode.candidates.Copy()
rule.trim_candidates()
if (rule.ready() && rule.candidates.len > 0)
@@ -195,11 +196,12 @@ Property weights are:
config_tag = "chaotic"
curve_centre = 10
desc = "High chaos modes. Revs, wizard, clock cult. Multiple antags at once. Chaos is kept up all round."
property_weights = list("extended" = -1, "chaos" = 2)
property_weights = list("extended" = -1, "chaos" = 1)
weight = 1
event_frequency_lower = 2 MINUTES
event_frequency_upper = 10 MINUTES
flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON
min_players = 40
var/refund_cooldown = 0
/datum/dynamic_storyteller/chaotic/do_process()
@@ -221,6 +223,7 @@ Property weights are:
curve_centre = 2
curve_width = 1.5
weight = 2
min_players = 30
flags = WAROPS_ALWAYS_ALLOWED
property_weights = list("valid" = 3, "trust" = 5)
+2 -2
View File
@@ -663,7 +663,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(count)
target_amount = count
update_explanation_text()
/*
/datum/objective/capture
name = "capture"
var/captured_amount = 0
@@ -709,7 +709,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(count)
target_amount = count
update_explanation_text()
*/
//Changeling Objectives
/datum/objective/absorb
+2
View File
@@ -180,6 +180,7 @@
//Get the clone body ready
maim_clone(H)
ADD_TRAIT(H, TRAIT_MUTATION_STASIS, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
@@ -369,6 +370,7 @@
return
REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_MUTATION_STASIS, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, CLONING_POD_TRAIT)
+1 -1
View File
@@ -62,7 +62,7 @@
if(stat & BROKEN)
overlay_state = "[icon_state]_broken"
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha=128)
/obj/machinery/computer/power_change()
..()
+1 -1
View File
@@ -94,4 +94,4 @@
overlay_state = "alert:0"
. |= overlay_state
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha=128)
@@ -94,4 +94,4 @@
overlay_state = "alert:0"
. |= overlay_state
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha=128)
+1
View File
@@ -61,6 +61,7 @@
icon = 'icons/obj/doors/shutters_window.dmi'
icon_state = "closed"
opacity = 0
glass = 1
/obj/machinery/door/poddoor/shutters/window/preopen
icon_state = "open"
+5 -5
View File
@@ -77,23 +77,23 @@
if(is_station_level(z))
. += "fire_[GLOB.security_level]"
SSvis_overlays.add_vis_overlay(src, icon, "fire_[GLOB.security_level]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "fire_[GLOB.security_level]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
else
. += "fire_[SEC_LEVEL_GREEN]"
SSvis_overlays.add_vis_overlay(src, icon, "fire_[SEC_LEVEL_GREEN]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "fire_[SEC_LEVEL_GREEN]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
var/area/A = src.loc
A = A.loc
if(!detecting || !A.fire)
. += "fire_off"
SSvis_overlays.add_vis_overlay(src, icon, "fire_off", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "fire_off", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
else if(obj_flags & EMAGGED)
. += "fire_emagged"
SSvis_overlays.add_vis_overlay(src, icon, "fire_emagged", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "fire_emagged", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
else
. += "fire_on"
SSvis_overlays.add_vis_overlay(src, icon, "fire_on", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "fire_on", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
/obj/machinery/firealarm/emp_act(severity)
. = ..()
+2
View File
@@ -7,6 +7,8 @@
move_resist = INFINITY
obj_flags = 0
vis_flags = NONE
/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
return
+1
View File
@@ -7,6 +7,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
var/item_state = null
var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
+7 -2
View File
@@ -13,6 +13,7 @@
var/lit = FALSE
var/infinite = FALSE
var/start_lit = FALSE
var/heats_space = TRUE
/obj/item/candle/Initialize()
. = ..()
@@ -35,7 +36,7 @@
return ..()
/obj/item/candle/get_temperature()
return lit * heat
return lit * heat * heats_space
/obj/item/candle/proc/light(show_message)
if(!lit)
@@ -67,7 +68,8 @@
new /obj/item/trash/candle(loc)
qdel(src)
update_icon()
open_flame()
if(heats_space)
open_flame()
/obj/item/candle/attack_self(mob/user)
if(put_out_candle())
@@ -77,4 +79,7 @@
infinite = TRUE
start_lit = TRUE
/obj/item/candle/infinite/hugbox
heats_space = FALSE
#undef CANDLE_LUMINOSITY
+1 -1
View File
@@ -494,7 +494,7 @@
S.ckey = C.ckey
S.status_flags |= GODMODE
S.language_holder = user.language_holder.copy(S)
S.AddElement(/datum/element/ghost_role_eligibility)
S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE)
START_PROCESSING(SSprocessing,src)
var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN)
@@ -674,17 +674,14 @@
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)
new_spawn.AddElement(/datum/element/ghost_role_eligibility, free_ghosting = TRUE)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel))
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn, TRAIT_EXEMPT_HEALTH_EVENTS, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still elegible for ghost roles popups.
ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still eligible for ghost roles popups.
ADD_TRAIT(new_spawn, TRAIT_PACIFISM, GHOSTROLE_TRAIT)
to_chat(new_spawn,"<span class='boldwarning'>You may be 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)
to_chat(new_spawn,"<span class='boldwarning'>Ghosting is free!</span>")
var/datum/action/toggle_dead_chat_mob/D = new(new_spawn)
D.Grant(new_spawn)
+3
View File
@@ -47,6 +47,9 @@
// by default, vis_contents is inherited from the turf that was here before
vis_contents.Cut()
if(color)
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
assemble_baseturfs()
levelupdate()
@@ -74,12 +74,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
qdel(src)
@@ -34,7 +34,7 @@
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[T.owner.name] spent [threat_spent] on an assassination target.")
mode.log_threat("[T.owner.name] added [threat_spent] on an assassination target.")
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
@@ -96,6 +96,13 @@
equip(silent)
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
/datum/antagonist/traitor/antag_panel_objectives()
. = ..()
if(contractor_hub?.assigned_targets && length(contractor_hub.assigned_targets))
. += "<i><b>Contract Targets</b></i>:<br>"
for(var/datum/mind/M in contractor_hub.assigned_targets)
. += "<b> - </b>[key_name(M, FALSE, TRUE)]<br>"
/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
. = ..()
update_traitor_icons_added()
@@ -87,7 +87,7 @@
As is policy we've taken a portion of the station's funds to offset the overall cost.", null, "attention", null, "Nanotrasen Asset Protection")
/datum/syndicate_contract/proc/handleVictimExperience(var/mob/living/M) // They're off to holding - handle the return timer and give some text about what's going on.
addtimer(CALLBACK(src, .proc/returnVictim, M), (60 * 10) * 4) // Ship 'em back - dead or alive... 4 minutes wait.
addtimer(CALLBACK(src, .proc/returnVictim, M), 4 MINUTES) // Ship 'em back - dead or alive... 4 minutes wait.
if(M.stat != DEAD) //Even if they weren't the target, we're still treating them the same.
M.reagents.add_reagent(/datum/reagent/medicine/omnizine, 20) // Heal them up - gets them out of crit/soft crit.
M.flash_act()
@@ -147,4 +147,4 @@
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.can_heartattack())
C.set_heartattack(TRUE)
C.set_heartattack(TRUE)
@@ -667,7 +667,8 @@
else
set_light(0)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
update_light()
/obj/machinery/airalarm/process()
-38
View File
@@ -164,17 +164,6 @@
/obj/item/shield/riot)
crate_name = "riot shields crate"
/datum/supply_pack/security/armory/riotshotguns
name = "Riot Shotgun Crate"
desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
cost = 6500
contains = list(/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/storage/box/rubbershot,
/obj/item/storage/box/beanbag)
crate_name = "riot shotgun crate"
/datum/supply_pack/security/armory/russian
name = "Russian Surplus Crate"
desc = "Hello Comrade, we have the most modern russian military equipment the black market can offer, for the right price of course. Sadly we couldnt remove the lock so it requires Armory access to open."
@@ -216,23 +205,6 @@
/obj/item/clothing/gloves/combat)
crate_name = "swat crate"
/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
name = "SWAT tactical tasers Crate"
desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
cost = 7000
contains = list(/obj/item/gun/energy/e_gun/stun,
/obj/item/gun/energy/e_gun/stun)
crate_name = "swat taser crate"
/datum/supply_pack/security/armory/woodstock
name = "WoodStock Classic Shotguns Crate"
desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun)
crate_name = "woodstock shotguns crate"
/datum/supply_pack/security/armory/wt550
name = "WT-550 Semi-Auto Rifle Crate"
desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
@@ -260,13 +232,3 @@
/obj/item/ammo_box/magazine/wt550m9/wtrubber,
/obj/item/ammo_box/magazine/wt550m9/wtrubber)
crate_name = "auto rifle ammo crate"
/datum/supply_pack/security/armory/wt550ammo_special
name = "WT-550 Semi-Auto SMG Special Ammo Crate"
desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtic,
/obj/item/ammo_box/magazine/wt550m9/wtic)
crate_name = "auto rifle ammo crate"
-24
View File
@@ -206,30 +206,6 @@
/obj/item/storage/box/mre/menu4/safe)
crate_name = "MRE crate (emergency rations)"
/datum/supply_pack/emergency/syndicate
name = "NULL_ENTRY"
desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
hidden = TRUE
cost = 20000
contains = list()
crate_name = "emergency crate"
crate_type = /obj/structure/closet/crate/internals
dangerous = TRUE
/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
var/crate_value = 30
var/list/uplink_items = get_uplink_items(SSticker.mode)
while(crate_value)
var/category = pick(uplink_items)
var/item = pick(uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
continue
if(crate_value < I.cost)
continue
crate_value -= I.cost
new I.item(C)
/datum/supply_pack/emergency/plasma_spacesuit
name = "Plasmaman Space Envirosuits"
desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
-29
View File
@@ -108,17 +108,6 @@
/obj/item/clothing/gloves/color/latex/nitrile)
crate_name = "nitrile gloves crate"
/datum/supply_pack/science/nuke_b_gone
name = "Nuke Defusal Kit"
desc = "Contains set of tools to defuse a nuke."
cost = 7500 //Useful for traitors/nukies that fucked up
dangerous = TRUE
hidden = TRUE
contains = list(/obj/item/nuke_core_container/nt,
/obj/item/screwdriver/nuke/nt,
/obj/item/paper/guides/nt/nuke_instructions)
crate_name = "safe defusal kit storage"
/datum/supply_pack/science/plasma
name = "Plasma Assembly Crate"
desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
@@ -191,17 +180,6 @@
crate_name = "slime core crate"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/supermater
name = "Supermatter Extraction Tools Crate"
desc = "Contains a set of tools to extract a sliver of supermatter. Consult your CE today!"
cost = 7500 //Useful for traitors that fucked up
hidden = TRUE
contains = list(/obj/item/nuke_core_container/supermatter,
/obj/item/scalpel/supermatter,
/obj/item/hemostat/supermatter,
/obj/item/paper/guides/antag/supermatter_sliver)
crate_name = "supermatter extraction kit crate"
/datum/supply_pack/science/tablets
name = "Tablet Crate"
desc = "What's a computer? Contains five cargo tablets."
@@ -224,10 +202,3 @@
crate_type = /obj/structure/closet/crate/secure/science
dangerous = TRUE
/datum/supply_pack/science/tech_slugs
name = "Tech Slug Ammo Shells"
desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
cost = 1700
contains = list(/obj/item/storage/box/techsslug,
/obj/item/storage/box/techsslug)
crate_name = "tech slug crate"
+1 -1
View File
@@ -59,7 +59,7 @@
SA.del_on_death = FALSE
spawned_mobs += SA
SA.AddElement(/datum/element/ghost_role_eligibility)
SA.AddElement(/datum/element/ghost_role_eligibility, penalize_on_ghost = TRUE)
to_chat(SA, "<span class='userdanger'>Hello world!</span>")
to_chat(SA, "<span class='warning'>Due to freak radiation and/or chemicals \
and/or lucky chance, you have gained human level intelligence \
+44
View File
@@ -0,0 +1,44 @@
/**
* Internal atom that copies an appearance on to the blocker plane
*
* Copies an appearance vis render_target and render_source on to the emissive blocking plane.
* This means that the atom in question will block any emissive sprites.
* This should only be used internally. If you are directly creating more of these, you're
* almost guaranteed to be doing something wrong.
*/
/atom/movable/emissive_blocker
name = ""
plane = EMISSIVE_BLOCKER_PLANE
layer = EMISSIVE_BLOCKER_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
//Why?
//render_targets copy the transform of the target as well, but vis_contents also applies the transform
//to what's in it. Applying RESET_TRANSFORM here makes vis_contents not apply the transform.
//Since only render_target handles transform we don't get any applied transform "stacking"
appearance_flags = RESET_TRANSFORM
/atom/movable/emissive_blocker/Initialize(mapload, source)
. = ..()
verbs.Cut() //Cargo culting from lighting object, this maybe affects memory usage?
render_source = source
/atom/movable/emissive_blocker/ex_act(severity)
return FALSE
/atom/movable/emissive_blocker/singularity_act()
return
/atom/movable/emissive_blocker/singularity_pull()
return
/atom/movable/emissive_blocker/blob_act()
return
/atom/movable/emissive_blocker/onTransitZ()
return
//Prevents people from moving these after creation, because they shouldn't be.
/atom/movable/emissive_blocker/forceMove(atom/destination, no_tp=FALSE, harderforce = FALSE)
if(harderforce)
return ..()
+25 -11
View File
@@ -263,14 +263,15 @@ Works together with spawning an observer, noted above.
*/
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
penalize = suiciding || penalize // suicide squad.
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize)
penalize = !(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING) && (suiciding || penalize) // suicide squad.
voluntary_ghosted = voluntary
if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
if(!key || key[1] == "@" || (sig_flags & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(get_turf(src), src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.can_reenter_corpse = can_reenter_corpse || (sig_flags & COMPONENT_FREE_GHOSTING)
if (client && client.prefs && client.prefs.auto_ooc)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
@@ -297,12 +298,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE) & COMPONENT_BLOCK_GHOSTING)
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE)
if(sig_flags & COMPONENT_BLOCK_GHOSTING)
return
if(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING)
penalty = 0
if(stat != DEAD)
succumb()
if(stat == DEAD)
if(stat == DEAD || sig_flags & COMPONENT_FREE_GHOSTING)
ghostize(1)
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
@@ -321,7 +327,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE)
if(sig_flags & COMPONENT_BLOCK_GHOSTING)
return
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
@@ -333,10 +341,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
ghostize(0, penalize = TRUE)
if(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING)
penalty = 0
if(sig_flags & COMPONENT_FREE_GHOSTING)
ghostize(1)
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
ghostize(0, penalize = TRUE)
@@ -670,7 +684,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return 0
transfer_ckey(target, FALSE)
target.AddElement(/datum/element/ghost_role_eligibility)
target.AddElement(/datum/element/ghost_role_eligibility, penalize_on_ghost = FALSE, free_ghosting = TRUE)
target.faction = list("neutral")
return 1
@@ -10,6 +10,8 @@
combat_flags = COMBAT_FLAGS_DEFAULT
status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
//Hair colour and style
var/hair_color = "000"
var/hair_style = "Bald"
@@ -323,6 +323,8 @@
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded")
/mob/living/carbon/human/proc/handle_active_genes()
if(HAS_TRAIT(src, TRAIT_MUTATION_STASIS))
return
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_life(src)
@@ -12,6 +12,7 @@
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey
gib_type = /obj/effect/decal/cleanable/blood/gibs
unique_name = TRUE
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
hud_type = /datum/hud/monkey
+1 -1
View File
@@ -161,7 +161,7 @@
if(!has_legs && has_arms < 2)
limbless_slowdown += 6 - (has_arms * 3)
if(limbless_slowdown)
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, movetypes=GROUND)
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, blacklisted_movetypes = FLYING|FLOATING)
else
remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
@@ -10,6 +10,8 @@
has_limbs = 1
hud_type = /datum/hud/robot
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
var/custom_name = ""
var/braintype = "Cyborg"
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
+2
View File
@@ -8,6 +8,8 @@
pressure_resistance = 8
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
throwforce = 10
blocks_emissive = EMISSIVE_BLOCK_GENERIC
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
var/datum/mind/mind
var/list/datum/action/actions = list()
@@ -57,12 +57,12 @@ It is possible to destroy the net by the occupant or someone else.
continue//So all they're left with are shoes and uniform.
H.dropItemToGround(W)
H.dna.species.give_important_for_life(H) // After we remove items, at least give them what they need to live.
/*
var/datum/antagonist/antag_datum
for(var/datum/antagonist/ninja/AD in GLOB.antagonists) //Because only ninjas get capture objectives; They're not doable without the suit.
if(AD.owner == master)
antag_datum = AD
break
for(var/datum/objective/capture/capture in antag_datum)
if(istype(affecting, /mob/living/carbon/human)) //Humans.
if(affecting.stat == DEAD)//Dead folks are worth less.
@@ -87,7 +87,7 @@ It is possible to destroy the net by the occupant or someone else.
capture.captured_amount+=1
continue
capture.captured_amount+=2
*/
affecting.revive(1, 1) //Basically a revive and full heal, including limbs/organs
//In case people who have been captured dead want to hang out at the holding area
+1 -4
View File
@@ -22,7 +22,7 @@ Contents:
armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100)
strip_delay = 12
actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjasmoke, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninjanet, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth, /datum/action/item_action/toggle_glove)
actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjasmoke, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth, /datum/action/item_action/toggle_glove)
//Important parts of the suit.
var/mob/living/carbon/human/affecting = null
@@ -175,9 +175,6 @@ Contents:
if(istype(action, /datum/action/item_action/ninjastar))
ninjastar()
return TRUE
if(istype(action, /datum/action/item_action/ninjanet))
ninjanet()
return TRUE
if(istype(action, /datum/action/item_action/ninja_sword_recall))
ninja_sword_recall()
return TRUE
+10 -5
View File
@@ -308,12 +308,17 @@
if(update & 2)
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
if(!(stat & (BROKEN|MAINT)) && update_state & UPSTATE_ALLGOOD)
SSvis_overlays.add_vis_overlay(src, icon, "apcox-[locked]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco3-[hijackerreturn ? "3" : charging]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apcox-[locked]", layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apcox-[locked]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco3-[hijackerreturn ? "3" : charging]", layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco3-[hijackerreturn ? "3" : charging]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
if(operating)
SSvis_overlays.add_vis_overlay(src, icon, "apco0-[equipment]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco1-[lighting]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco2-[environ]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco0-[equipment]", layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco0-[equipment]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco1-[lighting]", layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco1-[lighting]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco2-[environ]", layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, "apco2-[environ]", EMISSIVE_LAYER, EMISSIVE_PLANE, dir)
// And now, separately for cleanness, the lighting changing
if(update_state & UPSTATE_ALLGOOD)
+1 -1
View File
@@ -312,7 +312,7 @@
/obj/machinery/light/update_overlays()
. = ..()
if(on && status == LIGHT_OK)
var/mutable_appearance/glowybit = mutable_appearance(overlayicon, base_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
var/mutable_appearance/glowybit = mutable_appearance(overlayicon, base_state, EMISSIVE_LAYER, EMISSIVE_PLANE)
glowybit.alpha = CLAMP(light_power*250, 30, 200)
. += glowybit
@@ -95,7 +95,7 @@
name = "scatter laser shell"
desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a scatter laser weapon in a ballistic package."
icon_state = "lshell"
projectile_type = /obj/item/projectile/beam/weak
projectile_type = /obj/item/projectile/beam/scatter
pellets = 6
variance = 35
@@ -130,12 +130,16 @@
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
/obj/item/ammo_casing/shotgun/dart/bioterror
desc = "A shotgun dart filled with deadly toxins."
desc = "A shotgun dart filled with an obscene amount of lethal reagents. God help whoever is shot with this."
projectile_type = /obj/item/projectile/bullet/dart/piercing
reagent_amount = 50
/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/toxin/fentanyl, 6)
reagents.add_reagent(/datum/reagent/toxin/spore, 6)
reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 6) //;HELP OPS IN MAINT
reagents.add_reagent(/datum/reagent/toxin/coniine, 6)
reagents.add_reagent(/datum/reagent/toxin/sodium_thiopental, 6)
reagents.add_reagent(/datum/reagent/toxin/amanitin, 12) //for a nasty surprise after you get shot and somehow escape and don't think to quickly purge, and even shock those who are loaded up on purging agents
reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 6)
reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 6) //;HELPIES OPS IN MAINT
reagents.add_reagent(/datum/reagent/impedrezene, 6)
reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 5) //this and the acid equal about 25ish burn, not counting the minute toxin damage dealt by their metabolism, this makes each dart about as lethal as a stechkin shot in upfront damage
reagents.add_reagent(/datum/reagent/toxin/acid, 5)
reagents.add_reagent(/datum/reagent/consumable/frostoil, 10) //tempgun slowdown goes both ways and adds to the burn
@@ -273,7 +273,7 @@
icon_state = "dshotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
weapon_weight = WEAPON_MEDIUM
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
+1 -1
View File
@@ -50,7 +50,7 @@
/obj/item/projectile/beam/scatter
name = "laser pellet"
icon_state = "scatterlaser"
damage = 5
damage = 12.5
/obj/item/projectile/beam/xray
name = "\improper X-ray beam"
@@ -29,6 +29,9 @@
reagents.handle_reactions()
return BULLET_ACT_HIT
/obj/item/projectile/bullet/dart/piercing
piercing = TRUE
/obj/item/projectile/bullet/dart/metalfoam/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/aluminium, 15)
@@ -18,13 +18,28 @@
/obj/item/projectile/bullet/shotgun_stunslug
name = "stunslug"
damage = 5
stamina = 20
knockdown = 100
stamina = 30
stutter = 5
jitter = 20
range = 7
icon_state = "spark"
color = "#FFFF00"
var/tase_duration = 50
/obj/item/projectile/bullet/shotgun_stunslug/on_hit(atom/target, blocked = FALSE)
. = ..()
if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks!
do_sparks(1, TRUE, src)
if(iscarbon(target))
var/mob/living/carbon/C = target
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "tased", /datum/mood_event/tased)
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
C.IgniteMob()
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if(tase_duration && (C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE) && !HAS_TRAIT(C, TRAIT_TASED_RESISTANCE))
C.electrocute_act(15, src, 1, SHOCK_NOSTUN)
C.apply_status_effect(STATUS_EFFECT_TASED_WEAK, tase_duration)
/obj/item/projectile/bullet/shotgun_meteorslug
name = "meteorslug"
@@ -93,7 +108,6 @@
/obj/item/projectile/bullet/scattershot
damage = 20
stamina = 65
/obj/item/projectile/bullet/seed
damage = 4
-6
View File
@@ -65,7 +65,6 @@
var/refund_amount = 0 // specified refund amount in case there needs to be a TC penalty for refunds.
var/refundable = FALSE
var/surplus = 100 // Chance of being included in the surplus crate.
var/surplus_nullcrates //Chance of being included in null crates. null = pull from surplus
var/cant_discount = FALSE
var/limited_stock = -1 //Setting this above zero limits how many times this item can be bought by the same traitor in a round, -1 is unlimited
var/list/include_modes = list() // Game modes to allow this item in.
@@ -76,11 +75,6 @@
var/restricted = FALSE // Adds restrictions for VR/Events
var/illegal_tech = TRUE // Can this item be deconstructed to unlock certain techweb research nodes?
/datum/uplink_item/New()
. = ..()
if(isnull(surplus_nullcrates))
surplus_nullcrates = surplus
/datum/uplink_item/proc/get_discount()
return pick(4;0.75,2;0.5,1;0.25)
@@ -56,6 +56,13 @@
item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun
cost = 12
/datum/uplink_item/ammo/shotgun/bioterror
name = "12g Bioterror Dart Drum"
desc = "An additional 8-round bioterror dart magazine for use with the Bulldog shotgun. \
Pierces armor and injects are horrid cocktail of death into your target. Be careful about friendly fire."
cost = 6 //legacy price
item = /obj/item/ammo_box/magazine/m12g/bioterror
/datum/uplink_item/ammo/shotgun/buck
name = "12g Buckshot Drum"
desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy."
@@ -66,20 +73,12 @@
desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \
'I'm a fire starter, twisted fire starter!'"
item = /obj/item/ammo_box/magazine/m12g/dragon
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/meteor
name = "12g Meteorslug Shells"
desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \
Great for blasting airlocks off their frames and knocking down enemies."
item = /obj/item/ammo_box/magazine/m12g/meteor
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/scatter
name = "12g Scatter Laser shot Slugs"
desc = "An alternative 8-round Scatter Laser Shot magazine for use in the Bulldog shotgun."
item = /obj/item/ammo_box/magazine/m12g/scatter
cost = 4 // most armor has less laser protection then bullet
/datum/uplink_item/ammo/shotgun/slug
name = "12g Slug Drum"
@@ -93,7 +92,6 @@
desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \
Saying that they're completely non-lethal would be lying."
item = /obj/item/ammo_box/magazine/m12g/stun
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/revolver
name = ".357 Speed Loader"
@@ -101,7 +101,6 @@
item = /obj/item/clothing/shoes/chameleon/noslip
cost = 2
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
player_minimum = 20
/datum/uplink_item/stealthy_tools/syndigaloshes/nuke
item = /obj/item/clothing/shoes/chameleon/noslip