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:
@@ -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" = 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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user