Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into uplinkclothinggetssuckies

# Conflicts:
#	code/modules/uplink/uplink_items/uplink_badass.dm
This commit is contained in:
ZeroMan
2020-03-21 02:17:13 -04:00
85 changed files with 151865 additions and 1683 deletions
@@ -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
+1 -36
View File
@@ -125,28 +125,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"cock_length" = 6,
"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" = "Single",
"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" = "C",
@@ -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"]
+5 -4
View File
@@ -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
+16 -1
View File
@@ -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
+1 -1
View File
@@ -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
@@ -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,
+1 -1
View File
@@ -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>")
+24 -19
View File
@@ -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
+11 -6
View File
@@ -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 ..()
+4
View File
@@ -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)
+1 -1
View File
@@ -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)
@@ -76,6 +76,7 @@
cost = 2
illegal_tech = FALSE
<<<<<<< HEAD
/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."
@@ -83,4 +84,13 @@
cost = 4
limited_stock = 1
cant_discount = TRUE
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear)
=======
/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
>>>>>>> 9c40389e4f970e47f7fdcf5962be0a661b7932f0
@@ -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)