Files

1001 lines
37 KiB
Plaintext

/obj/item/storage/belt
name = "not actually a toolbelt"
desc = "Can hold various things. This is the base type of /belt, are you sure you should have this?"
icon = 'icons/obj/clothing/belts.dmi'
icon_state = "utility"
inhand_icon_state = "utility"
worn_icon_state = "utility"
lefthand_file = 'icons/mob/inhands/equipment/belt_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/belt_righthand.dmi'
abstract_type = /obj/item/storage/belt
slot_flags = ITEM_SLOT_BELT
attack_verb_continuous = list("whips", "lashes", "disciplines")
attack_verb_simple = list("whip", "lash", "discipline")
max_integrity = 300
equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
w_class = WEIGHT_CLASS_BULKY
var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding
/obj/item/storage/belt/suicide_act(mob/living/carbon/user)
user.visible_message(span_suicide("[user] begins belting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
return BRUTELOSS
/obj/item/storage/belt/update_overlays()
. = ..()
if(!content_overlays)
return
for(var/obj/item/I in contents)
. += I.get_belt_overlay()
/obj/item/storage/belt/Initialize(mapload)
. = ..()
AddElement(/datum/element/attack_equip)
update_appearance()
/obj/item/storage/belt/utility
name = "toolbelt" //Carn: utility belt is nicer, but it bamboozles the text parsing.
desc = "Holds tools."
icon_state = "utility"
inhand_icon_state = "utility"
worn_icon_state = "utility"
content_overlays = TRUE
custom_premium_price = PAYCHECK_CREW * 2
drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
storage_type = /datum/storage/utility_belt
/obj/item/storage/belt/utility/chief
name = "chief engineer's toolbelt"
desc = "Holds tools, looks snazzy."
icon_state = "utility_ce"
inhand_icon_state = "utility_ce"
worn_icon_state = "utility_ce"
/obj/item/storage/belt/utility/chief/full
preload = TRUE
/obj/item/storage/belt/utility/chief/full/PopulateContents()
SSwardrobe.provide_type(/obj/item/screwdriver/power, src)
SSwardrobe.provide_type(/obj/item/crowbar/power, src)
SSwardrobe.provide_type(/obj/item/weldingtool/experimental, src)
SSwardrobe.provide_type(/obj/item/multitool, src)
SSwardrobe.provide_type(/obj/item/stack/cable_coil, src)
SSwardrobe.provide_type(/obj/item/extinguisher/mini, src)
SSwardrobe.provide_type(/obj/item/analyzer/ranged, src) //SKYRAT EDIT - Ranged Analyzer for CE - ORIGINAL: SSwardrobe.provide_type(/obj/item/analyzer, src)
//much roomier now that we've managed to remove two tools
/obj/item/storage/belt/utility/chief/full/get_types_to_preload()
var/list/to_preload = list() //Yes this is a pain. Yes this is the point
to_preload += /obj/item/screwdriver/power
to_preload += /obj/item/crowbar/power
to_preload += /obj/item/weldingtool/experimental
to_preload += /obj/item/multitool
to_preload += /obj/item/stack/cable_coil
to_preload += /obj/item/extinguisher/mini
to_preload += /obj/item/analyzer/ranged // SKYRAT EDIT - Ranged Analyzer for CE
return to_preload
/obj/item/storage/belt/utility/full/PopulateContents()
SSwardrobe.provide_type(/obj/item/screwdriver, src)
SSwardrobe.provide_type(/obj/item/wrench, src)
SSwardrobe.provide_type(/obj/item/weldingtool, src)
SSwardrobe.provide_type(/obj/item/crowbar, src)
SSwardrobe.provide_type(/obj/item/wirecutters, src)
SSwardrobe.provide_type(/obj/item/multitool, src)
SSwardrobe.provide_type(/obj/item/stack/cable_coil, src)
/obj/item/storage/belt/utility/full/get_types_to_preload()
var/list/to_preload = list() //Yes this is a pain. Yes this is the point
to_preload += /obj/item/screwdriver
to_preload += /obj/item/wrench
to_preload += /obj/item/weldingtool
to_preload += /obj/item/crowbar
to_preload += /obj/item/wirecutters
to_preload += /obj/item/multitool
to_preload += /obj/item/stack/cable_coil
return to_preload
/obj/item/storage/belt/utility/full/powertools
preload = FALSE
/obj/item/storage/belt/utility/full/powertools/PopulateContents()
new /obj/item/screwdriver/power(src)
new /obj/item/crowbar/power(src)
new /obj/item/weldingtool/electric(src) // SKYRAT EDIT - original: new /obj/item/weldingtool/experimental(src)
new /obj/item/multitool(src)
new /obj/item/holosign_creator/atmos(src)
new /obj/item/extinguisher/mini(src)
new /obj/item/stack/cable_coil(src)
/obj/item/storage/belt/utility/full/powertools/rcd/PopulateContents()
new /obj/item/screwdriver/power(src)
new /obj/item/crowbar/power(src)
new /obj/item/weldingtool/experimental(src)
new /obj/item/multitool(src)
new /obj/item/construction/rcd/loaded/upgraded(src)
new /obj/item/extinguisher/mini(src)
new /obj/item/stack/cable_coil(src)
/obj/item/storage/belt/utility/full/engi/PopulateContents()
SSwardrobe.provide_type(/obj/item/screwdriver, src)
SSwardrobe.provide_type(/obj/item/wrench, src)
SSwardrobe.provide_type(/obj/item/weldingtool/largetank, src)
SSwardrobe.provide_type(/obj/item/crowbar, src)
SSwardrobe.provide_type(/obj/item/wirecutters, src)
SSwardrobe.provide_type(/obj/item/multitool, src)
SSwardrobe.provide_type(/obj/item/stack/cable_coil, src)
/obj/item/storage/belt/utility/full/engi/get_types_to_preload()
var/list/to_preload = list() //Yes this is a pain. Yes this is the point
to_preload += /obj/item/screwdriver
to_preload += /obj/item/wrench
to_preload += /obj/item/weldingtool/largetank
to_preload += /obj/item/crowbar
to_preload += /obj/item/wirecutters
to_preload += /obj/item/multitool
to_preload += /obj/item/stack/cable_coil
return to_preload
/obj/item/storage/belt/utility/atmostech/PopulateContents()
SSwardrobe.provide_type(/obj/item/screwdriver, src)
SSwardrobe.provide_type(/obj/item/wrench, src)
SSwardrobe.provide_type(/obj/item/weldingtool, src)
SSwardrobe.provide_type(/obj/item/crowbar, src)
SSwardrobe.provide_type(/obj/item/wirecutters, src)
SSwardrobe.provide_type(/obj/item/t_scanner, src)
SSwardrobe.provide_type(/obj/item/extinguisher/mini, src)
/obj/item/storage/belt/utility/atmostech/get_types_to_preload()
var/list/to_preload = list() //Yes this is a pain. Yes this is the point
to_preload += /obj/item/screwdriver
to_preload += /obj/item/wrench
to_preload += /obj/item/weldingtool
to_preload += /obj/item/crowbar
to_preload += /obj/item/wirecutters
to_preload += /obj/item/t_scanner
to_preload += /obj/item/extinguisher/mini
return to_preload
/obj/item/storage/belt/utility/full/inducer/PopulateContents()
SSwardrobe.provide_type(/obj/item/screwdriver, src)
SSwardrobe.provide_type(/obj/item/wrench, src)
SSwardrobe.provide_type(/obj/item/weldingtool, src)
SSwardrobe.provide_type(/obj/item/crowbar/red, src)
SSwardrobe.provide_type(/obj/item/wirecutters, src)
SSwardrobe.provide_type(/obj/item/multitool, src)
SSwardrobe.provide_type(/obj/item/inducer, src)
/obj/item/storage/belt/utility/full/inducer/get_types_to_preload()
var/list/to_preload = list() //Yes this is a pain. Yes this is the point
to_preload += /obj/item/screwdriver
to_preload += /obj/item/wrench
to_preload += /obj/item/weldingtool
to_preload += /obj/item/crowbar
to_preload += /obj/item/wirecutters
to_preload += /obj/item/multitool
to_preload += /obj/item/inducer
return to_preload
/obj/item/storage/belt/utility/syndicate
preload = FALSE
/obj/item/storage/belt/utility/syndicate/PopulateContents()
new /obj/item/screwdriver/nuke(src)
new /obj/item/wrench/combat(src)
new /obj/item/weldingtool/largetank(src)
new /obj/item/crowbar(src)
new /obj/item/wirecutters(src)
new /obj/item/multitool(src)
new /obj/item/inducer/syndicate(src)
/obj/item/storage/belt/medical
name = "medical belt"
desc = "Can hold various medical equipment."
icon_state = "medical"
inhand_icon_state = "medical"
worn_icon_state = "medical"
drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
storage_type = /datum/storage/medical_belt
/obj/item/storage/belt/medical/paramedic
name = "EMT belt"
icon_state = "emt"
inhand_icon_state = "security"
worn_icon_state = "emt"
preload = TRUE
/obj/item/storage/belt/medical/paramedic/PopulateContents()
SSwardrobe.provide_type(/obj/item/sensor_device, src)
SSwardrobe.provide_type(/obj/item/stack/medical/wrap/gauze/twelve, src)
SSwardrobe.provide_type(/obj/item/tourniquet, src)
SSwardrobe.provide_type(/obj/item/bonesetter, src)
SSwardrobe.provide_type(/obj/item/reagent_containers/syringe, src)
SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/ammoniated_mercury, src)
SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/formaldehyde, src)
update_appearance()
/obj/item/storage/belt/medical/paramedic/get_types_to_preload()
var/list/to_preload = list() //Yes this is a pain. Yes this is the point
to_preload += /obj/item/sensor_device
to_preload += /obj/item/stack/medical/wrap/gauze/twelve
to_preload += /obj/item/tourniquet
to_preload += /obj/item/bonesetter
to_preload += /obj/item/reagent_containers/syringe
to_preload += /obj/item/reagent_containers/cup/bottle/ammoniated_mercury
to_preload += /obj/item/reagent_containers/cup/bottle/formaldehyde
return to_preload
/obj/item/storage/belt/medical/ert
icon_state = "emt"
inhand_icon_state = "security"
worn_icon_state = "emt"
preload = TRUE
/obj/item/storage/belt/medical/ert/PopulateContents()
SSwardrobe.provide_type(/obj/item/sensor_device, src)
SSwardrobe.provide_type(/obj/item/pinpointer/crew, src)
SSwardrobe.provide_type(/obj/item/scalpel/advanced, src)
SSwardrobe.provide_type(/obj/item/retractor/advanced, src)
SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, src)
SSwardrobe.provide_type(/obj/item/cautery/advanced, src)
SSwardrobe.provide_type(/obj/item/surgical_drapes, src)
update_appearance()
/obj/item/storage/belt/medical/ert/get_types_to_preload()
var/list/to_preload = list()
to_preload += /obj/item/sensor_device
to_preload += /obj/item/pinpointer/crew
to_preload += /obj/item/scalpel/advanced
to_preload += /obj/item/retractor/advanced
to_preload += /obj/item/stack/medical/bone_gel
to_preload += /obj/item/cautery/advanced
to_preload += /obj/item/surgical_drapes
return to_preload
/obj/item/storage/belt/security
name = "security belt"
desc = "Can hold security gear like handcuffs and flashes."
icon_state = "security"
inhand_icon_state = "security"//Could likely use a better one.
worn_icon_state = "security"
content_overlays = TRUE
storage_type = /datum/storage/security_belt
/obj/item/storage/belt/security/full/PopulateContents()
new /obj/item/reagent_containers/spray/pepper(src)
new /obj/item/restraints/handcuffs(src)
new /obj/item/grenade/flashbang(src)
new /obj/item/assembly/flash/handheld(src)
new /obj/item/melee/baton/security/loaded(src)
update_appearance()
/obj/item/storage/belt/security/webbing
name = "security webbing"
desc = "Unique and versatile chest rig, can hold security gear."
icon_state = "securitywebbing"
inhand_icon_state = "securitywebbing"
worn_icon_state = "securitywebbing"
content_overlays = FALSE
custom_premium_price = PAYCHECK_COMMAND * 3
storage_type = /datum/storage/security_belt/webbing
/obj/item/storage/belt/mining
name = "explorer's webbing"
desc = "A versatile chest rig, cherished by miners and hunters alike."
icon_state = "explorer1"
inhand_icon_state = "explorer1"
worn_icon_state = "explorer1"
w_class = WEIGHT_CLASS_BULKY
storage_type = /datum/storage/mining_belt
/obj/item/storage/belt/mining/vendor/PopulateContents()
new /obj/item/survivalcapsule(src)
/obj/item/storage/belt/mining/alt
icon_state = "explorer2"
inhand_icon_state = "explorer2"
worn_icon_state = "explorer2"
/obj/item/storage/belt/mining/healing/PopulateContents()
for(var/i in 1 to 2)
new /obj/item/reagent_containers/hypospray/medipen/survival/luxury(src)
for(var/i in 1 to 2)
new /obj/item/reagent_containers/hypospray/medipen/survival(src)
for(var/i in 1 to 2)
var/obj/item/organ/monster_core/core = new /obj/item/organ/monster_core/regenerative_core/legion(src)
core.preserve()
/obj/item/storage/belt/mining/primitive
name = "hunter's belt"
desc = "A versatile belt, woven from sinew."
icon_state = "ebelt"
inhand_icon_state = "ebelt"
worn_icon_state = "ebelt"
storage_type = /datum/storage/mining_belt/primitive
/obj/item/storage/belt/soulstone
name = "soul stone belt"
desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away."
icon_state = "soulstonebelt"
inhand_icon_state = "soulstonebelt"
worn_icon_state = "soulstonebelt"
drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
storage_type = /datum/storage/soulstone_belt
/obj/item/storage/belt/soulstone/full/PopulateContents()
for(var/i in 1 to 6)
new /obj/item/soulstone/mystic(src)
/obj/item/storage/belt/soulstone/full/chappy/PopulateContents()
for(var/i in 1 to 6)
new /obj/item/soulstone/anybody/chaplain(src)
/obj/item/storage/belt/champion
name = "championship belt"
desc = "Proves to the world that you are the strongest!"
icon_state = "championbelt"
inhand_icon_state = "championbelt"
worn_icon_state = "championbelt"
custom_materials = list(/datum/material/gold=SMALL_MATERIAL_AMOUNT *4)
storage_type = /datum/storage/champion_belt
/obj/item/storage/belt/champion/Initialize(mapload)
. = ..()
AddElement(/datum/element/adjust_fishing_difficulty, -2)
/obj/item/storage/belt/military
name = "chest rig"
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "militarywebbing"
inhand_icon_state = "militarywebbing"
worn_icon_state = "militarywebbing"
resistance_flags = FIRE_PROOF
storage_type = /datum/storage/military_belt
/obj/item/storage/belt/military/snack
name = "tactical snack rig"
storage_type = /datum/storage/military_belt/snack
/obj/item/storage/belt/military/snack/Initialize(mapload)
. = ..()
var/sponsor = pick("Donk Co.", "Waffle Corp.", "Roffle Co.", "Gorlex Marauders", "Tiger Cooperative")
desc = "A set of snack-tical webbing worn by athletes of the [sponsor] VR sports division."
/obj/item/storage/belt/military/snack/full/Initialize(mapload)
. = ..()
var/amount = 5
var/rig_snacks
while(contents.len <= amount)
rig_snacks = pick(list(
/obj/item/food/candy,
/obj/item/food/cheesiehonkers,
/obj/item/food/cheesynachos,
/obj/item/food/chips,
/obj/item/food/cubannachos,
/obj/item/food/donkpocket,
/obj/item/food/nachos,
/obj/item/food/nugget,
/obj/item/food/rofflewaffles,
/obj/item/food/sosjerky,
/obj/item/food/spacetwinkie,
/obj/item/food/spaghetti/pastatomato,
/obj/item/food/syndicake,
/obj/item/reagent_containers/cup/glass/drinkingglass/filled/nuka_cola,
/obj/item/reagent_containers/cup/glass/dry_ramen,
/obj/item/reagent_containers/cup/soda_cans/cola,
/obj/item/reagent_containers/cup/soda_cans/dr_gibb,
/obj/item/reagent_containers/cup/soda_cans/lemon_lime,
/obj/item/reagent_containers/cup/soda_cans/pwr_game,
/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind,
/obj/item/reagent_containers/cup/soda_cans/space_up,
/obj/item/reagent_containers/cup/soda_cans/starkist,
))
new rig_snacks(src)
/obj/item/storage/belt/military/abductor
name = "agent belt"
desc = "A belt used by abductor agents."
icon = 'icons/obj/antags/abductor.dmi'
icon_state = "belt"
inhand_icon_state = "security"
worn_icon_state = "security"
content_overlays = TRUE
/obj/item/storage/belt/military/abductor/full/PopulateContents()
new /obj/item/screwdriver/abductor(src)
new /obj/item/wrench/abductor(src)
new /obj/item/weldingtool/abductor(src)
new /obj/item/crowbar/abductor(src)
new /obj/item/wirecutters/abductor(src)
new /obj/item/multitool/abductor(src)
new /obj/item/stack/cable_coil(src)
/obj/item/storage/belt/military/army
name = "army belt"
desc = "A belt used by military forces."
icon_state = "military"
inhand_icon_state = "security"
worn_icon_state = "military"
/obj/item/storage/belt/military/assault
name = "assault belt"
desc = "A tactical assault belt."
icon_state = "assault"
inhand_icon_state = "security"
worn_icon_state = "assault"
storage_type = /datum/storage/military_belt/assault
/obj/item/storage/belt/military/assault/full/PopulateContents()
generate_items_inside(list(
/obj/item/ammo_box/magazine/wt550m9 = 4,
/obj/item/ammo_box/magazine/wt550m9/wtap = 2,
), src)
/obj/item/storage/belt/grenade
name = "grenadier belt"
desc = "A belt for holding grenades."
icon_state = "grenadebeltnew"
inhand_icon_state = "security"
worn_icon_state = "grenadebeltnew"
drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
storage_type = /datum/storage/grenade_belt
/obj/item/storage/belt/grenade/full/PopulateContents()
generate_items_inside(list(
/obj/item/grenade/chem_grenade/incendiary = 2,
/obj/item/grenade/empgrenade = 2,
/obj/item/grenade/frag = 10,
/obj/item/grenade/flashbang = 2,
/obj/item/grenade/gluon = 4,
/obj/item/grenade/smokebomb = 4,
/obj/item/grenade/syndieminibomb = 2,
/obj/item/multitool = 1,
/obj/item/screwdriver = 1,
), src)
/obj/item/storage/belt/wands
name = "wand belt"
desc = "A belt designed to hold various rods of power. A veritable fanny pack of exotic magic."
icon_state = "soulstonebelt"
inhand_icon_state = "soulstonebelt"
worn_icon_state = "soulstonebelt"
storage_type = /datum/storage/wands_belt
/// Put some wands in that bad boy
/obj/item/storage/belt/wands/full/proc/create_wands()
new /obj/item/gun/magic/wand/death(src)
new /obj/item/gun/magic/wand/resurrection(src)
new /obj/item/gun/magic/wand/fireball(src) //SKYRAT EDIT - Trades polymorph for second fireball
new /obj/item/gun/magic/wand/teleport(src)
new /obj/item/gun/magic/wand/door(src)
new /obj/item/gun/magic/wand/fireball(src)
new /obj/item/gun/magic/wand/shrink(src)
/obj/item/storage/belt/wands/full/PopulateContents()
create_wands()
for(var/obj/item/gun/magic/wand/W in contents) //All wands in this pack come in the best possible condition
W.max_charges = initial(W.max_charges)
W.charges = W.max_charges
/// Filled with budget wands instead of cool ones
/obj/item/storage/belt/wands/full/discount
/// Which wands can appear?
var/static/list/possible_options = list(
/obj/item/gun/magic/wand/animate,
/obj/item/gun/magic/wand/babel,
/obj/item/gun/magic/wand/bald,
/obj/item/gun/magic/wand/door,
/obj/item/gun/magic/wand/fireball,
/obj/item/gun/magic/wand/freeze,
/obj/item/gun/magic/wand/hallucination,
/obj/item/gun/magic/wand/levitate,
/obj/item/gun/magic/wand/pax,
/obj/item/gun/magic/wand/pizza,
/obj/item/gun/magic/wand/plague,
/obj/item/gun/magic/wand/prank,
/obj/item/gun/magic/wand/rebel,
/obj/item/gun/magic/wand/repulse,
/obj/item/gun/magic/wand/swap,
/obj/item/gun/magic/wand/teleport,
/obj/item/gun/magic/wand/tentacles,
/obj/item/gun/magic/wand/zap,
)
/obj/item/storage/belt/wands/full/discount/create_wands()
var/list/available_options = possible_options.Copy()
for (var/i in 1 to 6)
if (!length(available_options))
break
var/wand_path = pick_n_take(available_options)
new wand_path(src)
/// Not a subtype of bandolier because it acts pretty differently
/obj/item/storage/belt/wand_bandolier
name = "wand bandolier"
desc = "A bandolier for holding a whole lot of wands. If worn on your suit, swaps expended wands for fresh ones on the fly."
icon_state = "bandolier"
inhand_icon_state = "bandolier"
worn_icon_state = "bandolier"
storage_type = /datum/storage/wands_belt
w_class = WEIGHT_CLASS_NORMAL
/obj/item/storage/belt/wand_bandolier/equipped(mob/user, slot)
. = ..()
if (!(slot & ITEM_SLOT_SUITSTORE))
return
ADD_CLOTHING_TRAIT(user, TRAIT_GUNFLIP)
RegisterSignal(user, COMSIG_MOB_FIRED_GUN, PROC_REF(on_gun_fired))
/obj/item/storage/belt/wand_bandolier/dropped(mob/user)
. = ..()
REMOVE_CLOTHING_TRAIT(user, TRAIT_GUNFLIP)
UnregisterSignal(user, COMSIG_MOB_FIRED_GUN)
/// After we fire a gun, check if it's a wand. If it is and it's empty, do a swap
/obj/item/storage/belt/wand_bandolier/proc/on_gun_fired(mob/living/wizard, obj/item/gun/magic/wand/old_wand)
SIGNAL_HANDLER
INVOKE_ASYNC(src, PROC_REF(equip_new_wand), wizard, old_wand)
/obj/item/storage/belt/wand_bandolier/proc/equip_new_wand(mob/living/wizard, obj/item/gun/magic/wand/old_wand)
if (!istype(old_wand))
return
if (!atom_storage.real_location.contents.len) // no other wands
return
if (old_wand.charges > 1) // It hasn't subtracted yet
return
var/obj/item/fresh_wand
for (var/obj/item/gun/magic/wand/checked in atom_storage.real_location.contents)
if (checked.charges)
fresh_wand = checked
break
if (!fresh_wand || fresh_wand.on_found())
return // Nothing to swap with
wizard.temporarilyRemoveItemFromInventory(old_wand)
if (!wizard.put_in_hands(fresh_wand))
return
to_chat(wizard, span_notice("You quickly draw [fresh_wand]."))
if (atom_storage.attempt_insert(old_wand, wizard))
return
old_wand.forceMove(wizard.drop_location())
to_chat(wizard, span_warning("...and drop [old_wand] on the ground."))
/obj/item/storage/belt/janitor
name = "janibelt"
desc = "A belt used to hold most janitorial supplies."
icon_state = "janibelt"
inhand_icon_state = "janibelt"
worn_icon_state = "janibelt"
drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
storage_type = /datum/storage/janitor_belt
/obj/item/storage/belt/janitor/full/PopulateContents()
new /obj/item/lightreplacer(src)
new /obj/item/reagent_containers/spray/cleaner(src)
new /obj/item/soap/nanotrasen(src)
new /obj/item/holosign_creator(src)
new /obj/item/melee/flyswatter(src)
/obj/item/storage/belt/bandolier
name = "bandolier"
desc = "A bandolier for holding rifle shotgun, and bigger revolver caliber ammunition."
icon_state = "bandolier"
inhand_icon_state = "bandolier"
worn_icon_state = "bandolier"
storage_type = /datum/storage/bandolier_belt
/obj/item/storage/belt/bandolier/china_lake_extra/PopulateContents()
generate_items_inside(list(
/obj/item/ammo_casing/a40mm = 12,
), src)
/obj/item/storage/belt/fannypack
name = "fannypack"
desc = "A dorky fannypack for keeping small items in. Concealed enough, or ugly enough to avert their eyes, that others won't see what you put in or take out easily."
icon_state = "fannypack_leather"
inhand_icon_state = null
worn_icon_state = "fannypack_leather"
dying_key = DYE_REGISTRY_FANNYPACK
custom_price = PAYCHECK_CREW * 2
storage_type = /datum/storage/fanny_pack
/obj/item/storage/belt/fannypack/black
name = "black fannypack"
icon_state = "fannypack_black"
worn_icon_state = "fannypack_black"
/obj/item/storage/belt/fannypack/red
name = "red fannypack"
icon_state = "fannypack_red"
worn_icon_state = "fannypack_red"
/obj/item/storage/belt/fannypack/purple
name = "purple fannypack"
icon_state = "fannypack_purple"
worn_icon_state = "fannypack_purple"
/obj/item/storage/belt/fannypack/blue
name = "blue fannypack"
icon_state = "fannypack_blue"
worn_icon_state = "fannypack_blue"
/obj/item/storage/belt/fannypack/orange
name = "orange fannypack"
icon_state = "fannypack_orange"
worn_icon_state = "fannypack_orange"
/obj/item/storage/belt/fannypack/white
name = "white fannypack"
icon_state = "fannypack_white"
worn_icon_state = "fannypack_white"
/obj/item/storage/belt/fannypack/green
name = "green fannypack"
icon_state = "fannypack_green"
worn_icon_state = "fannypack_green"
/obj/item/storage/belt/fannypack/pink
name = "pink fannypack"
icon_state = "fannypack_pink"
worn_icon_state = "fannypack_pink"
/obj/item/storage/belt/fannypack/cyan
name = "cyan fannypack"
icon_state = "fannypack_cyan"
worn_icon_state = "fannypack_cyan"
/obj/item/storage/belt/fannypack/yellow
name = "yellow fannypack"
icon_state = "fannypack_yellow"
worn_icon_state = "fannypack_yellow"
/obj/item/storage/belt/fannypack/cummerbund
name = "cummerbund"
desc = "A pleated sash that pairs well with a suit jacket."
icon_state = "cummerbund"
inhand_icon_state = null
worn_icon_state = "cummerbund"
/obj/item/storage/belt/fannypack/yellow/bee_terrorist/PopulateContents()
new /obj/item/grenade/c4 (src)
new /obj/item/reagent_containers/applicator/pill/cyanide(src)
new /obj/item/grenade/chem_grenade/facid(src)
/obj/item/storage/belt/fannypack/black/rogue
name = "fannypack of ULTIMATE DESPAIR"
/obj/item/storage/belt/fannypack/black/rogue/PopulateContents()
new /obj/item/food/drug/saturnx(src)
new /obj/item/reagent_containers/cup/blastoff_ampoule(src)
new /obj/item/reagent_containers/hypospray/medipen/methamphetamine(src)
/obj/item/storage/belt/sheath
desc = "holds like, blades and stuff. You should not be seeing this."
w_class = WEIGHT_CLASS_BULKY
interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS
var/stored_blade
actions_types = list(/datum/action/innate/blade_counter)
action_slots = ITEM_SLOT_BELT | ITEM_SLOT_SUITSTORE
COOLDOWN_DECLARE(resheath_cooldown)
COOLDOWN_DECLARE(full_ability_cooldown)
/obj/item/storage/belt/sheath/Initialize(mapload)
. = ..()
AddElement(/datum/element/update_icon_updates_onmob, action_slots)
RegisterSignal(src, COMSIG_ATOM_STORED_ITEM, PROC_REF(post_resheath))
/obj/item/storage/belt/sheath/Destroy(force)
. = ..()
UnregisterSignal(src, COMSIG_ATOM_STORED_ITEM)
/obj/item/storage/belt/sheath/examine(mob/user)
. = ..()
if(length(contents))
. += span_notice("Alt-click it to quickly draw the blade.")
/obj/item/storage/belt/sheath/click_alt(mob/user)
if(!length(contents))
balloon_alert(user, "it's empty!")
return CLICK_ACTION_BLOCKING
var/obj/item/stored_item = contents[1]
user.visible_message(span_notice("[user] takes [stored_item] out of [src]."), span_notice("You take [stored_item] out of [src]."))
user.put_in_hands(stored_item)
update_appearance()
return CLICK_ACTION_SUCCESS
/obj/item/storage/belt/sheath/update_icon_state()
icon_state = initial(icon_state)
inhand_icon_state = initial(inhand_icon_state)
worn_icon_state = initial(worn_icon_state)
if(contents.len)
icon_state += "-full"
inhand_icon_state += "-full"
worn_icon_state += "-full"
return ..()
/obj/item/storage/belt/sheath/PopulateContents()
if(stored_blade)
new stored_blade(src)
update_appearance()
/obj/item/storage/belt/sheath/proc/post_resheath()
SIGNAL_HANDLER
COOLDOWN_START(src, resheath_cooldown, 10 SECONDS)
/datum/action/innate/blade_counter
name = "Counterattack"
desc = "Anticipate an enemy's attack and strike back with your sheathed blade."
button_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "declaration"
ranged_mousepointer = 'icons/effects/mouse_pointers/honorbound.dmi'
enable_text = "You prepare to counterattack a target..."
disable_text = "You relax your stance."
click_action = TRUE
var/datum/weakref/eyed_fool
/datum/action/innate/blade_counter/IsAvailable(feedback = TRUE)
if(!isliving(owner))
return FALSE
var/obj/item/storage/belt/sheath/owners_sheath = target
if(!COOLDOWN_FINISHED(owners_sheath, full_ability_cooldown))
if(feedback)
to_chat(owner, span_warning("You failed a counterattack too recently!"))
return FALSE
if(!length(owners_sheath.contents))
if(feedback)
to_chat(owner, span_warning("Your sheath is empty!"))
return FALSE
if(!COOLDOWN_FINISHED(owners_sheath, resheath_cooldown))
if(feedback)
to_chat(owner, span_warning("You only just resheathed your blade!"))
return FALSE
return TRUE
/datum/action/innate/blade_counter/proc/final_checks(atom/cast_on)
if(!isliving(cast_on))
return FALSE
if(owner == cast_on)
to_chat(owner, span_warning("You can't counterattack yourself!"))
return FALSE
var/mob/living/target = cast_on
if(!target.mind)
to_chat(owner, span_warning("They are too unpredictable to counterattack!"))
return FALSE
var/obj/item/storage/belt/sheath/oursheath = target
if(!length(oursheath.contents))
return FALSE
return TRUE
/datum/action/innate/blade_counter/do_ability(mob/living/swordsman, mob/living/cast_on)
if(!final_checks(cast_on))
return TRUE
var/obj/item/storage/belt/sheath/used_sheath = target
RegisterSignal(swordsman, COMSIG_LIVING_CHECK_BLOCK, PROC_REF(counter_attack))
swordsman.Immobilize(1 SECONDS)
eyed_fool = WEAKREF(cast_on)
swordsman.visible_message(span_danger("[swordsman] widens [swordsman.p_their()] stance, [swordsman.p_their()] hand hovering over \the [used_sheath]!"), span_notice("You prepare to counterattack [cast_on]!"))
addtimer(CALLBACK(src, PROC_REF(relax), swordsman, used_sheath), 1 SECONDS)
COOLDOWN_START(used_sheath, full_ability_cooldown, 60 SECONDS)
unset_ranged_ability(swordsman)
return TRUE
#define COUNTERMULTIPLIER 3
/datum/action/innate/blade_counter/proc/counter_attack(mob/living/forward_thinker, atom/attackingthing, damage, attack_text, attack_type)
SIGNAL_HANDLER
var/obj/item/storage/belt/sheath/used_sheath = target
if(!used_sheath || !length(used_sheath.contents) || (attack_type != MELEE_ATTACK && attack_type != UNARMED_ATTACK))
return FAILED_BLOCK
var/obj/item/justicetool = used_sheath.contents[1]
var/mob/living/fool = isliving(attackingthing) ? attackingthing : attackingthing.loc
if(used_sheath.loc != forward_thinker || fool != eyed_fool.resolve() || !forward_thinker.put_in_active_hand(justicetool))
return FAILED_BLOCK
do_strike(fool, forward_thinker, justicetool)
playsound(forward_thinker, 'sound/items/unsheath.ogg', 50, TRUE)
COOLDOWN_RESET(used_sheath, full_ability_cooldown)
return SUCCESSFUL_BLOCK
/datum/action/innate/blade_counter/proc/do_strike(mob/living/fool, mob/living/forward_thinker, obj/item/justicetool)
var/obj/item/bodypart/offending_hand = fool.get_active_hand()
forward_thinker.visible_message(span_danger("[forward_thinker] swiftly draws \the [justicetool] and strikes [fool] during [fool.p_their()] attack!"), span_notice("You swiftly draw \the [justicetool] and counter-attack [fool]!"))
fool.apply_damage(
damage = justicetool.force * COUNTERMULTIPLIER,
damagetype = justicetool.damtype,
def_zone = offending_hand,
blocked = fool.run_armor_check(offending_hand, MELEE, armour_penetration = justicetool.armour_penetration, silent = TRUE),
wound_bonus = justicetool.wound_bonus * COUNTERMULTIPLIER,
exposed_wound_bonus = justicetool.exposed_wound_bonus * COUNTERMULTIPLIER,
sharpness = justicetool.sharpness,
attack_direction = get_dir(forward_thinker, fool),
attacking_item = justicetool,
)
/datum/action/innate/blade_counter/proc/relax(mob/living/holder, obj/item/storage/belt/sheath/active_sheath)
UnregisterSignal(holder, COMSIG_LIVING_CHECK_BLOCK)
/datum/action/innate/blade_counter/gunpowered
name = "Powered Counterattack"
desc = "Anticipate an enemy's attack and attempt to strike back, at great risk to yourself. The firing angle requires it be held on your hip."
/// Whether the currently relevant counterattack succeeded.
var/succeeded_attempt = FALSE
/datum/action/innate/blade_counter/gunpowered/do_ability(mob/living/swordsman, mob/living/cast_on)
. = ..()
succeeded_attempt = FALSE
/datum/action/innate/blade_counter/gunpowered/do_strike(mob/living/fool, mob/living/forward_thinker, obj/item/justicetool)
if(forward_thinker.get_slot_by_item(target) == ITEM_SLOT_SUITSTORE)
return ..()
succeeded_attempt = TRUE
var/obj/item/bodypart/offending_hand = fool.get_active_hand()
var/obj/item/bodypart/risked_hand = forward_thinker.get_active_hand()
if(iscarbon(fool) && offending_hand.dismember(BRUTE, FALSE, WOUND_SLASH))
forward_thinker.visible_message(span_danger("[forward_thinker] swiftly draws \the [justicetool] and strikes [fool] during [fool.p_their()] attack, sending [fool.p_their()] arm flying!"),
span_notice("You swiftly draw \the [justicetool] and cut off [fool]'s arm!"))
else
fool.apply_damage(
damage = justicetool.force * COUNTERMULTIPLIER,
damagetype = justicetool.damtype,
def_zone = offending_hand,
blocked = fool.run_armor_check(offending_hand, MELEE, armour_penetration = justicetool.armour_penetration, silent = TRUE),
wound_bonus = justicetool.wound_bonus * COUNTERMULTIPLIER,
exposed_wound_bonus = justicetool.exposed_wound_bonus * COUNTERMULTIPLIER,
sharpness = justicetool.sharpness,
attack_direction = get_dir(forward_thinker, fool),
attacking_item = justicetool,
)
forward_thinker.visible_message(span_danger("[forward_thinker] swiftly draws \the [justicetool] and strikes [fool] during [fool.p_their()] attack!"),
span_notice("You swiftly draw \the [justicetool] and strike them mid-attack!"))
if(!IS_ROBOTIC_LIMB(risked_hand))
forward_thinker.visible_message(span_danger("[forward_thinker]'s arm is unable to withstand the force of the attack!"),
span_danger("You feel a sharp pain as your arm is mutilated by the force of the attack!"))
forward_thinker.apply_damage(
damage = 50,
damagetype = BRUTE,
def_zone = risked_hand,
wound_bonus = 50,
wound_clothing = FALSE,
)
/datum/action/innate/blade_counter/gunpowered/relax(mob/living/holder, obj/item/storage/belt/sheath/active_sheath)
..()
if(succeeded_attempt || holder.get_slot_by_item(target) == ITEM_SLOT_SUITSTORE)
return
if(length(active_sheath.contents))
var/obj/item/denied_weapon = active_sheath.contents[1]
denied_weapon.forceMove(get_turf(holder))
denied_weapon.throw_at(pick(RANGE_TURFS(3, denied_weapon)), 3, 3)
// We can assume that the holder is a carbon, and thus has an actual arm, because they have a belt slot.
var/obj/item/bodypart/worthless_hand = holder.get_active_hand()
if(!worthless_hand)
worthless_hand = holder.get_inactive_hand()
if(!worthless_hand)
holder.visible_message(span_danger("[holder]'s sheath misfires, sending their blade flying!"),
span_danger("Your sheath misfires, sending your blade flying!"))
return
if(IS_ROBOTIC_LIMB(worthless_hand) || !worthless_hand.dismember(BRUTE, FALSE, WOUND_BLUNT))
holder.visible_message(span_danger("[holder]'s arm is mutilated as they misfire [holder.p_their()] sheathed blade!"),
span_danger("Your arm is mutilated as you fail to safely fire your blade!"))
holder.apply_damage(
damage = 50,
damagetype = BRUTE,
def_zone = worthless_hand,
wound_bonus = 50,
wound_clothing = FALSE,
)
return
holder.visible_message(span_danger("[holder]'s arm is violently torn off as they misfire [holder.p_their()] sheathed blade!"),
span_danger("Your arm is torn off as you fail to safely fire your blade!"))
#undef COUNTERMULTIPLIER
/obj/item/storage/belt/sheath/sabre
name = "sabre sheath"
desc = "An ornate sheath designed to hold an officer's blade."
icon_state = "sheath"
inhand_icon_state = "sheath"
worn_icon_state = "sheath"
storage_type = /datum/storage/sabre_belt
stored_blade = /obj/item/melee/sabre
/obj/item/storage/belt/sheath/grass_sabre
name = "sabre sheath"
desc = "A simple grass sheath designed to hold a sabre of... some sort. An actual metal one might be too sharp, though..."
icon_state = "grass_sheath"
inhand_icon_state = "grass_sheath"
worn_icon_state = "grass_sheath"
storage_type = /datum/storage/green_sabre_belt
/obj/item/storage/belt/sheath/gladius
name = "gladius scabbard"
desc = "A fun-sized sheath for a fun-sized sword."
icon_state = "gladius_sheath"
inhand_icon_state = "gladius_sheath"
worn_icon_state = "gladius_sheath"
storage_type = /datum/storage/gladius_belt
stored_blade = /obj/item/claymore/gladius
/obj/item/storage/belt/sheath/katana
name = "katana sheath"
desc = "A sheath that houses the nimble katana."
icon_state = "katana_sheath"
inhand_icon_state = "katana_sheath"
worn_icon_state = "katana_sheath"
slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
storage_type = /datum/storage/katana_sheath
stored_blade = /obj/item/katana
/obj/item/storage/belt/sheath/katana/empty
stored_blade = NONE
/obj/item/storage/belt/sheath/katana/toy
action_slots = NONE
storage_type = /datum/storage/toy_sheath
stored_blade = /obj/item/toy/katana
/obj/item/storage/belt/sheath/katana/toy/empty
stored_blade = NONE
/obj/item/storage/belt/sheath/ninja
name = "energy katana sheath"
desc = "A high tech katana sheath that allows for quick blade movements."
icon_state = "ninja_sheath"
inhand_icon_state = "ninja_sheath"
worn_icon_state = "ninja_sheath"
storage_type = /datum/storage/ninja_sheath
stored_blade = /obj/item/energy_katana
/obj/item/storage/belt/sheath/hanzo_katana
name = "hanzo katana sheath"
desc = "A normal black sheath meant to house the legendary hanzo steel."
icon_state = "hanzo_sheath"
inhand_icon_state = "hanzo_sheath"
worn_icon_state = "hanzo_sheath"
slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
storage_type = /datum/storage/hanzo_sheath
stored_blade = /obj/item/nullrod/claymore/katana
/obj/item/storage/belt/sheath/hanzo_katana/empty
stored_blade = NONE
/obj/item/storage/belt/plant
name = "botanical belt"
desc = "A sturdy leather belt used to hold most hydroponics supplies."
icon_state = "plantbelt"
inhand_icon_state = "utility"
worn_icon_state = "plantbelt"
content_overlays = TRUE
storage_type = /datum/storage/plant_belt
/obj/item/storage/belt/sheath/sabre/gunpowered
name = "modified sabre sheath"
desc = "An imitation of a design made by the infamous Cold Space Wind. Has a trigger mechanism to more forcefully draw the blade."
icon_state = "gunsheath"
actions_types = list(/datum/action/innate/blade_counter/gunpowered)
stored_blade = null
/obj/item/storage/belt/sheath/grass_sabre/gunpowered
name = "modified sabre sheath"
desc = "An imitation of a design grown by the infamous Tiziran Plasma Fire. Has a trigger mechanism to more forcefully draw the blade."
icon_state = "grass_gunsheath"
actions_types = list(/datum/action/innate/blade_counter/gunpowered)