Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit629
@@ -11,6 +11,7 @@
|
||||
#include "map_files\OmegaStation\OmegaStation.dmm"
|
||||
#include "map_files\PubbyStation\PubbyStation.dmm"
|
||||
#include "map_files\BoxStation\BoxStation.dmm"
|
||||
#include "map_files\LambdaStation\lambda.dmm"
|
||||
|
||||
#ifdef TRAVISBUILDING
|
||||
#include "templates.dm"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#define FORCE_MAP "_maps/lambdastation.json"
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"map_name": "Lambda Station",
|
||||
"map_path": "map_files/LambdaStation",
|
||||
"map_file": "lambda.dmm",
|
||||
"shuttles": {
|
||||
"cargo": "cargo_box",
|
||||
"ferry": "ferry_fancy",
|
||||
"whiteship": "whiteship_meta",
|
||||
"emergency": "emergency_meta"
|
||||
}
|
||||
}
|
||||
@@ -36,9 +36,6 @@
|
||||
#define CAN_CLIMAX_WITH (1<<7)
|
||||
#define GENITAL_CAN_AROUSE (1<<8)
|
||||
|
||||
#define BREASTS_SIZE_DEF "c" //lowercase cause those sprite accessory don't use uppercased letters.
|
||||
|
||||
#define DEF_BREASTS_SHAPE "Pair"
|
||||
|
||||
#define DEF_VAGINA_SHAPE "Human"
|
||||
|
||||
@@ -51,11 +48,6 @@
|
||||
#define COCK_DIAMETER_RATIO_MIN 0.15
|
||||
|
||||
#define DEF_COCK_SHAPE "Human"
|
||||
|
||||
#define KNOT_GIRTH_RATIO_MAX 3
|
||||
#define KNOT_GIRTH_RATIO_DEF 2.1
|
||||
#define KNOT_GIRTH_RATIO_MIN 1.25
|
||||
|
||||
#define BALLS_VOLUME_BASE 25
|
||||
#define BALLS_VOLUME_MULT 1
|
||||
|
||||
@@ -65,21 +57,17 @@
|
||||
#define BALLS_SIZE_DEF 2
|
||||
#define BALLS_SIZE_MAX 3
|
||||
|
||||
#define BALLS_SACK_SIZE_MIN 1
|
||||
#define BALLS_SACK_SIZE_DEF 8
|
||||
#define BALLS_SACK_SIZE_MAX 40
|
||||
|
||||
#define CUM_RATE 2 // holy shit what a really shitty define name - relates to units per arbitrary measure of time?
|
||||
#define CUM_RATE_MULT 1
|
||||
#define CUM_EFFICIENCY 1 //amount of nutrition required per life()
|
||||
|
||||
#define EGG_GIRTH_MIN 1//inches
|
||||
#define EGG_GIRTH_DEF 6
|
||||
#define EGG_GIRTH_MAX 16
|
||||
|
||||
#define BREASTS_VOLUME_BASE 50 //base volume for the reagents in the breasts, multiplied by the size then multiplier. 50u for A cups, 850u for HH cups.
|
||||
#define BREASTS_VOLUME_MULT 1 //global multiplier for breast volume.
|
||||
|
||||
#define BREASTS_SIZE_DEF "c" //lowercase cause those sprite accessory don't use uppercased letters.
|
||||
|
||||
#define DEF_BREASTS_SHAPE "Pair"
|
||||
|
||||
#define MILK_RATE 5
|
||||
#define MILK_RATE_MULT 1
|
||||
#define MILK_EFFICIENCY 1
|
||||
@@ -94,8 +82,6 @@
|
||||
//Citadel istypes
|
||||
#define isgenital(A) (istype(A, /obj/item/organ/genital))
|
||||
|
||||
#define isborer(A) (istype(A, /mob/living/simple_animal/borer))
|
||||
|
||||
#define CITADEL_MENTOR_OOC_COLOUR "#224724"
|
||||
|
||||
//xenobio console upgrade stuff
|
||||
|
||||
@@ -131,6 +131,8 @@
|
||||
#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech"
|
||||
#define TRAIT_SOOTHED_THROAT "soothed-throat"
|
||||
#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
|
||||
#define TRAIT_QUICK_CARRY "quick-carry"
|
||||
#define TRAIT_QUICKER_CARRY "quicker-carry"
|
||||
#define TRAIT_STRONG_GRABBER "strong_grabber"
|
||||
#define TRAIT_CALCIUM_HEALER "calcium_healer"
|
||||
#define TRAIT_MAGIC_CHOKE "magic_choke"
|
||||
@@ -144,6 +146,7 @@
|
||||
#define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites.
|
||||
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
|
||||
#define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events"
|
||||
#define TRAIT_NO_MIDROUND_ANTAG "no-midround-antag" //can't be turned into an antag by random events
|
||||
|
||||
// mobility flag traits
|
||||
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
|
||||
@@ -223,10 +226,12 @@
|
||||
#define GHOSTROLE_TRAIT "ghostrole"
|
||||
#define APHRO_TRAIT "aphro"
|
||||
#define BLOODSUCKER_TRAIT "bloodsucker"
|
||||
#define CLOTHING_TRAIT "clothing" //used for quirky carrygloves
|
||||
|
||||
// unique trait sources, still defines
|
||||
#define STATUE_MUTE "statue"
|
||||
#define CLONING_POD_TRAIT "cloning-pod"
|
||||
#define VIRTUAL_REALITY_TRAIT "vr_trait"
|
||||
#define CHANGELING_DRAIN "drain"
|
||||
#define CHANGELING_HIVEMIND_MUTE "ling_mute"
|
||||
#define ABYSSAL_GAZE_BLIND "abyssal_gaze"
|
||||
|
||||
@@ -139,18 +139,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/proc/has_ovipositor()
|
||||
var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(G && istype(G, /obj/item/organ/genital/ovipositor))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/has_eggsack()
|
||||
var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_TESTICLES)
|
||||
if(G && istype(G, /obj/item/organ/genital/eggsack))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/proc/is_groin_exposed(list/L)
|
||||
if(!L)
|
||||
L = get_equipped_items()
|
||||
|
||||
@@ -184,28 +184,14 @@
|
||||
"cock_length" = COCK_SIZE_DEF,
|
||||
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
||||
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"has_sheath" = FALSE,
|
||||
"sheath_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"has_balls" = FALSE,
|
||||
"balls_internal" = FALSE,
|
||||
"balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"balls_amount" = 2,
|
||||
"balls_sack_size" = BALLS_SACK_SIZE_DEF,
|
||||
"balls_size" = BALLS_SIZE_DEF,
|
||||
"balls_shape" = DEF_BALLS_SHAPE,
|
||||
"balls_cum_rate" = CUM_RATE,
|
||||
"balls_cum_mult" = CUM_RATE_MULT,
|
||||
"balls_efficiency" = CUM_EFFICIENCY,
|
||||
"has_ovi" = FALSE,
|
||||
"ovi_shape" = "knotted",
|
||||
"ovi_length" = 6,
|
||||
"ovi_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"has_eggsack" = FALSE,
|
||||
"eggsack_internal" = TRUE,
|
||||
"eggsack_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"eggsack_size" = BALLS_SACK_SIZE_DEF,
|
||||
"eggsack_egg_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"eggsack_egg_size" = EGG_GIRTH_DEF,
|
||||
"has_breasts" = FALSE,
|
||||
"breasts_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
"breasts_size" = pick(GLOB.breasts_size_list),
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
RegisterSignal(current_mind, COMSIG_PRE_MIND_TRANSFER, .proc/pre_player_transfer)
|
||||
if(mastermind?.current)
|
||||
mastermind.current.audiovisual_redirect = M
|
||||
ADD_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG, VIRTUAL_REALITY_TRAIT)
|
||||
|
||||
/datum/component/virtual_reality/UnregisterFromParent()
|
||||
. = ..()
|
||||
@@ -69,6 +70,7 @@
|
||||
current_mind = null
|
||||
if(mastermind?.current)
|
||||
mastermind.current.audiovisual_redirect = null
|
||||
REMOVE_TRAIT(parent, TRAIT_NO_MIDROUND_ANTAG, VIRTUAL_REALITY_TRAIT)
|
||||
|
||||
/**
|
||||
* Called when attempting to connect a mob to a virtual reality mob.
|
||||
@@ -235,7 +237,7 @@
|
||||
qdel(src)
|
||||
|
||||
/**
|
||||
* Used for recursive virtual realities shenanigeans and should be called only through the above proc.
|
||||
* Used for recursive virtual realities shenanigeans and should be called by the above proc.
|
||||
*/
|
||||
/datum/component/virtual_reality/proc/vr_in_a_vr(mob/player, deathcheck = FALSE, lethal_cleanup = FALSE)
|
||||
var/mob/M = parent
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
if(findtext(A, "[mutation1]") && findtext(A, "[mutation2]"))
|
||||
return GLOB.mutation_recipes[A]
|
||||
|
||||
/datum/generecipe/x_ray
|
||||
required = "/datum/mutation/human/thermal; /datum/mutation/human/radioactive"
|
||||
result = /datum/mutation/human/thermal/x_ray
|
||||
|
||||
/datum/generecipe/shock
|
||||
required = "/datum/mutation/human/insulated; /datum/mutation/human/radioactive"
|
||||
result = SHOCKTOUCH
|
||||
@@ -29,4 +25,4 @@
|
||||
|
||||
/datum/generecipe/tonguechem
|
||||
required = "/datum/mutation/human/tongue_spike; /datum/mutation/human/stimmed"
|
||||
result = TONGUESPIKECHEM
|
||||
result = TONGUESPIKECHEM
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
var/slowdown_priority = 50 //to make sure the stronger effect overrides
|
||||
var/affect_crawl = FALSE
|
||||
var/nextmove_modifier = 1
|
||||
var/stamdmg_per_ds = 1 //a 20 duration would do 20 stamdmg, disablers do 24 or something
|
||||
var/stamdmg_per_ds = 0 //a 20 duration would do 20 stamdmg, disablers do 24 or something
|
||||
var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
|
||||
|
||||
/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
|
||||
@@ -172,6 +172,7 @@
|
||||
slowdown_priority = 100
|
||||
nextmove_modifier = 2
|
||||
blocks_combatmode = TRUE
|
||||
stamdmg_per_ds = 1
|
||||
|
||||
/datum/status_effect/electrode/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
|
||||
. = ..()
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
if (!istype(M, required_type))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if (M.GetComponent(/datum/component/virtual_reality))
|
||||
if (HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG))
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if (!M.client) // Are they connected?
|
||||
|
||||
@@ -205,13 +205,18 @@
|
||||
difficulty = 10
|
||||
|
||||
/datum/objective_item/special/boh
|
||||
name = "a bag of holding."
|
||||
name = "a type of bag of holding."
|
||||
targetitem = /obj/item/storage/backpack/holding
|
||||
difficulty = 10
|
||||
|
||||
/datum/objective_item/special/hypercell
|
||||
name = "a hyper-capacity power cell."
|
||||
targetitem = /obj/item/stock_parts/cell/hyper
|
||||
/datum/objective_item/special/adv_surgical_drapes
|
||||
name = "a set of smart surgical drapes."
|
||||
targetitem = /obj/item/surgical_drapes/advanced
|
||||
difficulty = 10 //would be 15 but cmo rarely have it on themselfs and leave it in their lockers...
|
||||
|
||||
/datum/objective_item/special/bluespace
|
||||
name = "a bluespace power cell."
|
||||
targetitem = /obj/item/stock_parts/cell/bluespace
|
||||
difficulty = 5
|
||||
|
||||
/datum/objective_item/special/laserpointer
|
||||
|
||||
@@ -17,7 +17,7 @@ Buildable meters
|
||||
icon = 'icons/obj/atmospherics/pipes/pipe_item.dmi'
|
||||
icon_state = "simple"
|
||||
item_state = "buildpipe"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
level = 2
|
||||
var/piping_layer = PIPING_LAYER_DEFAULT
|
||||
var/RPD_type
|
||||
|
||||
@@ -52,9 +52,7 @@
|
||||
pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
|
||||
|
||||
/obj/effect/projectile_lighting
|
||||
var/owner
|
||||
|
||||
/obj/effect/projectile_lighting/Initialize(mapload, color, range, intensity, owner_key)
|
||||
/obj/effect/projectile_lighting/Initialize(mapload, color, range, intensity)
|
||||
. = ..()
|
||||
set_light(range, intensity, color)
|
||||
owner = owner_key
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/proc/generate_tracer_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5, light_range = 2, light_color_override, light_intensity = 1, instance_key) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
|
||||
/proc/generate_tracer_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5, light_range = 2, light_color_override, light_intensity = 1, list/turfs) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
|
||||
if(!istype(starting) || !istype(ending) || !ispath(beam_type))
|
||||
return
|
||||
var/datum/point/midpoint = point_midpoint_points(starting, ending)
|
||||
@@ -9,17 +9,15 @@
|
||||
. = PB
|
||||
if(light_range > 0 && light_intensity > 0)
|
||||
var/list/turf/line = getline(starting.return_turf(), ending.return_turf())
|
||||
tracing_line:
|
||||
for(var/i in line)
|
||||
var/turf/T = i
|
||||
for(var/obj/effect/projectile_lighting/PL in T)
|
||||
if(PL.owner == instance_key)
|
||||
continue tracing_line
|
||||
QDEL_IN(new /obj/effect/projectile_lighting(T, light_color_override, light_range, light_intensity, instance_key), qdel_in > 0? qdel_in : 5)
|
||||
for(var/i in line)
|
||||
if(turfs[i])
|
||||
continue
|
||||
turfs[i] = TRUE
|
||||
QDEL_IN(new /obj/effect/projectile_lighting(i, light_color_override, light_range, light_intensity), qdel_in > 0? qdel_in : 5)
|
||||
line = null
|
||||
if(qdel_in)
|
||||
QDEL_IN(PB, qdel_in)
|
||||
|
||||
d
|
||||
/obj/effect/projectile/tracer
|
||||
name = "beam"
|
||||
icon = 'icons/obj/projectiles_tracer.dmi'
|
||||
|
||||
@@ -855,4 +855,19 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return
|
||||
|
||||
/obj/item/proc/unembedded()
|
||||
return
|
||||
return
|
||||
|
||||
/**
|
||||
* Sets our slowdown and updates equipment slowdown of any mob we're equipped on.
|
||||
*/
|
||||
/obj/item/proc/set_slowdown(new_slowdown)
|
||||
slowdown = new_slowdown
|
||||
if(CHECK_BITFIELD(item_flags, IN_INVENTORY))
|
||||
var/mob/living/L = loc
|
||||
if(istype(L))
|
||||
L.update_equipment_speed_mods()
|
||||
|
||||
/obj/item/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
if(var_name == NAMEOF(src, slowdown))
|
||||
set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior.
|
||||
|
||||
@@ -143,33 +143,61 @@
|
||||
|
||||
/obj/item/melee/rapier
|
||||
name = "plastitanium rapier"
|
||||
desc = "A impossibly thin blade made of plastitanium with a tip made of diamond. It looks to be able to cut through any armor."
|
||||
desc = "A thin blade made of plastitanium with a diamond tip. It appears to be coated in a persistent layer of an unknown substance."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "rapier"
|
||||
item_state = "rapier"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
force = 25
|
||||
throwforce = 35
|
||||
block_chance = 0
|
||||
armour_penetration = 100
|
||||
force = 15
|
||||
throwforce = 25
|
||||
block_chance = 50
|
||||
armour_penetration = 200 //Apparently this gives it the ability to pierce block
|
||||
flags_1 = CONDUCT_1
|
||||
obj_flags = UNIQUE_RENAME
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
|
||||
attack_verb = list("slashed", "cut", "pierces", "pokes")
|
||||
total_mass = 3.4
|
||||
attack_verb = list("stabs", "punctures", "pierces", "pokes")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
total_mass = 0.4
|
||||
|
||||
/obj/item/melee/rapier/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 20, 65, 0)
|
||||
|
||||
/obj/item/melee/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(attack_type == PROJECTILE_ATTACK)
|
||||
final_block_chance = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/rapier/on_exit_storage(datum/component/storage/S)
|
||||
var/obj/item/storage/belt/sabre/rapier/B = S.parent
|
||||
if(istype(B))
|
||||
playsound(B, 'sound/items/unsheath.ogg', 25, 1)
|
||||
..()
|
||||
|
||||
/obj/item/melee/rapier/on_enter_storage(datum/component/storage/S)
|
||||
var/obj/item/storage/belt/sabre/rapier/B = S.parent
|
||||
if(istype(B))
|
||||
playsound(B, 'sound/items/sheath.ogg', 25, 1)
|
||||
..()
|
||||
|
||||
/obj/item/melee/rapier/get_belt_overlay()
|
||||
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "rapier")
|
||||
|
||||
/obj/item/melee/rapier/get_worn_belt_overlay(icon_file)
|
||||
return mutable_appearance(icon_file, "-rapier")
|
||||
|
||||
/obj/item/melee/rapier/attack(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/H = target
|
||||
var/loss = H.getStaminaLoss()
|
||||
H.Dizzy(10)
|
||||
H.adjustStaminaLoss(30)
|
||||
if((loss > 40) && prob(loss)) // if above 40, roll for sleep using 1% every 1 stamina damage
|
||||
H.Sleeping(180)
|
||||
|
||||
/obj/item/melee/classic_baton
|
||||
name = "police baton"
|
||||
desc = "A wooden truncheon for beating criminal scum."
|
||||
|
||||
@@ -795,18 +795,12 @@
|
||||
|
||||
/obj/item/storage/belt/sabre/rapier
|
||||
name = "rapier sheath"
|
||||
desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal."
|
||||
desc = "A sinister, thin sheath, suitable for a rapier."
|
||||
icon_state = "rsheath"
|
||||
item_state = "rsheath"
|
||||
force = 5
|
||||
throwforce = 15
|
||||
block_chance = 30
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
attack_verb = list("bashed", "slashes", "prods", "pokes")
|
||||
fitting_swords = list(/obj/item/melee/rapier)
|
||||
starting_sword = /obj/item/melee/rapier
|
||||
|
||||
/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(attack_type == PROJECTILE_ATTACK)
|
||||
final_block_chance = 0 //To thin to block bullets
|
||||
return ..()
|
||||
|
||||
@@ -259,6 +259,42 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
new /obj/item/ammo_box/a762(src)
|
||||
|
||||
/obj/item/storage/toolbox/infiltrator
|
||||
name = "insidious case"
|
||||
desc = "Bearing the emblem of the Syndicate, this case contains a full infiltrator stealth suit, and has enough room to fit weaponry if necessary while being quite the heavy bludgeoning implement when in a pinch."
|
||||
icon_state = "infiltrator_case"
|
||||
item_state = "infiltrator_case"
|
||||
force = 12
|
||||
throwforce = 16
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
has_latches = FALSE
|
||||
|
||||
/obj/item/storage/toolbox/infiltrator/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.silent = TRUE
|
||||
STR.max_items = 10
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.can_hold = typecacheof(list(
|
||||
/obj/item/clothing/head/helmet/infiltrator,
|
||||
/obj/item/clothing/suit/armor/vest/infiltrator,
|
||||
/obj/item/clothing/under/syndicate/bloodred,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile/infiltrator,
|
||||
/obj/item/clothing/mask/infiltrator,
|
||||
/obj/item/clothing/shoes/combat/sneakboots,
|
||||
/obj/item/gun/ballistic/automatic/pistol,
|
||||
/obj/item/gun/ballistic/revolver,
|
||||
/obj/item/ammo_box
|
||||
))
|
||||
|
||||
/obj/item/storage/toolbox/infiltrator/PopulateContents()
|
||||
new /obj/item/clothing/head/helmet/infiltrator(src)
|
||||
new /obj/item/clothing/suit/armor/vest/infiltrator(src)
|
||||
new /obj/item/clothing/under/syndicate/bloodred(src)
|
||||
new /obj/item/clothing/gloves/color/latex/nitrile/infiltrator(src)
|
||||
new /obj/item/clothing/mask/infiltrator(src)
|
||||
new /obj/item/clothing/shoes/combat/sneakboots(src)
|
||||
|
||||
/obj/item/storage/toolbox/plastitanium/gold_real
|
||||
name = "golden toolbox"
|
||||
desc = "A larger then normal toolbox made of gold plated plastitanium."
|
||||
|
||||
@@ -374,6 +374,12 @@
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/grenade/spawnergrenade/buzzkill(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/sleepytime/PopulateContents()
|
||||
new /obj/item/clothing/under/syndicate/bloodred/sleepytime(src)
|
||||
new /obj/item/reagent_containers/food/drinks/mug/coco(src)
|
||||
new /obj/item/toy/plush/carpplushie(src)
|
||||
new /obj/item/bedsheet/syndie(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/kitchen_gun
|
||||
name = "Kitchen Gun (TM) package"
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
var/obj/item/twohanded/offhand/O = user.get_inactive_held_item()
|
||||
if(O && istype(O))
|
||||
O.unwield()
|
||||
slowdown -= slowdown_wielded
|
||||
set_slowdown(slowdown - slowdown_wielded)
|
||||
|
||||
/obj/item/twohanded/proc/wield(mob/living/carbon/user)
|
||||
if(wielded)
|
||||
@@ -88,7 +88,7 @@
|
||||
O.desc = "Your second grip on [src]."
|
||||
O.wielded = TRUE
|
||||
user.put_in_inactive_hand(O)
|
||||
slowdown += slowdown_wielded
|
||||
set_slowdown(slowdown + slowdown_wielded)
|
||||
|
||||
/obj/item/twohanded/dropped(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -195,9 +195,7 @@
|
||||
return
|
||||
if(isgolem(user) && can_transfer)
|
||||
var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
|
||||
if(transfer_choice != "Yes")
|
||||
return
|
||||
if(QDELETED(src) || uses <= 0)
|
||||
if(transfer_choice != "Yes" || QDELETED(src) || uses <= 0 || !user.canUseTopic(src, BE_CLOSE, NO_DEXTERY, NO_TK))
|
||||
return
|
||||
log_game("[key_name(user)] golem-swapped into [src]")
|
||||
user.visible_message("<span class='notice'>A faint light leaves [user], moving to [src] and animating it!</span>","<span class='notice'>You leave your old body behind, and transfer into [src]!</span>")
|
||||
@@ -680,8 +678,9 @@
|
||||
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_PACIFISM,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_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)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
INVOKE_ASYNC(B, /obj/effect/mine/pickup/bloodbath/.proc/mineEffect, H) //could use moving out from the mine
|
||||
|
||||
for(var/mob/living/carbon/human/P in GLOB.player_list)
|
||||
if(P == H)
|
||||
if(P == H || HAS_TRAIT(P, TRAIT_NO_MIDROUND_ANTAG))
|
||||
continue
|
||||
to_chat(P, "<span class='userdanger'>You have an overwhelming desire to kill [H]. [H.p_theyve(TRUE)] been marked red! Whoever [H.p_they()] [H.p_were()], friend or foe, go kill [H.p_them()]!</span>")
|
||||
P.put_in_hands(new /obj/item/kitchen/knife/butcher(P), TRUE)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/datum/traitor_class/human/freeform/forge_objectives(datum/antagonist/traitor/T)
|
||||
var/datum/objective/escape/O = new
|
||||
O.explanation_text = "You have no goals! Whatever you can do do antagonize Nanotrasen, do it! The gimmickier, the better! Make sure to escape alive, though!"
|
||||
O.explanation_text = "You have no explicit goals! While we don't approve of mindless slaughter, you may antagonize nanotrasen any way you wish! Make sure to escape alive and not in custody, though!"
|
||||
O.owner = T.owner
|
||||
T.add_objective(O)
|
||||
return
|
||||
|
||||
@@ -125,28 +125,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"cock_length" = COCK_SIZE_DEF,
|
||||
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
||||
"cock_color" = "fff",
|
||||
"has_sheath" = FALSE,
|
||||
"sheath_color" = "fff",
|
||||
"has_balls" = FALSE,
|
||||
"balls_internal" = FALSE,
|
||||
"balls_color" = "fff",
|
||||
"balls_amount" = 2,
|
||||
"balls_sack_size" = BALLS_SACK_SIZE_DEF,
|
||||
"balls_shape" = DEF_BALLS_SHAPE,
|
||||
"balls_size" = BALLS_SIZE_DEF,
|
||||
"balls_cum_rate" = CUM_RATE,
|
||||
"balls_cum_mult" = CUM_RATE_MULT,
|
||||
"balls_efficiency" = CUM_EFFICIENCY,
|
||||
"has_ovi" = FALSE,
|
||||
"ovi_shape" = "knotted",
|
||||
"ovi_length" = 6,
|
||||
"ovi_color" = "fff",
|
||||
"has_eggsack" = FALSE,
|
||||
"eggsack_internal" = TRUE,
|
||||
"eggsack_color" = "fff",
|
||||
"eggsack_size" = BALLS_SACK_SIZE_DEF,
|
||||
"eggsack_egg_color" = "fff",
|
||||
"eggsack_egg_size" = EGG_GIRTH_DEF,
|
||||
"has_breasts" = FALSE,
|
||||
"breasts_color" = "fff",
|
||||
"breasts_size" = BREASTS_SIZE_DEF,
|
||||
@@ -1924,6 +1910,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
new_dors = input(user, "Choose your character's dorsal tube type:", "Character Preference") as null|anything in GLOB.xeno_dorsal_list
|
||||
if(new_dors)
|
||||
features["xenodorsal"] = new_dors
|
||||
|
||||
//Genital code
|
||||
if("cock_color")
|
||||
var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null
|
||||
@@ -1964,22 +1951,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_shape)
|
||||
features["balls_shape"] = new_shape
|
||||
|
||||
if("egg_size")
|
||||
var/new_size
|
||||
var/list/egg_sizes = list(1,2,3)
|
||||
new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes
|
||||
if(new_size)
|
||||
features["eggsack_egg_size"] = new_size
|
||||
|
||||
if("egg_color")
|
||||
var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null
|
||||
if(new_egg_color)
|
||||
var/temp_hsv = RGBtoHSV(new_egg_color)
|
||||
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("breasts_size")
|
||||
var/new_size
|
||||
new_size = input(user, "Breast Size", "Character Preference") as null|anything in GLOB.breasts_size_list
|
||||
@@ -2113,14 +2084,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["has_balls"] = FALSE
|
||||
if("has_balls")
|
||||
features["has_balls"] = !features["has_balls"]
|
||||
if("has_ovi")
|
||||
features["has_ovi"] = !features["has_ovi"]
|
||||
if("has_eggsack")
|
||||
features["has_eggsack"] = !features["has_eggsack"]
|
||||
if("balls_internal")
|
||||
features["balls_internal"] = !features["balls_internal"]
|
||||
if("eggsack_internal")
|
||||
features["eggsack_internal"] = !features["eggsack_internal"]
|
||||
if("has_breasts")
|
||||
features["has_breasts"] = !features["has_breasts"]
|
||||
if(features["has_breasts"] == FALSE)
|
||||
|
||||
@@ -452,7 +452,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_balls_color"] >> features["balls_color"]
|
||||
S["feature_balls_size"] >> features["balls_size"]
|
||||
S["feature_balls_shape"] >> features["balls_shape"]
|
||||
S["feature_balls_sack_size"] >> features["balls_sack_size"]
|
||||
//breasts features
|
||||
S["feature_has_breasts"] >> features["has_breasts"]
|
||||
S["feature_breasts_size"] >> features["breasts_size"]
|
||||
|
||||
@@ -447,7 +447,7 @@
|
||||
permeability_coefficient = 0.01
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
|
||||
var/vchange = 1
|
||||
var/voice_change = 1 ///This determines if the voice changer is on or off.
|
||||
|
||||
var/datum/action/item_action/chameleon/change/chameleon_action
|
||||
|
||||
@@ -470,15 +470,14 @@
|
||||
chameleon_action.emp_randomise(INFINITY)
|
||||
|
||||
/obj/item/clothing/mask/chameleon/attack_self(mob/user)
|
||||
vchange = !vchange
|
||||
to_chat(user, "<span class='notice'>The voice changer is now [vchange ? "on" : "off"]!</span>")
|
||||
|
||||
voice_change = !voice_change
|
||||
to_chat(user, "<span class='notice'>The voice changer is now [voice_change ? "on" : "off"]!</span>")
|
||||
|
||||
/obj/item/clothing/mask/chameleon/drone
|
||||
//Same as the drone chameleon hat, undroppable and no protection
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
// Can drones use the voice changer part? Let's not find out.
|
||||
vchange = 0
|
||||
voice_change = 0
|
||||
|
||||
/obj/item/clothing/mask/chameleon/drone/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
|
||||
/obj/item/clothing/gloves/color/latex
|
||||
name = "latex gloves"
|
||||
desc = "Cheap sterile gloves made from latex."
|
||||
desc = "Cheap sterile gloves made from latex. Transfers basic paramedical knowledge to the wearer via the use of nanochips."
|
||||
icon_state = "latex"
|
||||
item_state = "lgloves"
|
||||
siemens_coefficient = 0.3
|
||||
@@ -202,14 +202,34 @@
|
||||
item_color="mime"
|
||||
transfer_prints = TRUE
|
||||
resistance_flags = NONE
|
||||
var/carrytrait = TRAIT_QUICK_CARRY
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot == SLOT_GLOVES)
|
||||
ADD_TRAIT(user, carrytrait, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/dropped(mob/user)
|
||||
..()
|
||||
REMOVE_TRAIT(user, carrytrait, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/nitrile
|
||||
name = "nitrile gloves"
|
||||
desc = "Pricy sterile gloves that are stronger than latex."
|
||||
desc = "Pricy sterile gloves that are stronger than latex. Transfers advanced paramedical knowledge to the wearer via the use of nanochips."
|
||||
icon_state = "nitrile"
|
||||
item_state = "nitrilegloves"
|
||||
item_color = "cmo"
|
||||
transfer_prints = FALSE
|
||||
carrytrait = TRAIT_QUICKER_CARRY
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/nitrile/infiltrator
|
||||
name = "insidious combat gloves"
|
||||
desc = "Specialized combat gloves for carrying people around. Transfers tactical kidnapping knowledge to the user via the use of nanochips."
|
||||
icon_state = "infiltrator"
|
||||
item_state = "infiltrator"
|
||||
siemens_coefficient = 0
|
||||
permeability_coefficient = 0.3
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/clothing/gloves/color/white
|
||||
name = "white gloves"
|
||||
|
||||
@@ -256,6 +256,21 @@
|
||||
strip_delay = 100
|
||||
mutantrace_variation = STYLE_MUZZLE
|
||||
|
||||
/obj/item/clothing/head/helmet/infiltrator
|
||||
name = "insidious helmet"
|
||||
desc = "An insidious armored combat helmet signed with Syndicate insignia. The visor is coated with a resistant paste guaranteed to withstand bright flashes perfectly."
|
||||
icon_state = "infiltrator"
|
||||
item_state = "infiltrator"
|
||||
armor = list("melee" = 40, "bullet" = 40, "laser" = 30, "energy" = 40, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
flash_protect = 2
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
dynamic_hair_suffix = ""
|
||||
dynamic_fhair_suffix = ""
|
||||
strip_delay = 80
|
||||
mutantrace_variation = STYLE_MUZZLE
|
||||
|
||||
//LightToggle
|
||||
|
||||
/obj/item/clothing/head/helment/ComponentInitialize()
|
||||
|
||||
@@ -12,6 +12,20 @@
|
||||
/obj/item/clothing/mask/balaclava/attack_self(mob/user)
|
||||
adjustmask(user)
|
||||
|
||||
/obj/item/clothing/mask/infiltrator
|
||||
name = "insidious balaclava"
|
||||
desc = "An incredibly suspicious balaclava made with Syndicate nanofibers to absorb impacts slightly while obfuscating the voice and face using a garbled vocoder."
|
||||
icon_state = "syndicate_balaclava"
|
||||
item_state = "syndicate_balaclava"
|
||||
clothing_flags = ALLOWINTERNALS
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
visor_flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 100, "acid" = 40)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
var/voice_unknown = TRUE ///This makes it so that your name shows up as unknown when wearing the mask.
|
||||
|
||||
/obj/item/clothing/mask/luchador
|
||||
name = "Luchador Mask"
|
||||
desc = "Worn by robust fighters, flying high to defeat their foes!"
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
permeability_coefficient = 0.05 //Thick soles, and covers the ankle
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
|
||||
/obj/item/clothing/shoes/combat/sneakboots
|
||||
name = "insidious sneakboots"
|
||||
desc = "A pair of insidious boots with special noise muffling soles which very slightly drown out your footsteps. They would be absolutely perfect for stealth operations were it not for the iconic Syndicate flairs."
|
||||
icon_state = "sneakboots"
|
||||
item_state = "sneakboots"
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
clothing_flags = TRAIT_SILENT_STEP
|
||||
|
||||
/obj/item/clothing/shoes/combat/swat //overpowered boots for death squads
|
||||
name = "\improper SWAT boots"
|
||||
desc = "High speed, no drag combat boots."
|
||||
|
||||
@@ -191,6 +191,15 @@
|
||||
. = ..()
|
||||
allowed = GLOB.detective_vest_allowed
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/infiltrator
|
||||
name = "insidious combat vest"
|
||||
desc = "An insidious combat vest designed using Syndicate nanofibers to absorb the supreme majority of kinetic blows. Although it doesn't look like it'll do too much for energy impacts."
|
||||
icon_state = "infiltrator"
|
||||
item_state = "infiltrator"
|
||||
armor = list("melee" = 30, "bullet" = 40, "laser" = 20, "energy" = 30, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
strip_delay = 80
|
||||
|
||||
//All of the armor below is mostly unused
|
||||
|
||||
/obj/item/clothing/suit/armor/centcom
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/can_adjust = TRUE
|
||||
var/adjusted = NORMAL_STYLE
|
||||
var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only
|
||||
var/dummy_thick = FALSE // is able to hold accessories on its item
|
||||
var/obj/item/clothing/accessory/attached_accessory
|
||||
var/mutable_appearance/accessory_overlay
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
@@ -82,6 +83,10 @@
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] already has an accessory.</span>")
|
||||
return
|
||||
if(dummy_thick)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] is too bulky and cannot have accessories attached to it!</span>")
|
||||
return
|
||||
else
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(I))
|
||||
return
|
||||
|
||||
@@ -19,6 +19,25 @@
|
||||
alt_covers_chest = TRUE
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
|
||||
/obj/item/clothing/under/syndicate/bloodred
|
||||
name = "blood-red sneaksuit"
|
||||
desc = "An insidious armored jumpsuit lined with Syndicate nanofibers and prototype platings, slightly resistant to most forms of damage, but is far too bulky to have anything attached to it. It still counts as stealth if there are no witnesses."
|
||||
icon_state = "bloodred_pajamas"
|
||||
item_state = "bl_suit"
|
||||
item_color = "bloodred_pajamas"
|
||||
dummy_thick = TRUE
|
||||
armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/syndicate/bloodred/sleepytime
|
||||
name = "blood-red pajamas"
|
||||
desc = "Do operatives dream of nuclear sheep?"
|
||||
icon_state = "bloodred_pajamas"
|
||||
item_state = "bl_suit"
|
||||
item_color = "bloodred_pajamas"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
|
||||
|
||||
/obj/item/clothing/under/syndicate/tacticool
|
||||
name = "tacticool turtleneck"
|
||||
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
|
||||
@@ -75,7 +94,7 @@
|
||||
item_color = "rus_under"
|
||||
can_adjust = FALSE
|
||||
armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
resistance_flags = NONE
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/syndicate/baseball
|
||||
name = "major league, number unknown"
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
..()
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
H.put_in_hands(new /obj/item/valentine)
|
||||
var/obj/item/storage/backpack/b = locate() in H.contents
|
||||
new /obj/item/reagent_containers/food/snacks/candyheart(b)
|
||||
new /obj/item/storage/fancy/heart_box(b)
|
||||
var/obj/item/storage/backpack/B = locate() in H.contents
|
||||
if(B)
|
||||
new /obj/item/reagent_containers/food/snacks/candyheart(B)
|
||||
new /obj/item/storage/fancy/heart_box(B)
|
||||
|
||||
var/list/valentines = list()
|
||||
for(var/mob/living/M in GLOB.player_list)
|
||||
if(!M.stat && M.client && M.mind)
|
||||
if(!M.stat && M.client && M.mind && !HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG))
|
||||
valentines |= M
|
||||
|
||||
|
||||
|
||||
@@ -4,11 +4,26 @@
|
||||
weight = 10
|
||||
max_occurrences = 2
|
||||
min_players = 1
|
||||
var/forced_hallucination
|
||||
|
||||
/datum/round_event_control/mass_hallucination/admin_setup()
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
forced_hallucination = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in subtypesof(/datum/hallucination)
|
||||
|
||||
/datum/round_event/mass_hallucination
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/mass_hallucination/start()
|
||||
var/datum/round_event_control/mass_hallucination/M = control
|
||||
if(M.forced_hallucination)
|
||||
for(var/mob/living/carbon/C in GLOB.alive_mob_list)
|
||||
if (HAS_TRAIT(C,TRAIT_EXEMPT_HEALTH_EVENTS))
|
||||
continue
|
||||
new M.forced_hallucination(C, TRUE)
|
||||
return
|
||||
|
||||
switch(rand(1,4))
|
||||
if(1) //same sound for everyone
|
||||
var/sound = pick("airlock","airlock_pry","console","explosion","far_explosion","mech","glass","alarm","beepsky","mech","wall_decon","door_hack","tesla")
|
||||
@@ -37,4 +52,4 @@
|
||||
for(var/mob/living/carbon/C in GLOB.alive_mob_list)
|
||||
if (HAS_TRAIT(C,TRAIT_EXEMPT_HEALTH_EVENTS))
|
||||
continue
|
||||
new picked_hallucination(C, TRUE)
|
||||
new picked_hallucination(C, TRUE)
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
to_chat(user, "<span class='notice'>You place [I] into [src] to start the fermentation process.</span>")
|
||||
addtimer(CALLBACK(src, .proc/makeWine, fruit), rand(80, 120) * speed_multiplier)
|
||||
return TRUE
|
||||
var/obj/item/W = I
|
||||
if(W)
|
||||
if(W.is_refillable())
|
||||
return FALSE //so we can refill them via their afterattack.
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
desc = "A device which causes kinetic accelerators to permanently gain damage against creature types killed with it."
|
||||
id = "bountymod"
|
||||
materials = list(/datum/material/iron = 4000, /datum/material/silver = 4000, /datum/material/gold = 4000, /datum/material/bluespace = 4000)
|
||||
reagents_list = list("blood" = 40)
|
||||
reagents_list = list(/datum/reagent/blood = 40)
|
||||
build_path = /obj/item/borg/upgrade/modkit/bounty
|
||||
|
||||
//Spooky special loot
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
return /datum/reagent/blood/jellyblood
|
||||
if(dna?.species?.exotic_blood)
|
||||
return dna.species.exotic_blood
|
||||
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
|
||||
else if((dna && (NOBLOOD in dna.species.species_traits)) || HAS_TRAIT(src, TRAIT_NOCLONE))
|
||||
return
|
||||
else
|
||||
return /datum/reagent/blood
|
||||
|
||||
@@ -880,10 +880,20 @@
|
||||
return (ishuman(target) && !CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
|
||||
/mob/living/carbon/human/proc/fireman_carry(mob/living/carbon/target)
|
||||
if(can_be_firemanned(target))
|
||||
visible_message("<span class='notice'>[src] starts lifting [target] onto their back...</span>",
|
||||
"<span class='notice'>You start lifting [target] onto your back...</span>")
|
||||
if(do_after(src, 30, TRUE, target))
|
||||
var/carrydelay = 50 //if you have latex you are faster at grabbing
|
||||
var/skills_space = "" //cobby told me to do this
|
||||
if(HAS_TRAIT(src, TRAIT_QUICKER_CARRY))
|
||||
carrydelay = 30
|
||||
skills_space = "expertly"
|
||||
else if(HAS_TRAIT(src, TRAIT_QUICK_CARRY))
|
||||
carrydelay = 40
|
||||
skills_space = "quickly"
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
visible_message("<span class='notice'>[src] starts [skills_space] lifting [target] onto their back..</span>",
|
||||
//Joe Medic starts quickly/expertly lifting Grey Tider onto their back..
|
||||
"<span class='notice'>[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space] start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]</span>")
|
||||
//(Using your gloves' nanochips, you/You) ( /quickly/expertly) start to lift Grey Tider onto your back(, while assisted by the nanochips in your gloves../...)
|
||||
if(do_after(src, carrydelay, TRUE, target))
|
||||
//Second check to make sure they're still valid to be carried
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
target.set_resting(FALSE, TRUE)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/mob/living/carbon/human/GetVoice()
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
|
||||
var/obj/item/clothing/mask/chameleon/V = wear_mask
|
||||
if(V.vchange && wear_id)
|
||||
if(V.voice_change && wear_id)
|
||||
var/obj/item/card/id/idcard = wear_id.GetID()
|
||||
if(istype(idcard))
|
||||
return idcard.registered_name
|
||||
@@ -21,6 +21,12 @@
|
||||
return real_name
|
||||
else
|
||||
return real_name
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/infiltrator))
|
||||
var/obj/item/clothing/mask/infiltrator/V = wear_mask
|
||||
if(V.voice_unknown)
|
||||
return ("Unknown")
|
||||
else
|
||||
return real_name
|
||||
if(mind)
|
||||
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling && changeling.mimicing )
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
id = "spaceskeleton"
|
||||
limbs_id = "skeleton"
|
||||
blacklisted = 1
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
|
||||
|
||||
/datum/species/skeleton/space/check_roundstart_eligible()
|
||||
return FALSE
|
||||
@@ -913,8 +913,8 @@
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/reagent_containers/borghypo/syndicate,
|
||||
/obj/item/twohanded/shockpaddles/syndicate,
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/surgical_drapes,
|
||||
/obj/item/healthanalyzer/advanced,
|
||||
/obj/item/surgical_drapes/advanced,
|
||||
/obj/item/retractor,
|
||||
/obj/item/hemostat,
|
||||
/obj/item/cautery,
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
name = "energy dagger"
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
embedding = embedding.setRating(embed_chance = 100) //rule of cool
|
||||
embedding = list("embed_chance" = 100, "embedded_fall_chance" = 0)//rule of cool
|
||||
throwforce = 35
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
|
||||
to_chat(user, "<span class='warning'>[src] is now active.</span>")
|
||||
|
||||
@@ -28,6 +28,16 @@
|
||||
/datum/duel/New()
|
||||
id = next_id++
|
||||
|
||||
/datum/duel/Destroy()
|
||||
if(gun_A)
|
||||
gun_A.duel = null
|
||||
gun_A = null
|
||||
if(gun_B)
|
||||
gun_B.duel = null
|
||||
gun_B = null
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/datum/duel/proc/try_begin()
|
||||
//Check if both guns are held and if so begin.
|
||||
var/mob/living/A = get_duelist(gun_A)
|
||||
@@ -45,13 +55,13 @@
|
||||
|
||||
message_duelists("<span class='notice'>Set your gun setting and move [required_distance] steps away from your opponent.</span>")
|
||||
|
||||
START_PROCESSING(SSobj,src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/duel/proc/get_duelist(obj/gun)
|
||||
var/mob/living/G = gun.loc
|
||||
if(!istype(G) || !G.is_holding(gun))
|
||||
return null
|
||||
return G
|
||||
/datum/duel/proc/get_duelist(obj/item/gun/energy/dueling/G)
|
||||
var/mob/living/L = G.loc
|
||||
if(!istype(L) || !L.is_holding(G))
|
||||
return
|
||||
return L
|
||||
|
||||
/datum/duel/proc/message_duelists(message)
|
||||
var/mob/living/LA = get_duelist(gun_A)
|
||||
@@ -66,7 +76,7 @@
|
||||
|
||||
/datum/duel/proc/end()
|
||||
message_duelists("<span class='notice'>Duel finished. Re-engaging safety.</span>")
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
state = DUEL_IDLE
|
||||
|
||||
/datum/duel/process()
|
||||
@@ -129,10 +139,11 @@
|
||||
return FALSE
|
||||
if(!isturf(A.loc) || !isturf(B.loc))
|
||||
return FALSE
|
||||
if(get_dist(A,B) != required_distance)
|
||||
if(get_dist(A, B) != required_distance)
|
||||
return FALSE
|
||||
for(var/turf/T in getline(get_turf(A),get_turf(B)))
|
||||
if(is_blocked_turf(T,TRUE))
|
||||
for(var/i in getline(A.loc, B.loc))
|
||||
var/turf/T = i
|
||||
if(is_blocked_turf(T, TRUE))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -180,7 +191,6 @@
|
||||
return "duel_red"
|
||||
|
||||
/obj/item/gun/energy/dueling/attack_self(mob/living/user)
|
||||
. = ..()
|
||||
if(duel.state == DUEL_IDLE)
|
||||
duel.try_begin()
|
||||
else
|
||||
@@ -205,12 +215,9 @@
|
||||
add_overlay(setting_overlay)
|
||||
|
||||
/obj/item/gun/energy/dueling/Destroy()
|
||||
. = ..()
|
||||
if(duel.gun_A == src)
|
||||
duel.gun_A = null
|
||||
if(duel.gun_B == src)
|
||||
duel.gun_B = null
|
||||
duel = null
|
||||
if(duel)
|
||||
qdel(duel)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/dueling/can_trigger_gun(mob/living/user)
|
||||
. = ..()
|
||||
@@ -234,10 +241,8 @@
|
||||
if(duel.state == DUEL_READY)
|
||||
duel.confirmations[src] = TRUE
|
||||
to_chat(user,"<span class='notice'>You confirm your readiness.</span>")
|
||||
return
|
||||
else if(!is_duelist(target)) //I kinda want to leave this out just to see someone shoot a bystander or missing.
|
||||
to_chat(user,"<span class='warning'>[src] safety system prevents shooting anyone but your designated opponent.</span>")
|
||||
return
|
||||
else
|
||||
duel.fired[src] = TRUE
|
||||
. = ..()
|
||||
|
||||
@@ -181,13 +181,6 @@
|
||||
listeningTo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
chambered = null
|
||||
recharge_newshot()
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/proc/aiming_beam(force_update = FALSE)
|
||||
var/diff = abs(aiming_lastangle - lastangle)
|
||||
if(!check_user())
|
||||
@@ -302,7 +295,7 @@
|
||||
if(istype(object, /obj/screen) && !istype(object, /obj/screen/click_catcher))
|
||||
return
|
||||
process_aim()
|
||||
if(aiming_time_left <= aiming_time_fire_threshold && check_user() && ((lastfire + delay) <= world.time))
|
||||
if(fire_check())
|
||||
sync_ammo()
|
||||
do_fire(M.client.mouseObject, M, FALSE, M.client.mouseParams, M.zone_selected)
|
||||
stop_aiming()
|
||||
@@ -310,11 +303,16 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/do_fire(atom/target, mob/living/user, message = TRUE, params, zone_override = "", bonus_spread = 0)
|
||||
if(!fire_check())
|
||||
return
|
||||
. = ..()
|
||||
if(.)
|
||||
lastfire = world.time
|
||||
stop_aiming()
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/proc/fire_check()
|
||||
return (aiming_time_left <= aiming_time_fire_threshold) && check_user() && ((lastfire + delay) <= world.time)
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/proc/sync_ammo()
|
||||
for(var/obj/item/ammo_casing/energy/beam_rifle/AC in contents)
|
||||
AC.sync_stats()
|
||||
@@ -531,21 +529,15 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/tracer/beam_rifle
|
||||
var/constant_tracer = FALSE
|
||||
|
||||
/obj/item/projectile/beam/beam_rifle/hitscan/generate_hitscan_tracers(cleanup = TRUE, duration = 5, impacting = TRUE, highlander)
|
||||
set waitfor = FALSE
|
||||
if(isnull(highlander))
|
||||
highlander = constant_tracer
|
||||
if(highlander && istype(gun))
|
||||
QDEL_LIST(gun.current_tracers)
|
||||
for(var/datum/point/p in beam_segments)
|
||||
gun.current_tracers += generate_tracer_between_points(p, beam_segments[p], tracer_type, color, 0, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity)
|
||||
/obj/item/projectile/beam/beam_rifle/hitscan/generate_hitscan_tracers(cleanup = TRUE, duration = 5, impacting = TRUE, generation, highlander = constant_tracer)
|
||||
if(!highlander)
|
||||
return ..()
|
||||
else
|
||||
for(var/datum/point/p in beam_segments)
|
||||
generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity)
|
||||
if(cleanup)
|
||||
QDEL_LIST(beam_segments)
|
||||
beam_segments = null
|
||||
QDEL_NULL(beam_index)
|
||||
duration = 0
|
||||
. = ..()
|
||||
if(!generation) //first one
|
||||
QDEL_LIST(gun.current_tracers)
|
||||
gun.current_tracers += .
|
||||
|
||||
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam
|
||||
tracer_type = /obj/effect/projectile/tracer/tracer/aiming
|
||||
@@ -560,4 +552,5 @@
|
||||
hitscan_light_color_override = "#99ff99"
|
||||
|
||||
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
// this is all shitcode never ever add it to the game it's for debugging only.
|
||||
|
||||
/datum/action/item_action/chameleon/change/gun/update_look(mob/user, obj/item/picked_item)
|
||||
. = ..()
|
||||
var/obj/item/gun/energy/laser/chameleon/CG = target
|
||||
CG.get_chameleon_projectile(picked_item)
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon
|
||||
name = "practice laser gun"
|
||||
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/chameleon)
|
||||
clumsy_check = 0
|
||||
item_flags = NONE
|
||||
pin = /obj/item/firing_pin
|
||||
cell_type = /obj/item/stock_parts/cell/bluespace
|
||||
|
||||
var/datum/action/item_action/chameleon/change/gun/chameleon_action
|
||||
var/list/chameleon_projectile_vars
|
||||
var/list/chameleon_ammo_vars
|
||||
var/list/chameleon_gun_vars
|
||||
var/list/projectile_copy_vars
|
||||
var/list/ammo_copy_vars
|
||||
var/list/gun_copy_vars
|
||||
var/badmin_mode = FALSE
|
||||
var/can_hitscan = FALSE
|
||||
var/hitscan_mode = FALSE
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/Initialize()
|
||||
. = ..()
|
||||
chameleon_action = new(src)
|
||||
chameleon_action.chameleon_type = /obj/item/gun
|
||||
chameleon_action.chameleon_name = "Gun"
|
||||
chameleon_action.chameleon_blacklist = typecacheof(/obj/item/gun/magic, ignore_root_path = FALSE)
|
||||
chameleon_action.initialize_disguises()
|
||||
|
||||
projectile_copy_vars = list("name", "icon", "icon_state", "item_state", "speed", "color", "hitsound", "forcedodge", "impact_effect_type", "range", "suppressed", "hitsound_wall", "impact_effect_type", "pass_flags", "tracer_type", "muzzle_type", "impact_type")
|
||||
chameleon_projectile_vars = list("name" = "practice laser", "icon" = 'icons/obj/projectiles.dmi', "icon_state" = "laser")
|
||||
gun_copy_vars = list("fire_sound", "burst_size", "fire_delay")
|
||||
chameleon_gun_vars = list()
|
||||
ammo_copy_vars = list("firing_effect_type")
|
||||
chameleon_ammo_vars = list()
|
||||
recharge_newshot()
|
||||
get_chameleon_projectile(/obj/item/gun/energy/laser)
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/proc/reset_chameleon_vars()
|
||||
chameleon_ammo_vars = list()
|
||||
chameleon_gun_vars = list()
|
||||
chameleon_projectile_vars = list()
|
||||
var/static/list/blacklisted_vars = list("locs", "loc", "contents", "x", "y", "z", "parent_type", "type", "vars")
|
||||
if(chambered)
|
||||
for(var/v in ammo_copy_vars)
|
||||
if(v in blacklisted_vars) //Just in case admins go crazy.
|
||||
continue
|
||||
chambered.vv_edit_var(v, initial(chambered.vars[v]))
|
||||
for(var/v in gun_copy_vars)
|
||||
if(v in blacklisted_vars)
|
||||
continue
|
||||
vv_edit_var(v, initial(vars[v]))
|
||||
vars[v] = initial(vars[v])
|
||||
QDEL_NULL(chambered.BB)
|
||||
chambered.newshot()
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/proc/set_chameleon_ammo(obj/item/ammo_casing/AC, passthrough = TRUE, reset = FALSE)
|
||||
if(!istype(AC))
|
||||
CRASH("[AC] is not /obj/item/ammo_casing!")
|
||||
return FALSE
|
||||
for(var/V in ammo_copy_vars)
|
||||
if(AC.vars.Find(V))
|
||||
chameleon_ammo_vars[V] = AC.vars[V]
|
||||
chambered?.vv_edit_var(V, AC.vars[V])
|
||||
if(passthrough)
|
||||
var/obj/item/projectile/P = AC.BB
|
||||
set_chameleon_projectile(P)
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/proc/set_chameleon_projectile(obj/item/projectile/P)
|
||||
if(!istype(P))
|
||||
CRASH("[P] is not /obj/item/projectile!")
|
||||
return FALSE
|
||||
chameleon_projectile_vars = list("name" = "practice laser", "icon" = 'icons/obj/projectiles.dmi', "icon_state" = "laser", "nodamage" = TRUE)
|
||||
for(var/V in projectile_copy_vars)
|
||||
if(P.vars.Find(V))
|
||||
chameleon_projectile_vars[V] = P.vars[V]
|
||||
if(istype(chambered, /obj/item/ammo_casing/energy/chameleon))
|
||||
var/obj/item/ammo_casing/energy/chameleon/AC = chambered
|
||||
AC.projectile_vars = chameleon_projectile_vars.Copy()
|
||||
if(!P.tracer_type)
|
||||
can_hitscan = FALSE
|
||||
set_hitscan(FALSE)
|
||||
else
|
||||
can_hitscan = TRUE
|
||||
if(badmin_mode)
|
||||
qdel(chambered.BB)
|
||||
chambered.projectile_type = P.type
|
||||
chambered.newshot()
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/proc/set_chameleon_gun(obj/item/gun/G , passthrough = TRUE)
|
||||
if(!istype(G))
|
||||
CRASH("[G] is not /obj/item/gun!")
|
||||
return FALSE
|
||||
for(var/V in gun_copy_vars)
|
||||
if(vars.Find(V) && G.vars.Find(V))
|
||||
chameleon_gun_vars[V] = G.vars[V]
|
||||
vv_edit_var(V, G.vars[V])
|
||||
if(passthrough)
|
||||
if(istype(G, /obj/item/gun/ballistic))
|
||||
var/obj/item/gun/ballistic/BG = G
|
||||
var/obj/item/ammo_box/AB = new BG.mag_type(G)
|
||||
qdel(BG)
|
||||
if(!istype(AB)||!AB.ammo_type)
|
||||
qdel(AB)
|
||||
return FALSE
|
||||
var/obj/item/ammo_casing/AC = new AB.ammo_type(G)
|
||||
set_chameleon_ammo(AC)
|
||||
else if(istype(G, /obj/item/gun/magic))
|
||||
var/obj/item/gun/magic/MG = G
|
||||
var/obj/item/ammo_casing/AC = new MG.ammo_type(G)
|
||||
set_chameleon_ammo(AC)
|
||||
else if(istype(G, /obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/EG = G
|
||||
if(islist(EG.ammo_type) && EG.ammo_type.len)
|
||||
var/obj/item/ammo_casing/AC = EG.ammo_type[1]
|
||||
set_chameleon_ammo(AC)
|
||||
else if(istype(G, /obj/item/gun/syringe))
|
||||
var/obj/item/ammo_casing/AC = new /obj/item/ammo_casing/syringegun(src)
|
||||
set_chameleon_ammo(AC)
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(!can_hitscan)
|
||||
to_chat(user, "<span class='warning'>[src]'s current disguised gun does not allow it to enable high velocity mode!</span>")
|
||||
return
|
||||
if(!chambered)
|
||||
to_chat(user, "<span class='warning'>Unknown error in energy lens: Please reset chameleon disguise and try again.</span>")
|
||||
return
|
||||
set_hitscan(!hitscan_mode)
|
||||
to_chat(user, "<span class='notice'>You toggle [src]'s high velocity beam mode to [hitscan_mode? "on" : "off"].</span>")
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/proc/set_hitscan(hitscan)
|
||||
var/obj/item/ammo_casing/energy/chameleon/AC = chambered
|
||||
AC.hitscan_mode = hitscan
|
||||
hitscan_mode = hitscan
|
||||
|
||||
/obj/item/gun/energy/laser/chameleon/proc/get_chameleon_projectile(guntype)
|
||||
reset_chameleon_vars()
|
||||
var/obj/item/gun/G = new guntype(src)
|
||||
set_chameleon_gun(G)
|
||||
qdel(G)
|
||||
|
||||
/obj/item/ammo_casing/energy/chameleon
|
||||
projectile_type = /obj/item/projectile/energy/chameleon
|
||||
e_cost = 0
|
||||
var/hitscan_mode = FALSE
|
||||
var/list/projectile_vars = list()
|
||||
|
||||
/obj/item/ammo_casing/energy/chameleon/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
. = ..()
|
||||
if(!BB)
|
||||
newshot()
|
||||
for(var/V in projectile_vars)
|
||||
if(BB.vars.Find(V))
|
||||
BB.vv_edit_var(V, projectile_vars[V])
|
||||
if(hitscan_mode)
|
||||
BB.hitscan = TRUE
|
||||
|
||||
/obj/item/projectile/energy/chameleon
|
||||
nodamage = TRUE
|
||||
@@ -52,6 +52,8 @@
|
||||
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
|
||||
var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end. Used for hitscan effect generation.
|
||||
var/datum/point/beam_index
|
||||
/// Used in generate_hitscan_tracers to determine which "cycle" we're on.
|
||||
var/hitscan_effect_generation = 0
|
||||
var/tracer_type
|
||||
var/muzzle_type
|
||||
var/impact_type
|
||||
@@ -89,10 +91,10 @@
|
||||
var/decayedRange //stores original range
|
||||
var/reflect_range_decrease = 5 //amount of original range that falls off when reflecting, so it doesn't go forever
|
||||
var/is_reflectable = FALSE // Can it be reflected or not?
|
||||
|
||||
|
||||
/// factor to multiply by for zone accuracy percent.
|
||||
var/zone_accuracy_factor = 1
|
||||
|
||||
|
||||
//Effects
|
||||
var/stun = 0
|
||||
var/knockdown = 0
|
||||
@@ -656,18 +658,20 @@
|
||||
if(trajectory && beam_index)
|
||||
var/datum/point/pcache = trajectory.copy_to()
|
||||
beam_segments[beam_index] = pcache
|
||||
generate_hitscan_tracers(null, null, impacting)
|
||||
generate_hitscan_tracers(null, null, impacting, hitscan_effect_generation++)
|
||||
|
||||
/obj/item/projectile/proc/generate_hitscan_tracers(cleanup = TRUE, duration = 3, impacting = TRUE)
|
||||
/obj/item/projectile/proc/generate_hitscan_tracers(cleanup = TRUE, duration = 3, impacting = TRUE, generation)
|
||||
if(!length(beam_segments))
|
||||
return
|
||||
. = list()
|
||||
if(tracer_type)
|
||||
var/tempref = REF(src)
|
||||
var/list/turfs = list()
|
||||
for(var/datum/point/p in beam_segments)
|
||||
generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity, tempref)
|
||||
. += generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity, turfs)
|
||||
if(muzzle_type && duration > 0)
|
||||
var/datum/point/p = beam_segments[1]
|
||||
var/atom/movable/thing = new muzzle_type
|
||||
. += thing
|
||||
p.move_atom_to_src(thing)
|
||||
var/matrix/M = new
|
||||
M.Turn(original_angle)
|
||||
@@ -678,6 +682,7 @@
|
||||
if(impacting && impact_type && duration > 0)
|
||||
var/datum/point/p = beam_segments[beam_segments[beam_segments.len]]
|
||||
var/atom/movable/thing = new impact_type
|
||||
. += thing
|
||||
p.move_atom_to_src(thing)
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
stutter = 10
|
||||
jitter = 20
|
||||
hitsound = 'sound/weapons/taserhit.ogg'
|
||||
range = 7
|
||||
range = 14
|
||||
speed = 0.6
|
||||
tracer_type = /obj/effect/projectile/tracer/stun
|
||||
muzzle_type = /obj/effect/projectile/muzzle/stun
|
||||
impact_type = /obj/effect/projectile/impact/stun
|
||||
@@ -42,9 +43,9 @@
|
||||
knockdown_stamoverride = 0
|
||||
knockdown_stam_max = 0
|
||||
strong_tase = FALSE
|
||||
range = 12
|
||||
|
||||
/obj/item/projectile/energy/electrode/security/hos
|
||||
knockdown = 100
|
||||
knockdown_stamoverride = 30
|
||||
knockdown_stam_max = null
|
||||
tase_duration = 10
|
||||
|
||||
@@ -356,7 +356,6 @@
|
||||
replace_beaker(user, B)
|
||||
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
|
||||
updateUsrDialog()
|
||||
update_icon()
|
||||
else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag))
|
||||
to_chat(user, "<span class='warning'>You can't load [I] into [src]!</span>")
|
||||
return ..()
|
||||
|
||||
@@ -55,6 +55,10 @@ Nothing else in the console has ID requirements.
|
||||
if (istype(ID, /datum/material))
|
||||
var/datum/material/material = ID
|
||||
return material.name
|
||||
|
||||
else if(GLOB.chemical_reagents_list[ID])
|
||||
var/datum/reagent/reagent = GLOB.chemical_reagents_list[ID]
|
||||
return reagent.name
|
||||
return ID
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any).
|
||||
|
||||
@@ -705,8 +705,9 @@
|
||||
desc = "A miraculous chemical mix that grants human like intelligence to living beings. It has been modified with Syndicate technology to also grant an internal radio implant to the target and authenticate with identification systems."
|
||||
|
||||
/obj/item/slimepotion/slime/sentience/nuclear/after_success(mob/living/user, mob/living/simple_animal/SM)
|
||||
var/obj/item/implant/radio/syndicate/imp = new
|
||||
imp.implant(SM, user)
|
||||
if(SM.can_be_implanted())
|
||||
var/obj/item/implant/radio/syndicate/imp = new
|
||||
imp.implant(SM, user)
|
||||
|
||||
SM.access_card = new /obj/item/card/id/syndicate(SM)
|
||||
ADD_TRAIT(SM.access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
|
||||
@@ -961,11 +962,12 @@
|
||||
icon_state = "potgrey"
|
||||
|
||||
/obj/item/slimepotion/slime/slimeradio/attack(mob/living/M, mob/user)
|
||||
if(!ismob(M))
|
||||
return
|
||||
if(!isanimal(M))
|
||||
to_chat(user, "<span class='warning'>[M] is too complex for the potion!</span>")
|
||||
return
|
||||
if(!M.can_be_implanted())
|
||||
to_chat(user, "<span class='warning'>[M] is incompatible with the potion!</span>")
|
||||
return
|
||||
if(M.stat)
|
||||
to_chat(user, "<span class='warning'>[M] is dead!</span>")
|
||||
return
|
||||
|
||||
@@ -163,7 +163,7 @@ GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.player_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(T && is_away_level(T.z))
|
||||
if((T && is_away_level(T.z)) || HAS_TRAIT(H, TRAIT_NO_MIDROUND_ANTAG))
|
||||
continue
|
||||
if(summon_type == SUMMON_MAGIC)
|
||||
give_magic(H)
|
||||
|
||||
@@ -289,7 +289,7 @@
|
||||
|
||||
/obj/item/surgical_drapes/advanced
|
||||
name = "smart surgical drapes"
|
||||
desc = "A quite quirky set of drapes with wireless synchronization to the station's research networks, with an integrated display allowing users to execute advanced surgeries without the aid of an operating computer."
|
||||
desc = "A smart set of drapes with wireless synchronization to the station's research networks, with an integrated display allowing users to execute advanced surgeries without the aid of an operating computer."
|
||||
var/datum/techweb/linked_techweb
|
||||
|
||||
/obj/item/surgical_drapes/advanced/Initialize(mapload)
|
||||
|
||||
@@ -75,3 +75,20 @@
|
||||
item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate
|
||||
cost = 2
|
||||
illegal_tech = FALSE
|
||||
|
||||
/datum/uplink_item/badass/tactical_naptime
|
||||
name = "Sleepy Time Pajama Bundle"
|
||||
desc = "Even soldiers need to get a good nights rest. Comes with some cozy as heck sleeping wear, a blankie to keep yourself warm in deep space, a hot mug of cocoa for you and your fuzzy friend."
|
||||
item = /obj/item/storage/box/syndie_kit/sleepytime
|
||||
cost = 4
|
||||
limited_stock = 1
|
||||
cant_discount = TRUE
|
||||
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/badass/shades
|
||||
name = "Big Sunglasses"
|
||||
desc = "Prevents flashes and looks badbass with some Smokes."
|
||||
item = /obj/item/clothing/glasses/sunglasses/big
|
||||
cost = 1
|
||||
surplus = 5
|
||||
illegal_tech = FALSE
|
||||
|
||||
@@ -9,18 +9,28 @@
|
||||
|
||||
/datum/uplink_item/suits/turtlenck
|
||||
name = "Tactical Turtleneck"
|
||||
desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake."
|
||||
desc = "A slightly armored conspicious jumpsuit that has no suit sensors attached to them, if someone sees you in this hope they think its a fake."
|
||||
item = /obj/item/clothing/under/syndicate
|
||||
cost = 1
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these
|
||||
|
||||
/datum/uplink_item/suits/turtlenck_skirt
|
||||
name = "Tactical Skirtleneck"
|
||||
desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake."
|
||||
desc = "A slightly armored conspicious jumpsuit that has no suit sensors attached to them, if someone sees you in this hope they think its a fake."
|
||||
item = /obj/item/clothing/under/syndicate/skirt
|
||||
cost = 1
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these
|
||||
|
||||
/datum/uplink_item/suits/infiltrator_bundle
|
||||
name = "Insidious Infiltration Gear Case"
|
||||
desc = "Developed by Roseus Galactic in conjunction with the Gorlex Marauders to produce a functional suit for urban operations, \
|
||||
this suit proves to be cheaper than your standard issue hardsuit, with none of the movement restrictions (or the space proofing) of the outdated spacesuits employed by the company. \
|
||||
Comes with an armored vest, helmet, blood-red sneaksuit, sneakboots, specialized combat gloves and a high-tech balaclava which obfuscates both your voice and your face. The case is also rather useful as a storage container and bludgeoning implement."
|
||||
item = /obj/item/storage/toolbox/infiltrator
|
||||
cost = 3
|
||||
limited_stock = 1 //you only get one so you don't end up with too many gun cases
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/suits/padding
|
||||
name = "Soft Padding"
|
||||
desc = "An inconspicious soft padding meant to be worn underneath jumpsuits, will cushion the user from melee harm."
|
||||
|
||||
@@ -147,9 +147,9 @@
|
||||
|
||||
/datum/uplink_item/dangerous/rapier
|
||||
name = "Rapier"
|
||||
desc = "A fancy rapier with a diamond tip piercing anything that it comes into contack with. \
|
||||
The rapier comes with its own sheath, this is rather noticeable as only the captain is known to carry a sheath. \
|
||||
The sheath itself can be used to block melee attacks only. Its also jet black colours."
|
||||
desc = "An elegant plastitanium rapier with a diamond tip and coated in a specialized knockout poison. \
|
||||
The rapier comes with its own sheath, and is capable of puncturing through almost any defense. \
|
||||
However, due to the size of the blade and obvious nature of the sheath, the weapon stands out as being obviously nefarious."
|
||||
item = /obj/item/storage/belt/sabre/rapier
|
||||
cost = 8
|
||||
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
name = "Headset Upgrader"
|
||||
desc = "A device that can be used to make one headset immune to flashbangs."
|
||||
item = /obj/item/headsetupgrader
|
||||
cost = 3
|
||||
cost = 1
|
||||
|
||||
/datum/uplink_item/device_tools/medgun
|
||||
name = "Medbeam Gun"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "kevinz000"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "disabler taser alt fire shots are faster and have a 14 tile range now"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "kevinz000"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "HoS taser now only applies tased effect for 1 second and warden's pump action stun blaster no longer applies it at all."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Putnam3145"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Mass hallucination can better be admemed"
|
||||
@@ -0,0 +1,5 @@
|
||||
author: "necromanceranne"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "Altered the plastitanium rapier from a perfect AP but weaker esword equivalent to a more unique sleep inducing melee weapon."
|
||||
- rscadd: "Touched up all the relevant sprites."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "dapnee"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Lambdastation and it's accompanying files"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "NecromancerAnne and goldnharl"
|
||||
delete-after: True
|
||||
changes:
|
||||
- imageadd: "Sprite cleanups and animations for energy guns."
|
||||
@@ -0,0 +1,6 @@
|
||||
author: "Ghommie (plus a fix originally done by Skogol)"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Drinks dispensers now only show the container they are holding."
|
||||
- bugfix: "Ghost cafe patrons are warded against a few more events now."
|
||||
- bugfix: "Fixed RnD machineries UI displaying designs' required reagents' typepaths instead of names."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "kevinz000"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "beam rifles are less terrible code"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Trilbyspaceclone"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "Pipes are small now"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "zeroisthebiggay"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "box station hos office"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Trilbyspaceclone"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Edaggers now enbed as intended"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "wesoda25"
|
||||
delete-after: True
|
||||
changes:
|
||||
- code_imp: "You no longer hit fermenting barrels when taking reagents from them"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Trilbyspaceclone"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "The sleeper agents can be outfitted with some larger then normal sunglasses for 1TC in Badass category"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Ghommie"
|
||||
delete-after: True
|
||||
changes:
|
||||
- imageadd: "Resprited some sprite_accessory icon states."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Putnam3145"
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "Waffle co objective rewritten to make more clear it's not a murderbone objective"
|
||||
@@ -0,0 +1,7 @@
|
||||
author: "NecromancerAnne and zawo and zeroisthebiggay and carlarctg"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "The Infiltrator Bundle, an armor kit for 3TC. Murder people in style!"
|
||||
- rscadd: "Some pajamas for nukies to get plenty of bed rest."
|
||||
- rscadd: "halved firefight carry delay with latex or nitrile gloves"
|
||||
- tweak: "headset upgrade is cheaper"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Seris02"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "removes xray from the gene pool"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Trilbyspaceclone"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "The Syndi Medical borg has been outfitted with the newest and latest ~~Stolen~~ MediCo Gear on the market"
|
||||
@@ -0,0 +1,5 @@
|
||||
author: "Trilbyspaceclone"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Ninjas may be asked to steal the CMO's smart drapes"
|
||||
- tweak: "Hyper Cell steal goal is upgraded to a bluespace cell, as well as the BoH goal now wants a type of BoH rather then the normal default one."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "YakumoChen"
|
||||
delete-after: True
|
||||
changes:
|
||||
- server: "Templates Headers will now correctly use the Citadel Official Wiki Link"
|
||||
@@ -0,0 +1,5 @@
|
||||
author: "kevinz000"
|
||||
delete-after: True
|
||||
changes:
|
||||
- code_imp: "slowdown on items should now be set by set_slowdown()."
|
||||
- bugfix: "hypereutactic blades properly slow down their wielders when being used and vv-editing an item's slowdown will once again properly update someone's slowdown to take the new value into account."
|
||||
@@ -25,7 +25,7 @@
|
||||
<td valign='top'>
|
||||
<div align='center'><font size='3'><b>Traditional Games Space Station 13</b></font></div>
|
||||
|
||||
<p><div align='center'><font size='3'><a href="https://citadel-station.net/forum/index.php">Forum</a> | <a href="https://katlin.dog/citadel-wiki">Wiki</a> | <a href="https://github.com/Citadel-Station-13/Citadel-Station-13">Source</a></font></div></p>
|
||||
<p><div align='center'><font size='3'><a href="https://citadel-station.net/forum/index.php">Forum</a> | <a href="https://citadel-station.net/wiki/index.php?title=Main_Page">Wiki</a> | <a href="https://github.com/Citadel-Station-13/Citadel-Station-13">Source</a></font></div></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 218 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1018 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1006 B |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 414 KiB After Width: | Height: | Size: 415 KiB |
|
Before Width: | Height: | Size: 429 KiB After Width: | Height: | Size: 430 KiB |
|
Before Width: | Height: | Size: 382 KiB After Width: | Height: | Size: 384 KiB |
|
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 336 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |