Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit655
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#define GENITAL_CAN_AROUSE (1<<8)
|
||||
#define GENITAL_UNDIES_HIDDEN (1<<9)
|
||||
#define UPDATE_OWNER_APPEARANCE (1<<10)
|
||||
#define GENITAL_CAN_TAUR (1<<11)
|
||||
|
||||
|
||||
#define DEF_VAGINA_SHAPE "Human"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -184,6 +184,7 @@
|
||||
"cock_length" = COCK_SIZE_DEF,
|
||||
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
||||
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"cock_taur" = FALSE,
|
||||
"has_balls" = FALSE,
|
||||
"balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"balls_size" = BALLS_SIZE_DEF,
|
||||
|
||||
@@ -25,7 +25,8 @@ GLOBAL_VAR_INIT(midnight_rollovers, 0)
|
||||
GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
|
||||
/proc/update_midnight_rollover()
|
||||
if (world.timeofday < GLOB.rollovercheck_last_timeofday) //TIME IS GOING BACKWARDS!
|
||||
return GLOB.midnight_rollovers++
|
||||
GLOB.midnight_rollovers++
|
||||
GLOB.rollovercheck_last_timeofday = world.timeofday
|
||||
return GLOB.midnight_rollovers
|
||||
|
||||
/proc/weekdayofthemonth()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,6 +33,13 @@
|
||||
/obj/item/organ/ears/cat = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/papermask
|
||||
name = "Paper Mask"
|
||||
result = /obj/item/clothing/mask/paper
|
||||
time = 10
|
||||
reqs = list(/obj/item/paper = 20)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
////////
|
||||
//Huds//
|
||||
////////
|
||||
|
||||
@@ -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 .
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
var/datum/action/drop/drop = new/datum/action/drop()
|
||||
|
||||
/datum/martial_art/wrestling/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(!can_use(A, D))
|
||||
return 0
|
||||
switch(streak)
|
||||
if("drop")
|
||||
streak = ""
|
||||
@@ -448,6 +450,8 @@
|
||||
/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(!can_use(A,D))
|
||||
return ..()
|
||||
if(A.pulling == D || A == D) // don't stun grab yoursel
|
||||
return FALSE
|
||||
A.start_pulling(D)
|
||||
@@ -476,3 +480,19 @@
|
||||
if(H.get_item_by_slot(SLOT_BELT) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
//Subtype of wrestling, reserved for the wrestling belts found in the holodeck
|
||||
/datum/martial_art/wrestling/holodeck
|
||||
name = "Holodeck Wrestling"
|
||||
|
||||
/obj/item/storage/belt/champion/wrestling/holodeck
|
||||
name = "Holodeck Wrestling Belt"
|
||||
style = new /datum/martial_art/wrestling/holodeck
|
||||
|
||||
//Make sure that moves can only be used on people wearing the holodeck belt
|
||||
/datum/martial_art/wrestling/holodeck/can_use(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(!(istype(D.mind?.martial_art, /datum/martial_art/wrestling/holodeck)))
|
||||
return 0
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -470,7 +470,6 @@
|
||||
/datum/objective/steal,
|
||||
/datum/objective/download,
|
||||
/datum/objective/nuclear,
|
||||
/datum/objective/capture,
|
||||
/datum/objective/absorb,
|
||||
/datum/objective/custom
|
||||
)
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
/area/holodeck/rec_center/winterwonderland
|
||||
name = "Holodeck - Winter Wonderland"
|
||||
|
||||
/area/holodeck/rec_center/wrestlingarena
|
||||
name = "Holodeck - Wrestling Arena"
|
||||
|
||||
// Bad programs
|
||||
|
||||
/area/holodeck/rec_center/burn
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -77,14 +77,14 @@
|
||||
|
||||
/datum/sabotage_objective/processing/supermatter/can_run()
|
||||
return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines)
|
||||
|
||||
/*
|
||||
/datum/sabotage_objective/station_integrity
|
||||
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
|
||||
sabotage_type = "integrity"
|
||||
|
||||
/datum/sabotage_objective/station_integrity/check_conditions()
|
||||
return 5-(max(SSticker.station_integrity*4,320)/80)
|
||||
|
||||
*/
|
||||
/datum/sabotage_objective/cloner
|
||||
name = "Destroy all Nanotrasen cloning machines."
|
||||
sabotage_type = "cloner"
|
||||
@@ -98,6 +98,9 @@
|
||||
special_equipment = list(/obj/item/aiModule/syndicate)
|
||||
excludefromjob = list("Chief Engineer","Research Director","Head of Personnel","Captain","Chief Medical Officer","Head Of Security")
|
||||
|
||||
/datum/sabotage_objective/ai_law/can_run()
|
||||
return length(active_ais())
|
||||
|
||||
/datum/sabotage_objective/ai_law/check_conditions()
|
||||
for (var/i in GLOB.ai_list)
|
||||
var/mob/living/silicon/ai/aiPlayer = i
|
||||
|
||||
@@ -207,11 +207,14 @@
|
||||
|
||||
/obj/machinery/sleeper/ui_data()
|
||||
var/list/data = list()
|
||||
var/chemical_list = list()
|
||||
var/blood_percent = 0
|
||||
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
data["efficiency"] = efficiency
|
||||
data["current_vol"] = reagents.total_volume
|
||||
data["tot_capacity"] = reagents.maximum_volume
|
||||
data["blood_levels"] = blood_percent
|
||||
data["blood_status"] = "Patient either has no blood, or does not require it to function."
|
||||
data["chemical_list"] = chemical_list
|
||||
|
||||
data["chems"] = list()
|
||||
for(var/chem in available_chems)
|
||||
@@ -247,10 +250,13 @@
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
|
||||
|
||||
if(mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
|
||||
chemical_list += list(list("name" = R.name, "volume" = R.volume))
|
||||
else
|
||||
chemical_list = "Patient has no reagents."
|
||||
|
||||
data["occupant"]["failing_organs"] = list()
|
||||
var/mob/living/carbon/C = mob_occupant
|
||||
if(C)
|
||||
@@ -259,21 +265,25 @@
|
||||
continue
|
||||
data["occupant"]["failing_organs"] += list(list("name" = Or.name))
|
||||
|
||||
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
|
||||
var/blood_id = C.get_blood_id()
|
||||
if(blood_id)
|
||||
data["occupant"]["blood"] = list() // We can start populating this list.
|
||||
var/blood_type = C.dna.blood_type
|
||||
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
|
||||
if(R)
|
||||
blood_type = R.name
|
||||
else
|
||||
blood_type = blood_id
|
||||
data["occupant"]["blood"]["maxBloodVolume"] = (BLOOD_VOLUME_NORMAL*C.blood_ratio)
|
||||
data["occupant"]["blood"]["currentBloodVolume"] = C.blood_volume
|
||||
data["occupant"]["blood"]["dangerBloodVolume"] = BLOOD_VOLUME_SAFE
|
||||
data["occupant"]["blood"]["bloodType"] = blood_type
|
||||
if(istype(C)) //Non-carbons shouldn't be able to enter sleepers, but this is to prevent runtimes if something ever breaks
|
||||
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
|
||||
blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
|
||||
var/blood_id = C.get_blood_id()
|
||||
var/blood_warning = ""
|
||||
if(blood_percent < 80)
|
||||
blood_warning = "Patient has low blood levels."
|
||||
if(blood_percent < 60)
|
||||
blood_warning = "Patient has DANGEROUSLY low blood levels."
|
||||
if(blood_id)
|
||||
var/blood_type = C.dna.blood_type
|
||||
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
|
||||
if(R)
|
||||
blood_type = R.name
|
||||
else
|
||||
blood_type = blood_id
|
||||
data["blood_status"] = "Patient has [blood_type] type blood. [blood_warning]"
|
||||
data["blood_levels"] = blood_percent
|
||||
return data
|
||||
|
||||
/obj/machinery/sleeper/ui_act(action, params)
|
||||
@@ -309,14 +319,14 @@
|
||||
if(allowed(usr))
|
||||
if(!is_operational())
|
||||
return
|
||||
reagents.remove_reagent(chem, 10)
|
||||
reagents.remove_reagent(chem, 1000)
|
||||
return
|
||||
if(chem in available_chems)
|
||||
if(!is_operational())
|
||||
return
|
||||
/*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in
|
||||
if(R.purity < 0.8)*/
|
||||
reagents.remove_reagent(chem, 10)
|
||||
reagents.remove_reagent(chem, 1000)
|
||||
else
|
||||
visible_message("<span class='warning'>Access Denied.</span>")
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -384,8 +384,8 @@
|
||||
desc = "The POWER that gamers CRAVE! In partnership with Vlad's Salad."
|
||||
icon_state = "poster39"
|
||||
|
||||
/obj/structure/sign/poster/contraband/sun_kist
|
||||
name = "Sun-kist"
|
||||
/obj/structure/sign/poster/contraband/starkist
|
||||
name = "Star-kist"
|
||||
desc = "Drink the stars!"
|
||||
icon_state = "poster40"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
/obj/item
|
||||
name = "item"
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
///icon state name for inhanf overlays
|
||||
blocks_emissive = EMISSIVE_BLOCK_GENERIC
|
||||
|
||||
///icon state name for inhand overlays
|
||||
var/item_state = null
|
||||
///Icon file for left hand inhand overlays
|
||||
var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
if(H && (H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
|
||||
@@ -182,8 +182,8 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
|
||||
new/datum/stack_recipe("crate", /obj/structure/closet/crate, 5, time = 90, one_per_turf = TRUE), \
|
||||
null, \
|
||||
new /datum/stack_recipe_list("airlock assemblies", list( \
|
||||
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 6, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
)), \
|
||||
))
|
||||
|
||||
|
||||
@@ -243,6 +243,7 @@
|
||||
//door.req_access = req_access
|
||||
door.electronics = electronics
|
||||
door.heat_proof = heat_proof_finished
|
||||
door.security_level = 0
|
||||
if(electronics.one_access)
|
||||
door.req_one_access = electronics.accesses
|
||||
else
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
airlock_type = /obj/machinery/door/airlock/highsecurity
|
||||
noglass = TRUE
|
||||
material_type = /obj/item/stack/sheet/plasteel
|
||||
material_amt = 6
|
||||
material_amt = 4
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_vault
|
||||
name = "vault door assembly"
|
||||
@@ -124,7 +124,7 @@
|
||||
airlock_type = /obj/machinery/door/airlock/vault
|
||||
noglass = TRUE
|
||||
material_type = /obj/item/stack/sheet/plasteel
|
||||
material_amt = 8
|
||||
material_amt = 6
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_shuttle
|
||||
name = "shuttle airlock assembly"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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."
|
||||
@@ -311,7 +287,7 @@
|
||||
|
||||
/datum/supply_pack/emergency/specialops
|
||||
name = "Special Ops Supplies"
|
||||
desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
|
||||
desc = "(*!&@#NEED SOMETHING TO DEAL WITH THE GREYTIDE, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
|
||||
hidden = TRUE
|
||||
cost = 2200
|
||||
contains = list(/obj/item/storage/box/emps,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -125,6 +125,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"cock_length" = COCK_SIZE_DEF,
|
||||
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
||||
"cock_color" = "fff",
|
||||
"cock_taur" = FALSE,
|
||||
"has_balls" = FALSE,
|
||||
"balls_color" = "fff",
|
||||
"balls_shape" = DEF_BALLS_SHAPE,
|
||||
@@ -762,7 +763,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
else
|
||||
dat += "<b>Penis Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'> </span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><br>"
|
||||
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a>"
|
||||
var/tauric_shape = FALSE
|
||||
if(features["cock_taur"])
|
||||
var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[features["cock_shape"]]
|
||||
if(P.taur_icon && pref_species.mutant_bodyparts["taur"])
|
||||
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
|
||||
if(T.taur_mode & P.accepted_taurs)
|
||||
tauric_shape = TRUE
|
||||
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]][tauric_shape ? " (Taur)" : ""]</a>"
|
||||
dat += "<b>Penis Length:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a>"
|
||||
dat += "<b>Penis Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=cock_visibility;task=input'>[features["cock_visibility"]]</a>"
|
||||
dat += "<b>Has Testicles:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a>"
|
||||
@@ -1610,7 +1618,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("mutant_color2")
|
||||
var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference") as color|null
|
||||
var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference","#"+features["mcolor2"]) as color|null
|
||||
if(new_mutantcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
||||
if(new_mutantcolor == "#000000")
|
||||
@@ -1621,7 +1629,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("mutant_color3")
|
||||
var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference") as color|null
|
||||
var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference","#"+features["mcolor3"]) as color|null
|
||||
if(new_mutantcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
||||
if(new_mutantcolor == "#000000")
|
||||
@@ -1922,7 +1930,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
//Genital code
|
||||
if("cock_color")
|
||||
var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null
|
||||
var/new_cockcolor = input(user, "Penis color:", "Character Preference","#"+features["cock_color"]) as color|null
|
||||
if(new_cockcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_cockcolor)
|
||||
if(new_cockcolor == "#000000")
|
||||
@@ -1941,8 +1949,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
if("cock_shape")
|
||||
var/new_shape
|
||||
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list
|
||||
var/list/hockeys = list()
|
||||
if(pref_species.mutant_bodyparts["taur"])
|
||||
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
|
||||
for(var/A in GLOB.cock_shapes_list)
|
||||
var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[A]
|
||||
if(P.taur_icon && T.taur_mode & P.accepted_taurs)
|
||||
LAZYSET(hockeys, "[A] (Taur)", A)
|
||||
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in (GLOB.cock_shapes_list + hockeys)
|
||||
if(new_shape)
|
||||
features["cock_taur"] = FALSE
|
||||
if(hockeys[new_shape])
|
||||
new_shape = hockeys[new_shape]
|
||||
features["cock_taur"] = TRUE
|
||||
features["cock_shape"] = new_shape
|
||||
|
||||
if("cock_visibility")
|
||||
@@ -1951,7 +1970,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["cock_visibility"] = n_vis
|
||||
|
||||
if("balls_color")
|
||||
var/new_ballscolor = input(user, "Testicles Color:", "Character Preference") as color|null
|
||||
var/new_ballscolor = input(user, "Testicles Color:", "Character Preference","#"+features["balls_color"]) as color|null
|
||||
if(new_ballscolor)
|
||||
var/temp_hsv = RGBtoHSV(new_ballscolor)
|
||||
if(new_ballscolor == "#000000")
|
||||
@@ -1978,7 +1997,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["breasts_shape"] = new_shape
|
||||
|
||||
if("breasts_color")
|
||||
var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null
|
||||
var/new_breasts_color = input(user, "Breast Color:", "Character Preference","#"+features["breasts_color"]) as color|null
|
||||
if(new_breasts_color)
|
||||
var/temp_hsv = RGBtoHSV(new_breasts_color)
|
||||
if(new_breasts_color == "#000000")
|
||||
@@ -2000,7 +2019,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["vag_shape"] = new_shape
|
||||
|
||||
if("vag_color")
|
||||
var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null
|
||||
var/new_vagcolor = input(user, "Vagina color:", "Character Preference","#"+features["vag_color"]) as color|null
|
||||
if(new_vagcolor)
|
||||
var/temp_hsv = RGBtoHSV(new_vagcolor)
|
||||
if(new_vagcolor == "#000000")
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 27
|
||||
#define SAVEFILE_VERSION_MAX 28
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -151,6 +151,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(tennis == "Hidden")
|
||||
features["balls_visibility"] = GEN_VISIBLE_NEVER
|
||||
|
||||
if(current_version < 28)
|
||||
var/hockey
|
||||
S["feature_cock_shape"] >> hockey
|
||||
var/list/malformed_hockeys = list("Taur, Flared" = "Flared", "Taur, Knotted" = "Knotted", "Taur, Tapered" = "Tapered")
|
||||
if(malformed_hockeys[hockey])
|
||||
features["cock_shape"] = malformed_hockeys[hockey]
|
||||
features["cock_taur"] = TRUE
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey)
|
||||
return
|
||||
@@ -457,6 +465,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_cock_color"] >> features["cock_color"]
|
||||
S["feature_cock_length"] >> features["cock_length"]
|
||||
S["feature_cock_diameter"] >> features["cock_diameter"]
|
||||
S["feature_cock_taur"] >> features["cock_taur"]
|
||||
S["feature_cock_visibility"] >> features["cock_visibility"]
|
||||
//balls features
|
||||
S["feature_has_balls"] >> features["has_balls"]
|
||||
@@ -673,6 +682,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["feature_cock_shape"], features["cock_shape"])
|
||||
WRITE_FILE(S["feature_cock_color"], features["cock_color"])
|
||||
WRITE_FILE(S["feature_cock_length"], features["cock_length"])
|
||||
WRITE_FILE(S["feature_cock_taur"], features["cock_taur"])
|
||||
WRITE_FILE(S["feature_cock_visibility"], features["cock_visibility"])
|
||||
|
||||
WRITE_FILE(S["feature_has_balls"], features["has_balls"])
|
||||
|
||||
@@ -342,3 +342,45 @@
|
||||
desc = "A bandana made from durathread, you wish it would provide some protection to its wearer, but it's far too thin..."
|
||||
icon_state = "banddurathread"
|
||||
|
||||
/obj/item/clothing/mask/paper
|
||||
name = "paper mask"
|
||||
desc = "A neat, circular mask made out of paper."
|
||||
icon_state = "plainmask"
|
||||
item_state = "plainmask"
|
||||
flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
|
||||
|
||||
/obj/item/clothing/mask/paper/ui_action_click(mob/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
var/list/options = list()
|
||||
options["Blank"] = "plainmask"
|
||||
options["Neutral"] = "neutralmask"
|
||||
options["Eyes"] = "eyemask"
|
||||
options["Sleeping"] ="sleepingmask"
|
||||
options["Heart"] = "heartmask"
|
||||
options["Core"] = "coremask"
|
||||
options["Plus"] = "plusmask"
|
||||
options["Square"] ="squaremask"
|
||||
options["Bullseye"] = "bullseyemask"
|
||||
options["Vertical"] = "verticalmask"
|
||||
options["Horizontal"] = "horizontalmask"
|
||||
options["X"] ="xmask"
|
||||
options["Bugeyes"] = "bugmask"
|
||||
options["Double"] = "doublemask"
|
||||
options["Mark"] = "markmask"
|
||||
|
||||
var/choice = input(user,"What symbol would you want on this mask?","Morph Mask") in options
|
||||
|
||||
if(src && choice && !user.incapacitated() && in_range(user,src))
|
||||
icon_state = options[choice]
|
||||
user.update_inv_wear_mask()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
to_chat(user, "<span class='notice'>Your paper mask now has a [choice] symbol!</span>")
|
||||
return 1
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 ..()
|
||||
@@ -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
|
||||
|
||||
@@ -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..
|
||||
|
||||
@@ -112,6 +112,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
recolorentiresprite = TRUE
|
||||
if(!recolorentiresprite) //we want this to proc before stand logs in, so the overlay isnt gone for some reason
|
||||
cooloverlay = mutable_appearance(icon, theme)
|
||||
add_overlay(cooloverlay)
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/Login() //if we have a mind, set its name to ours when it logs in
|
||||
..()
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
pull_force = MOVE_FORCE_OVERPOWERING
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
|
||||
var/list/crusher_loot
|
||||
var/medal_type
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -189,96 +189,139 @@
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "id" = ckey(R.name), "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
data["beakerContents"] = beakerContents
|
||||
data["beakerContents"] = beakerContents
|
||||
|
||||
var/bufferContents[0]
|
||||
if(reagents.total_volume)
|
||||
for(var/datum/reagent/N in reagents.reagent_list)
|
||||
bufferContents.Add(list(list("name" = N.name, "id" = ckey(N.name), "volume" = N.volume))) // ^
|
||||
data["bufferContents"] = bufferContents
|
||||
data["bufferContents"] = bufferContents
|
||||
|
||||
//Calculated at init time as it never changes
|
||||
data["pillStyles"] = pillStyles
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_master/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("eject")
|
||||
replace_beaker(usr)
|
||||
. = TRUE
|
||||
|
||||
if("ejectp")
|
||||
if("ejectPillBottle")
|
||||
replace_pillbottle(usr)
|
||||
. = TRUE
|
||||
|
||||
if("transferToBuffer")
|
||||
if(beaker)
|
||||
var/reagent = GLOB.name2reagent[params["id"]]
|
||||
var/amount = text2num(params["amount"])
|
||||
if (amount > 0)
|
||||
end_fermi_reaction()
|
||||
beaker.reagents.trans_id_to(src, reagent, amount)
|
||||
. = TRUE
|
||||
else if (amount == -1) // -1 means custom amount
|
||||
useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null
|
||||
if (useramount > 0)
|
||||
end_fermi_reaction()
|
||||
beaker.reagents.trans_id_to(src, reagent, useramount)
|
||||
. = TRUE
|
||||
|
||||
if("transferFromBuffer")
|
||||
if("transfer")
|
||||
if(!beaker)
|
||||
return FALSE
|
||||
var/reagent = GLOB.name2reagent[params["id"]]
|
||||
var/amount = text2num(params["amount"])
|
||||
if (amount > 0)
|
||||
if(mode)
|
||||
reagents.trans_id_to(beaker, reagent, amount)
|
||||
. = TRUE
|
||||
else
|
||||
reagents.remove_reagent(reagent, amount)
|
||||
. = TRUE
|
||||
else if (amount == -1) // -1 means custom amount
|
||||
useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null
|
||||
if (useramount > 0)
|
||||
end_fermi_reaction()
|
||||
reagents.trans_id_to(beaker, reagent, useramount)
|
||||
. = TRUE
|
||||
var/to_container = params["to"]
|
||||
// Custom amount
|
||||
if (amount == -1)
|
||||
amount = text2num(input(
|
||||
"Enter the amount you want to transfer:",
|
||||
name, ""))
|
||||
if (amount == null || amount <= 0)
|
||||
return FALSE
|
||||
if (to_container == "buffer")
|
||||
end_fermi_reaction()
|
||||
beaker.reagents.trans_id_to(src, reagent, amount)
|
||||
return TRUE
|
||||
if (to_container == "beaker" && mode)
|
||||
end_fermi_reaction()
|
||||
reagents.trans_id_to(beaker, reagent, amount)
|
||||
return TRUE
|
||||
if (to_container == "beaker" && !mode)
|
||||
end_fermi_reaction()
|
||||
reagents.remove_reagent(reagent, amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
if("toggleMode")
|
||||
mode = !mode
|
||||
. = TRUE
|
||||
|
||||
if("createPill")
|
||||
var/many = params["many"]
|
||||
if("pillStyle")
|
||||
var/id = text2num(params["id"])
|
||||
chosenPillStyle = id
|
||||
return TRUE
|
||||
|
||||
if("create")
|
||||
if(reagents.total_volume == 0)
|
||||
return
|
||||
if(!condi)
|
||||
var/amount = 1
|
||||
var/vol_each = min(reagents.total_volume, 50)
|
||||
if(text2num(many))
|
||||
amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10)
|
||||
if(!amount)
|
||||
return
|
||||
vol_each = min(reagents.total_volume / amount, 50)
|
||||
var/name = html_decode(stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
return FALSE
|
||||
var/item_type = params["type"]
|
||||
// Get amount of items
|
||||
var/amount = text2num(params["amount"])
|
||||
if(amount == null)
|
||||
amount = text2num(input(usr,
|
||||
"Max 10. Buffer content will be split evenly.",
|
||||
"How many to make?", 1))
|
||||
amount = clamp(round(amount), 0, 10)
|
||||
if (amount <= 0)
|
||||
return FALSE
|
||||
// Get units per item
|
||||
var/vol_each = text2num(params["volume"])
|
||||
var/vol_each_text = params["volume"]
|
||||
var/vol_each_max = reagents.total_volume / amount
|
||||
if (item_type == "pill")
|
||||
vol_each_max = min(50, vol_each_max)
|
||||
else if (item_type == "patch")
|
||||
vol_each_max = min(40, vol_each_max)
|
||||
else if (item_type == "bottle")
|
||||
vol_each_max = min(30, vol_each_max)
|
||||
else if (item_type == "condimentPack")
|
||||
vol_each_max = min(10, vol_each_max)
|
||||
else if (item_type == "condimentBottle")
|
||||
vol_each_max = min(50, vol_each_max)
|
||||
else if (item_type == "hypoVial")
|
||||
vol_each_max = min(60, vol_each_max)
|
||||
else if (item_type == "smartDart")
|
||||
vol_each_max = min(20, vol_each_max)
|
||||
else
|
||||
return FALSE
|
||||
if(vol_each_text == "auto")
|
||||
vol_each = vol_each_max
|
||||
if(vol_each == null)
|
||||
vol_each = text2num(input(usr,
|
||||
"Maximum [vol_each_max] units per item.",
|
||||
"How many units to fill?",
|
||||
vol_each_max))
|
||||
vol_each = clamp(vol_each, 0, vol_each_max)
|
||||
if(vol_each <= 0)
|
||||
return FALSE
|
||||
// Get item name
|
||||
var/name = params["name"]
|
||||
var/name_has_units = item_type == "pill" || item_type == "patch"
|
||||
if(!name)
|
||||
var/name_default = reagents.get_master_reagent_name()
|
||||
if (name_has_units)
|
||||
name_default += " ([vol_each]u)"
|
||||
name = stripped_input(usr,
|
||||
"Name:",
|
||||
"Give it a name!",
|
||||
name_default,
|
||||
MAX_NAME_LEN)
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
|
||||
return FALSE
|
||||
// Start filling
|
||||
if(item_type == "pill")
|
||||
var/obj/item/reagent_containers/pill/P
|
||||
var/target_loc = drop_location()
|
||||
var/drop_threshold = INFINITY
|
||||
if(bottle)
|
||||
var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
|
||||
var/datum/component/storage/STRB = bottle.GetComponent(
|
||||
/datum/component/storage)
|
||||
if(STRB)
|
||||
drop_threshold = STRB.max_items - bottle.contents.len
|
||||
target_loc = bottle
|
||||
|
||||
for(var/i in 1 to amount)
|
||||
if(i <= drop_threshold)
|
||||
P = new(target_loc)
|
||||
for(var/i = 0; i < amount; i++)
|
||||
if(i < drop_threshold)
|
||||
P = new/obj/item/reagent_containers/pill(target_loc)
|
||||
else
|
||||
P = new(drop_location())
|
||||
P = new/obj/item/reagent_containers/pill(drop_location())
|
||||
P.name = trim("[name] pill")
|
||||
if(chosenPillStyle == RANDOM_PILL_STYLE)
|
||||
P.icon_state ="pill[rand(1,21)]"
|
||||
@@ -287,171 +330,62 @@
|
||||
if(P.icon_state == "pill4")
|
||||
P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality."
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P,vol_each)
|
||||
else
|
||||
var/name = html_decode(stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
var/obj/item/reagent_containers/food/condiment/pack/P = new/obj/item/reagent_containers/food/condiment/pack(drop_location())
|
||||
|
||||
P.originalname = name
|
||||
P.name = trim("[name] pack")
|
||||
P.desc = "A small condiment pack. The label says it contains [name]."
|
||||
reagents.trans_to(P,10)
|
||||
. = TRUE
|
||||
|
||||
if("pillStyle")
|
||||
var/id = text2num(params["id"])
|
||||
chosenPillStyle = id
|
||||
|
||||
if("createPatch")
|
||||
var/many = params["many"]
|
||||
if(reagents.total_volume == 0)
|
||||
return
|
||||
var/amount = 1
|
||||
var/vol_each = min(reagents.total_volume, 40)
|
||||
if(text2num(many))
|
||||
amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10)
|
||||
if(!amount)
|
||||
return
|
||||
vol_each = min(reagents.total_volume / amount, 40)
|
||||
var/name = html_decode(stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
var/obj/item/reagent_containers/pill/P
|
||||
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new/obj/item/reagent_containers/pill/patch(drop_location())
|
||||
P.name = trim("[name] patch")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P,vol_each)
|
||||
. = TRUE
|
||||
|
||||
if("createBottle")
|
||||
var/many = params["many"]
|
||||
if(reagents.total_volume == 0)
|
||||
return
|
||||
|
||||
if(condi)
|
||||
var/name = html_decode(stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
var/obj/item/reagent_containers/food/condiment/P = new(drop_location())
|
||||
P.originalname = name
|
||||
P.name = trim("[name] bottle")
|
||||
reagents.trans_to(P, P.volume)
|
||||
else
|
||||
var/amount_full = 0
|
||||
var/vol_part = min(reagents.total_volume, 30)
|
||||
if(text2num(many))
|
||||
amount_full = round(reagents.total_volume / 30)
|
||||
vol_part = ((reagents.total_volume*1000) % 30000) / 1000 //% operator doesn't support decimals.
|
||||
var/name = html_decode(stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
|
||||
reagents.trans_to(P, vol_each)
|
||||
return TRUE
|
||||
if(item_type == "patch")
|
||||
var/obj/item/reagent_containers/pill/patch/P
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new/obj/item/reagent_containers/pill/patch(drop_location())
|
||||
P.name = trim("[name] patch")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P, vol_each)
|
||||
return TRUE
|
||||
if(item_type == "bottle")
|
||||
var/obj/item/reagent_containers/glass/bottle/P
|
||||
for(var/i = 0; i < amount_full; i++)
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new/obj/item/reagent_containers/glass/bottle(drop_location())
|
||||
P.name = trim("[name] bottle")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P, 30)
|
||||
|
||||
if(vol_part)
|
||||
P = new/obj/item/reagent_containers/glass/bottle(drop_location())
|
||||
reagents.trans_to(P, vol_each)
|
||||
return TRUE
|
||||
if(item_type == "condimentPack")
|
||||
var/obj/item/reagent_containers/food/condiment/pack/P
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new/obj/item/reagent_containers/food/condiment/pack(drop_location())
|
||||
P.originalname = name
|
||||
P.name = trim("[name] pack")
|
||||
P.desc = "A small condiment pack. The label says it contains [name]."
|
||||
reagents.trans_to(P, vol_each)
|
||||
return TRUE
|
||||
if(item_type == "condimentBottle")
|
||||
var/obj/item/reagent_containers/food/condiment/P
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new/obj/item/reagent_containers/food/condiment(drop_location())
|
||||
P.originalname = name
|
||||
P.name = trim("[name] bottle")
|
||||
reagents.trans_to(P, vol_each)
|
||||
return TRUE
|
||||
if(item_type == "hypoVial")
|
||||
var/obj/item/reagent_containers/glass/bottle/vial/small/P
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
|
||||
P.name = trim("[name] hypovial")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P, vol_part)
|
||||
. = TRUE
|
||||
//CITADEL ADD Hypospray Vials
|
||||
if("createVial")
|
||||
var/many = params["many"]
|
||||
if(reagents.total_volume == 0)
|
||||
return
|
||||
reagents.trans_to(P, vol_each)
|
||||
return TRUE
|
||||
if(item_type == "smartDart")
|
||||
var/obj/item/reagent_containers/syringe/dart/P
|
||||
for(var/i = 0; i < amount; i++)
|
||||
P = new /obj/item/reagent_containers/syringe/dart(drop_location())
|
||||
P.name = trim("[name] SmartDart")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P, vol_each)
|
||||
P.mode=!mode
|
||||
P.update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
var/amount_full = 0
|
||||
var/vol_part = min(reagents.total_volume, 60)
|
||||
if(text2num(many))
|
||||
amount_full = round(reagents.total_volume / 60)
|
||||
vol_part = reagents.total_volume % 60
|
||||
var/name = html_decode(stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
|
||||
var/obj/item/reagent_containers/glass/bottle/vial/small/P
|
||||
for(var/i = 0; i < amount_full; i++)
|
||||
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
|
||||
P.name = trim("[name] hypovial")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P, 60)
|
||||
|
||||
if(vol_part)
|
||||
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
|
||||
P.name = trim("[name] hypovial")
|
||||
adjust_item_drop_location(P)
|
||||
reagents.trans_to(P, vol_part)
|
||||
. = TRUE
|
||||
|
||||
if("createDart")
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(!(istype(R, /datum/reagent/medicine)))
|
||||
visible_message("<b>The [src]</b> beeps, \"<span class='warning'>SmartDarts are insoluble with non-medicinal compounds.\"</span>")
|
||||
return
|
||||
|
||||
var/many = params["many"]
|
||||
if(reagents.total_volume == 0)
|
||||
return
|
||||
var/amount = 1
|
||||
var/vol_each = min(reagents.total_volume, 20)
|
||||
if(text2num(many))
|
||||
amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many darts?", amount) as num|null), 0, 10)
|
||||
if(!amount)
|
||||
return
|
||||
vol_each = min(reagents.total_volume / amount, 20)
|
||||
|
||||
var/name = html_decode(stripped_input(usr,"Name:","Name your SmartDart!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN))
|
||||
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
|
||||
var/obj/item/reagent_containers/syringe/dart/D
|
||||
for(var/i = 0; i < amount; i++)
|
||||
D = new /obj/item/reagent_containers/syringe/dart(drop_location())
|
||||
D.name = trim("[name] SmartDart")
|
||||
adjust_item_drop_location(D)
|
||||
reagents.trans_to(D, vol_each)
|
||||
D.mode=!mode
|
||||
D.update_icon()
|
||||
. = TRUE
|
||||
|
||||
//END CITADEL ADDITIONS
|
||||
if("analyzeBeak")
|
||||
var/datum/reagent/R = GLOB.name2reagent[params["id"]]
|
||||
if(R)
|
||||
var/state = "Unknown"
|
||||
if(initial(R.reagent_state) == 1)
|
||||
state = "Solid"
|
||||
else if(initial(R.reagent_state) == 2)
|
||||
state = "Liquid"
|
||||
else if(initial(R.reagent_state) == 3)
|
||||
state = "Gas"
|
||||
var/const/P = 3 //The number of seconds between life ticks
|
||||
var/T = initial(R.metabolization_rate) * (60 / P)
|
||||
var/datum/chemical_reaction/Rcr = get_chemical_reaction(R)
|
||||
if(Rcr && Rcr.FermiChem)
|
||||
fermianalyze = TRUE
|
||||
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
|
||||
var/datum/reagent/targetReagent = beaker.reagents.has_reagent(R)
|
||||
|
||||
if(!targetReagent)
|
||||
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
|
||||
else
|
||||
fermianalyze = FALSE
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
|
||||
screen = "analyze"
|
||||
return
|
||||
|
||||
if("analyzeBuff")
|
||||
if("analyze")
|
||||
var/datum/reagent/R = GLOB.name2reagent[params["id"]]
|
||||
if(R)
|
||||
var/state = "Unknown"
|
||||
@@ -476,7 +410,7 @@
|
||||
fermianalyze = FALSE
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
|
||||
screen = "analyze"
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if("goScreen")
|
||||
screen = params["screen"]
|
||||
@@ -527,4 +461,4 @@
|
||||
condi = TRUE
|
||||
|
||||
#undef PILL_STYLE_COUNT
|
||||
#undef RANDOM_PILL_STYLE
|
||||
#undef RANDOM_PILL_STYLE
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
|
||||
if(item_to_retrieve.loc)
|
||||
item_to_retrieve.loc.visible_message("<span class='warning'>The [item_to_retrieve.name] suddenly disappears!</span>")
|
||||
if(!L.put_in_hands(item_to_retrieve))
|
||||
if(!isitem(item_to_retrieve) || !L.put_in_hands(item_to_retrieve))
|
||||
item_to_retrieve.forceMove(L.drop_location())
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears!</span>")
|
||||
playsound(get_turf(L), 'sound/magic/summonitems_generic.ogg', 50, 1)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user