Merge branch 'master' into Clinging-to-hope

This commit is contained in:
Qwertytoforty
2021-11-14 16:43:35 -05:00
committed by GitHub
374 changed files with 20608 additions and 22123 deletions
+7
View File
@@ -423,6 +423,13 @@
/datum/action/item_action/remove_badge
name = "Remove Holobadge"
// Clown Acrobat Shoes
/datum/action/item_action/slipping
name = "Tactical Slip"
desc = "Activates the clown shoes' ankle-stimulating module, allowing the user to do a short slip forward going under anyone."
button_icon_state = "clown"
// Jump boots
/datum/action/item_action/bhop
name = "Activate Jump Boots"
+66
View File
@@ -0,0 +1,66 @@
/**
* # Custom User Item
*
* Holder for CUIs
*
* This datum is a holder that is essentially a "model" of the `customuseritems`
* database table, and is used for giving people their CUIs on spawn.
* It is instanced as part of the client data loading framework on the client.
*
*/
/datum/custom_user_item
/// Can this be used on all characters?
var/all_characters_allowed = FALSE
/// Name of the character that can have this item.
var/characer_name
/// Are all jobs allowed?
var/all_jobs_allowed = FALSE
/// List of allowed jobs
var/list/allowed_jobs = list()
/// Custom item typepath
var/object_typepath
/// Custom item name override
var/item_name_override
/// Custom item description override
var/item_desc_override
/// Raw job mask
var/raw_job_mask
/**
* CUI Info Parser
*
* Parses all the raw info into usable stuff, and also does validity checks
* Returns TRUE if its a valid item, and FALSE if not
*
* Arguments:
* * owning_ckey - Player who owns this item. Used for logging purposes.
*/
/datum/custom_user_item/proc/parse_info(owning_ckey)
. = FALSE // Setting this here means it will return false even if it runtimes
// Sort path
if(!object_typepath || !ispath(object_typepath))
stack_trace("Incorrect database entry found in table 'customuseritems' path value is [object_typepath ? object_typepath : "(NULL)"], which doesnt exist. Ask the host to look at CUI entries for [owning_ckey]")
return
// Sort job mask
if(raw_job_mask == "*")
all_jobs_allowed = TRUE
else
var/list/local_allowed_jobs = splittext(raw_job_mask, ",")
for(var/i in 1 to length(local_allowed_jobs))
if(istext(local_allowed_jobs[i]))
local_allowed_jobs[i] = trim(local_allowed_jobs[i])
allowed_jobs = local_allowed_jobs
// Sort character name
if(characer_name == "*")
all_characters_allowed = TRUE
return TRUE
/datum/custom_user_item/vv_edit_var(var_name, var_value)
return FALSE // fuck off
@@ -49,6 +49,7 @@ Bonus
healed += min(E.brute_dam, get_damage) + min(E.burn_dam, get_damage)
E.heal_damage(get_damage, get_damage, 0, 0)
M.adjustToxLoss(healed)
M.UpdateAppearance()
else
@@ -56,6 +57,7 @@ Bonus
M.adjustFireLoss(-get_damage)
M.adjustBruteLoss(-get_damage)
M.adjustToxLoss(get_damage)
M.UpdateAppearance()
else
return
+16 -3
View File
@@ -19,6 +19,8 @@
var/headers
/// URL that the request is being sent to
var/url
/// If present, response body will be saved to this file.
var/output_file
/// The raw response, which will be decoeded into a [/datum/http_response]
var/_raw_response
/// Callback for executing after async requests. Will be called with an argument of [/datum/http_response] as first argument
@@ -42,7 +44,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
* * _body - The body of the request, if applicable
* * _headers - Associative list of HTTP headers to send, if applicab;e
*/
/datum/http_request/proc/prepare(_method, _url, _body = "", list/_headers)
/datum/http_request/proc/prepare(_method, _url, _body = "", list/_headers, _output_file)
if(!length(_headers))
headers = ""
else
@@ -51,6 +53,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
method = _method
url = _url
body = _body
output_file = _output_file
/**
* Blocking executor
@@ -60,7 +63,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
*/
/datum/http_request/proc/execute_blocking()
CRASH("Attempted to execute a blocking HTTP request")
// _raw_response = rustg_http_request_blocking(method, url, body, headers)
// _raw_response = rustg_http_request_blocking(method, url, body, headers, build_options())
/**
* Async execution starter
@@ -73,7 +76,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
if(in_progress)
CRASH("Attempted to re-use a request object.")
id = rustg_http_request_async(method, url, body, headers)
id = rustg_http_request_async(method, url, body, headers, build_options())
if(isnull(text2num(id)))
_raw_response = "Proc error: [id]"
@@ -81,6 +84,16 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
else
in_progress = TRUE
/**
* Options builder
*
* Builds options for if we want to download files with SShttp
*/
/datum/http_request/proc/build_options()
if(output_file)
return json_encode(list("output_filename" = output_file, "body_filename" = null))
return null
/**
* Async completion checker
*
+6 -3
View File
@@ -86,7 +86,7 @@
return ..()
/datum/mind/proc/get_display_key()
var/clientKey = current?.client.get_display_key()
var/clientKey = current?.client?.get_display_key()
return clientKey ? clientKey : key
/datum/mind/proc/transfer_to(mob/living/new_character)
@@ -107,6 +107,8 @@
for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
var/datum/antagonist/A = a
A.on_body_transfer(old_current, current)
if(vampire)
vampire.update_owner(new_character)
transfer_antag_huds(hud_to_transfer) //inherit the antag HUD
transfer_actions(new_character)
if(martial_art)
@@ -1544,14 +1546,15 @@
SSticker.mode.equip_syndicate(current)
/datum/mind/proc/make_Vampire()
/datum/mind/proc/make_vampire(ancient_vampire = FALSE)
if(!(src in SSticker.mode.vampires))
SSticker.mode.vampires += src
SSticker.mode.grant_vampire_powers(current)
special_role = SPECIAL_ROLE_VAMPIRE
SSticker.mode.forge_vampire_objectives(src)
SSticker.mode.greet_vampire(src)
SSticker.mode.update_vampire_icons_added(src)
if(!ancient_vampire)
SSticker.mode.forge_vampire_objectives(src)
/datum/mind/proc/make_Changeling()
if(!(src in SSticker.mode.changelings))
+9 -15
View File
@@ -1103,21 +1103,15 @@
if(H.mind)
if(!H.mind.vampire)
H.make_vampire()
if(H.mind.vampire)
H.mind.vampire.bloodusable = 9999
H.mind.vampire.bloodtotal = 9999
H.mind.vampire.check_vampire_upgrade(0)
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/bats)
to_chat(H, "You have gained the ability to shapeshift into bat form. This is a weak form with no abilities, only useful for stealth.")
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shapeshift/hellhound)
to_chat(H, "You have gained the ability to shapeshift into lesser hellhound form. This is a combat form with different abilities, tough but not invincible. It can regenerate itself over time by resting.")
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/raise_vampires)
to_chat(H, "You have gained the ability to Raise Vampires. This extremely powerful AOE ability affects all humans near you. Vampires/thralls are healed. Corpses are raised as vampires. Others are stunned, then brain damaged, then killed.")
H.dna.SetSEState(GLOB.jumpblock, 1)
singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED)
H.update_mutations()
H.gene_stability = 100
H.mind.make_vampire(TRUE)
H.mind.vampire.bloodusable = 9999
H.mind.vampire.bloodtotal = 9999
H.mind.offstation_role = TRUE
H.mind.vampire.add_subclass(SUBCLASS_ANCIENT, FALSE)
H.dna.SetSEState(GLOB.jumpblock, TRUE)
singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED)
H.update_mutations()
H.gene_stability = 100
/datum/outfit/admin/wizard
name = "Blue Wizard"
+47 -7
View File
@@ -131,6 +131,11 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
var/special_availability_check = 0//Whether the spell needs to bypass the action button's IsAvailable()
var/sound = null //The sound the spell makes when it is cast
/// If the ability is for vampires
var/vampire_ability = FALSE
var/required_blood = 0
var/gain_desc = null
var/deduct_blood_on_cast = TRUE
/* Checks if the user can cast the spell
* @param charge_check If the proc should do the cooldown check
@@ -190,6 +195,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
charge_counter = charge_max
else
start_recharge()
if(!gain_desc)
gain_desc = "You can now use [src]."
/obj/effect/proc_holder/spell/Destroy()
QDEL_NULL(action)
@@ -238,6 +245,9 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
action.UpdateButtonIcon()
/obj/effect/proc_holder/spell/proc/before_cast(list/targets)
if(vampire_ability)
if(!before_cast_vampire(targets))
return
if(overlay)
for(var/atom/target in targets)
var/location
@@ -594,25 +604,55 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
var/mob/living/carbon/human/H = user
var/clothcheck = locate(/obj/effect/proc_holder/spell/noclothes) in user.mob_spell_list
var/clothcheck2 = user.mind && (locate(/obj/effect/proc_holder/spell/noclothes) in user.mind.spell_list)
if(clothes_req && !clothcheck && !clothcheck2) //clothes check
if(clothes_req && !clothcheck && !clothcheck2 && !vampire_ability) //clothes check
var/obj/item/clothing/robe = H.wear_suit
var/obj/item/clothing/hat = H.head
var/obj/item/clothing/shoes = H.shoes
if(!robe || !hat || !shoes)
if(show_message)
to_chat(user, "<span class='notice'>Your outfit isn't complete, you should put on your robe and wizard hat, as well as sandals.</span>")
return 0
return FALSE
if(!robe.magical || !hat.magical || !shoes.magical)
if(show_message)
to_chat(user, "<span class='notice'>Your outfit isn't magical enough, you should put on your robe and wizard hat, as well as your sandals.</span>")
return 0
return FALSE
else
if(clothes_req || human_req)
if(clothes_req || human_req || vampire_ability)
if(show_message)
to_chat(user, "<span class='notice'>This spell can only be cast by humans!</span>")
return 0
return FALSE
if(nonabstract_req && (isbrain(user) || ispAI(user)))
if(show_message)
to_chat(user, "<span class='notice'>This spell can only be cast by physical beings!</span>")
return 0
return 1
return FALSE
if(vampire_ability)
var/datum/vampire/vampire = user.mind.vampire
if(!vampire)
return FALSE
var/fullpower = vampire.get_ability(/datum/vampire_passive/full)
if(user.stat >= DEAD)
if(show_message)
to_chat(user, "<span class='warning'>Not while you're dead!</span>")
return FALSE
if(vampire.nullified >= VAMPIRE_COMPLETE_NULLIFICATION && !fullpower) // above 100 nullification vampire powers are useless
if(show_message)
to_chat(user, "<span class='warning'>Something is blocking your powers!</span>")
return FALSE
if(vampire.bloodusable < required_blood)
if(show_message)
to_chat(user, "<span class='warning'>You require at least [required_blood] units of usable blood to do that!</span>")
return FALSE
//chapel check
if(istype(get_area(user), /area/chapel) && !fullpower)
if(show_message)
to_chat(user, "<span class='warning'>Your powers are useless on this holy ground.</span>")
return FALSE
return TRUE
+42 -13
View File
@@ -12,16 +12,18 @@
include_user = 1
nonabstract_req = 1
centcom_cancast = 0 //Prevent people from getting to centcom
var/sound1 = 'sound/magic/ethereal_enter.ogg'
var/jaunt_duration = 50 //in deciseconds
var/jaunt_in_time = 5
var/jaunt_in_type = /obj/effect/temp_visual/wizard
var/jaunt_out_type = /obj/effect/temp_visual/wizard/out
var/jaunt_type_path = /obj/effect/dummy/spell_jaunt
var/jaunt_water_effect = TRUE
action_icon_state = "jaunt"
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
playsound(get_turf(user), sound1, 50, 1, -1)
for(var/mob/living/target in targets)
if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains
to_chat(target, "<span class='warning'>You are somehow too bound to your current location to abandon it.</span>")
@@ -31,13 +33,14 @@
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/do_jaunt(mob/living/target)
target.notransform = 1
var/turf/mobloc = get_turf(target)
var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt(mobloc)
var/obj/effect/dummy/spell_jaunt/holder = new jaunt_type_path(mobloc)
new jaunt_out_type(mobloc, target.dir)
target.ExtinguishMob()
target.forceMove(holder)
target.reset_perspective(holder)
target.notransform = 0 //mob is safely inside holder now, no need for protection.
jaunt_steam(mobloc)
if(jaunt_water_effect)
jaunt_steam(mobloc)
sleep(jaunt_duration)
@@ -45,22 +48,28 @@
qdel(holder)
return
mobloc = get_turf(target.loc)
jaunt_steam(mobloc)
if(jaunt_water_effect)
jaunt_steam(mobloc)
target.canmove = 0
holder.reappearing = 1
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
sleep(25 - jaunt_in_time)
sleep(jaunt_in_time * 4)
new jaunt_in_type(mobloc, holder.dir)
target.setDir(holder.dir)
sleep(jaunt_in_time)
qdel(holder)
if(!QDELETED(target))
if(mobloc.density)
if(is_blocked_turf(mobloc, TRUE))
for(var/turf/T in orange(7))
if(T)
if(target.Move(T))
break
target.canmove = 1
if(isspaceturf(T))
continue
if(target.Move(T))
target.remove_CC()
return
for(var/turf/space/S in orange(7))
if(target.Move(S))
break
target.remove_CC()
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/jaunt_steam(mobloc)
var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread()
@@ -90,14 +99,34 @@
return
var/turf/newLoc = get_step(src,direction)
setDir(direction)
if(!(newLoc.flags & NOJAUNT))
if(can_move(newLoc))
forceMove(newLoc)
else
to_chat(user, "<span class='warning'>Some strange aura is blocking the way!</span>")
to_chat(user, "<span class='warning'>Something is blocking the way!</span>")
movedelay = world.time + movespeed
/obj/effect/dummy/spell_jaunt/proc/can_move(turf/T)
if(T.flags & NOJAUNT)
return FALSE
return TRUE
/obj/effect/dummy/spell_jaunt/ex_act(blah)
return
/obj/effect/dummy/spell_jaunt/bullet_act(blah)
return
/obj/effect/dummy/spell_jaunt/blood_pool
name = "sanguine pool"
desc = "a pool of living blood."
movespeed = 1.5
/obj/effect/dummy/spell_jaunt/blood_pool/relaymove(mob/user, direction)
..()
new /obj/effect/decal/cleanable/blood(loc)
/obj/effect/dummy/spell_jaunt/blood_pool/can_move(turf/T)
if(isspaceturf(T) || T.density)
return FALSE
return TRUE
+3 -3
View File
@@ -93,11 +93,11 @@
/obj/effect/proc_holder/spell/targeted/mime/fingergun
name = "Finger Gun"
desc = "Shoot stunning, invisible bullets out of your fingers! 6 bullets available per cast. Use your fingers to holster them manually."
desc = "Shoot stunning, invisible bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually."
school = "mime"
panel = "Mime"
clothes_req = 0
charge_max = 600
charge_max = 300
range = -1
include_user = 1
human_req = 1
@@ -117,7 +117,7 @@
revert_cast(user)
/obj/effect/proc_holder/spell/targeted/mime/fingergun/fake
desc = "Pretend you're shooting bullets out of your fingers! 6 bullets available per cast. Use your fingers to holster them manually."
desc = "Pretend you're shooting bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually."
gun = /obj/item/gun/projectile/revolver/fingergun/fake
// Mime Spellbooks
+2
View File
@@ -95,6 +95,7 @@
invocation = "none"
invocation_type = "none"
action_icon_state = "vampire_bats"
gain_desc = "You have gained the ability to shapeshift into bat form. This is a weak form with no abilities, only useful for stealth."
shapeshift_type = /mob/living/simple_animal/hostile/scarybat/adminvampire
current_shapes = list(/mob/living/simple_animal/hostile/scarybat/adminvampire)
@@ -108,6 +109,7 @@
invocation_type = "none"
action_background_icon_state = "bg_demon"
action_icon_state = "glare"
gain_desc = "You have gained the ability to shapeshift into lesser hellhound form. This is a combat form with different abilities, tough but not invincible. It can regenerate itself over time by resting."
shapeshift_type = /mob/living/simple_animal/hostile/hellhound
current_shapes = list(/mob/living/simple_animal/hostile/hellhound)
+11 -2
View File
@@ -8,12 +8,16 @@
var/include_space = 0 //whether it includes space tiles in possible teleport locations
var/include_dense = 0 //whether it includes dense tiles in possible teleport locations
/// Whether the spell can teleport to light locations
var/include_light_turfs = TRUE
var/sound1 = 'sound/weapons/zapbang.ogg'
var/sound2 = 'sound/weapons/zapbang.ogg'
/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets,mob/living/user = usr)
playsound(get_turf(user), sound1, 50,1)
if(sound1)
playsound(get_turf(user), sound1, 50,1)
for(var/mob/living/target in targets)
var/list/turfs = new/list()
for(var/turf/T in range(target,outer_tele_radius))
@@ -22,6 +26,10 @@
if(T.density && !include_dense) continue
if(T.x>world.maxx-outer_tele_radius || T.x<outer_tele_radius) continue //putting them at the edge is dumb
if(T.y>world.maxy-outer_tele_radius || T.y<outer_tele_radius) continue
if(!include_light_turfs)
var/lightingcount = T.get_lumcount() * 10
if(lightingcount > 2)
continue
turfs += T
if(!turfs.len)
@@ -37,4 +45,5 @@
return
target.forceMove(picked)
playsound(get_turf(user), sound2, 50,1)
if(sound2)
playsound(get_turf(user), sound2, 50,1)
+53
View File
@@ -134,6 +134,59 @@
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
owner.stun_absorption -= "blooddrunk"
/datum/status_effect/bloodswell
id = "bloodswell"
duration = 30 SECONDS
tick_interval = 0
alert_type = /obj/screen/alert/status_effect/blood_swell
var/bonus_damage_applied = FALSE
/obj/screen/alert/status_effect/blood_swell
name = "Blood Swell"
desc = "Your body has been infused with crimson magics, your resistance to attacks has greatly increased!"
icon = 'icons/mob/actions/actions.dmi'
icon_state = "blood_swell_status"
/datum/status_effect/bloodswell/on_apply()
. = ..()
if(!. || !ishuman(owner))
return FALSE
ADD_TRAIT(owner, TRAIT_CHUNKYFINGERS, VAMPIRE_TRAIT)
var/mob/living/carbon/human/H = owner
H.physiology.brute_mod *= 0.5
H.physiology.burn_mod *= 0.8
H.physiology.stamina_mod *= 0.5
H.physiology.stun_mod *= 0.5
if(owner.mind.vampire.get_ability(/datum/vampire_passive/blood_swell_upgrade))
bonus_damage_applied = TRUE
H.physiology.melee_bonus += 10
H.dna.species.punchstunthreshold += 8 //higher chance to stun but not 100%
/datum/status_effect/bloodswell/on_remove()
if(!ishuman(owner))
return
REMOVE_TRAIT(owner, TRAIT_CHUNKYFINGERS, VAMPIRE_TRAIT)
var/mob/living/carbon/human/H = owner
H.physiology.brute_mod /= 0.5
H.physiology.burn_mod /= 0.8
H.physiology.stamina_mod /= 0.5
H.physiology.stun_mod /= 0.5
if(bonus_damage_applied)
bonus_damage_applied = FALSE
H.physiology.melee_bonus -= 10
H.dna.species.punchstunthreshold -= 8
/datum/status_effect/blood_rush
alert_type = null
duration = 10 SECONDS
/datum/status_effect/blood_rush/on_apply()
ADD_TRAIT(owner, TRAIT_GOTTAGOFAST, VAMPIRE_TRAIT)
return TRUE
/datum/status_effect/blood_rush/on_remove()
REMOVE_TRAIT(owner, TRAIT_GOTTAGOFAST, VAMPIRE_TRAIT)
/datum/status_effect/exercised
id = "Exercised"
duration = 1200
+4
View File
@@ -45,3 +45,7 @@
/datum/status_effect/high_five/on_remove()
owner.visible_message("[owner] was left hanging....")
/datum/status_effect/charging
id = "charging"
alert_type = null
+13 -9
View File
@@ -272,14 +272,6 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
cost = 15
containername = "laser crate"
/datum/supply_packs/security/taser
name = "Stun Guns Crate"
contains = list(/obj/item/gun/energy/gun/advtaser,
/obj/item/gun/energy/gun/advtaser,
/obj/item/gun/energy/gun/advtaser)
cost = 15
containername = "stun gun crate"
/datum/supply_packs/security/disabler
name = "Disabler Crate"
contains = list(/obj/item/gun/energy/disabler,
@@ -507,7 +499,7 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
/obj/item/reagent_containers/spray/pepper,
/obj/item/flash,
/obj/item/grenade/flashbang,
/obj/item/storage/belt/security/sec,
/obj/item/storage/belt/security,
/obj/item/holosign_creator/security,
/obj/item/clothing/mask/gas/sechailer,
/obj/item/clothing/glasses/hud/security/sunglasses,
@@ -1216,6 +1208,12 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
containertype = /obj/structure/closet/critter/deer
containername = "deer crate"
/datum/supply_packs/organic/bunny
name = "Bunny Crate"
cost = 20
containertype = /obj/structure/closet/critter/bunny
containername = "bunny crate"
////// hippy gear
/datum/supply_packs/organic/hydroponics // -- Skie
@@ -1456,6 +1454,12 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
containertype = /obj/structure/closet/crate/secure
containername = "shaft miner starter kit"
/datum/supply_packs/misc/carpet
name = "Carpet Crate"
cost = 20
contains = list(/obj/item/stack/tile/carpet/twenty)
containername = "carpet crate"
///////////// Paper Work
+24 -21
View File
@@ -167,18 +167,19 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
//Clown
/datum/uplink_item/jobspecific/clowngrenade
name = "Banana Grenade"
desc = "A grenade that explodes into HONK! brand banana peels that are genetically modified to be extra slippery and extrude caustic acid when stepped on"
desc = "A grenade that explodes into HONK! brand banana peels that are genetically modified to be extra slippery and extrude caustic acid when stepped on."
reference = "BG"
item = /obj/item/grenade/clown_grenade
cost = 5
job = list("Clown")
/datum/uplink_item/jobspecific/clownmagboots
name = "Clown Magboots"
desc = "A pair of modified clown shoes fitted with an advanced magnetic traction system. Look and sound exactly like regular clown shoes unless closely inspected."
reference = "CM"
item = /obj/item/clothing/shoes/magboots/clown
/datum/uplink_item/jobspecific/clownslippers
name = "Clown Acrobatic Shoes"
desc = "A pair of modified clown shoes fitted with a built-in propulsion system that allows the user to perform a short slip below anyone. Turning on the waddle dampeners removes the slowdown on the shoes."
reference = "CAS"
item = /obj/item/clothing/shoes/clown_shoes/slippers
cost = 3
surplus = 75
job = list("Clown")
/datum/uplink_item/jobspecific/trick_revolver
@@ -560,13 +561,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/twohanded/chainsaw
cost = 13
/datum/uplink_item/dangerous/batterer
name = "Mind Batterer"
desc = "A device that has a chance of knocking down people around you for a long amount of time. 50% chance per person. The user is unaffected. Has 5 charges."
reference = "BTR"
item = /obj/item/batterer
cost = 5
// SUPPORT AND MECHAS
/datum/uplink_item/support
@@ -707,12 +701,12 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 2
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/bullstun
name = "Bulldog - 12g Stun Slug Magazine"
desc = "An alternative 8-round stun slug magazine for use in the Bulldog shotgun. Saying that they're completely non-lethal would be lying."
reference = "12SS"
item = /obj/item/ammo_box/magazine/m12g/stun
cost = 3
/datum/uplink_item/ammo/bullmeteor
name = "12g Meteorslug Shells"
desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. Great for blasting airlocks off their frames and knocking down enemies."
reference = "12MS"
item = /obj/item/ammo_box/magazine/m12g/meteor
cost = 2
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/bulldragon
@@ -876,6 +870,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/CQC_manual
cost = 13
cant_discount = TRUE
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_weapons/cameraflash
name = "Camera Flash"
@@ -972,6 +967,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 5
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_weapons/combat_minus
name = "Experimental Krav Gloves"
desc = "Experimental gloves with installed nanochips that teach you Krav Maga when worn, great as a cheap backup weapon. Warning, the nanochips will override any other fighting styles such as CQC. Do not look as fly as the Warden's"
reference = "CGM"
item = /obj/item/clothing/gloves/color/black/krav_maga
cost = 10
excludefrom = list(/datum/game_mode/nuclear)
// GRENADES AND EXPLOSIVES
/datum/uplink_item/explosives
@@ -979,7 +982,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/explosives/plastic_explosives
name = "Composition C-4"
desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect an assembly to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds."
desc = "C-4 is plastic explosive of the common variety Composition C. Reliably destroys the object it's placed on, assuming it isn't bomb resistant. Does not stick to crewmembers. Will only destroy station floors if placed directly on it. It has a modifiable timer with a minimum setting of 10 seconds."
reference = "C4"
item = /obj/item/grenade/plastic/c4
cost = 1
@@ -1004,7 +1007,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
name = "Composition X-4"
desc = "X-4 is a shaped charge designed to be safe to the user while causing maximum damage to the occupants of the room beach breached. It has a modifiable timer with a minimum setting of 10 seconds."
reference = "X4"
item = /obj/item/grenade/plastic/x4
item = /obj/item/grenade/plastic/c4/x4
cost = 2
gamemodes = list(/datum/game_mode/nuclear)