Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit629
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" = 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
|
||||
|
||||
169
code/modules/projectiles/guns/misc/chameleon.dm
Normal file
169
code/modules/projectiles/guns/misc/chameleon.dm
Normal file
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user