Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into putnamos-for-real
This commit is contained in:
@@ -49,7 +49,9 @@
|
||||
var/original_name
|
||||
desc = "A large piece of space-resistant printed paper."
|
||||
icon = 'icons/obj/contraband.dmi'
|
||||
plane = ABOVE_WALL_PLANE
|
||||
anchored = TRUE
|
||||
buildable_sign = FALSE //Cannot be unwrenched from a wall.
|
||||
var/ruined = FALSE
|
||||
var/random_basetype
|
||||
var/never_random = FALSE // used for the 'random' subclasses.
|
||||
@@ -68,6 +70,8 @@
|
||||
name = "poster - [name]"
|
||||
desc = "A large piece of space-resistant printed paper. [desc]"
|
||||
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 300)), 0)
|
||||
|
||||
/obj/structure/sign/poster/proc/randomise(base_type)
|
||||
var/list/poster_types = subtypesof(base_type)
|
||||
var/list/approved_types = list()
|
||||
@@ -424,6 +428,11 @@
|
||||
desc = "A poster decipting a snake shaped into an ominous 'S'!"
|
||||
icon_state = "poster47"
|
||||
|
||||
/obj/structure/sign/poster/contraband/bountyhunters
|
||||
name = "Bounty Hunters"
|
||||
desc = "A poster advertising bounty hunting services. \"I hear you got a problem.\""
|
||||
icon_state = "poster48"
|
||||
|
||||
/obj/structure/sign/poster/official
|
||||
poster_item_name = "motivational poster"
|
||||
poster_item_desc = "An official Nanotrasen-issued poster to foster a compliant and obedient workforce. It comes with state-of-the-art adhesive backing, for easy pinning to any vertical surface."
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one?
|
||||
var/beauty = 0
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
|
||||
. = ..()
|
||||
@@ -26,6 +27,8 @@
|
||||
if(LAZYLEN(diseases_to_add))
|
||||
AddComponent(/datum/component/infective, diseases_to_add)
|
||||
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, beauty)), 0)
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
|
||||
if(mergeable_decal)
|
||||
qdel(C)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
name = "xeno blood"
|
||||
desc = "It's green and acidic. It looks like... <i>blood?</i>"
|
||||
color = BLOOD_COLOR_XENO
|
||||
beauty = -250
|
||||
|
||||
/obj/effect/decal/cleanable/blood/splatter/xeno
|
||||
color = BLOOD_COLOR_XENO
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
blood_state = BLOOD_STATE_BLOOD
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
|
||||
if (C.blood_DNA)
|
||||
@@ -45,12 +46,14 @@
|
||||
icon_state = "tracks"
|
||||
desc = "They look like tracks left by wheels."
|
||||
random_icon_states = null
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
|
||||
name = "blood"
|
||||
icon_state = "ltrails_1"
|
||||
desc = "Your instincts say you shouldn't be following these."
|
||||
random_icon_states = null
|
||||
beauty = -50
|
||||
var/list/existing_dirs = list()
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder/update_icon()
|
||||
@@ -88,7 +91,7 @@
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
if(S && S.bloody_shoes[blood_state])
|
||||
if(color != bloodtype_to_color(S.last_bloodtype))
|
||||
if(color != S.last_blood_color)
|
||||
return
|
||||
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
shoe_types |= S.type
|
||||
@@ -101,7 +104,7 @@
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
if(S && S.bloody_shoes[blood_state])
|
||||
if(color != bloodtype_to_color(S.last_bloodtype))//last entry - we check its color
|
||||
if(color != S.last_blood_color)//last entry - we check its color
|
||||
return
|
||||
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
shoe_types |= S.type
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "Someone should clean that up."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "shards"
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/ash
|
||||
name = "ashes"
|
||||
@@ -10,6 +11,7 @@
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "ash"
|
||||
mergeable_decal = FALSE
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/ash/Initialize()
|
||||
. = ..()
|
||||
@@ -24,6 +26,7 @@
|
||||
/obj/effect/decal/cleanable/ash/large
|
||||
name = "large pile of ashes"
|
||||
icon_state = "big_ash"
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/ash/large/Initialize()
|
||||
. = ..()
|
||||
@@ -34,6 +37,7 @@
|
||||
desc = "Back to sand."
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "tiny"
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/glass/Initialize()
|
||||
. = ..()
|
||||
@@ -52,6 +56,7 @@
|
||||
canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/closed/wall, /obj/structure/falsewall)
|
||||
smooth = SMOOTH_FALSE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
beauty = -75
|
||||
|
||||
/obj/effect/decal/cleanable/dirt/Initialize()
|
||||
. = ..()
|
||||
@@ -72,6 +77,10 @@
|
||||
desc = "It's still good. Four second rule!"
|
||||
icon_state = "flour"
|
||||
|
||||
/obj/effect/decal/cleanable/dirt/dust
|
||||
name = "dust"
|
||||
desc = "A thin layer of dust coating the floor."
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/ecto
|
||||
name = "ectoplasmic puddle"
|
||||
desc = "You know who to call."
|
||||
@@ -80,8 +89,11 @@
|
||||
/obj/effect/decal/cleanable/greenglow
|
||||
name = "glowing goo"
|
||||
desc = "Jeez. I hope that's not for lunch."
|
||||
light_power = 1
|
||||
light_range = 1
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
icon_state = "greenglow"
|
||||
beauty = -300
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -97,6 +109,7 @@
|
||||
layer = WALL_OBJ_LAYER
|
||||
icon_state = "cobweb1"
|
||||
resistance_flags = FLAMMABLE
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/cobweb/cobweb2
|
||||
icon_state = "cobweb2"
|
||||
@@ -108,10 +121,12 @@
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "molten"
|
||||
mergeable_decal = FALSE
|
||||
beauty = -150
|
||||
|
||||
/obj/effect/decal/cleanable/molten_object/large
|
||||
name = "big gooey grey mass"
|
||||
icon_state = "big_molten"
|
||||
beauty = -300
|
||||
|
||||
//Vomit (sorry)
|
||||
/obj/effect/decal/cleanable/vomit
|
||||
@@ -120,6 +135,7 @@
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "vomit_1"
|
||||
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
|
||||
beauty = -150
|
||||
|
||||
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user)
|
||||
. = ..()
|
||||
@@ -152,6 +168,7 @@
|
||||
gender = NEUTER
|
||||
icon = 'icons/effects/tomatodecal.dmi'
|
||||
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/plant_smudge
|
||||
name = "plant smudge"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
blood_state = BLOOD_STATE_OIL
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
mergeable_decal = FALSE
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
|
||||
. = ..()
|
||||
@@ -50,6 +51,7 @@
|
||||
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
|
||||
blood_state = BLOOD_STATE_OIL
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/oil/Initialize()
|
||||
. = ..()
|
||||
@@ -58,6 +60,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/oil/streak
|
||||
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/oil/slippery
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "Graffiti. Damn kids."
|
||||
icon = 'icons/effects/crayondecal.dmi'
|
||||
icon_state = "rune1"
|
||||
plane = GAME_PLANE //makes the graffiti visible over a wall.
|
||||
plane = ABOVE_WALL_PLANE //makes the graffiti visible over a wall.
|
||||
gender = NEUTER
|
||||
mergeable_decal = FALSE
|
||||
var/do_icon_rotate = TRUE
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
icon = 'icons/turf/decals.dmi'
|
||||
icon_state = "warningline"
|
||||
layer = TURF_DECAL_LAYER
|
||||
plane = ABOVE_WALL_PLANE
|
||||
|
||||
/obj/effect/turf_decal/Initialize()
|
||||
..()
|
||||
@@ -45,4 +46,4 @@
|
||||
var/turf/T = loc
|
||||
if(!istype(T)) //you know this will happen somehow
|
||||
CRASH("Turf decal initialized in an object/nullspace")
|
||||
T.AddComponent(/datum/component/decal, icon, icon_state, dir, CLEAN_GOD, color, null, null, alpha)
|
||||
T.AddElement(/datum/element/decal, icon, icon_state, turn(dir, -dir2angle(T.dir)), CLEAN_GOD, color, null, null, alpha)
|
||||
|
||||
@@ -469,6 +469,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
/obj/effect/landmark/stationroom
|
||||
var/list/templates = list()
|
||||
layer = BULLET_HOLE_LAYER
|
||||
plane = ABOVE_WALL_PLANE
|
||||
|
||||
/obj/effect/landmark/stationroom/New()
|
||||
..()
|
||||
|
||||
@@ -5,19 +5,21 @@
|
||||
anchored = TRUE
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "uglymine"
|
||||
var/triggered = 0
|
||||
/// We manually check to see if we've been triggered in case multiple atoms cross us in the time between the mine being triggered and it actually deleting, to avoid a race condition with multiple detonations
|
||||
var/triggered = FALSE
|
||||
|
||||
/obj/effect/mine/proc/mineEffect(mob/victim)
|
||||
to_chat(victim, "<span class='danger'>*click*</span>")
|
||||
|
||||
/obj/effect/mine/Crossed(AM as mob|obj)
|
||||
if(isturf(loc))
|
||||
if(ismob(AM))
|
||||
var/mob/MM = AM
|
||||
if(!(MM.movement_type & FLYING))
|
||||
triggermine(AM)
|
||||
else
|
||||
triggermine(AM)
|
||||
/obj/effect/mine/Crossed(atom/movable/AM)
|
||||
if(triggered || !isturf(loc))
|
||||
return
|
||||
. = ..()
|
||||
|
||||
if(AM.movement_type & FLYING)
|
||||
return
|
||||
|
||||
triggermine(AM)
|
||||
|
||||
/obj/effect/mine/proc/triggermine(mob/victim)
|
||||
if(triggered)
|
||||
@@ -27,9 +29,13 @@
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
mineEffect(victim)
|
||||
SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED)
|
||||
triggered = 1
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir)
|
||||
. = ..()
|
||||
triggermine()
|
||||
|
||||
/obj/effect/mine/explosive
|
||||
name = "explosive mine"
|
||||
@@ -50,6 +56,18 @@
|
||||
if(isliving(victim))
|
||||
victim.DefaultCombatKnockdown(stun_time)
|
||||
|
||||
/obj/effect/mine/shrapnel
|
||||
name = "shrapnel mine"
|
||||
var/shrapnel_type = /obj/item/projectile/bullet/shrapnel
|
||||
var/shrapnel_magnitude = 3
|
||||
|
||||
/obj/effect/mine/shrapnel/mineEffect(mob/victim)
|
||||
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude)
|
||||
|
||||
/obj/effect/mine/shrapnel/sting
|
||||
name = "stinger mine"
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball
|
||||
|
||||
/obj/effect/mine/kickmine
|
||||
name = "kick mine"
|
||||
|
||||
@@ -105,7 +123,7 @@
|
||||
/obj/effect/mine/pickup/triggermine(mob/victim)
|
||||
if(triggered)
|
||||
return
|
||||
triggered = 1
|
||||
triggered = TRUE
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
mineEffect(victim)
|
||||
qdel(src)
|
||||
@@ -128,14 +146,13 @@
|
||||
spawn(0)
|
||||
new /datum/hallucination/delusion(victim, TRUE, "demon",duration,0)
|
||||
|
||||
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
var/obj/item/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
victim.log_message("entered a blood frenzy", LOG_ATTACK)
|
||||
|
||||
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
|
||||
victim.drop_all_held_items()
|
||||
victim.put_in_hands(chainsaw, forced = TRUE)
|
||||
chainsaw.attack_self(victim)
|
||||
chainsaw.wield(victim)
|
||||
victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
|
||||
to_chat(victim, "<span class='warning'>KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!</span>")
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
|
||||
//This is ment for "low" loot that anyone could fine in a toilet, for better gear use high loot toilet
|
||||
//This is meant for "low" loot that anyone could find in a toilet, for better gear use high loot toilet
|
||||
loot = list("" = 30,
|
||||
/obj/item/lighter = 2,
|
||||
/obj/item/tape/random = 1,
|
||||
@@ -476,7 +476,7 @@
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
|
||||
//This is ment for "prison" loot that is rather rare and ment for "prisoners if they get a crowbar to fine, or sec.
|
||||
//This is meant for "prison" loot that is rather rare and meant for "prisoners if they get a crowbar to fine, or sec.
|
||||
loot = list("" = 10,
|
||||
/obj/item/lighter = 5,
|
||||
/obj/item/poster/random_contraband = 5,
|
||||
@@ -491,7 +491,7 @@
|
||||
/obj/item/kitchen/knife = 5,
|
||||
/obj/item/screwdriver = 5,
|
||||
/obj/item/crowbar/red = 1, //Dont you need a crowbar to open this?
|
||||
/obj/item/stack/medical/bruise_pack = 3,
|
||||
/obj/item/stack/medical/suture = 3,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/vodka = 2,
|
||||
/obj/item/radio = 5,
|
||||
/obj/item/flashlight = 4,
|
||||
@@ -611,13 +611,13 @@
|
||||
/obj/item/clothing/mask/breath = 5,
|
||||
/obj/item/clothing/mask/breath/medical = 1
|
||||
)
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/welder_tools/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
/obj/effect/spawner/lootdrop/low_tools/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/breathing_tanks/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
@@ -644,3 +644,76 @@
|
||||
|
||||
/obj/effect/spawner/lootdrop/glowstick/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
// Random Parts
|
||||
|
||||
/obj/effect/spawner/lootdrop/stock_parts
|
||||
name = "random stock parts spawner"
|
||||
lootcount = 1
|
||||
loot = list(
|
||||
/obj/item/stock_parts/capacitor,
|
||||
/obj/item/stock_parts/scanning_module,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stock_parts/micro_laser,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/cell
|
||||
)
|
||||
|
||||
// Random Weapon Parts
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
name = "random weapon parts spawner 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 13,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 13,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 12,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
name = "random weapon parts spawner 20%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 80,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 5,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo
|
||||
name = "random ammo 75%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 25,
|
||||
/obj/item/ammo_box/magazine/wt550m9 = 1,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 7,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 7,
|
||||
/obj/item/ammo_casing/a762 = 15,
|
||||
/obj/item/ammo_box/a762 = 15,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo/fiftypercent
|
||||
name = "random ammo 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/ammo_box/magazine/wt550m9 = 2,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 10,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 10,
|
||||
/obj/item/ammo_casing/a762 = 7,
|
||||
/obj/item/ammo_box/a762 = 7,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo/shotgun
|
||||
name = "random ammo 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/ammo_box/shotgun/loaded/buckshot = 5,
|
||||
/obj/item/ammo_box/shotgun/loaded/beanbag = 5,
|
||||
/obj/item/ammo_box/shotgun/loaded/incendiary = 5,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 8,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 9,
|
||||
/obj/item/ammo_casing/shotgun = 8,
|
||||
/obj/item/ammo_casing/shotgun/incendiary = 10,
|
||||
)
|
||||
|
||||
@@ -24,6 +24,23 @@ again.
|
||||
name = "window spawner"
|
||||
spawn_list = list(/obj/structure/grille, /obj/structure/window/fulltile)
|
||||
dir = SOUTH
|
||||
var/electrochromatic
|
||||
var/electrochromatic_id
|
||||
|
||||
/obj/effect/spawner/structure/window/Initialize()
|
||||
. = ..()
|
||||
if(!electrochromatic)
|
||||
return
|
||||
if(!electrochromatic_id)
|
||||
stack_trace("Electrochromatic window spawner set without electromatic id.")
|
||||
return
|
||||
if(electrochromatic_id[1] == "!")
|
||||
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
|
||||
for(var/obj/structure/window/W in get_turf(src))
|
||||
W.electrochromatic_id = electrochromatic_id
|
||||
W.make_electrochromatic()
|
||||
if(electrochromatic == ELECTROCHROMATIC_DIMMED)
|
||||
W.electrochromatic_dim()
|
||||
|
||||
/obj/effect/spawner/structure/window/hollow
|
||||
name = "hollow window spawner"
|
||||
@@ -140,13 +157,16 @@ again.
|
||||
spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/spawner/north, /obj/structure/window/reinforced/spawner/west)
|
||||
. = ..()
|
||||
|
||||
//tinted
|
||||
//tinted and electrochromatic
|
||||
|
||||
/obj/effect/spawner/structure/window/reinforced/tinted
|
||||
name = "tinted reinforced window spawner"
|
||||
icon_state = "twindow_spawner"
|
||||
spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/tinted/fulltile)
|
||||
|
||||
/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic
|
||||
name = "electrochromatic reinforced window spawner"
|
||||
electrochromatic = ELECTROCHROMATIC_DIMMED
|
||||
|
||||
//shuttle window
|
||||
|
||||
|
||||
@@ -95,6 +95,56 @@
|
||||
icon_state = "warden_gaze"
|
||||
duration = 3
|
||||
|
||||
/obj/effect/temp_visual/ratvar/volt_hit
|
||||
name = "volt blast"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 8
|
||||
icon_state = "volt_hit"
|
||||
light_range = 1.5
|
||||
light_power = 2
|
||||
light_color = LIGHT_COLOR_ORANGE
|
||||
var/mob/user
|
||||
var/damage = 20
|
||||
|
||||
/obj/effect/temp_visual/ratvar/volt_hit/Initialize(mapload, caster)
|
||||
. = ..()
|
||||
user = caster
|
||||
if(user)
|
||||
var/matrix/M = new
|
||||
M.Turn(Get_Angle(src, user))
|
||||
transform = M
|
||||
INVOKE_ASYNC(src, .proc/volthit)
|
||||
|
||||
/obj/effect/temp_visual/ratvar/volt_hit/proc/volthit()
|
||||
if(user)
|
||||
Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
|
||||
var/hit_amount = 0
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/living/L in T)
|
||||
if(is_servant_of_ratvar(L))
|
||||
continue
|
||||
var/obj/item/I = L.anti_magic_check()
|
||||
if(I)
|
||||
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
|
||||
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")
|
||||
continue
|
||||
L.visible_message("<span class='warning'>[L] is struck by a [name]!</span>", "<span class='userdanger'>You're struck by a [name]!</span>")
|
||||
L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
|
||||
log_combat(user, L, "struck with a volt blast")
|
||||
hit_amount++
|
||||
for(var/obj/mecha/M in T)
|
||||
if(M.occupant)
|
||||
if(is_servant_of_ratvar(M.occupant))
|
||||
continue
|
||||
to_chat(M.occupant, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
|
||||
M.visible_message("<span class='warning'>[M] is struck by a [name]!</span>")
|
||||
M.take_damage(damage, BURN, 0, 0)
|
||||
hit_amount++
|
||||
if(hit_amount)
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', damage*hit_amount, 1, -1)
|
||||
else
|
||||
playsound(src, "sparks", 50, 1)
|
||||
|
||||
/obj/effect/temp_visual/ratvar/ocular_warden/Initialize()
|
||||
. = ..()
|
||||
pixel_x = rand(-8, 8)
|
||||
|
||||
+236
-35
@@ -4,6 +4,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// if true, everyone item when created will have its name changed to be
|
||||
// more... RPG-like.
|
||||
|
||||
GLOBAL_VAR_INIT(stickpocalypse, FALSE) // if true, all non-embeddable items will be able to harmlessly stick to people when thrown
|
||||
GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to embed in people, takes precedence over stickpocalypse
|
||||
|
||||
/obj/item
|
||||
name = "item"
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
@@ -55,7 +58,17 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
/// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives.
|
||||
var/stagger_force
|
||||
|
||||
/**
|
||||
* Set FALSE and then checked at the end of on mob/living/attackby(), set TRUE on living/pre_attacked_by().
|
||||
* Should it be FALSE by the end of the item/attack(), that means the item overrode the standard attack behaviour
|
||||
* and the user still needs the delay applied. We can't be using return values since that'll stop afterattack() from being triggered.
|
||||
*/
|
||||
var/attack_delay_done = FALSE
|
||||
///next_move click/attack delay of this item.
|
||||
var/click_delay = CLICK_CD_MELEE
|
||||
|
||||
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
|
||||
var/current_equipped_slot
|
||||
pass_flags = PASSTABLE
|
||||
pressure_resistance = 4
|
||||
var/obj/item/master = null
|
||||
@@ -95,7 +108,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
|
||||
|
||||
var/datum/embedding_behavior/embedding
|
||||
var/list/embedding = NONE
|
||||
|
||||
var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES
|
||||
var/heat = 0
|
||||
@@ -132,15 +145,25 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
|
||||
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
|
||||
|
||||
/* Our block parry data. Should be set in init, or something if you are using it.
|
||||
* This won't be accessed without ITEM_CAN_BLOCK or ITEM_CAN_PARRY so do not set it unless you have to to save memory.
|
||||
* If you decide it's a good idea to leave this unset while turning the flags on, you will runtime. Enjoy.
|
||||
* If this is set to a path, it'll run get_block_parry_data(path). YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
*/
|
||||
var/datum/block_parry_data/block_parry_data
|
||||
|
||||
///Skills vars
|
||||
//list of skill PATHS exercised when using this item. An associated bitfield can be set to indicate additional ways the skill is used by this specific item.
|
||||
var/list/datum/skill/used_skills
|
||||
var/skill_difficulty = THRESHOLD_COMPETENT //how difficult it's to use this item in general.
|
||||
var/skill_difficulty = THRESHOLD_UNTRAINED //how difficult it's to use this item in general.
|
||||
var/skill_gain = DEF_SKILL_GAIN //base skill value gain from using this item.
|
||||
|
||||
var/canMouseDown = FALSE
|
||||
|
||||
|
||||
/obj/item/Initialize()
|
||||
|
||||
if (attack_verb)
|
||||
if(attack_verb)
|
||||
attack_verb = typelist("attack_verb", attack_verb)
|
||||
|
||||
. = ..()
|
||||
@@ -148,9 +171,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
new path(src)
|
||||
actions_types = null
|
||||
|
||||
if(GLOB.rpg_loot_items)
|
||||
AddComponent(/datum/component/fantasy)
|
||||
|
||||
if(force_string)
|
||||
item_flags |= FORCE_STRING_OVERRIDE
|
||||
|
||||
@@ -160,15 +180,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
if(damtype == "brute")
|
||||
hitsound = "swing_hit"
|
||||
|
||||
if (!embedding)
|
||||
embedding = getEmbeddingBehavior()
|
||||
else if (islist(embedding))
|
||||
embedding = getEmbeddingBehavior(arglist(embedding))
|
||||
else if (!istype(embedding, /datum/embedding_behavior))
|
||||
stack_trace("Invalid type [embedding.type] found in .embedding during /obj/item Initialize()")
|
||||
|
||||
if(sharpness) //give sharp objects butchering functionality, for consistency
|
||||
AddComponent(/datum/component/butchering, 80 * toolspeed)
|
||||
if(used_skills)
|
||||
for(var/path in used_skills)
|
||||
var/datum/skill/S = GLOB.skill_datums[path]
|
||||
LAZYADD(used_skills[path], S.skill_traits)
|
||||
|
||||
/obj/item/Destroy()
|
||||
item_flags &= ~DROPDEL //prevent reqdels
|
||||
@@ -179,6 +194,26 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
qdel(X)
|
||||
return ..()
|
||||
|
||||
/obj/item/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
// this proc says it's for initializing components, but we're initializing elements too because it's you and me against the world >:)
|
||||
if(!LAZYLEN(embedding))
|
||||
if(GLOB.embedpocalypse)
|
||||
embedding = EMBED_POINTY
|
||||
name = "pointy [name]"
|
||||
else if(GLOB.stickpocalypse)
|
||||
embedding = EMBED_HARMLESS
|
||||
name = "sticky [name]"
|
||||
|
||||
updateEmbedding()
|
||||
|
||||
if(GLOB.rpg_loot_items)
|
||||
AddComponent(/datum/component/fantasy)
|
||||
|
||||
if(sharpness) //give sharp objects butchering functionality, for consistency
|
||||
AddComponent(/datum/component/butchering, 80 * toolspeed)
|
||||
|
||||
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
|
||||
if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside))
|
||||
return 0
|
||||
@@ -229,8 +264,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
if(resistance_flags & FIRE_PROOF)
|
||||
. += "[src] is made of fire-retardant materials."
|
||||
|
||||
|
||||
|
||||
if(item_flags & (ITEM_CAN_BLOCK | ITEM_CAN_PARRY))
|
||||
var/datum/block_parry_data/data = return_block_parry_datum(block_parry_data)
|
||||
. += "[src] has the capacity to be used to block and/or parry. <a href='?src=[REF(data)];name=[name];block=[item_flags & ITEM_CAN_BLOCK];parry=[item_flags & ITEM_CAN_PARRY];render=1'>\[Show Stats\]</a>"
|
||||
|
||||
if(!user.research_scanner)
|
||||
return
|
||||
@@ -285,6 +321,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return
|
||||
if(anchored)
|
||||
return
|
||||
if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS)
|
||||
if(current_equipped_slot in user.check_obscured_slots())
|
||||
to_chat(src, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
return FALSE
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
var/mob/living/carbon/C = user
|
||||
@@ -306,7 +346,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
C.update_damage_overlays()
|
||||
return
|
||||
|
||||
if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid.
|
||||
if(acid_level > 20 && ismob(loc))// so we can still remove the clothes on us that have acid.
|
||||
var/mob/living/carbon/C = user
|
||||
if(istype(C))
|
||||
if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
|
||||
@@ -349,6 +389,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return
|
||||
if(anchored)
|
||||
return
|
||||
if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS)
|
||||
if(current_equipped_slot in user.check_obscured_slots())
|
||||
to_chat(src, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, user.loc, TRUE)
|
||||
|
||||
@@ -392,6 +437,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/obj/item/proc/dropped(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
current_equipped_slot = null
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Remove(user)
|
||||
@@ -404,6 +451,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
// called just as an item is picked up (loc is not yet changed)
|
||||
/obj/item/proc/pickup(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_PICKUP, user)
|
||||
item_flags |= IN_INVENTORY
|
||||
|
||||
@@ -420,14 +468,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return usr.client.Click(src, src_location, src_control, params)
|
||||
var/list/directaccess = usr.DirectAccess() //This, specifically, is what requires the copypaste. If this were after the adjacency check, then it'd be impossible to use items in your inventory, among other things.
|
||||
//If this were before the above checks, then trying to click on items would act a little funky and signal overrides wouldn't work.
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
if((C.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && ((C.CanReach(src) || (src in directaccess)) && (C.CanReach(over) || (over in directaccess))))
|
||||
if(!C.get_active_held_item())
|
||||
C.UnarmedAttack(src, TRUE)
|
||||
if(C.get_active_held_item() == src)
|
||||
melee_attack_chain(C, over)
|
||||
return TRUE //returning TRUE as a "is this overridden?" flag
|
||||
if(SEND_SIGNAL(usr, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE) && ((usr.CanReach(src) || (src in directaccess)) && (usr.CanReach(over) || (over in directaccess))))
|
||||
if(!usr.get_active_held_item())
|
||||
usr.UnarmedAttack(src, TRUE)
|
||||
if(usr.get_active_held_item() == src)
|
||||
melee_attack_chain(usr, over)
|
||||
return TRUE //returning TRUE as a "is this overridden?" flag
|
||||
if(!Adjacent(usr) || !over.Adjacent(usr))
|
||||
return // should stop you from dragging through windows
|
||||
|
||||
@@ -440,7 +486,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// for items that can be placed in multiple slots
|
||||
// note this isn't called during the initial dressing of a player
|
||||
/obj/item/proc/equipped(mob/user, slot)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
. = SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
|
||||
current_equipped_slot = slot
|
||||
if(!(. & COMPONENT_NO_GRANT_ACTIONS))
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
@@ -466,11 +514,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise.
|
||||
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
|
||||
//Set disable_warning to TRUE if you wish it to not give you outputs.
|
||||
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
|
||||
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
|
||||
if(!M)
|
||||
return FALSE
|
||||
|
||||
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self)
|
||||
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self, clothing_check, return_warning)
|
||||
|
||||
/obj/item/verb/verb_pickup()
|
||||
set src in oview(1)
|
||||
@@ -605,6 +653,18 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/itempush = 1
|
||||
if(w_class < 4)
|
||||
itempush = 0 //too light to push anything
|
||||
if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
|
||||
var/volume = get_volume_by_throwforce_and_or_w_class()
|
||||
if (throwforce > 0)
|
||||
if (throwhitsound)
|
||||
playsound(hit_atom, throwhitsound, volume, TRUE, -1)
|
||||
else if(hitsound)
|
||||
playsound(hit_atom, hitsound, volume, TRUE, -1)
|
||||
else
|
||||
playsound(hit_atom, 'sound/weapons/genhit.ogg',volume, TRUE, -1)
|
||||
else
|
||||
playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
|
||||
|
||||
return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum)
|
||||
|
||||
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
|
||||
@@ -736,6 +796,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
..()
|
||||
|
||||
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, M)
|
||||
if(istype(M) && M.dirty < 100)
|
||||
M.dirty++
|
||||
|
||||
@@ -782,14 +843,17 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/user = usr
|
||||
tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
|
||||
|
||||
/obj/item/MouseExited()
|
||||
/obj/item/MouseExited(location,control,params)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params)
|
||||
deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes
|
||||
closeToolTip(usr)
|
||||
|
||||
/obj/item/MouseEntered(location,control,params)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params)
|
||||
|
||||
// Called when a mob tries to use the item as a tool.
|
||||
// Handles most checks.
|
||||
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks, skill_gain_mult = 1, max_level = INFINITY)
|
||||
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks, skill_gain_mult = STD_USE_TOOL_MULT)
|
||||
// No delay means there is no start message, and no reason to call tool_start_check before use_tool.
|
||||
// Run the start check here so we wouldn't have to call it manually.
|
||||
if(!delay && !tool_start_check(user, amount))
|
||||
@@ -802,7 +866,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
if(delay)
|
||||
if(user.mind && used_skills)
|
||||
delay = user.mind.skill_holder.item_action_skills_mod(src, delay, skill_difficulty, SKILL_USE_TOOL, NONE, FALSE)
|
||||
delay = user.mind.item_action_skills_mod(src, delay, skill_difficulty, SKILL_USE_TOOL, null, FALSE)
|
||||
|
||||
// Create a callback with checks that would be called every tick by do_after.
|
||||
var/datum/callback/tool_check = CALLBACK(src, .proc/tool_check_callback, user, amount, extra_checks)
|
||||
@@ -828,11 +892,14 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
if(delay >= MIN_TOOL_SOUND_DELAY)
|
||||
play_tool_sound(target, volume)
|
||||
|
||||
|
||||
if(user.mind && used_skills && skill_gain_mult)
|
||||
var/gain = skill_gain + delay/SKILL_GAIN_DELAY_DIVISOR
|
||||
for(var/skill in used_skills)
|
||||
if(!(used_skills[skill] & SKILL_TRAINING_TOOL))
|
||||
if(!(SKILL_TRAINING_TOOL in used_skills[skill]))
|
||||
continue
|
||||
user.mind.skill_holder.auto_gain_experience(skill, skill_gain*skill_gain_mult, GET_STANDARD_LVL(max_level))
|
||||
var/datum/skill/S = GLOB.skill_datums[skill]
|
||||
user.mind.auto_gain_experience(skill, gain*skill_gain_mult*S.item_skill_gain_multi)
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -893,11 +960,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// if w_volume is 0 you fucked up anyways lol
|
||||
return w_volume || AUTO_SCALE_VOLUME(w_class)
|
||||
|
||||
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
|
||||
/obj/item/proc/embedded(atom/embedded_target)
|
||||
return
|
||||
|
||||
/obj/item/proc/unembedded()
|
||||
return
|
||||
if(item_flags & DROPDEL)
|
||||
QDEL_NULL(src)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Sets our slowdown and updates equipment slowdown of any mob we're equipped on.
|
||||
@@ -913,3 +982,135 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
. = ..()
|
||||
if(var_name == NAMEOF(src, slowdown))
|
||||
set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior.
|
||||
/**
|
||||
* Does the current embedding var meet the criteria for being harmless? Namely, does it explicitly define the pain multiplier and jostle pain mult to be 0? If so, return true.
|
||||
*
|
||||
*/
|
||||
/obj/item/proc/isEmbedHarmless()
|
||||
if(embedding)
|
||||
return !isnull(embedding["pain_mult"]) && !isnull(embedding["jostle_pain_mult"]) && embedding["pain_mult"] == 0 && embedding["jostle_pain_mult"] == 0
|
||||
|
||||
///In case we want to do something special (like self delete) upon failing to embed in something, return true
|
||||
/obj/item/proc/failedEmbed()
|
||||
if(item_flags & DROPDEL)
|
||||
QDEL_NULL(src)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
|
||||
|
||||
|
||||
* tryEmbed() is for when you want to try embedding something without dealing with the damage + hit messages of calling hitby() on the item while targetting the target.
|
||||
|
||||
|
||||
|
||||
*
|
||||
|
||||
|
||||
|
||||
* Really, this is used mostly with projectiles with shrapnel payloads, from [/datum/element/embed/proc/checkEmbedProjectile], and called on said shrapnel. Mostly acts as an intermediate between different embed elements.
|
||||
|
||||
|
||||
|
||||
*
|
||||
|
||||
|
||||
|
||||
* Arguments:
|
||||
|
||||
|
||||
|
||||
* * target- Either a body part, a carbon, or a closed turf. What are we hitting?
|
||||
|
||||
|
||||
|
||||
* * forced- Do we want this to go through 100%?
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/obj/item/proc/tryEmbed(atom/target, forced=FALSE, silent=FALSE)
|
||||
|
||||
|
||||
|
||||
if(!isbodypart(target) && !iscarbon(target) && !isclosedturf(target))
|
||||
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
if(!forced && !LAZYLEN(embedding))
|
||||
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_EMBED_TRY_FORCE, target, forced, silent))
|
||||
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
failedEmbed()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///For when you want to disable an item's embedding capabilities (like transforming weapons and such), this proc will detach any active embed elements from it.
|
||||
|
||||
|
||||
|
||||
/obj/item/proc/disableEmbedding()
|
||||
|
||||
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_DISABLE_EMBED)
|
||||
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///For when you want to add/update the embedding on an item. Uses the vars in [/obj/item/embedding], and defaults to config values for values that aren't set. Will automatically detach previous embed elements on this item.
|
||||
|
||||
|
||||
|
||||
/obj/item/proc/updateEmbedding()
|
||||
if(!islist(embedding) || !LAZYLEN(embedding))
|
||||
return
|
||||
|
||||
AddElement(/datum/element/embed,\
|
||||
embed_chance = (!isnull(embedding["embed_chance"]) ? embedding["embed_chance"] : EMBED_CHANCE),\
|
||||
fall_chance = (!isnull(embedding["fall_chance"]) ? embedding["fall_chance"] : EMBEDDED_ITEM_FALLOUT),\
|
||||
pain_chance = (!isnull(embedding["pain_chance"]) ? embedding["pain_chance"] : EMBEDDED_PAIN_CHANCE),\
|
||||
pain_mult = (!isnull(embedding["pain_mult"]) ? embedding["pain_mult"] : EMBEDDED_PAIN_MULTIPLIER),\
|
||||
remove_pain_mult = (!isnull(embedding["remove_pain_mult"]) ? embedding["remove_pain_mult"] : EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER),\
|
||||
rip_time = (!isnull(embedding["rip_time"]) ? embedding["rip_time"] : EMBEDDED_UNSAFE_REMOVAL_TIME),\
|
||||
ignore_throwspeed_threshold = (!isnull(embedding["ignore_throwspeed_threshold"]) ? embedding["ignore_throwspeed_threshold"] : FALSE),\
|
||||
impact_pain_mult = (!isnull(embedding["impact_pain_mult"]) ? embedding["impact_pain_mult"] : EMBEDDED_IMPACT_PAIN_MULTIPLIER),\
|
||||
jostle_chance = (!isnull(embedding["jostle_chance"]) ? embedding["jostle_chance"] : EMBEDDED_JOSTLE_CHANCE),\
|
||||
jostle_pain_mult = (!isnull(embedding["jostle_pain_mult"]) ? embedding["jostle_pain_mult"] : EMBEDDED_JOSTLE_PAIN_MULTIPLIER),\
|
||||
pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\
|
||||
embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD))
|
||||
return TRUE
|
||||
@@ -143,8 +143,8 @@ RLD
|
||||
//if user can't be seen from A (only checks surroundings' opaqueness) and can't see A.
|
||||
//jarring, but it should stop people from targetting atoms they can't see...
|
||||
//excluding darkness, to allow RLD to be used to light pitch black dark areas.
|
||||
if(!((user in view(view_range, A)) || (user in viewers(view_range, A))))
|
||||
to_chat(user, "<span class='warning'>You focus, pointing \the [src] at whatever outside your field of vision in the given direction... to no avail.</span>")
|
||||
if(!((user in view(view_range, A)) || (user in fov_viewers(view_range, A))))
|
||||
to_chat(user, "<span class='warning'>You focus, pointing \the [src] at whatever outside your field of vision in that direction... to no avail.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -154,7 +154,8 @@ RLD
|
||||
icon_state = "rcd"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
custom_price = 900
|
||||
custom_price = PRICE_ABOVE_EXPENSIVE
|
||||
custom_premium_price = PRICE_ALMOST_ONE_GRAND
|
||||
max_matter = 160
|
||||
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
|
||||
has_ammobar = TRUE
|
||||
@@ -745,7 +746,7 @@ RLD
|
||||
if(istype(A, /obj/machinery/light/))
|
||||
if(checkResource(deconcost, user))
|
||||
to_chat(user, "<span class='notice'>You start deconstructing [A]...</span>")
|
||||
user.Beam(A,icon_state="nzcrentrs_power",time=15)
|
||||
user.Beam(A,icon_state="light_beam",time=15)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, decondelay, target = A))
|
||||
if(!useResource(deconcost, user))
|
||||
@@ -759,7 +760,7 @@ RLD
|
||||
var/turf/closed/wall/W = A
|
||||
if(checkResource(floorcost, user))
|
||||
to_chat(user, "<span class='notice'>You start building a wall light...</span>")
|
||||
user.Beam(A,icon_state="nzcrentrs_power",time=15)
|
||||
user.Beam(A,icon_state="light_beam",time=15)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 0)
|
||||
if(do_after(user, floordelay, target = A))
|
||||
@@ -805,7 +806,7 @@ RLD
|
||||
var/turf/open/floor/F = A
|
||||
if(checkResource(floorcost, user))
|
||||
to_chat(user, "<span class='notice'>You start building a floor light...</span>")
|
||||
user.Beam(A,icon_state="nzcrentrs_power",time=15)
|
||||
user.Beam(A,icon_state="light_beam",time=15)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
if(do_after(user, floordelay, target = A))
|
||||
@@ -834,6 +835,12 @@ RLD
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/construction/rld/mini
|
||||
name = "mini-rapid-light-device (MRLD)"
|
||||
desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges."
|
||||
matter = 100
|
||||
max_matter = 100
|
||||
|
||||
/obj/item/rcd_upgrade
|
||||
name = "RCD advanced design disk"
|
||||
desc = "It seems to be empty."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/item/twohanded/rcl
|
||||
/obj/item/rcl
|
||||
name = "rapid cable layer"
|
||||
desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!"
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
@@ -23,15 +23,26 @@
|
||||
var/datum/radial_menu/persistent/wiring_gui_menu
|
||||
var/mob/listeningTo
|
||||
|
||||
/obj/item/twohanded/rcl/Initialize()
|
||||
/obj/item/rcl/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/rcl/ComponentInitialize()
|
||||
/obj/item/rcl/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
AddComponent(/datum/component/two_handed)
|
||||
|
||||
/obj/item/twohanded/rcl/attackby(obj/item/W, mob/user)
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/rcl/proc/on_wield(obj/item/source, mob/user)
|
||||
active = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/rcl/proc/on_unwield(obj/item/source, mob/user)
|
||||
active = FALSE
|
||||
|
||||
/obj/item/rcl/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
|
||||
@@ -86,26 +97,26 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/twohanded/rcl/examine(mob/user)
|
||||
/obj/item/rcl/examine(mob/user)
|
||||
. = ..()
|
||||
if(loaded)
|
||||
. += "<span class='info'>It contains [loaded.amount]/[max_amount] cables.</span>"
|
||||
|
||||
/obj/item/twohanded/rcl/Destroy()
|
||||
/obj/item/rcl/Destroy()
|
||||
QDEL_NULL(loaded)
|
||||
last = null
|
||||
listeningTo = null
|
||||
QDEL_NULL(wiring_gui_menu)
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/rcl/update_icon_state()
|
||||
/obj/item/rcl/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
item_state = initial(item_state)
|
||||
if(!loaded || !loaded.amount)
|
||||
icon_state += "-empty"
|
||||
item_state += "-0"
|
||||
|
||||
/obj/item/twohanded/rcl/update_overlays()
|
||||
/obj/item/rcl/update_overlays()
|
||||
. = ..()
|
||||
if(!loaded || !loaded.amount)
|
||||
return
|
||||
@@ -113,7 +124,7 @@
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
|
||||
/obj/item/rcl/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands || !(loaded?.amount))
|
||||
return
|
||||
@@ -121,7 +132,7 @@
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
/obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1)
|
||||
/obj/item/rcl/proc/is_empty(mob/user, loud = 1)
|
||||
update_icon()
|
||||
if(!loaded || !loaded.amount)
|
||||
if(loud)
|
||||
@@ -130,26 +141,23 @@
|
||||
QDEL_NULL(loaded)
|
||||
loaded = null
|
||||
QDEL_NULL(wiring_gui_menu)
|
||||
unwield(user)
|
||||
active = wielded
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/twohanded/rcl/pickup(mob/user)
|
||||
/obj/item/rcl/pickup(mob/user)
|
||||
..()
|
||||
getMobhook(user)
|
||||
|
||||
|
||||
|
||||
/obj/item/twohanded/rcl/dropped(mob/wearer)
|
||||
/obj/item/rcl/dropped(mob/wearer)
|
||||
..()
|
||||
UnregisterSignal(wearer, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
last = null
|
||||
|
||||
/obj/item/twohanded/rcl/attack_self(mob/user)
|
||||
/obj/item/rcl/attack_self(mob/user)
|
||||
..()
|
||||
active = wielded
|
||||
if(!active)
|
||||
last = null
|
||||
else if(!last)
|
||||
@@ -158,7 +166,7 @@
|
||||
last = C
|
||||
break
|
||||
|
||||
obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
obj/item/rcl/proc/getMobhook(mob/to_hook)
|
||||
if(listeningTo == to_hook)
|
||||
return
|
||||
if(listeningTo)
|
||||
@@ -166,7 +174,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
RegisterSignal(to_hook, COMSIG_MOVABLE_MOVED, .proc/trigger)
|
||||
listeningTo = to_hook
|
||||
|
||||
/obj/item/twohanded/rcl/proc/trigger(mob/user)
|
||||
/obj/item/rcl/proc/trigger(mob/user)
|
||||
if(active)
|
||||
layCable(user)
|
||||
if(wiring_gui_menu) //update the wire options as you move
|
||||
@@ -174,7 +182,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
|
||||
//previous contents of trigger(), lays cable each time the player moves
|
||||
/obj/item/twohanded/rcl/proc/layCable(mob/user)
|
||||
/obj/item/rcl/proc/layCable(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
if(is_empty(user, 0))
|
||||
@@ -207,7 +215,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
update_icon()
|
||||
|
||||
//searches the current tile for a stub cable of the same colour
|
||||
/obj/item/twohanded/rcl/proc/findLinkingCable(mob/user)
|
||||
/obj/item/rcl/proc/findLinkingCable(mob/user)
|
||||
var/turf/T
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
@@ -223,10 +231,8 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
continue
|
||||
if(C.d1 == 0)
|
||||
return C
|
||||
return
|
||||
|
||||
|
||||
/obj/item/twohanded/rcl/proc/wiringGuiGenerateChoices(mob/user)
|
||||
/obj/item/rcl/proc/wiringGuiGenerateChoices(mob/user)
|
||||
var/fromdir = 0
|
||||
var/obj/structure/cable/linkingCable = findLinkingCable(user)
|
||||
if(linkingCable)
|
||||
@@ -243,12 +249,12 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
wiredirs[icondir] = img
|
||||
return wiredirs
|
||||
|
||||
/obj/item/twohanded/rcl/proc/showWiringGui(mob/user)
|
||||
/obj/item/rcl/proc/showWiringGui(mob/user)
|
||||
var/list/choices = wiringGuiGenerateChoices(user)
|
||||
|
||||
wiring_gui_menu = show_radial_menu_persistent(user, src , choices, select_proc = CALLBACK(src, .proc/wiringGuiReact, user), radius = 42)
|
||||
|
||||
/obj/item/twohanded/rcl/proc/wiringGuiUpdate(mob/user)
|
||||
/obj/item/rcl/proc/wiringGuiUpdate(mob/user)
|
||||
if(!wiring_gui_menu)
|
||||
return
|
||||
|
||||
@@ -259,7 +265,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
|
||||
//Callback used to respond to interactions with the wiring menu
|
||||
/obj/item/twohanded/rcl/proc/wiringGuiReact(mob/living/user,choice)
|
||||
/obj/item/rcl/proc/wiringGuiReact(mob/living/user,choice)
|
||||
if(!choice) //close on a null choice (the center button)
|
||||
QDEL_NULL(wiring_gui_menu)
|
||||
return
|
||||
@@ -290,7 +296,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
wiringGuiUpdate(user)
|
||||
|
||||
/obj/item/twohanded/rcl/ui_action_click(mob/user, action)
|
||||
/obj/item/rcl/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/rcl_col))
|
||||
current_color_index++;
|
||||
if (current_color_index > colors.len)
|
||||
@@ -308,13 +314,13 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
else //open the menu
|
||||
showWiringGui(user)
|
||||
|
||||
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
|
||||
/obj/item/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
|
||||
loaded = new()
|
||||
loaded.max_amount = max_amount
|
||||
loaded.amount = max_amount
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/rcl/ghetto
|
||||
/obj/item/rcl/ghetto
|
||||
actions_types = list()
|
||||
max_amount = 30
|
||||
name = "makeshift rapid cable layer"
|
||||
|
||||
@@ -7,7 +7,7 @@ RSF
|
||||
name = "\improper Rapid-Service-Fabricator"
|
||||
desc = "A device used to rapidly deploy service items."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rcd"
|
||||
icon_state = "rsf"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
opacity = 0
|
||||
@@ -110,7 +110,7 @@ RSF
|
||||
name = "Cookie Synthesizer"
|
||||
desc = "A self-recharging device used to rapidly deploy cookies."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rcd"
|
||||
icon_state = "rsf"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
var/matter = 10
|
||||
|
||||
@@ -125,3 +125,112 @@
|
||||
user.put_in_hands(ink)
|
||||
to_chat(user, "<span class='notice'>You remove [ink] from [src].</span>")
|
||||
ink = null
|
||||
|
||||
|
||||
/obj/item/airlock_painter/decal
|
||||
name = "decal painter"
|
||||
desc = "An airlock painter, reprogramed to use a different style of paint in order to apply decals for floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed. Alt-Click to change design."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "decal_sprayer"
|
||||
item_state = "decalsprayer"
|
||||
custom_materials = list(/datum/material/iron=2000, /datum/material/glass=500)
|
||||
var/stored_dir = 2
|
||||
var/stored_color = ""
|
||||
var/stored_decal = "warningline"
|
||||
var/stored_decal_total = "warningline"
|
||||
var/color_list = list("","red","white")
|
||||
var/dir_list = list(1,2,4,8)
|
||||
var/decal_list = list(list("Warning Line","warningline"),
|
||||
list("Warning Line Corner","warninglinecorner"),
|
||||
list("Caution Label","caution"),
|
||||
list("Directional Arrows","arrows"),
|
||||
list("Stand Clear Label","stand_clear"),
|
||||
list("Box","box"),
|
||||
list("Box Corner","box_corners"),
|
||||
list("Delivery Marker","delivery"),
|
||||
list("Warning Box","warn_full"))
|
||||
|
||||
/obj/item/airlock_painter/decal/afterattack(atom/target, mob/user, proximity)
|
||||
. = ..()
|
||||
var/turf/open/floor/F = target
|
||||
if(!proximity)
|
||||
to_chat(user, "<span class='notice'>You need to get closer!</span>")
|
||||
return
|
||||
if(use_paint(user) && isturf(F))
|
||||
F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, turn(stored_dir, -dir2angle(F.dir)), CLEAN_STRONG, color, null, null, alpha)
|
||||
|
||||
/obj/item/airlock_painter/decal/attack_self(mob/user)
|
||||
if((ink) && (ink.charges >= 1))
|
||||
to_chat(user, "<span class='notice'>[src] beeps to prevent you from removing the toner until out of charges.</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/airlock_painter/decal/AltClick(mob/user)
|
||||
. = ..()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/airlock_painter/decal/Initialize()
|
||||
. = ..()
|
||||
ink = new /obj/item/toner/large(src)
|
||||
|
||||
/obj/item/airlock_painter/decal/proc/update_decal_path()
|
||||
var/yellow_fix = "" //This will have to do until someone refactor's markings.dm
|
||||
if (stored_color)
|
||||
yellow_fix = "_"
|
||||
stored_decal_total = "[stored_decal][yellow_fix][stored_color]"
|
||||
return
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["decal_direction"] = stored_dir
|
||||
data["decal_color"] = stored_color
|
||||
data["decal_style"] = stored_decal
|
||||
data["decal_list"] = list()
|
||||
data["color_list"] = list()
|
||||
data["dir_list"] = list()
|
||||
|
||||
for(var/i in decal_list)
|
||||
data["decal_list"] += list(list(
|
||||
"name" = i[1],
|
||||
"decal" = i[2]
|
||||
))
|
||||
for(var/j in color_list)
|
||||
data["color_list"] += list(list(
|
||||
"colors" = j
|
||||
))
|
||||
for(var/k in dir_list)
|
||||
data["dir_list"] += list(list(
|
||||
"dirs" = k
|
||||
))
|
||||
return data
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_act(action,list/params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
//Lists of decals and designs
|
||||
if("select decal")
|
||||
var/selected_decal = params["decals"]
|
||||
stored_decal = selected_decal
|
||||
if("select color")
|
||||
var/selected_color = params["colors"]
|
||||
stored_color = selected_color
|
||||
if("selected direction")
|
||||
var/selected_direction = text2num(params["dirs"])
|
||||
stored_dir = selected_direction
|
||||
update_decal_path()
|
||||
. = TRUE
|
||||
|
||||
/obj/item/airlock_painter/decal/debug
|
||||
name = "extreme decal painter"
|
||||
icon_state = "decal_sprayer_ex"
|
||||
|
||||
/obj/item/airlock_painter/decal/debug/Initialize()
|
||||
. = ..()
|
||||
ink = new /obj/item/toner/extreme(src)
|
||||
@@ -58,18 +58,22 @@
|
||||
/obj/item/wallframe/proc/after_attach(var/obj/O)
|
||||
transfer_fingerprints_to(O)
|
||||
|
||||
/obj/item/wallframe/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
// For camera-building borgs
|
||||
var/turf/T = get_step(get_turf(user), user.dir)
|
||||
if(iswallturf(T))
|
||||
T.attackby(src, user, params)
|
||||
/obj/item/wallframe/screwdriver_act(mob/user, obj/item/I)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
// For camera-building borgs
|
||||
var/turf/T = get_step(get_turf(user), user.dir)
|
||||
if(iswallturf(T))
|
||||
T.attackby(src, user)
|
||||
|
||||
/obj/item/wallframe/wrench_act(mob/user, obj/item/I)
|
||||
if(!custom_materials)
|
||||
return
|
||||
var/metal_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)]/MINERAL_MATERIAL_AMOUNT)
|
||||
var/glass_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)]/MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
if(istype(W, /obj/item/wrench) && (metal_amt || glass_amt))
|
||||
if(metal_amt || glass_amt)
|
||||
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
|
||||
if(metal_amt)
|
||||
new /obj/item/stack/sheet/metal(get_turf(src), metal_amt)
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/obj/item/binoculars
|
||||
name = "binoculars"
|
||||
desc = "Used for long-distance surveillance."
|
||||
item_state = "binoculars"
|
||||
icon_state = "binoculars"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/mob/listeningTo
|
||||
var/zoom_out_amt = 6
|
||||
var/zoom_amt = 10
|
||||
|
||||
/obj/item/binoculars/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/binoculars/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12)
|
||||
|
||||
/obj/item/binoculars/Destroy()
|
||||
listeningTo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/binoculars/proc/on_wield(obj/item/source, mob/user)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/unwield)
|
||||
listeningTo = user
|
||||
user.visible_message("<span class='notice'>[user] holds [src] up to [user.p_their()] eyes.</span>", "<span class='notice'>You hold [src] up to your eyes.</span>")
|
||||
item_state = "binoculars_wielded"
|
||||
user.regenerate_icons()
|
||||
if(!user?.client)
|
||||
return
|
||||
var/client/C = user.client
|
||||
var/_x = 0
|
||||
var/_y = 0
|
||||
switch(user.dir)
|
||||
if(NORTH)
|
||||
_y = zoom_amt
|
||||
if(EAST)
|
||||
_x = zoom_amt
|
||||
if(SOUTH)
|
||||
_y = -zoom_amt
|
||||
if(WEST)
|
||||
_x = -zoom_amt
|
||||
C.change_view(world.view + zoom_out_amt)
|
||||
C.pixel_x = world.icon_size*_x
|
||||
C.pixel_y = world.icon_size*_y
|
||||
/obj/item/binoculars/proc/on_unwield(obj/item/source, mob/user)
|
||||
unwield(user)
|
||||
|
||||
/obj/item/binoculars/proc/unwield(mob/user)
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
user.visible_message("<span class='notice'>[user] lowers [src].</span>", "<span class='notice'>You lower [src].</span>")
|
||||
item_state = "binoculars"
|
||||
user.regenerate_icons()
|
||||
if(user && user.client)
|
||||
user.regenerate_icons()
|
||||
var/client/C = user.client
|
||||
C.change_view(CONFIG_GET(string/default_view))
|
||||
user.client.pixel_x = 0
|
||||
user.client.pixel_y = 0
|
||||
@@ -0,0 +1,69 @@
|
||||
/obj/item/broom
|
||||
name = "broom"
|
||||
desc = "This is my BROOMSTICK! It can be used manually or braced with two hands to sweep items as you move. It has a telescopic handle for compact storage."
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "broom0"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
|
||||
force = 8
|
||||
throwforce = 10
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("swept", "brushed off", "bludgeoned", "whacked")
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/broom/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/broom/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12, icon_wielded="broom1")
|
||||
|
||||
/obj/item/broom/update_icon_state()
|
||||
icon_state = "broom0"
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/broom/proc/on_wield(obj/item/source, mob/user)
|
||||
to_chat(user, "<span class='notice'>You brace the [src] against the ground in a firm sweeping stance.</span>")
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/sweep)
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/broom/proc/on_unwield(obj/item/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/obj/item/broom/afterattack(atom/A, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
sweep(user, A, FALSE)
|
||||
|
||||
/obj/item/broom/proc/sweep(mob/user, atom/A, moving = TRUE)
|
||||
var/turf/target
|
||||
if (!moving)
|
||||
if (isturf(A))
|
||||
target = A
|
||||
else
|
||||
target = A.loc
|
||||
else
|
||||
target = user.loc
|
||||
if (!isturf(target))
|
||||
return
|
||||
if (locate(/obj/structure/table) in target.contents)
|
||||
return
|
||||
var/i = 0
|
||||
for(var/obj/item/garbage in target.contents)
|
||||
if(!garbage.anchored)
|
||||
garbage.Move(get_step(target, user.dir), user.dir)
|
||||
i++
|
||||
if(i >= 20)
|
||||
break
|
||||
if(i >= 1)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1)
|
||||
|
||||
/obj/item/broom/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) //bless you whoever fixes this copypasta
|
||||
J.put_in_cart(src, user)
|
||||
J.mybroom=src
|
||||
J.update_icon()
|
||||
@@ -83,7 +83,7 @@
|
||||
/obj/item/card/emag/bluespace
|
||||
name = "bluespace cryptographic sequencer"
|
||||
desc = "It's a blue card with a magnetic strip attached to some circuitry. It appears to have some sort of transmitter attached to it."
|
||||
color = rgb(40, 130, 255)
|
||||
icon_state = "emag_bs"
|
||||
prox_check = FALSE
|
||||
|
||||
/obj/item/card/emag/attack()
|
||||
@@ -166,6 +166,7 @@
|
||||
slot_flags = ITEM_SLOT_ID
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
var/id_type_name = "identification card"
|
||||
var/mining_points = 0 //For redeeming at mining equipment vendors
|
||||
var/list/access = list()
|
||||
var/registered_name = null // The name registered_name on the card
|
||||
@@ -174,6 +175,8 @@
|
||||
var/bank_support = ID_FREE_BANK_ACCOUNT
|
||||
var/datum/bank_account/registered_account
|
||||
var/obj/machinery/paystand/my_store
|
||||
var/uses_overlays = TRUE
|
||||
var/icon/cached_flat_icon
|
||||
|
||||
/obj/item/card/id/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -187,6 +190,15 @@
|
||||
if(ID_LOCKED_BANK_ACCOUNT)
|
||||
registered_account = new /datum/bank_account/remote/non_transferable(pick(GLOB.redacted_strings))
|
||||
|
||||
/obj/item/card/id/Destroy()
|
||||
if(bank_support == ID_LOCKED_BANK_ACCOUNT)
|
||||
QDEL_NULL(registered_account)
|
||||
else
|
||||
registered_account = null
|
||||
if(my_store)
|
||||
my_store.my_card = null
|
||||
my_store = null
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
@@ -311,20 +323,19 @@
|
||||
registered_account.bank_card_talk("<span class='warning'>ERROR: UNABLE TO LOGIN DUE TO SCHEDULED MAINTENANCE. MAINTENANCE IS SCHEDULED TO COMPLETE IN [(registered_account.withdrawDelay - world.time)/10] SECONDS.</span>", TRUE)
|
||||
return
|
||||
|
||||
var/amount_to_remove = FLOOR(input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null, 1)
|
||||
var/amount_to_remove = input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null
|
||||
|
||||
if(!amount_to_remove || amount_to_remove < 0)
|
||||
return
|
||||
if(!alt_click_can_use_id(user))
|
||||
return
|
||||
if(registered_account.adjust_money(-amount_to_remove))
|
||||
amount_to_remove = FLOOR(min(amount_to_remove, registered_account.account_balance), 1)
|
||||
if(amount_to_remove && registered_account.adjust_money(-amount_to_remove))
|
||||
var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove)
|
||||
user.put_in_hands(holochip)
|
||||
to_chat(user, "<span class='notice'>You withdraw [amount_to_remove] credits into a holochip.</span>")
|
||||
return
|
||||
else
|
||||
var/difference = amount_to_remove - registered_account.account_balance
|
||||
registered_account.bank_card_talk("<span class='warning'>ERROR: The linked account requires [difference] more credit\s to perform that withdrawal.</span>", TRUE)
|
||||
registered_account.bank_card_talk("<span class='warning'>ERROR: The linked account has no sufficient credits to perform that withdrawal.</span>", TRUE)
|
||||
|
||||
/obj/item/card/id/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -354,20 +365,38 @@
|
||||
/obj/item/card/id/RemoveID()
|
||||
return src
|
||||
|
||||
/*
|
||||
Usage:
|
||||
update_label()
|
||||
Sets the id name to whatever registered_name and assignment is
|
||||
/obj/item/card/id/update_overlays()
|
||||
. = ..()
|
||||
if(!uses_overlays)
|
||||
return
|
||||
cached_flat_icon = null
|
||||
var/job = assignment ? ckey(GetJobName()) : null
|
||||
if(registered_name == "Captain")
|
||||
job = "captain"
|
||||
if(registered_name && registered_name != "Captain")
|
||||
. += mutable_appearance(icon, "assigned")
|
||||
if(job)
|
||||
. += mutable_appearance(icon, "id[job]")
|
||||
|
||||
/obj/item/card/id/proc/get_cached_flat_icon()
|
||||
if(!cached_flat_icon)
|
||||
cached_flat_icon = getFlatIcon(src)
|
||||
return cached_flat_icon
|
||||
|
||||
|
||||
/obj/item/card/id/get_examine_string(mob/user, thats = FALSE)
|
||||
if(uses_overlays)
|
||||
return "[icon2html(get_cached_flat_icon(), user)] [thats? "That's ":""][get_examine_name(user)]" //displays all overlays in chat
|
||||
return ..()
|
||||
|
||||
update_label("John Doe", "Clowny")
|
||||
Properly formats the name and occupation and sets the id name to the arguments
|
||||
*/
|
||||
/obj/item/card/id/proc/update_label(newname, newjob)
|
||||
if(newname || newjob)
|
||||
name = "[(!newname) ? "identification card" : "[newname]'s ID Card"][(!newjob) ? "" : " ([newjob])"]"
|
||||
update_icon()
|
||||
return
|
||||
|
||||
name = "[(!registered_name) ? "identification card" : "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]"
|
||||
update_icon()
|
||||
|
||||
/obj/item/card/id/silver
|
||||
name = "silver identification card"
|
||||
@@ -380,6 +409,7 @@ update_label("John Doe", "Clowny")
|
||||
/obj/item/card/id/silver/reaper
|
||||
name = "Thirteen's ID Card (Reaper)"
|
||||
access = list(ACCESS_MAINT_TUNNELS)
|
||||
icon_state = "reaper"
|
||||
assignment = "Reaper"
|
||||
registered_name = "Thirteen"
|
||||
|
||||
@@ -531,7 +561,7 @@ update_label("John Doe", "Clowny")
|
||||
/obj/item/card/id/ert
|
||||
name = "\improper CentCom ID"
|
||||
desc = "An ERT ID card."
|
||||
icon_state = "centcom"
|
||||
icon_state = "ert_commander"
|
||||
registered_name = "Emergency Response Team Commander"
|
||||
assignment = "Emergency Response Team Commander"
|
||||
|
||||
@@ -540,6 +570,7 @@ update_label("John Doe", "Clowny")
|
||||
. = ..()
|
||||
|
||||
/obj/item/card/id/ert/Security
|
||||
icon_state = "ert_security"
|
||||
registered_name = "Security Response Officer"
|
||||
assignment = "Security Response Officer"
|
||||
|
||||
@@ -548,6 +579,7 @@ update_label("John Doe", "Clowny")
|
||||
. = ..()
|
||||
|
||||
/obj/item/card/id/ert/Engineer
|
||||
icon_state = "ert_engineer"
|
||||
registered_name = "Engineer Response Officer"
|
||||
assignment = "Engineer Response Officer"
|
||||
|
||||
@@ -556,6 +588,7 @@ update_label("John Doe", "Clowny")
|
||||
. = ..()
|
||||
|
||||
/obj/item/card/id/ert/Medical
|
||||
icon_state = "ert_medical"
|
||||
registered_name = "Medical Response Officer"
|
||||
assignment = "Medical Response Officer"
|
||||
|
||||
@@ -564,6 +597,7 @@ update_label("John Doe", "Clowny")
|
||||
. = ..()
|
||||
|
||||
/obj/item/card/id/ert/chaplain
|
||||
icon_state = "ert_chaplain"
|
||||
registered_name = "Religious Response Officer"
|
||||
assignment = "Religious Response Officer"
|
||||
|
||||
@@ -616,40 +650,49 @@ update_label("John Doe", "Clowny")
|
||||
. += "<span class='notice'>Your sentence is up! You're free!</span>"
|
||||
|
||||
/obj/item/card/id/prisoner/one
|
||||
icon_state = "prisoner_001"
|
||||
name = "Prisoner #13-001"
|
||||
registered_name = "Prisoner #13-001"
|
||||
|
||||
/obj/item/card/id/prisoner/two
|
||||
icon_state = "prisoner_002"
|
||||
name = "Prisoner #13-002"
|
||||
registered_name = "Prisoner #13-002"
|
||||
|
||||
/obj/item/card/id/prisoner/three
|
||||
icon_state = "prisoner_003"
|
||||
name = "Prisoner #13-003"
|
||||
registered_name = "Prisoner #13-003"
|
||||
|
||||
/obj/item/card/id/prisoner/four
|
||||
icon_state = "prisoner_004"
|
||||
name = "Prisoner #13-004"
|
||||
registered_name = "Prisoner #13-004"
|
||||
|
||||
/obj/item/card/id/prisoner/five
|
||||
icon_state = "prisoner_005"
|
||||
name = "Prisoner #13-005"
|
||||
registered_name = "Prisoner #13-005"
|
||||
|
||||
/obj/item/card/id/prisoner/six
|
||||
icon_state = "prisoner_006"
|
||||
name = "Prisoner #13-006"
|
||||
registered_name = "Prisoner #13-006"
|
||||
|
||||
/obj/item/card/id/prisoner/seven
|
||||
icon_state = "prisoner_007"
|
||||
name = "Prisoner #13-007"
|
||||
registered_name = "Prisoner #13-007"
|
||||
|
||||
/obj/item/card/id/mining
|
||||
name = "mining ID"
|
||||
icon_state = "retro"
|
||||
access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
|
||||
|
||||
/obj/item/card/id/away
|
||||
name = "a perfectly generic identification card"
|
||||
desc = "A perfectly generic identification card. Looks like it could use some flavor."
|
||||
icon_state = "retro"
|
||||
access = list(ACCESS_AWAY_GENERAL)
|
||||
|
||||
/obj/item/card/id/away/hotel
|
||||
@@ -692,6 +735,7 @@ update_label("John Doe", "Clowny")
|
||||
/obj/item/card/id/departmental_budget
|
||||
name = "departmental card (FUCK)"
|
||||
desc = "Provides access to the departmental budget."
|
||||
icon_state = "budgetcard"
|
||||
var/department_ID = ACCOUNT_CIV
|
||||
var/department_name = ACCOUNT_CIV_NAME
|
||||
|
||||
@@ -704,6 +748,7 @@ update_label("John Doe", "Clowny")
|
||||
B.bank_cards += src
|
||||
name = "departmental card ([department_name])"
|
||||
desc = "Provides access to the [department_name]."
|
||||
icon_state = "[lowertext(department_ID)]_budget"
|
||||
SSeconomy.dep_cards += src
|
||||
|
||||
/obj/item/card/id/departmental_budget/Destroy()
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
// CHAINSAW
|
||||
/obj/item/chainsaw
|
||||
name = "chainsaw"
|
||||
desc = "A versatile power tool. Useful for limbing trees and delimbing humans."
|
||||
icon_state = "chainsaw_off"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 13
|
||||
var/force_on = 24
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
throwforce = 13
|
||||
throw_speed = 2
|
||||
throw_range = 4
|
||||
custom_materials = list(/datum/material/iron=13000)
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = "swing_hit"
|
||||
sharpness = IS_SHARP
|
||||
actions_types = list(/datum/action/item_action/startchainsaw)
|
||||
tool_behaviour = TOOL_SAW
|
||||
toolspeed = 0.5
|
||||
var/on = FALSE
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/chainsaw/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/chainsaw/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 30, 100, 0, 'sound/weapons/chainsawhit.ogg', TRUE)
|
||||
AddComponent(/datum/component/two_handed, require_twohands=TRUE)
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/chainsaw/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/chainsaw/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/chainsaw/suicide_act(mob/living/carbon/user)
|
||||
if(on)
|
||||
user.visible_message("<span class='suicide'>[user] begins to tear [user.p_their()] head off with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/chainsawhit.ogg', 100, 1)
|
||||
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(myhead)
|
||||
myhead.dismember()
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] smashes [src] into [user.p_their()] neck, destroying [user.p_their()] esophagus! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/genhit1.ogg', 100, 1)
|
||||
return(BRUTELOSS)
|
||||
|
||||
/obj/item/chainsaw/attack_self(mob/user)
|
||||
on = !on
|
||||
to_chat(user, "As you pull the starting cord dangling from [src], [on ? "it begins to whirr." : "the chain stops moving."]")
|
||||
force = on ? force_on : initial(force)
|
||||
throwforce = on ? force_on : force
|
||||
update_icon()
|
||||
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
|
||||
butchering.butchering_enabled = on
|
||||
|
||||
if(on)
|
||||
hitsound = 'sound/weapons/chainsawhit.ogg'
|
||||
else
|
||||
hitsound = "swing_hit"
|
||||
|
||||
/obj/item/chainsaw/update_icon_state()
|
||||
icon_state = "chainsaw_[on ? "on" : "off"]"
|
||||
|
||||
/obj/item/chainsaw/get_dismemberment_chance()
|
||||
if(wielded)
|
||||
. = ..()
|
||||
|
||||
/obj/item/chainsaw/doomslayer
|
||||
name = "THE GREAT COMMUNICATOR"
|
||||
desc = "<span class='warning'>VRRRRRRR!!!</span>"
|
||||
armour_penetration = 100
|
||||
force_on = 30
|
||||
|
||||
/obj/item/chainsaw/doomslayer/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = 100
|
||||
return ..()
|
||||
|
||||
/obj/item/chainsaw/doomslayer/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(attack_type & ATTACK_TYPE_PROJECTILE)
|
||||
owner.visible_message("<span class='danger'>Ranged attacks just make [owner] angrier!</span>")
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
|
||||
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
|
||||
return ..()
|
||||
@@ -65,7 +65,7 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_blocker)
|
||||
|
||||
/obj/item/gun/energy/chrono_gun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
|
||||
/obj/item/gun/energy/chrono_gun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, stam_cost = 0)
|
||||
if(field)
|
||||
field_disconnect(field)
|
||||
..()
|
||||
|
||||
@@ -8,6 +8,9 @@ CIGARS
|
||||
SMOKING PIPES
|
||||
CHEAP LIGHTERS
|
||||
ZIPPO
|
||||
ROLLING PAPER
|
||||
VAPES
|
||||
BONGS
|
||||
|
||||
CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
*/
|
||||
@@ -506,7 +509,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
resistance_flags = FIRE_PROOF
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
grind_results = list(/datum/reagent/iron = 1, /datum/reagent/fuel = 5, /datum/reagent/oil = 5)
|
||||
custom_price = 55
|
||||
custom_price = PRICE_ALMOST_CHEAP
|
||||
|
||||
/obj/item/lighter/Initialize()
|
||||
. = ..()
|
||||
@@ -616,6 +619,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
desc = "A cheap-as-free lighter."
|
||||
icon_state = "lighter"
|
||||
fancy = FALSE
|
||||
custom_price = PRICE_CHEAP_AS_FREE
|
||||
overlay_list = list(
|
||||
"transp",
|
||||
"tall",
|
||||
@@ -790,6 +794,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
reagents.clear_reagents()
|
||||
|
||||
/obj/item/clothing/mask/vape/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(slot == SLOT_WEAR_MASK)
|
||||
if(!screw)
|
||||
to_chat(user, "<span class='notice'>You start puffing on the vape.</span>")
|
||||
@@ -799,6 +804,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
to_chat(user, "<span class='warning'>You need to close the cap first!</span>")
|
||||
|
||||
/obj/item/clothing/mask/vape/dropped(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.get_item_by_slot(SLOT_WEAR_MASK) == src)
|
||||
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
name = "Security Cameras (Computer Board)"
|
||||
build_path = /obj/machinery/computer/security
|
||||
|
||||
/obj/item/circuitboard/computer/security/shuttle
|
||||
name = "Shuttlelinking Security Cameras (Computer Board)"
|
||||
build_path = /obj/machinery/computer/security/shuttle
|
||||
|
||||
/obj/item/circuitboard/computer/xenobiology
|
||||
name = "circuit board (Xenobiology Console)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/xenobio
|
||||
@@ -112,9 +116,9 @@
|
||||
build_path = /obj/machinery/computer/cloning
|
||||
var/list/records = list()
|
||||
|
||||
/obj/item/circuitboard/computer/prototype_cloning
|
||||
/obj/item/circuitboard/computer/cloning/prototype
|
||||
name = "Prototype Cloning (Computer Board)"
|
||||
build_path = /obj/machinery/computer/prototype_cloning
|
||||
build_path = /obj/machinery/computer/cloning/prototype
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/battle
|
||||
name = "Arcade Battle (Computer Board)"
|
||||
@@ -293,6 +297,10 @@
|
||||
name = "Mining Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/mining
|
||||
|
||||
/obj/item/circuitboard/computer/snow_taxi
|
||||
name = "Snow Taxi (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/snow_taxi
|
||||
|
||||
/obj/item/circuitboard/computer/white_ship
|
||||
name = "White Ship (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship
|
||||
@@ -375,3 +383,11 @@
|
||||
/obj/item/circuitboard/computer/nanite_cloud_controller
|
||||
name = "Nanite Cloud Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/nanite_cloud_controller
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle/flight_control
|
||||
name = "Shuttle Flight Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/custom_shuttle
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle/docker
|
||||
name = "Shuttle Navigation Computer (Computer Board)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/shuttle_docker/custom
|
||||
|
||||
@@ -61,6 +61,14 @@
|
||||
name = "Experimental Clone Pod (Machine Board)"
|
||||
build_path = /obj/machinery/clonepod/experimental
|
||||
|
||||
/obj/item/circuitboard/machine/sheetifier
|
||||
name = "Sheet-meister 2000 (Machine Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/sheetifier
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/manipulator = 2,
|
||||
/obj/item/stock_parts/matter_bin = 2)
|
||||
|
||||
/obj/item/circuitboard/machine/abductor
|
||||
name = "alien board (Report This)"
|
||||
icon_state = "abductor_mod"
|
||||
@@ -692,6 +700,17 @@
|
||||
def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high)
|
||||
needs_anchored = FALSE
|
||||
|
||||
/obj/item/circuitboard/machine/chem_dispenser/apothecary
|
||||
name = "Apotechary Chem Dispenser (Machine Board)"
|
||||
build_path = /obj/machinery/chem_dispenser/apothecary
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/matter_bin = 1,
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stack/sheet/glass = 1,
|
||||
/obj/item/stock_parts/cell = 1)
|
||||
def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/upgraded/plus)
|
||||
|
||||
/obj/item/circuitboard/machine/chem_dispenser/drinks
|
||||
name = "Soda Dispenser (Machine Board)"
|
||||
build_path = /obj/machinery/chem_dispenser/drinks
|
||||
@@ -707,6 +726,10 @@
|
||||
def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high)
|
||||
needs_anchored = FALSE
|
||||
|
||||
/obj/item/circuitboard/machine/sleeper/party
|
||||
name = "Party Pod (Machine Board)"
|
||||
build_path = /obj/machinery/sleeper/party
|
||||
|
||||
/obj/item/circuitboard/machine/smoke_machine
|
||||
name = "Smoke Machine (Machine Board)"
|
||||
build_path = /obj/machinery/smoke_machine
|
||||
@@ -884,6 +907,16 @@
|
||||
name = "Departmental Protolathe - Service (Machine Board)"
|
||||
build_path = /obj/machinery/rnd/production/protolathe/department/service
|
||||
|
||||
/obj/item/circuitboard/machine/bepis
|
||||
name = "BEPIS Chamber (Machine Board)"
|
||||
build_path = /obj/machinery/rnd/bepis
|
||||
req_components = list(
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stock_parts/micro_laser = 1,
|
||||
/obj/item/stock_parts/scanning_module = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/techfab
|
||||
name = "\improper Techfab (Machine Board)"
|
||||
build_path = /obj/machinery/rnd/production/techfab
|
||||
@@ -1068,3 +1101,37 @@
|
||||
/obj/item/stock_parts/matter_bin = 3,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/hypnochair
|
||||
name = "Enhanced Interrogation Chamber (Machine Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/hypnochair
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/micro_laser = 2,
|
||||
/obj/item/stock_parts/scanning_module = 2
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/shuttle/engine
|
||||
name = "Thruster (Machine Board)"
|
||||
build_path = /obj/machinery/shuttle/engine
|
||||
req_components = list()
|
||||
|
||||
/obj/item/circuitboard/machine/shuttle/engine/plasma
|
||||
name = "Plasma Thruster (Machine Board)"
|
||||
build_path = /obj/machinery/shuttle/engine/plasma
|
||||
req_components = list(/obj/item/stock_parts/capacitor = 2,
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/stock_parts/micro_laser = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/shuttle/engine/void
|
||||
name = "Void Thruster (Machine Board)"
|
||||
build_path = /obj/machinery/shuttle/engine/void
|
||||
req_components = list(/obj/item/stock_parts/capacitor/quadratic = 2,
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/stock_parts/micro_laser/quadultra = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/shuttle/heater
|
||||
name = "Electronic Engine Heater (Machine Board)"
|
||||
build_path = /obj/machinery/atmospherics/components/unary/shuttle/heater
|
||||
req_components = list(/obj/item/stock_parts/micro_laser = 2,
|
||||
/obj/item/stock_parts/matter_bin = 1)
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
var/obj/effect/decal/cleanable/C = locate() in target
|
||||
qdel(C)
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
target.clean_blood()
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
target.wash_cream()
|
||||
return
|
||||
@@ -180,4 +181,4 @@
|
||||
name = "Canned Laughter"
|
||||
desc = "Just looking at this makes you want to giggle."
|
||||
icon_state = "laughter"
|
||||
list_reagents = list(/datum/reagent/consumable/laughter = 50)
|
||||
list_reagents = list(/datum/reagent/consumable/laughter = 50)
|
||||
|
||||
@@ -91,6 +91,11 @@
|
||||
|
||||
refill()
|
||||
|
||||
/obj/item/toy/crayon/examine(mob/user)
|
||||
. = ..()
|
||||
if(can_change_colour)
|
||||
. += "<span class='notice'>Ctrl-click [src] while it's on your person to quickly recolour it.</span>"
|
||||
|
||||
/obj/item/toy/crayon/proc/refill()
|
||||
if(charges == -1)
|
||||
charges_left = 100
|
||||
@@ -160,6 +165,12 @@
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/crayon/CtrlClick(mob/user)
|
||||
if(can_change_colour && !isturf(loc) && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
select_colour(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/crayon/proc/staticDrawables()
|
||||
|
||||
. = list()
|
||||
@@ -237,14 +248,7 @@
|
||||
else
|
||||
paint_mode = PAINT_NORMAL
|
||||
if("select_colour")
|
||||
if(can_change_colour)
|
||||
var/chosen_colour = input(usr,"","Choose Color",paint_color) as color|null
|
||||
|
||||
if (!isnull(chosen_colour))
|
||||
paint_color = chosen_colour
|
||||
. = TRUE
|
||||
else
|
||||
. = FALSE
|
||||
. = can_change_colour && select_colour(usr)
|
||||
if("enter_text")
|
||||
var/txt = stripped_input(usr,"Choose what to write.",
|
||||
"Scribbles",default = text_buffer)
|
||||
@@ -254,6 +258,13 @@
|
||||
drawtype = "a"
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/crayon/proc/select_colour(mob/user)
|
||||
var/chosen_colour = input(user, "", "Choose Color", paint_color) as color|null
|
||||
if (!isnull(chosen_colour) && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
paint_color = chosen_colour
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/toy/crayon/proc/crayon_text_strip(text)
|
||||
var/static/regex/crayon_r = new /regex(@"[^\w!?,.=%#&+\/\-]")
|
||||
return replacetext(lowertext(text), crayon_r, "")
|
||||
@@ -726,12 +737,7 @@
|
||||
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
if(istype(target, /obj/structure/window))
|
||||
var/obj/structure/window/W = target
|
||||
W.spraycan_paint(paint_color)
|
||||
else
|
||||
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
. = use_charges(user, 2)
|
||||
var/fraction = min(1, . / reagents.maximum_volume)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
var/on = FALSE //if the paddles are equipped (1) or on the defib (0)
|
||||
var/safety = TRUE //if you can zap people with the defibs on harm mode
|
||||
var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
|
||||
var/obj/item/twohanded/shockpaddles/paddles
|
||||
var/obj/item/shockpaddles/paddles
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/combat = FALSE //can we revive through space suits?
|
||||
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
|
||||
@@ -106,7 +106,6 @@
|
||||
|
||||
/obj/item/defibrillator/attackby(obj/item/W, mob/user, params)
|
||||
if(W == paddles)
|
||||
paddles.unwield()
|
||||
toggle_paddles()
|
||||
else if(istype(W, /obj/item/stock_parts/cell))
|
||||
var/obj/item/stock_parts/cell/C = W
|
||||
@@ -170,7 +169,6 @@
|
||||
return
|
||||
else
|
||||
//Remove from their hands and back onto the defib unit
|
||||
paddles.unwield()
|
||||
remove_paddles(user)
|
||||
|
||||
update_power()
|
||||
@@ -179,7 +177,7 @@
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/defibrillator/proc/make_paddles()
|
||||
return new /obj/item/twohanded/shockpaddles(src)
|
||||
return new /obj/item/shockpaddles(src)
|
||||
|
||||
/obj/item/defibrillator/equipped(mob/user, slot)
|
||||
..()
|
||||
@@ -256,13 +254,12 @@
|
||||
|
||||
/obj/item/defibrillator/compact/combat/loaded/attackby(obj/item/W, mob/user, params)
|
||||
if(W == paddles)
|
||||
paddles.unwield()
|
||||
toggle_paddles()
|
||||
return
|
||||
|
||||
//paddles
|
||||
|
||||
/obj/item/twohanded/shockpaddles
|
||||
/obj/item/shockpaddles
|
||||
name = "defibrillator paddles"
|
||||
desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
@@ -284,24 +281,48 @@
|
||||
var/grab_ghost = FALSE
|
||||
var/tlimit = DEFIB_TIME_LIMIT * 10
|
||||
var/disarm_shock_time = 10
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
var/mob/listeningTo
|
||||
/obj/item/shockpaddles/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
if(!req_defib)
|
||||
return //If it doesn't need a defib, just say it exists
|
||||
if (!loc || !istype(loc, /obj/item/defibrillator)) //To avoid weird issues from admin spawns
|
||||
return INITIALIZE_HINT_QDEL
|
||||
defib = loc
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/ComponentInitialize()
|
||||
/obj/item/shockpaddles/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/equipped(mob/user, slot)
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/shockpaddles/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/shockpaddles/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/shockpaddles/Destroy()
|
||||
defib = null
|
||||
return ..()
|
||||
|
||||
/obj/item/shockpaddles/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!req_defib)
|
||||
return
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/check_range)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/Moved()
|
||||
/obj/item/shockpaddles/Moved()
|
||||
. = ..()
|
||||
check_range()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/check_range()
|
||||
/obj/item/shockpaddles/proc/check_range()
|
||||
if(!req_defib || !defib)
|
||||
return
|
||||
if(!in_range(src,defib))
|
||||
@@ -312,7 +333,7 @@
|
||||
visible_message("<span class='notice'>[src] snap back into [defib].</span>")
|
||||
snap_back()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/recharge(var/time)
|
||||
/obj/item/shockpaddles/proc/recharge(var/time)
|
||||
if(req_defib || !time)
|
||||
return
|
||||
cooldown = TRUE
|
||||
@@ -324,57 +345,36 @@
|
||||
cooldown = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/New(mainunit)
|
||||
..()
|
||||
if(check_defib_exists(mainunit, src) && req_defib)
|
||||
defib = mainunit
|
||||
forceMove(defib)
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/update_icon_state()
|
||||
icon_state = "defibpaddles[wielded]"
|
||||
item_state = "defibpaddles[wielded]"
|
||||
if(cooldown)
|
||||
icon_state = "defibpaddles[wielded]_cooldown"
|
||||
|
||||
/obj/item/twohanded/shockpaddles/suicide_act(mob/user)
|
||||
/obj/item/shockpaddles/suicide_act(mob/user)
|
||||
user.visible_message("<span class='danger'>[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(req_defib)
|
||||
defib.deductcharge(revivecost)
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
return (OXYLOSS)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/dropped(mob/user)
|
||||
/obj/item/shockpaddles/update_icon_state()
|
||||
icon_state = "defibpaddles[wielded]"
|
||||
item_state = "defibpaddles[wielded]"
|
||||
if(cooldown)
|
||||
icon_state = "defibpaddles[wielded]_cooldown"
|
||||
|
||||
/obj/item/shockpaddles/dropped(mob/user)
|
||||
if(!req_defib)
|
||||
return ..()
|
||||
if(user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
var/obj/item/twohanded/offhand/O = user.get_inactive_held_item()
|
||||
if(istype(O))
|
||||
O.unwield()
|
||||
if(user != loc)
|
||||
to_chat(user, "<span class='notice'>The paddles snap back into the main unit.</span>")
|
||||
snap_back()
|
||||
return unwield(user)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/snap_back()
|
||||
/obj/item/shockpaddles/proc/snap_back()
|
||||
if(!defib)
|
||||
return
|
||||
defib.on = FALSE
|
||||
forceMove(defib)
|
||||
defib.update_power()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/check_defib_exists(mainunit, mob/living/carbon/M, obj/O)
|
||||
if(!req_defib)
|
||||
return TRUE //If it doesn't need a defib, just say it exists
|
||||
if (!mainunit || !istype(mainunit, /obj/item/defibrillator)) //To avoid weird issues from admin spawns
|
||||
qdel(O)
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/shockpaddles/attack(mob/M, mob/user)
|
||||
/obj/item/shockpaddles/attack(mob/M, mob/user)
|
||||
|
||||
if(busy)
|
||||
return
|
||||
@@ -426,18 +426,18 @@
|
||||
|
||||
do_help(H, user)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
|
||||
/obj/item/shockpaddles/proc/shock_touching(dmg, mob/H)
|
||||
if(!H.pulledby || !isliving(H.pulledby))
|
||||
return
|
||||
if(req_defib && defib.pullshocksafely)
|
||||
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
|
||||
return
|
||||
var/mob/living/M = H.pulledby
|
||||
if(M.electrocute_act(30, src))
|
||||
if(M.electrocute_act(30, H))
|
||||
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
|
||||
M.emote("scream")
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
|
||||
/obj/item/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
|
||||
if(req_defib && defib.safety)
|
||||
return
|
||||
if(!req_defib && !combat)
|
||||
@@ -465,7 +465,7 @@
|
||||
else
|
||||
recharge(60)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/do_harm(mob/living/carbon/H, mob/living/user)
|
||||
/obj/item/shockpaddles/proc/do_harm(mob/living/carbon/H, mob/living/user)
|
||||
if(req_defib && defib.safety)
|
||||
return
|
||||
if(!req_defib && !combat)
|
||||
@@ -520,7 +520,7 @@
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/do_help(mob/living/carbon/H, mob/living/user)
|
||||
/obj/item/shockpaddles/proc/do_help(mob/living/carbon/H, mob/living/user)
|
||||
user.visible_message("<span class='warning'>[user] begins to place [src] on [H]'s chest.</span>", "<span class='warning'>You begin to place [src] on [H]'s chest...</span>")
|
||||
busy = TRUE
|
||||
update_icon()
|
||||
@@ -677,14 +677,14 @@
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/cyborg
|
||||
/obj/item/shockpaddles/cyborg
|
||||
name = "cyborg defibrillator paddles"
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
req_defib = FALSE
|
||||
|
||||
/obj/item/twohanded/shockpaddles/cyborg/attack(mob/M, mob/user)
|
||||
/obj/item/shockpaddles/cyborg/attack(mob/M, mob/user)
|
||||
if(iscyborg(user))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.emagged)
|
||||
@@ -696,7 +696,7 @@
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/syndicate
|
||||
/obj/item/shockpaddles/syndicate
|
||||
name = "syndicate defibrillator paddles"
|
||||
desc = "A pair of paddles used to revive deceased operatives. It possesses both the ability to penetrate armor and to deliver powerful shocks offensively."
|
||||
combat = TRUE
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/flashlight
|
||||
name = "flashlight"
|
||||
desc = "A hand-held emergency light."
|
||||
custom_price = 100
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "flashlight"
|
||||
item_state = "flashlight"
|
||||
@@ -211,6 +211,7 @@
|
||||
light_color = "#CDDDFF"
|
||||
flashlight_power = 0.9
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
custom_price = PRICE_ALMOST_CHEAP
|
||||
|
||||
// the desk lamps are a bit special
|
||||
/obj/item/flashlight/lamp
|
||||
@@ -351,12 +352,13 @@
|
||||
brightness_on = 6 // luminosity when on
|
||||
light_color = "#FFAA44"
|
||||
flashlight_power = 0.8
|
||||
custom_price = PRICE_CHEAP
|
||||
|
||||
/obj/item/flashlight/lantern/jade
|
||||
name = "jade lantern"
|
||||
desc = "An ornate, green lantern."
|
||||
color = LIGHT_COLOR_GREEN
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/item/flashlight/slime
|
||||
gender = PLURAL
|
||||
@@ -429,7 +431,7 @@
|
||||
/obj/item/flashlight/glowstick
|
||||
name = "glowstick"
|
||||
desc = "A military-grade glowstick."
|
||||
custom_price = 50
|
||||
custom_price = PRICE_CHEAP_AS_FREE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
brightness_on = 4
|
||||
color = LIGHT_COLOR_GREEN
|
||||
|
||||
@@ -135,7 +135,8 @@
|
||||
outmsg = "<span class='warning'>You miss the lens of [C] with [src]!</span>"
|
||||
|
||||
//catpeople
|
||||
for(var/mob/living/carbon/human/H in view(1,targloc))
|
||||
var/list/viewers = fov_viewers(1,targloc)
|
||||
for(var/mob/living/carbon/human/H in viewers)
|
||||
if(!iscatperson(H) || H.incapacitated() || H.eye_blind )
|
||||
continue
|
||||
if(!H.lying)
|
||||
@@ -150,7 +151,7 @@
|
||||
H.visible_message("<span class='notice'>[H] stares at the light</span>","<span class = 'warning'> You stare at the light... </span>")
|
||||
|
||||
//cats!
|
||||
for(var/mob/living/simple_animal/pet/cat/C in view(1,targloc))
|
||||
for(var/mob/living/simple_animal/pet/cat/C in viewers)
|
||||
if(prob(50))
|
||||
C.visible_message("<span class='notice'>[C] pounces on the light!</span>","<span class='warning'>LIGHT!</span>")
|
||||
C.Move(targloc)
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
if(href_list["reset_radio_short"])
|
||||
pai.unshort_radio()
|
||||
if(href_list["setlaws"])
|
||||
var/newlaws = stripped_multiline_input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", MAX_MESSAGE_LEN)
|
||||
var/newlaws = stripped_multiline_input(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", "", MAX_MESSAGE_LEN)
|
||||
if(newlaws && pai)
|
||||
pai.add_supplied_law(0,newlaws)
|
||||
if(href_list["toggle_holo"])
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/obj/item/stack/circuit_stack
|
||||
name = "polycircuit aggregate"
|
||||
desc = "A dense, overdesigned cluster of electronics which attempted to function as a multipurpose circuit electronic. Circuits can be removed from it... if you don't bleed out in the process."
|
||||
icon_state = "circuit_mess"
|
||||
item_state = "rods"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_amount = 8
|
||||
var/circuit_type = /obj/item/electronics/airlock
|
||||
var/chosen_circuit = "airlock"
|
||||
|
||||
/obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it.
|
||||
to_chat(user, "<span class='warning'>You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.</span>")
|
||||
|
||||
/obj/item/stack/circuit_stack/attack_hand(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!user.get_inactive_held_item() == src)
|
||||
return ..()
|
||||
else
|
||||
if(zero_amount())
|
||||
return
|
||||
chosen_circuit = input("What type of circuit would you like to remove?", "Choose a Circuit Type", chosen_circuit) in list("airlock","firelock","fire alarm","air alarm","APC")
|
||||
if(zero_amount())
|
||||
return
|
||||
switch(chosen_circuit)
|
||||
if("airlock")
|
||||
circuit_type = /obj/item/electronics/airlock
|
||||
if("firelock")
|
||||
circuit_type = /obj/item/electronics/firelock
|
||||
if("fire alarm")
|
||||
circuit_type = /obj/item/electronics/firealarm
|
||||
if("air alarm")
|
||||
circuit_type = /obj/item/electronics/airalarm
|
||||
if("APC")
|
||||
circuit_type = /obj/item/electronics/apc
|
||||
to_chat(user, "<span class='notice'>You spot your circuit, and carefully attempt to remove it from [src], hold still!</span>")
|
||||
if(do_after(user, 30, target = user))
|
||||
if(!src || QDELETED(src))//Sanity Check.
|
||||
return
|
||||
var/returned_circuit = new circuit_type(src)
|
||||
user.put_in_hands(returned_circuit)
|
||||
use(1)
|
||||
if(!amount)
|
||||
to_chat(user, "<span class='notice'>You navigate the sharp edges of circuitry and remove the last board.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You navigate the sharp edges of circuitry and remove a single board from [src]</span>")
|
||||
else
|
||||
H.apply_damage(15, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
to_chat(user, "<span class='warning'>You give yourself a wicked cut on [src]'s many sharp corners and edges!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/stack/circuit_stack/full
|
||||
amount = 8
|
||||
@@ -258,6 +258,9 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
name = "\proper mini Integrated Subspace Transceiver "
|
||||
subspace_transmission = FALSE
|
||||
|
||||
/obj/item/radio/headset/silicon/pai/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/radio/headset/silicon/ai
|
||||
name = "\proper Integrated Subspace Transceiver "
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "station intercom"
|
||||
desc = "Talk through this."
|
||||
icon_state = "intercom"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
anchored = TRUE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
canhear_range = 2
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
/obj/item/radio/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/radio/interact(mob/user)
|
||||
if(unscrewed && !isAI(user))
|
||||
|
||||
@@ -6,12 +6,14 @@ T-RAY
|
||||
HEALTH ANALYZER
|
||||
GAS ANALYZER
|
||||
SLIME SCANNER
|
||||
NANITE SCANNER
|
||||
GENETICS SCANNER
|
||||
|
||||
*/
|
||||
/obj/item/t_scanner
|
||||
name = "\improper T-ray scanner"
|
||||
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
||||
custom_price = 150
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "t-ray0"
|
||||
var/on = FALSE
|
||||
@@ -650,9 +652,10 @@ SLIME SCANNER
|
||||
amount += inaccurate
|
||||
return DisplayTimeText(max(1,amount))
|
||||
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src)
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src, visible = TRUE)
|
||||
var/icon = target
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
if(visible)
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Results of analysis of [icon2html(icon, user)] [target].</span>")
|
||||
|
||||
var/list/airs = islist(mixture) ? mixture : list(mixture)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "scanner"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_price = 900
|
||||
custom_price = PRICE_ABOVE_EXPENSIVE
|
||||
|
||||
/obj/item/sensor_device/attack_self(mob/user)
|
||||
GLOB.crewmonitor.show(user,src) //Proc already exists, just had to call it
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Double-Bladed Energy Swords - Cheridan
|
||||
*/
|
||||
/obj/item/dualsaber
|
||||
icon_state = "dualsaber0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
name = "double-bladed energy sword"
|
||||
desc = "Handle with care."
|
||||
force = 3
|
||||
throwforce = 5
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
var/w_class_on = WEIGHT_CLASS_BULKY
|
||||
hitsound = "swing_hit"
|
||||
var/hitsound_on = 'sound/weapons/blade1.ogg'
|
||||
armour_penetration = 35
|
||||
var/saber_color = "green"
|
||||
light_color = "#00ff00"//green
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
|
||||
resistance_flags = FIRE_PROOF
|
||||
block_parry_data = /datum/block_parry_data/dual_esword
|
||||
var/hacked = FALSE
|
||||
/// Can this reflect all energy projectiles?
|
||||
var/can_reflect = TRUE
|
||||
var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD
|
||||
var/list/possible_colors = list("red", "blue", "green", "purple")
|
||||
var/list/rainbow_colors = list(LIGHT_COLOR_RED, LIGHT_COLOR_GREEN, LIGHT_COLOR_LIGHT_CYAN, LIGHT_COLOR_LAVENDER)
|
||||
var/spinnable = TRUE
|
||||
total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces.
|
||||
var/total_mass_on = 3.4
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
var/slowdown_wielded = 0
|
||||
|
||||
/datum/block_parry_data/dual_esword
|
||||
block_damage_absorption = 2
|
||||
block_damage_multiplier = 0.15
|
||||
block_damage_multiplier_override = list(
|
||||
ATTACK_TYPE_MELEE = 0.25
|
||||
)
|
||||
block_start_delay = 0 // instantaneous block
|
||||
block_stamina_cost_per_second = 2.5
|
||||
block_stamina_efficiency = 3
|
||||
block_lock_sprinting = TRUE
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
block_projectile_mitigation = 75
|
||||
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 8
|
||||
parry_time_spindown = 0
|
||||
// we want to signal to players the most dangerous phase, the time when automatic counterattack is a thing.
|
||||
parry_time_windup_visual_override = 1
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 4
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // esword users can attack while parrying.
|
||||
parry_time_perfect = 2 // first ds isn't perfect
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 10
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 25 // VERY generous
|
||||
parry_efficiency_perfect = 90
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_MELEE
|
||||
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
)
|
||||
|
||||
/obj/item/dualsaber/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/dualsaber/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=3, force_wielded=34, \
|
||||
wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
|
||||
|
||||
/obj/item/dualsaber/Initialize()
|
||||
. = ..()
|
||||
if(LAZYLEN(possible_colors))
|
||||
saber_color = pick(possible_colors)
|
||||
switch(saber_color)
|
||||
if("red")
|
||||
light_color = LIGHT_COLOR_RED
|
||||
if("green")
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
if("blue")
|
||||
light_color = LIGHT_COLOR_LIGHT_CYAN
|
||||
if("purple")
|
||||
light_color = LIGHT_COLOR_LAVENDER
|
||||
|
||||
/// Triggered on wield of two handed item
|
||||
/// Specific hulk checks due to reflection chance for balance issues and switches hitsounds.
|
||||
/obj/item/dualsaber/proc/on_wield(obj/item/source, mob/living/carbon/user)
|
||||
if(user.has_dna() && user.dna.check_mutation(HULK))
|
||||
to_chat(user, "<span class='warning'>You lack the grace to wield this!</span>")
|
||||
return COMPONENT_TWOHANDED_BLOCK_WIELD
|
||||
wielded = TRUE
|
||||
sharpness = IS_SHARP
|
||||
w_class = w_class_on
|
||||
total_mass = total_mass_on
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
slowdown += slowdown_wielded
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_light(brightness_on)
|
||||
AddElement(/datum/element/sword_point)
|
||||
item_flags |= (ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
|
||||
/// Triggered on unwield of two handed item
|
||||
/// switch hitsounds
|
||||
/obj/item/dualsaber/proc/on_unwield(obj/item/source, mob/living/carbon/user)
|
||||
sharpness = initial(sharpness)
|
||||
w_class = initial(w_class)
|
||||
total_mass = initial(total_mass)
|
||||
wielded = FALSE
|
||||
hitsound = "swing_hit"
|
||||
slowdown_wielded -= slowdown_wielded
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_light(0)
|
||||
RemoveElement(/datum/element/sword_point)
|
||||
item_flags &= ~(ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
|
||||
/obj/item/dualsaber/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/dualsaber/update_icon_state()
|
||||
if(wielded)
|
||||
icon_state = "dualsaber[saber_color][wielded]"
|
||||
else
|
||||
icon_state = "dualsaber0"
|
||||
clean_blood()
|
||||
|
||||
/obj/item/dualsaber/suicide_act(mob/living/carbon/user)
|
||||
if(wielded)
|
||||
user.visible_message("<span class='suicide'>[user] begins spinning way too fast! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)//stole from chainsaw code
|
||||
var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
B.organ_flags &= ~ORGAN_VITAL //this cant possibly be a good idea
|
||||
var/randdir
|
||||
for(var/i in 1 to 24)//like a headless chicken!
|
||||
if(user.is_holding(src))
|
||||
randdir = pick(GLOB.alldirs)
|
||||
user.Move(get_step(user, randdir),randdir)
|
||||
user.emote("spin")
|
||||
if (i == 3 && myhead)
|
||||
myhead.drop_limb()
|
||||
sleep(3)
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return OXYLOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] begins beating [user.p_them()]self to death with \the [src]'s handle! It probably would've been cooler if [user.p_they()] turned it on first!</span>")
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/dualsaber/attack(mob/target, mob/living/carbon/human/user)
|
||||
if(user.has_dna() && user.dna.check_mutation(HULK))
|
||||
to_chat(user, "<span class='warning'>You grip the blade too hard and accidentally drop it!</span>")
|
||||
user.dropItemToGround(src)
|
||||
return
|
||||
..()
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40))
|
||||
impale(user)
|
||||
return
|
||||
if(spinnable && (wielded) && prob(50))
|
||||
INVOKE_ASYNC(src, .proc/jedi_spin, user)
|
||||
|
||||
/obj/item/dualsaber/proc/jedi_spin(mob/living/user)
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
user.setDir(i)
|
||||
if(i == WEST)
|
||||
user.emote("flip")
|
||||
sleep(1)
|
||||
|
||||
/obj/item/dualsaber/proc/impale(mob/living/user)
|
||||
to_chat(user, "<span class='warning'>You twirl around a bit before losing your balance and impaling yourself on [src].</span>")
|
||||
if (force)
|
||||
user.take_bodypart_damage(20,25)
|
||||
else
|
||||
user.adjustStaminaLoss(25)
|
||||
|
||||
/obj/item/dualsaber/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!wielded)
|
||||
return NONE
|
||||
if(can_reflect && is_energy_reflectable_projectile(object) && (attack_type & ATTACK_TYPE_PROJECTILE))
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER //no you
|
||||
return BLOCK_SHOULD_REDIRECT | BLOCK_SUCCESS | BLOCK_REDIRECTED
|
||||
return ..()
|
||||
|
||||
/obj/item/dualsaber/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up
|
||||
if(wielded)
|
||||
to_chat(user, "<span class='warning'>You can't pick up such dangerous item with your meaty hands without losing fingers, better not to!</span>")
|
||||
return 1
|
||||
|
||||
/obj/item/dualsaber/process()
|
||||
if(wielded)
|
||||
if(hacked)
|
||||
rainbow_process()
|
||||
open_flame()
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/dualsaber/proc/rainbow_process()
|
||||
light_color = pick(rainbow_colors)
|
||||
|
||||
/obj/item/dualsaber/ignition_effect(atom/A, mob/user)
|
||||
// same as /obj/item/melee/transforming/energy, mostly
|
||||
if(!wielded)
|
||||
return ""
|
||||
var/in_mouth = ""
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.wear_mask)
|
||||
in_mouth = ", barely missing [user.p_their()] nose"
|
||||
. = "<span class='warning'>[user] swings [user.p_their()] [name][in_mouth]. [user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [A.name] in the process.</span>"
|
||||
playsound(loc, hitsound, get_clamped_volume(), 1, -1)
|
||||
add_fingerprint(user)
|
||||
// Light your candles while spinning around the room
|
||||
if(spinnable)
|
||||
INVOKE_ASYNC(src, .proc/jedi_spin, user)
|
||||
|
||||
/obj/item/dualsaber/green
|
||||
possible_colors = list("green")
|
||||
|
||||
/obj/item/dualsaber/red
|
||||
possible_colors = list("red")
|
||||
|
||||
/obj/item/dualsaber/blue
|
||||
possible_colors = list("blue")
|
||||
|
||||
/obj/item/dualsaber/purple
|
||||
possible_colors = list("purple")
|
||||
|
||||
/obj/item/dualsaber/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/multitool))
|
||||
if(!hacked)
|
||||
hacked = TRUE
|
||||
to_chat(user, "<span class='warning'>2XRNBW_ENGAGE</span>")
|
||||
saber_color = "rainbow"
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's starting to look like a triple rainbow - no, nevermind.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// HYPEREUTACTIC Blades /////////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/dualsaber/hypereutactic
|
||||
icon = 'icons/obj/1x2.dmi'
|
||||
icon_state = "hypereutactic"
|
||||
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
|
||||
item_state = "hypereutactic"
|
||||
inhand_x_dimension = 64
|
||||
inhand_y_dimension = 64
|
||||
name = "hypereutactic blade"
|
||||
desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
|
||||
force = 7
|
||||
hitsound_on = 'sound/weapons/nebhit.ogg'
|
||||
armour_penetration = 60
|
||||
light_color = "#37FFF7"
|
||||
rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
|
||||
spinnable = FALSE
|
||||
total_mass_on = 4
|
||||
slowdown_wielded = 1
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=7, force_wielded=40, \
|
||||
wieldsound='sound/weapons/nebon.ogg', unwieldsound='sound/weapons/nebhit.ogg')
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/update_icon_state()
|
||||
return
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/update_overlays()
|
||||
. = ..()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "hypereutactic_blade")
|
||||
var/mutable_appearance/gem_overlay = mutable_appearance(icon, "hypereutactic_gem")
|
||||
|
||||
if(light_color)
|
||||
blade_overlay.color = light_color
|
||||
gem_overlay.color = light_color
|
||||
|
||||
. += gem_overlay
|
||||
|
||||
if(wielded)
|
||||
. += blade_overlay
|
||||
|
||||
clean_blood()
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
|
||||
if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
|
||||
return
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
update_light()
|
||||
return TRUE
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
if(isinhands)
|
||||
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
|
||||
gem_inhand.color = light_color
|
||||
. += gem_inhand
|
||||
if(wielded)
|
||||
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
|
||||
blade_inhand.color = light_color
|
||||
. += blade_inhand
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/examine(mob/user)
|
||||
. = ..()
|
||||
if(!hacked)
|
||||
. += "<span class='notice'>Alt-click to recolor it.</span>"
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/rainbow_process()
|
||||
. = ..()
|
||||
update_icon()
|
||||
update_light()
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/chaplain
|
||||
name = "divine lightblade"
|
||||
desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
|
||||
force = 5
|
||||
block_chance = 50
|
||||
armour_penetration = 0
|
||||
var/chaplain_spawnable = TRUE
|
||||
can_reflect = FALSE
|
||||
obj_flags = UNIQUE_RENAME
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/chaplain/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=20, \
|
||||
wieldsound='sound/weapons/nebon.ogg', unwieldsound='sound/weapons/nebhit.ogg')
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
|
||||
@@ -0,0 +1,263 @@
|
||||
|
||||
/obj/item/electrostaff
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "electrostaff"
|
||||
item_state = "electrostaff"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
name = "riot suppression electrostaff"
|
||||
desc = "A large quarterstaff, with massive silver electrodes mounted at the end."
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
|
||||
throwforce = 15 //if you are a madman and finish someone off with this, power to you.
|
||||
throw_speed = 1
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
attack_verb = list("struck", "beaten", "thwacked", "pulped")
|
||||
total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on)
|
||||
block_parry_data = /datum/block_parry_data/electrostaff
|
||||
var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high
|
||||
var/on = FALSE
|
||||
var/can_block_projectiles = FALSE //can't block guns
|
||||
var/lethal_cost = 400 //10000/400*20 = 500. decent enough?
|
||||
var/lethal_damage = 20
|
||||
var/lethal_stam_cost = 4
|
||||
var/stun_cost = 333 //10000/333*25 = 750. stunbatons are at time of writing 10000/1000*49 = 490.
|
||||
var/stun_status_effect = STATUS_EFFECT_ELECTROSTAFF //a small slowdown effect
|
||||
var/stun_stamdmg = 40
|
||||
var/stun_status_duration = 25
|
||||
var/stun_stam_cost = 3.5
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
// haha security desword time /s
|
||||
/datum/block_parry_data/electrostaff
|
||||
block_damage_absorption = 0
|
||||
block_damage_multiplier = 1
|
||||
can_block_attack_types = ~ATTACK_TYPE_PROJECTILE // only able to parry non projectiles
|
||||
block_damage_multiplier_override = list(
|
||||
TEXT_ATTACK_TYPE_MELEE = 0.5, // only useful on melee and unarmed
|
||||
TEXT_ATTACK_TYPE_UNARMED = 0.3
|
||||
)
|
||||
block_start_delay = 0.5 // near instantaneous block
|
||||
block_stamina_cost_per_second = 3
|
||||
block_stamina_efficiency = 2 // haha this is a horrible idea
|
||||
// more slowdown that deswords because security
|
||||
block_slowdown = 2
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
|
||||
parry_time_windup = 1
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_time_spindown_visual_override = 1
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING // no attacking while parrying
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 0.5
|
||||
parry_efficiency_perfect = 100
|
||||
parry_imperfect_falloff_percent = 1
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 45 // really crappy vs projectiles
|
||||
)
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1 // extremely harsh window for projectiles
|
||||
)
|
||||
// not extremely punishing to fail, but no spamming the parry.
|
||||
parry_cooldown = 2.5 SECONDS
|
||||
parry_failed_stagger_duration = 1.5 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS
|
||||
|
||||
/obj/item/electrostaff/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ispath(cell))
|
||||
cell = new cell
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/turn_on)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/turn_off)
|
||||
|
||||
/obj/item/electrostaff/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=2, wieldsound="sparks", unwieldsound="sparks")
|
||||
|
||||
/obj/item/electrostaff/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
QDEL_NULL(cell)
|
||||
return ..()
|
||||
|
||||
/obj/item/electrostaff/get_cell()
|
||||
. = cell
|
||||
if(iscyborg(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
. = R.get_cell()
|
||||
|
||||
/obj/item/electrostaff/proc/min_hitcost()
|
||||
return min(stun_cost, lethal_cost)
|
||||
|
||||
/obj/item/electrostaff/proc/turn_on(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
item_flags |= (ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
if(!cell)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] has no cell.</span>")
|
||||
return
|
||||
if(cell.charge < min_hitcost())
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] is out of charge.</span>")
|
||||
return
|
||||
on = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You turn [src] on.</span>")
|
||||
|
||||
/obj/item/electrostaff/proc/turn_off(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
item_flags &= ~(ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You turn [src] off.</span>")
|
||||
on = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/electrostaff/update_icon_state()
|
||||
if(!wielded)
|
||||
icon_state = item_state = "electrostaff"
|
||||
else
|
||||
icon_state = item_state = (on? "electrostaff_1" : "electrostaff_0")
|
||||
set_light(7, on? 1 : 0, LIGHT_COLOR_CYAN)
|
||||
|
||||
/obj/item/electrostaff/examine(mob/living/user)
|
||||
. = ..()
|
||||
if(cell)
|
||||
. += "<span class='notice'>The cell charge is [round(cell.percent())]%.</span>"
|
||||
else
|
||||
. += "<span class='warning'>There is no cell installed!</span>"
|
||||
|
||||
/obj/item/electrostaff/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/stock_parts/cell))
|
||||
var/obj/item/stock_parts/cell/C = W
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>[src] already has a cell!</span>")
|
||||
else
|
||||
if(C.maxcharge < min_hit_cost())
|
||||
to_chat(user, "<span class='notice'>[src] requires a higher capacity cell.</span>")
|
||||
return
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
cell = C
|
||||
to_chat(user, "<span class='notice'>You install a cell in [src].</span>")
|
||||
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(cell)
|
||||
cell.update_icon()
|
||||
cell.forceMove(get_turf(src))
|
||||
cell = null
|
||||
to_chat(user, "<span class='notice'>You remove the cell from [src].</span>")
|
||||
turn_off(user, TRUE)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/electrostaff/process()
|
||||
deductcharge(50) //Wasteful!
|
||||
|
||||
/obj/item/electrostaff/proc/min_hit_cost()
|
||||
return min(lethal_cost, stun_cost)
|
||||
|
||||
/obj/item/electrostaff/proc/deductcharge(amount)
|
||||
var/obj/item/stock_parts/cell/C = get_cell()
|
||||
if(!C)
|
||||
turn_off()
|
||||
return FALSE
|
||||
C.use(min(amount, C.charge))
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
if(C.charge < min_hit_cost())
|
||||
turn_off()
|
||||
|
||||
/obj/item/electrostaff/attack(mob/living/target, mob/living/user)
|
||||
if(IS_STAMCRIT(user))//CIT CHANGE - makes it impossible to baton in stamina softcrit
|
||||
to_chat(user, "<span class='danger'>You're too exhausted to use [src] properly.</span>")//CIT CHANGE - ditto
|
||||
return //CIT CHANGE - ditto
|
||||
if(on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
clowning_around(user) //ouch!
|
||||
return
|
||||
if(iscyborg(target))
|
||||
return ..()
|
||||
var/list/return_list = list()
|
||||
if(target.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; run_block() handles that
|
||||
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(user.a_intent != INTENT_HARM)
|
||||
if(stun_act(target, user, null, return_list))
|
||||
user.do_attack_animation(target)
|
||||
user.adjustStaminaLossBuffered(stun_stam_cost)
|
||||
return
|
||||
else if(!harm_act(target, user, null, return_list))
|
||||
return ..() //if you can't fry them just beat them with it
|
||||
else //we did harm act them
|
||||
user.do_attack_animation(target)
|
||||
user.adjustStaminaLossBuffered(lethal_stam_cost)
|
||||
|
||||
/obj/item/electrostaff/proc/stun_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE, list/block_return = list())
|
||||
var/stunforce = block_calculate_resultant_damage(stun_stamdmg, block_return)
|
||||
if(!no_charge_and_force)
|
||||
if(!on)
|
||||
target.visible_message("<span class='warning'>[user] has bapped [target] with [src]. Luckily it was off.</span>", \
|
||||
"<span class='warning'>[user] has bapped you with [src]. Luckily it was off</span>")
|
||||
turn_off() //if it wasn't already off
|
||||
return FALSE
|
||||
var/obj/item/stock_parts/cell/C = get_cell()
|
||||
var/chargeleft = C.charge
|
||||
deductcharge(stun_cost)
|
||||
if(QDELETED(src) || QDELETED(C)) //boom
|
||||
return FALSE
|
||||
if(chargeleft < stun_cost)
|
||||
stunforce *= round(chargeleft/stun_cost, 0.1)
|
||||
target.adjustStaminaLoss(stunforce)
|
||||
target.apply_effect(EFFECT_STUTTER, stunforce)
|
||||
SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.visible_message("<span class='danger'>[user] has shocked [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has shocked you with [src]!</span>")
|
||||
log_combat(user, target, "stunned with an electrostaff")
|
||||
playsound(src, 'sound/weapons/staff.ogg', 50, 1, -1)
|
||||
target.apply_status_effect(stun_status_effect, stun_status_duration)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.forcesay(GLOB.hit_appends)
|
||||
return TRUE
|
||||
|
||||
/obj/item/electrostaff/proc/harm_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE, list/block_return = list())
|
||||
var/lethal_force = block_calculate_resultant_damage(lethal_damage, block_return)
|
||||
if(!no_charge_and_force)
|
||||
if(!on)
|
||||
return FALSE //standard item attack
|
||||
var/obj/item/stock_parts/cell/C = get_cell()
|
||||
var/chargeleft = C.charge
|
||||
deductcharge(lethal_cost)
|
||||
if(QDELETED(src) || QDELETED(C)) //boom
|
||||
return FALSE
|
||||
if(chargeleft < stun_cost)
|
||||
lethal_force *= round(chargeleft/lethal_cost, 0.1)
|
||||
target.adjustFireLoss(lethal_force) //good against ointment spam
|
||||
SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.visible_message("<span class='danger'>[user] has seared [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has seared you with [src]!</span>")
|
||||
log_combat(user, target, "burned with an electrostaff")
|
||||
playsound(src, 'sound/weapons/sear.ogg', 50, 1, -1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/electrostaff/proc/clowning_around(mob/living/user)
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
harm_act(user, user, TRUE)
|
||||
stun_act(user, user, TRUE)
|
||||
deductcharge(lethal_cost)
|
||||
|
||||
/obj/item/electrostaff/emp_act(severity)
|
||||
. = ..()
|
||||
if (!(. & EMP_PROTECT_SELF))
|
||||
turn_off()
|
||||
if(!iscyborg(loc))
|
||||
deductcharge(1000 / severity, TRUE, FALSE)
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Fireaxe
|
||||
*/
|
||||
/obj/item/fireaxe // DEM AXES MAN, marker -Agouri
|
||||
icon_state = "fireaxe0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/axes_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/axes_righthand.dmi'
|
||||
name = "fire axe"
|
||||
desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?"
|
||||
force = 5
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/fireaxe/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/fireaxe/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 100, 80, 0 , hitsound) //axes are not known for being precision butchering tools
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=24, icon_wielded="fireaxe1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/fireaxe/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/fireaxe/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/fireaxe/update_icon_state()
|
||||
icon_state = "fireaxe0"
|
||||
|
||||
/obj/item/fireaxe/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] axes [user.p_them()]self from head to toe! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/fireaxe/afterattack(atom/A, mob/living/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity || !wielded || IS_STAMCRIT(user))
|
||||
return
|
||||
if(istype(A, /obj/structure/window)) //destroys windows and grilles in one hit (or more if it has a ton of health like plasmaglass)
|
||||
var/obj/structure/window/W = A
|
||||
W.take_damage(200, BRUTE, "melee", 0)
|
||||
else if(istype(A, /obj/structure/grille))
|
||||
var/obj/structure/grille/G = A
|
||||
G.take_damage(40, BRUTE, "melee", 0)
|
||||
|
||||
/*
|
||||
* Bone Axe
|
||||
*/
|
||||
/obj/item/fireaxe/boneaxe // Blatant imitation of the fireaxe, but made out of bone.
|
||||
icon_state = "bone_axe0"
|
||||
name = "bone axe"
|
||||
desc = "A large, vicious axe crafted out of several sharpened bone plates and crudely tied together. Made of monsters, by killing monsters, for killing monsters."
|
||||
|
||||
/obj/item/fireaxe/boneaxe/update_icon_state()
|
||||
icon_state = "bone_axe0"
|
||||
|
||||
/obj/item/fireaxe/boneaxe/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=23, icon_wielded="bone_axe1")
|
||||
@@ -196,9 +196,8 @@
|
||||
sleep(1)
|
||||
previousturf = T
|
||||
operating = FALSE
|
||||
for(var/mob/M in viewers(1, loc))
|
||||
if((M.client && M.machine == src))
|
||||
attack_self(M)
|
||||
if(usr.machine == src)
|
||||
attack_self(usr)
|
||||
|
||||
|
||||
/obj/item/flamethrower/proc/default_ignite(turf/target, release_amount = 0.05)
|
||||
|
||||
@@ -510,7 +510,7 @@
|
||||
oneuse = FALSE
|
||||
remarks = list("So that is how icing is made!", "Placing fruit on top? How simple...", "Huh layering cake seems harder then this...", "This book smells like candy", "A clown must have made this page, or they forgot to spell check it before printing...", "Wait, a way to cook slime to be safe?")
|
||||
|
||||
/obj/item/book/granter/crafting_recipe/coldcooking //IceCream
|
||||
/obj/item/book/granter/crafting_recipe/coldcooking //Icecream
|
||||
name = "Cooking with Ice"
|
||||
desc = "A cook book that teaches you many old icecream treats."
|
||||
crafting_recipe_types = list(/datum/crafting_recipe/food/banana_split, /datum/crafting_recipe/food/root_float, /datum/crafting_recipe/food/bluecharrie_float, /datum/crafting_recipe/food/charrie_float)
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
name = "antigravity grenade"
|
||||
icon_state = "emp"
|
||||
item_state = "emp"
|
||||
|
||||
|
||||
var/range = 7
|
||||
var/forced_value = 0
|
||||
var/duration = 300
|
||||
|
||||
/obj/item/grenade/antigravity/prime()
|
||||
/obj/item/grenade/antigravity/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
|
||||
|
||||
for(var/turf/T in view(range,src))
|
||||
var/datum/component/C = T.AddComponent(/datum/component/forced_gravity,forced_value)
|
||||
QDEL_IN(C,duration)
|
||||
|
||||
T.AddElement(/datum/element/forced_gravity, forced_value)
|
||||
addtimer(CALLBACK(T, /datum/.proc/_RemoveElement, list(forced_value)), duration)
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
to_chat(user, "<span class='notice'>You add [A] to the [initial(name)] assembly.</span>")
|
||||
|
||||
else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil))
|
||||
if (I.use_tool(src, user, 0, 1, max_level = JOB_SKILL_BASIC))
|
||||
if (I.use_tool(src, user, 0, 1, skill_gain_mult = TRIVIAL_USE_TOOL_MULT))
|
||||
det_time = 50 // In case the cable_coil was removed and readded.
|
||||
stage_change(WIRED)
|
||||
to_chat(user, "<span class='notice'>You rig the [initial(name)] assembly.</span>")
|
||||
@@ -174,10 +174,11 @@
|
||||
message_admins(message)
|
||||
user.log_message("primed [src] ([reagent_string])",LOG_GAME)
|
||||
|
||||
/obj/item/grenade/chem_grenade/prime()
|
||||
/obj/item/grenade/chem_grenade/prime(mob/living/lanced_by)
|
||||
if(stage != READY)
|
||||
return FALSE
|
||||
|
||||
. = ..()
|
||||
var/list/datum/reagents/reactants = list()
|
||||
for(var/obj/item/reagent_containers/glass/G in beakers)
|
||||
reactants += G.reagents
|
||||
@@ -217,7 +218,7 @@
|
||||
ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
|
||||
threatscale = 1.1 // 10% more effective.
|
||||
|
||||
/obj/item/grenade/chem_grenade/large/prime()
|
||||
/obj/item/grenade/chem_grenade/large/prime(mob/living/lanced_by)
|
||||
if(stage != READY)
|
||||
return FALSE
|
||||
|
||||
@@ -286,7 +287,7 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/grenade/chem_grenade/adv_release/prime()
|
||||
/obj/item/grenade/chem_grenade/adv_release/prime(mob/living/lanced_by)
|
||||
if(stage != READY)
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
var/max_spawned = 8
|
||||
var/segment_chance = 35
|
||||
|
||||
/obj/item/grenade/clusterbuster/prime()
|
||||
/obj/item/grenade/clusterbuster/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
var/numspawned = rand(min_spawned,max_spawned)
|
||||
var/again = 0
|
||||
@@ -59,7 +60,7 @@
|
||||
step_away(src,loc)
|
||||
addtimer(CALLBACK(src, .proc/prime), rand(15,60))
|
||||
|
||||
/obj/item/grenade/clusterbuster/segment/prime()
|
||||
/obj/item/grenade/clusterbuster/segment/prime(mob/living/lanced_by)
|
||||
new payload_spawner(drop_location(), payload, rand(min_spawned,max_spawned))
|
||||
playsound(src, prime_sound, 75, 1, -3)
|
||||
qdel(src)
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
icon_state = "emp"
|
||||
item_state = "emp"
|
||||
|
||||
/obj/item/grenade/empgrenade/prime()
|
||||
/obj/item/grenade/empgrenade/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
empulse(src, 4, 10)
|
||||
qdel(src)
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
var/flashbang_range = 7 //how many tiles away the mob will be stunned.
|
||||
|
||||
/obj/item/grenade/flashbang/prime()
|
||||
/obj/item/grenade/flashbang/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
var/flashbang_turf = get_turf(src)
|
||||
if(!flashbang_turf)
|
||||
@@ -42,3 +43,92 @@
|
||||
var/distance = get_dist(get_turf(M), source)
|
||||
if(M.flash_act(affect_silicon = 1))
|
||||
M.DefaultCombatKnockdown(max(200/max(1,distance), 60))
|
||||
|
||||
/obj/item/grenade/stingbang
|
||||
name = "stingbang"
|
||||
icon_state = "timeg"
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
var/flashbang_range = 1 //how many tiles away the mob will be stunned.
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball
|
||||
shrapnel_radius = 5
|
||||
custom_premium_price = 700 // mostly gotten through cargo, but throw in one for the sec vendor ;)
|
||||
|
||||
/obj/item/grenade/stingbang/mega
|
||||
name = "mega stingbang"
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/mega
|
||||
shrapnel_radius = 12
|
||||
|
||||
/obj/item/grenade/stingbang/prime(mob/living/lanced_by)
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
var/obj/item/bodypart/B = C.get_holding_bodypart_of_item(src)
|
||||
if(B)
|
||||
C.visible_message("<b><span class='danger'>[src] goes off in [C]'s hand, blowing [C.p_their()] [B.name] to bloody shreds!</span></b>", "<span class='userdanger'>[src] goes off in your hand, blowing your [B.name] to bloody shreds!</span>")
|
||||
B.dismember()
|
||||
|
||||
. = ..()
|
||||
update_mob()
|
||||
var/flashbang_turf = get_turf(src)
|
||||
if(!flashbang_turf)
|
||||
return
|
||||
do_sparks(rand(5, 9), FALSE, src)
|
||||
playsound(flashbang_turf, 'sound/weapons/flashbang.ogg', 50, TRUE, 8, 0.9)
|
||||
new /obj/effect/dummy/lighting_obj (flashbang_turf, LIGHT_COLOR_WHITE, (flashbang_range + 2), 2, 1)
|
||||
for(var/mob/living/M in get_hearers_in_view(flashbang_range, flashbang_turf))
|
||||
pop(get_turf(M), M)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/stingbang/proc/pop(turf/T , mob/living/M)
|
||||
if(M.stat == DEAD) //They're dead!
|
||||
return
|
||||
M.show_message("<span class='warning'>POP</span>", MSG_AUDIBLE)
|
||||
var/distance = max(0,get_dist(get_turf(src),T))
|
||||
|
||||
//Flash
|
||||
if(M.flash_act(affect_silicon = 1))
|
||||
M.Paralyze(max(10/max(1,distance), 5))
|
||||
M.Knockdown(max(100/max(1,distance), 60))
|
||||
|
||||
//Bang
|
||||
if(!distance || loc == M || loc == M.loc)
|
||||
M.Paralyze(20)
|
||||
M.Knockdown(200)
|
||||
M.soundbang_act(1, 200, 10, 15)
|
||||
if(M.apply_damages(10, 10))
|
||||
to_chat(M, "<span class='userdanger'>The blast from \the [src] bruises and burns you!</span>")
|
||||
|
||||
// only checking if they're on top of the tile, cause being one tile over will be its own punishment
|
||||
|
||||
// Grenade that releases more shrapnel the more times you use it in hand between priming and detonation (sorta like the 9bang from MW3), for admin goofs
|
||||
/obj/item/grenade/primer
|
||||
name = "rotfrag grenade"
|
||||
desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases shrapnel shards."
|
||||
icon_state = "timeg"
|
||||
item_state = "flashbang"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
var/rots_per_mag = 3 /// how many times we need to "rotate" the charge in hand per extra tile of magnitude
|
||||
shrapnel_type = /obj/item/projectile/bullet/shrapnel
|
||||
var/rots = 1 /// how many times we've "rotated" the charge
|
||||
|
||||
/obj/item/grenade/primer/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
rots++
|
||||
user.changeNext_move(CLICK_CD_RAPID)
|
||||
|
||||
/obj/item/grenade/primer/prime(mob/living/lanced_by)
|
||||
shrapnel_radius = round(rots / rots_per_mag)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/primer/stingbang
|
||||
name = "rotsting"
|
||||
desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases stingballs."
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
rots_per_mag = 2
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball
|
||||
|
||||
@@ -45,12 +45,13 @@
|
||||
|
||||
/obj/item/grenade/iedcasing/attack_self(mob/user) //
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
if(!botch_check(user))
|
||||
to_chat(user, "<span class='warning'>You light the [name]!</span>")
|
||||
cut_overlay("improvised_grenade_filled")
|
||||
preprime(user, null, FALSE)
|
||||
|
||||
/obj/item/grenade/iedcasing/prime() //Blowing that can up
|
||||
/obj/item/grenade/iedcasing/prime(mob/living/lanced_by) //Blowing that can up
|
||||
. = ..()
|
||||
update_mob()
|
||||
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
|
||||
qdel(src)
|
||||
|
||||
@@ -17,10 +17,31 @@
|
||||
var/det_time = 50
|
||||
var/display_timer = 1
|
||||
var/clumsy_check = GRENADE_CLUMSY_FUMBLE
|
||||
var/sticky = FALSE
|
||||
// I moved the explosion vars and behavior to base grenades because we want all grenades to call [/obj/item/grenade/proc/prime] so we can send COMSIG_GRENADE_PRIME
|
||||
///how big of a devastation explosion radius on prime
|
||||
var/ex_dev = 0
|
||||
///how big of a heavy explosion radius on prime
|
||||
var/ex_heavy = 0
|
||||
///how big of a light explosion radius on prime
|
||||
var/ex_light = 0
|
||||
///how big of a flame explosion radius on prime
|
||||
var/ex_flame = 0
|
||||
|
||||
// dealing with creating a [/datum/component/pellet_cloud] on prime
|
||||
/// if set, will spew out projectiles of this type
|
||||
var/shrapnel_type
|
||||
/// the higher this number, the more projectiles are created as shrapnel
|
||||
var/shrapnel_radius
|
||||
var/shrapnel_initialized
|
||||
|
||||
/obj/item/grenade/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] primes [src], then eats it! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(shrapnel_type && shrapnel_radius)
|
||||
shrapnel_initialized = TRUE
|
||||
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_radius)
|
||||
playsound(src, 'sound/items/eatfood.ogg', 50, 1)
|
||||
SEND_SIGNAL(src, COMSIG_GRENADE_ARMED, det_time)
|
||||
preprime(user, det_time)
|
||||
user.transferItemToLoc(src, user, TRUE)//>eat a grenade set to 5 seconds >rush captain
|
||||
sleep(det_time)//so you dont die instantly
|
||||
@@ -32,19 +53,21 @@
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
|
||||
/obj/item/grenade/proc/botch_check(mob/living/carbon/human/user)
|
||||
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
|
||||
if(clumsy)
|
||||
if(clumsy_check == GRENADE_CLUMSY_FUMBLE && prob(50))
|
||||
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
|
||||
preprime(user, 5, FALSE)
|
||||
return FALSE
|
||||
return TRUE
|
||||
else if(clumsy_check == GRENADE_NONCLUMSY_FUMBLE && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)))
|
||||
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
|
||||
preprime(user, 5, FALSE)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
else if(sticky && prob(50)) // to add risk to sticky tape grenade cheese, no return cause we still prime as normal after
|
||||
to_chat(user, "<span class='warning'>What the... [src] is stuck to your hand!</span>")
|
||||
ADD_TRAIT(src, TRAIT_NODROP, STICKY_NODROP)
|
||||
|
||||
/obj/item/grenade/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -56,8 +79,16 @@
|
||||
|
||||
|
||||
/obj/item/grenade/attack_self(mob/user)
|
||||
if(HAS_TRAIT(src, TRAIT_NODROP))
|
||||
to_chat(user, "<span class='notice'>You try prying [src] off your hand...</span>")
|
||||
if(do_after(user, 70, target=src))
|
||||
to_chat(user, "<span class='notice'>You manage to remove [src] from your hand.</span>")
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, STICKY_NODROP)
|
||||
|
||||
return
|
||||
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
if(!botch_check(user)) // if they botch the prime, it'll be handled in botch_check
|
||||
preprime(user)
|
||||
|
||||
/obj/item/grenade/proc/log_grenade(mob/user, turf/T)
|
||||
@@ -81,10 +112,18 @@
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
addtimer(CALLBACK(src, .proc/prime), isnull(delayoverride)? det_time : delayoverride)
|
||||
|
||||
/obj/item/grenade/proc/prime()
|
||||
/obj/item/grenade/proc/prime(mob/living/lanced_by)
|
||||
var/turf/T = get_turf(src)
|
||||
log_game("Grenade detonation at [AREACOORD(T)], location [loc]")
|
||||
|
||||
if(shrapnel_type && shrapnel_radius && !shrapnel_initialized) // add a second check for adding the component in case whatever triggered the grenade went straight to prime (badminnery for example)
|
||||
shrapnel_initialized = TRUE
|
||||
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_radius)
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_GRENADE_PRIME, lanced_by)
|
||||
if(ex_dev || ex_heavy || ex_light || ex_flame)
|
||||
explosion(loc, ex_dev, ex_heavy, ex_light, flame_range = ex_flame)
|
||||
|
||||
/obj/item/grenade/proc/update_mob()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/obj/item/grenade/plastic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/grenade/plastic/Destroy()
|
||||
qdel(nadeassembly)
|
||||
@@ -122,7 +122,9 @@
|
||||
var/obj/item/I = AM
|
||||
I.throw_speed = max(1, (I.throw_speed - 3))
|
||||
I.throw_range = max(1, (I.throw_range - 3))
|
||||
I.embedding = I.embedding.setRating(embed_chance = 0)
|
||||
if(I.embedding)
|
||||
I.embedding["embed_chance"] = 0
|
||||
I.updateEmbedding()
|
||||
|
||||
target.add_overlay(plastic_overlay, TRUE)
|
||||
if(!nadeassembly)
|
||||
@@ -205,9 +207,10 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/plastic/c4/prime()
|
||||
/obj/item/grenade/plastic/c4/prime(mob/living/lanced_by)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
. = ..()
|
||||
var/turf/location
|
||||
if(target)
|
||||
if(!QDELETED(target))
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
qdel(smoke)
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/smokebomb/prime()
|
||||
/obj/item/grenade/smokebomb/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.set_up(4, src)
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
var/spawner_type = null // must be an object path
|
||||
var/deliveryamt = 1 // amount of type to deliver
|
||||
|
||||
/obj/item/grenade/spawnergrenade/prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
|
||||
/obj/item/grenade/spawnergrenade/prime(mob/living/lanced_by) // Prime now just handles the two loops that query for people in lockers and people who can see it.
|
||||
. = ..()
|
||||
update_mob()
|
||||
if(spawner_type && deliveryamt)
|
||||
// Make a quick flash
|
||||
|
||||
@@ -4,27 +4,45 @@
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "syndicate"
|
||||
item_state = "flashbang"
|
||||
ex_dev = 1
|
||||
ex_heavy = 2
|
||||
ex_light = 4
|
||||
ex_flame = 2
|
||||
|
||||
|
||||
/obj/item/grenade/syndieminibomb/prime()
|
||||
/obj/item/grenade/syndieminibomb/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
explosion(src.loc,1,2,4,flame_range = 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion
|
||||
name = "HE Grenade"
|
||||
desc = "A compact shrapnel grenade meant to devastate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction."
|
||||
icon_state = "concussion"
|
||||
ex_heavy = 2
|
||||
ex_light = 3
|
||||
ex_flame = 3
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,0,2,3,flame_range = 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/syndieminibomb/concussion/frag
|
||||
/obj/item/grenade/frag
|
||||
name = "frag grenade"
|
||||
desc = "Fire in the hole."
|
||||
desc = "An anti-personnel fragmentation grenade, this weapon excels at killing soft targets by shredding them with metal shrapnel."
|
||||
icon_state = "frag"
|
||||
shrapnel_type = /obj/item/projectile/bullet/shrapnel
|
||||
shrapnel_radius = 4
|
||||
ex_heavy = 1
|
||||
ex_light = 3
|
||||
ex_flame = 4
|
||||
|
||||
/obj/item/grenade/frag/mega
|
||||
name = "FRAG grenade"
|
||||
desc = "An anti-everything fragmentation grenade, this weapon excels at killing anything any everything by shredding them with metal shrapnel."
|
||||
shrapnel_type = /obj/item/projectile/bullet/shrapnel/mega
|
||||
shrapnel_radius = 12
|
||||
|
||||
/obj/item/grenade/frag/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/gluon
|
||||
desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors."
|
||||
@@ -36,7 +54,8 @@
|
||||
var/rad_damage = 350
|
||||
var/stamina_damage = 30
|
||||
|
||||
/obj/item/grenade/gluon/prime()
|
||||
/obj/item/grenade/gluon/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
update_mob()
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
|
||||
radiation_pulse(src, rad_damage)
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
icon_state = "witchhunterhat"
|
||||
item_state = "witchhunterhat"
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
/obj/item/storage/box/holy/follower
|
||||
name = "Followers of the Chaplain Kit"
|
||||
|
||||
@@ -5,36 +5,30 @@
|
||||
icon_state = "implant"
|
||||
activated = 1
|
||||
var/obj/machinery/abductor/pad/home
|
||||
var/cooldown = 30
|
||||
var/next_use = 0
|
||||
|
||||
/obj/item/implant/abductor/activate()
|
||||
. = ..()
|
||||
if(cooldown == initial(cooldown))
|
||||
if(next_use <= world.time)
|
||||
home.Retrieve(imp_in,1)
|
||||
cooldown = 0
|
||||
START_PROCESSING(SSobj, src)
|
||||
next_use = world.time + 60 SECONDS
|
||||
else
|
||||
to_chat(imp_in, "<span class='warning'>You must wait [30 - cooldown] seconds to use [src] again!</span>")
|
||||
|
||||
/obj/item/implant/abductor/process()
|
||||
if(cooldown < initial(cooldown))
|
||||
cooldown++
|
||||
if(cooldown == initial(cooldown))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
to_chat(imp_in, "<span class='warning'>You must wait [DisplayTimeText(next_use - world.time)] to use [src] again!</span>")
|
||||
|
||||
/obj/item/implant/abductor/implant(mob/living/target, mob/user)
|
||||
if(..())
|
||||
var/obj/machinery/abductor/console/console
|
||||
if(ishuman(target))
|
||||
var/datum/antagonist/abductor/A = target.mind.has_antag_datum(/datum/antagonist/abductor)
|
||||
if(A)
|
||||
console = get_abductor_console(A.team.team_number)
|
||||
home = console.pad
|
||||
|
||||
if(!home)
|
||||
var/list/consoles = list()
|
||||
for(var/obj/machinery/abductor/console/C in GLOB.machines)
|
||||
consoles += C
|
||||
console = pick(consoles)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/obj/machinery/abductor/console/console
|
||||
if(ishuman(target))
|
||||
var/datum/antagonist/abductor/A = target.mind.has_antag_datum(/datum/antagonist/abductor)
|
||||
if(A)
|
||||
console = get_abductor_console(A.team.team_number)
|
||||
home = console.pad
|
||||
return TRUE
|
||||
|
||||
if(!home)
|
||||
var/list/consoles = list()
|
||||
for(var/obj/machinery/abductor/console/C in GLOB.machines)
|
||||
consoles += C
|
||||
console = pick(consoles)
|
||||
home = console.pad
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
if(ismob(loc))
|
||||
attack_self(loc)
|
||||
else
|
||||
for(var/mob/M in viewers(1, src))
|
||||
for(var/mob/M in fov_viewers(1, src))
|
||||
if(M.client)
|
||||
attack_self(M)
|
||||
add_fingerprint(usr)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
var/bayonet = FALSE //Can this be attached to a gun?
|
||||
custom_price = 250
|
||||
custom_price = PRICE_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/Initialize()
|
||||
. = ..()
|
||||
@@ -104,10 +104,10 @@
|
||||
desc = "An occult looking dagger that is cold to the touch. Somehow, the flawless orb on the pommel is made entirely of liquid blood."
|
||||
icon = 'icons/obj/ice_moon/artifacts.dmi'
|
||||
icon_state = "bloodletter"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
/// Bleed stacks applied when an organic mob target is hit
|
||||
var/bleed_stacks_per_hit = 3
|
||||
|
||||
|
||||
/obj/item/kitchen/knife/bloodletter/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(!isliving(target) || !proximity_flag)
|
||||
@@ -131,13 +131,14 @@
|
||||
custom_materials = list(/datum/material/iron=18000)
|
||||
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
custom_price = 600
|
||||
custom_price = PRICE_EXPENSIVE
|
||||
|
||||
/obj/item/kitchen/knife/combat
|
||||
name = "combat knife"
|
||||
icon_state = "buckknife"
|
||||
item_state = "knife"
|
||||
desc = "A military combat utility survival knife."
|
||||
embedding = list("pain_mult" = 4, "embed_chance" = 65, "fall_chance" = 10, "ignore_throwspeed_threshold" = TRUE)
|
||||
force = 20
|
||||
throwforce = 20
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
|
||||
@@ -148,6 +149,7 @@
|
||||
icon_state = "survivalknife"
|
||||
item_state = "knife"
|
||||
desc = "A hunting grade survival knife."
|
||||
embedding = list("pain_mult" = 4, "embed_chance" = 35, "fall_chance" = 10)
|
||||
force = 15
|
||||
throwforce = 15
|
||||
bayonet = TRUE
|
||||
@@ -159,6 +161,7 @@
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
desc = "A sharpened bone. The bare minimum in survival."
|
||||
embedding = list("pain_mult" = 4, "embed_chance" = 35, "fall_chance" = 10)
|
||||
force = 15
|
||||
throwforce = 15
|
||||
custom_materials = null
|
||||
@@ -198,8 +201,9 @@
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 1.5)
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
|
||||
custom_price = 200
|
||||
custom_price = PRICE_ALMOST_CHEAP
|
||||
|
||||
/obj/item/kitchen/rollingpin/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins flattening [user.p_their()] head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
@@ -103,11 +103,30 @@
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
sharpness = IS_SHARP
|
||||
embedding = list("embed_chance" = 75, "embedded_impact_pain_multiplier" = 10)
|
||||
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
|
||||
armour_penetration = 35
|
||||
block_chance = 50
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/energy_sword
|
||||
var/list/possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
|
||||
|
||||
/datum/block_parry_data/energy_sword
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 25
|
||||
parry_time_spindown = 0
|
||||
// we want to signal to players the most dangerous phase, the time when automatic counterattack is a thing.
|
||||
parry_time_windup_visual_override = 1
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 12
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // esword users can attack while
|
||||
parry_time_perfect = 2.5 // first ds isn't perfect
|
||||
parry_time_perfect_leeway = 1.5
|
||||
parry_imperfect_falloff_percent = 5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 65 // VERY generous
|
||||
parry_efficiency_perfect = 100
|
||||
parry_failed_stagger_duration = 4 SECONDS
|
||||
parry_cooldown = 0.5 SECONDS
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color()
|
||||
@@ -273,6 +292,10 @@
|
||||
light_color = "#37FFF7"
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/Initialize()
|
||||
icon_state_on = icon_state
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
@@ -290,6 +313,7 @@
|
||||
if(!supress_message_text)
|
||||
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
|
||||
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/update_overlays()
|
||||
. = ..()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
|
||||
@@ -345,7 +369,7 @@
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You combine the two light swords, making a single supermassive blade! You're cool.</span>")
|
||||
new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
|
||||
new /obj/item/dualsaber/hypereutactic(user.drop_location())
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
else
|
||||
|
||||
@@ -61,13 +61,25 @@
|
||||
force = 18
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
block_chance = 50
|
||||
armour_penetration = 75
|
||||
sharpness = IS_SHARP
|
||||
attack_verb = list("slashed", "cut")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
custom_materials = list(/datum/material/iron = 1000)
|
||||
total_mass = 3.4
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/captain_saber
|
||||
|
||||
/datum/block_parry_data/captain_saber
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 4
|
||||
parry_time_spindown = 1
|
||||
parry_time_perfect = 0.75
|
||||
parry_time_perfect_leeway = 0.75
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_perfect = 100
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = 2 SECONDS
|
||||
|
||||
/obj/item/melee/sabre/Initialize()
|
||||
. = ..()
|
||||
@@ -150,7 +162,6 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
force = 15
|
||||
throwforce = 25
|
||||
block_chance = 50
|
||||
armour_penetration = 200 //Apparently this gives it the ability to pierce block
|
||||
flags_1 = CONDUCT_1
|
||||
obj_flags = UNIQUE_RENAME
|
||||
@@ -159,16 +170,47 @@
|
||||
attack_verb = list("stabs", "punctures", "pierces", "pokes")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
total_mass = 0.4
|
||||
item_flags = ITEM_CAN_PARRY | NEEDS_PERMIT
|
||||
block_parry_data = /datum/block_parry_data/traitor_rapier
|
||||
|
||||
// Fast, efficient parry.
|
||||
/datum/block_parry_data/traitor_rapier
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 2
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 3
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1
|
||||
)
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 50 // useless after 3rd decisecond
|
||||
)
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 1
|
||||
parry_efficiency_perfect = 100
|
||||
parry_data = list(
|
||||
PARRY_DISARM_ATTACKER = TRUE,
|
||||
PARRY_KNOCKDOWN_ATTACKER = 10
|
||||
)
|
||||
parry_failed_stagger_duration = 2 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_RANGE
|
||||
parry_cooldown = 0
|
||||
|
||||
/obj/item/melee/rapier/active_parry_reflex_counter(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, parry_efficiency, list/effect_text)
|
||||
. = ..()
|
||||
if((attack_type & ATTACK_TYPE_PROJECTILE) && (parry_efficiency >= 100))
|
||||
. |= BLOCK_SHOULD_REDIRECT
|
||||
return_list[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
|
||||
|
||||
/obj/item/melee/rapier/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 20, 65, 0)
|
||||
|
||||
/obj/item/melee/rapier/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(attack_type == ATTACK_TYPE_PROJECTILE)
|
||||
final_block_chance = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/rapier/on_exit_storage(datum/component/storage/S)
|
||||
var/obj/item/storage/belt/sabre/rapier/B = S.parent
|
||||
if(istype(B))
|
||||
@@ -191,10 +233,9 @@
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/H = target
|
||||
var/loss = H.getStaminaLoss()
|
||||
H.Dizzy(10)
|
||||
H.adjustStaminaLoss(30)
|
||||
if((loss > 40) && prob(loss)) // if above 40, roll for sleep using 1% every 1 stamina damage
|
||||
if(CHECK_STAMCRIT(H) != NOT_STAMCRIT)
|
||||
H.Sleeping(180)
|
||||
|
||||
/obj/item/melee/classic_baton
|
||||
@@ -648,7 +689,7 @@
|
||||
item_state = "mace_greyscale"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS //Material type changes the prefix as well as the color.
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Material type changes the prefix as well as the color.
|
||||
custom_materials = list(/datum/material/iron = 12000) //Defaults to an Iron Mace.
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 14
|
||||
@@ -664,4 +705,4 @@
|
||||
. = ..()
|
||||
overlay = mutable_appearance(icon, overlay_state)
|
||||
overlay.appearance_flags = RESET_COLOR
|
||||
add_overlay(overlay)
|
||||
add_overlay(overlay)
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
throw_speed = 4
|
||||
if(attack_verb_on.len)
|
||||
attack_verb = attack_verb_on
|
||||
if(embedding)
|
||||
updateEmbedding()
|
||||
icon_state = icon_state_on
|
||||
w_class = w_class_on
|
||||
else
|
||||
@@ -62,6 +64,8 @@
|
||||
throw_speed = initial(throw_speed)
|
||||
if(attack_verb_off.len)
|
||||
attack_verb = attack_verb_off
|
||||
if(embedding)
|
||||
updateEmbedding()
|
||||
icon_state = initial(icon_state)
|
||||
w_class = initial(w_class)
|
||||
total_mass = initial(total_mass)
|
||||
|
||||
@@ -115,6 +115,44 @@
|
||||
new /obj/item/toy/crayon/spraycan(src)
|
||||
new /obj/item/clothing/shoes/sandal(src)
|
||||
|
||||
/obj/item/choice_beacon/hosgun
|
||||
name = "personal weapon beacon"
|
||||
desc = "Use this to summon your personal Head of Security issued firearm!"
|
||||
|
||||
/obj/item/choice_beacon/hosgun/generate_display_names()
|
||||
var/static/list/hos_gun_list
|
||||
if(!hos_gun_list)
|
||||
hos_gun_list = list()
|
||||
var/list/templist = subtypesof(/obj/item/storage/secure/briefcase/hos/) //we have to convert type = name to name = type, how lovely!
|
||||
for(var/V in templist)
|
||||
var/atom/A = V
|
||||
hos_gun_list[initial(A.name)] = A
|
||||
return hos_gun_list
|
||||
|
||||
/obj/item/choice_beacon/augments
|
||||
name = "augment beacon"
|
||||
desc = "Summons augmentations."
|
||||
|
||||
/obj/item/choice_beacon/augments/generate_display_names()
|
||||
var/static/list/augment_list
|
||||
if(!augment_list)
|
||||
augment_list = list()
|
||||
var/list/templist = list(
|
||||
/obj/item/organ/cyberimp/brain/anti_drop,
|
||||
/obj/item/organ/cyberimp/arm/toolset,
|
||||
/obj/item/organ/cyberimp/arm/surgery,
|
||||
/obj/item/organ/cyberimp/chest/thrusters,
|
||||
/obj/item/organ/lungs/cybernetic,
|
||||
/obj/item/organ/liver/cybernetic) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof
|
||||
for(var/V in templist)
|
||||
var/atom/A = V
|
||||
augment_list[initial(A.name)] = A
|
||||
return augment_list
|
||||
|
||||
/obj/item/choice_beacon/augments/spawn_option(obj/choice,mob/living/M)
|
||||
new choice(get_turf(M))
|
||||
to_chat(M, "<span class='hear'>You hear something crackle from the beacon for a moment before a voice speaks. \"Please stand by for a message from S.E.L.F. Message as follows: <b>Item request received. Your package has been transported, use the autosurgeon supplied to apply the upgrade.</b> Message ends.\"</span>")
|
||||
|
||||
/obj/item/skub
|
||||
desc = "It's skub."
|
||||
name = "skub"
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
var/occupant_weight = 0
|
||||
var/max_occupants = 3 //Hard-cap so you can't have infinite mice or something in one carrier
|
||||
var/max_occupant_weight = MOB_SIZE_SMALL //This is calculated from the mob sizes of occupants
|
||||
var/entrance_name = "door" //name of the entrance to the item
|
||||
var/escape_time = 200 //how long it takes for mobs above small sizes to escape (for small sizes, its randomly 1.5 to 2x this)
|
||||
var/load_time = 30 //how long it takes for mobs to be loaded into the pet carrier
|
||||
var/has_lock_sprites = TRUE //whether to load the lock overlays or not
|
||||
var/allows_hostiles = FALSE //does the pet carrier allow hostile entities to be held within it?
|
||||
|
||||
/obj/item/pet_carrier/Destroy()
|
||||
if(occupants.len)
|
||||
@@ -51,20 +56,20 @@
|
||||
else
|
||||
. += "<span class='notice'>It has nothing inside.</span>"
|
||||
if(user.canUseTopic(src))
|
||||
. += "<span class='notice'>Activate it in your hand to [open ? "close" : "open"] its door.</span>"
|
||||
. += "<span class='notice'>Activate it in your hand to [open ? "close" : "open"] its [entrance_name].</span>"
|
||||
if(!open)
|
||||
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] its door.</span>"
|
||||
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] its [entrance_name].</span>"
|
||||
|
||||
/obj/item/pet_carrier/attack_self(mob/living/user)
|
||||
if(open)
|
||||
to_chat(user, "<span class='notice'>You close [src]'s door.</span>")
|
||||
to_chat(user, "<span class='notice'>You close [src]'s [entrance_name].</span>")
|
||||
playsound(user, 'sound/effects/bin_close.ogg', 50, TRUE)
|
||||
open = FALSE
|
||||
else
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>[src] is locked!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You open [src]'s door.</span>")
|
||||
to_chat(user, "<span class='notice'>You open [src]'s [entrance_name].</span>")
|
||||
playsound(user, 'sound/effects/bin_open.ogg', 50, TRUE)
|
||||
open = TRUE
|
||||
update_icon()
|
||||
@@ -86,7 +91,7 @@
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(!open)
|
||||
to_chat(user, "<span class='warning'>You need to open [src]'s door!</span>")
|
||||
to_chat(user, "<span class='warning'>You need to open [src]'s [entrance_name]!</span>")
|
||||
return
|
||||
if(target.mob_size > max_occupant_weight)
|
||||
if(ishuman(target))
|
||||
@@ -94,13 +99,15 @@
|
||||
if(iscatperson(H))
|
||||
to_chat(user, "<span class='warning'>You'd need a lot of catnip and treats, plus maybe a laser pointer, for that to work.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Humans, generally, do not fit into pet carriers.</span>")
|
||||
to_chat(user, "<span class='warning'>Humans, generally, do not fit into [name]s.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You get the feeling [target] isn't meant for a [name].</span>")
|
||||
return
|
||||
if(user == target)
|
||||
to_chat(user, "<span class='warning'>Why would you ever do that?</span>")
|
||||
return
|
||||
if(ishostile(target) && !allows_hostiles && target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers
|
||||
to_chat(user, "<span class='warning'>You have a feeling you shouldn't keep this as a pet.</span>")
|
||||
load_occupant(user, target)
|
||||
|
||||
/obj/item/pet_carrier/relaymove(mob/living/user, direction)
|
||||
@@ -110,8 +117,8 @@
|
||||
remove_occupant(user)
|
||||
return
|
||||
else if(!locked)
|
||||
loc.visible_message("<span class='notice'>[user] pushes open the door to [src]!</span>", \
|
||||
"<span class='warning'>[user] pushes open the door of [src]!</span>")
|
||||
loc.visible_message("<span class='notice'>[user] pushes open the [entrance_name] to [src]!</span>", \
|
||||
"<span class='warning'>[user] pushes open the [entrance_name] of [src]!</span>")
|
||||
open = TRUE
|
||||
update_icon()
|
||||
return
|
||||
@@ -119,12 +126,19 @@
|
||||
container_resist(user)
|
||||
|
||||
/obj/item/pet_carrier/container_resist(mob/living/user)
|
||||
//don't do the whole resist timer thing if it's open!
|
||||
if(open)
|
||||
loc.visible_message("<span class='notice'>[user] climbs out of [src]!</span>", \
|
||||
"<span class='warning'>[user] jumps out of [src]!</span>")
|
||||
remove_occupant(user)
|
||||
return
|
||||
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(user.mob_size <= MOB_SIZE_SMALL)
|
||||
to_chat(user, "<span class='notice'>You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.)</span>")
|
||||
to_chat(loc, "<span class='warning'>You see [user] reach through the bars and fumble for the lock switch!</span>")
|
||||
if(!do_after(user, rand(300, 400), target = user) || open || !locked || !(user in occupants))
|
||||
to_chat(user, "<span class='notice'>You begin to try escaping the [src] and start fumbling for the lock switch... (This will take some time.)</span>")
|
||||
to_chat(loc, "<span class='warning'>You see [user] attempting to unlock the [src]!</span>")
|
||||
if(!do_after(user, rand(escape_time * 1.5, escape_time * 2), target = user) || open || !locked || !(user in occupants))
|
||||
return
|
||||
loc.visible_message("<span class='warning'>[user] flips the lock switch on [src] by reaching through!</span>", null, null, null, user)
|
||||
to_chat(user, "<span class='boldannounce'>Bingo! The lock pops open!</span>")
|
||||
@@ -132,12 +146,12 @@
|
||||
playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE)
|
||||
update_icon()
|
||||
else
|
||||
loc.visible_message("<span class='warning'>[src] starts rattling as something pushes against the door!</span>", null, null, null, user)
|
||||
loc.visible_message("<span class='warning'>[src] starts rattling as something pushes against the [entrance_name]!</span>", null, null, null, user)
|
||||
to_chat(user, "<span class='notice'>You start pushing out of [src]... (This will take about 20 seconds.)</span>")
|
||||
if(!do_after(user, 200, target = user) || open || !locked || !(user in occupants))
|
||||
if(!do_after(user, escape_time, target = user) || open || !locked || !(user in occupants))
|
||||
return
|
||||
loc.visible_message("<span class='warning'>[user] shoves out of [src]!</span>", null, null, null, user)
|
||||
to_chat(user, "<span class='notice'>You shove open [src]'s door against the lock's resistance and fall out!</span>")
|
||||
to_chat(user, "<span class='notice'>You shove open [src]'s [entrance_name] against the lock's resistance and fall out!</span>")
|
||||
locked = FALSE
|
||||
open = TRUE
|
||||
update_icon()
|
||||
@@ -151,7 +165,7 @@
|
||||
|
||||
/obj/item/pet_carrier/update_overlays()
|
||||
. = ..()
|
||||
if(!open)
|
||||
if(!open && has_lock_sprites)
|
||||
. += "[locked ? "" : "un"]locked"
|
||||
|
||||
/obj/item/pet_carrier/MouseDrop(atom/over_atom)
|
||||
@@ -170,7 +184,7 @@
|
||||
user.visible_message("<span class='notice'>[user] starts loading [target] into [src].</span>", \
|
||||
"<span class='notice'>You start loading [target] into [src]...</span>", null, null, target)
|
||||
to_chat(target, "<span class='userdanger'>[user] starts loading you into [user.p_their()] [name]!</span>")
|
||||
if(!do_mob(user, target, 30))
|
||||
if(!do_mob(user, target, load_time))
|
||||
return
|
||||
if(target in occupants)
|
||||
return
|
||||
@@ -192,9 +206,74 @@
|
||||
/obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf)
|
||||
if(!(occupant in occupants) || !istype(occupant))
|
||||
return
|
||||
occupant.forceMove(new_turf ? new_turf : drop_location())
|
||||
occupant.forceMove(new_turf ? new_turf : get_turf(src))
|
||||
occupants -= occupant
|
||||
occupant_weight -= occupant.mob_size
|
||||
occupant.setDir(SOUTH)
|
||||
|
||||
//bluespace jar, a reskin of the pet carrier that can fit people and smashes when thrown
|
||||
/obj/item/pet_carrier/bluespace
|
||||
name = "bluespace jar"
|
||||
desc = "A jar, that seems to be bigger on the inside, somehow allowing lifeforms to fit through its narrow entrance."
|
||||
open = FALSE //starts closed so it looks better on menus
|
||||
icon_state = "bluespace_jar"
|
||||
item_state = "bluespace_jar"
|
||||
lefthand_file = ""
|
||||
righthand_file = ""
|
||||
max_occupant_weight = MOB_SIZE_HUMAN //can fit people, like a bluespace bodybag!
|
||||
load_time = 40 //loading things into a jar takes longer than a regular pet carrier
|
||||
entrance_name = "lid"
|
||||
w_class = WEIGHT_CLASS_SMALL //it's a jar
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
max_occupants = 1 //far less than a regular carrier or bluespace bodybag, because it can be thrown to release the contents
|
||||
allows_hostiles = TRUE //can fit hostile creatures, with the move resist restrictions in place, this means they still cannot take things like legions/goliaths/etc regardless
|
||||
has_lock_sprites = FALSE //jar doesn't show the regular lock overlay
|
||||
custom_materials = list(/datum/material/glass = 1000, /datum/material/bluespace = 600)
|
||||
escape_time = 10 //half the time of a bluespace bodybag
|
||||
var/datum/gas_mixture/occupant_gas_supply
|
||||
|
||||
/obj/item/pet_carrier/bluespace/update_icon_state()
|
||||
if(open)
|
||||
icon_state = "bluespace_jar_open"
|
||||
else
|
||||
icon_state = "bluespace_jar"
|
||||
|
||||
/obj/item/pet_carrier/bluespace/throw_impact()
|
||||
. = ..()
|
||||
//delete the item upon impact, releasing the creature inside (this is handled by its deletion)
|
||||
if(occupants.len)
|
||||
loc.visible_message("<span class='warning'>The bluespace jar smashes, releasing [occupants[1]]!</span>")
|
||||
playsound(src, "shatter", 70, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/pet_carrier/bluespace/add_occupant(mob/living/occupant) //update the gas supply as required, this acts like magical internals
|
||||
. = ..()
|
||||
if(!occupant_gas_supply)
|
||||
occupant_gas_supply = new
|
||||
if(isanimal(occupant))
|
||||
var/mob/living/simple_animal/animal = occupant
|
||||
occupant_gas_supply.temperature = animal.minbodytemp //simple animals only care about temperature when their turf isnt a location
|
||||
else
|
||||
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
|
||||
ADD_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
|
||||
ADD_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
|
||||
|
||||
/obj/item/pet_carrier/bluespace/remove_occupant(mob/living/occupant)
|
||||
. = ..()
|
||||
if(ishuman(occupant))
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
|
||||
REMOVE_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
|
||||
|
||||
/obj/item/pet_carrier/bluespace/return_air()
|
||||
if(!occupant_gas_supply)
|
||||
occupant_gas_supply = new
|
||||
return occupant_gas_supply
|
||||
|
||||
#undef pet_carrier_full
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
custom_price = 600
|
||||
custom_price = PRICE_ABOVE_EXPENSIVE
|
||||
var/has_owner = FALSE
|
||||
var/pinpointer_owner = null
|
||||
|
||||
@@ -183,3 +183,20 @@
|
||||
|
||||
A.other_pair = B
|
||||
B.other_pair = A
|
||||
|
||||
/obj/item/pinpointer/shuttle
|
||||
name = "fugitive pinpointer"
|
||||
desc = "A handheld tracking device that locates the bounty hunter shuttle for quick escapes."
|
||||
icon_state = "pinpointer_hunter"
|
||||
var/obj/shuttleport
|
||||
|
||||
/obj/item/pinpointer/shuttle/Initialize(mapload)
|
||||
. = ..()
|
||||
shuttleport = SSshuttle.getShuttle("huntership")
|
||||
|
||||
/obj/item/pinpointer/shuttle/scan_for_target()
|
||||
target = shuttleport
|
||||
|
||||
/obj/item/pinpointer/shuttle/Destroy()
|
||||
shuttleport = null
|
||||
. = ..()
|
||||
@@ -0,0 +1,101 @@
|
||||
/obj/item/pitchfork
|
||||
icon_state = "pitchfork0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "pitchfork"
|
||||
desc = "A simple tool used for moving hay."
|
||||
force = 7
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
attack_verb = list("attacked", "impaled", "pierced")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/pitchfork/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/pitchfork/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=7, force_wielded=15, icon_wielded="pitchfork1")
|
||||
AddElement(/datum/element/sword_point)
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/pitchfork/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/pitchfork/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/pitchfork/update_icon_state()
|
||||
icon_state = "pitchfork0"
|
||||
|
||||
/obj/item/pitchfork/demonic
|
||||
name = "demonic pitchfork"
|
||||
desc = "A red pitchfork, it looks like the work of the devil."
|
||||
force = 19
|
||||
throwforce = 24
|
||||
|
||||
/obj/item/pitchfork/demonic/Initialize()
|
||||
. = ..()
|
||||
set_light(3,6,LIGHT_COLOR_RED)
|
||||
|
||||
/obj/item/pitchfork/demonic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=19, force_wielded=25)
|
||||
|
||||
/obj/item/pitchfork/demonic/greater
|
||||
force = 24
|
||||
throwforce = 50
|
||||
|
||||
/obj/item/pitchfork/demonic/greater/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=24, force_wielded=34)
|
||||
|
||||
/obj/item/pitchfork/demonic/ascended
|
||||
force = 100
|
||||
throwforce = 100
|
||||
|
||||
/obj/item/pitchfork/demonic/ascended/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=100, force_wielded=500000) // Kills you DEAD
|
||||
|
||||
/obj/item/pitchfork/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] impales [user.p_them()]self in [user.p_their()] abdomen with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/pitchfork/demonic/pickup(mob/living/user)
|
||||
. = ..()
|
||||
if(isliving(user) && user.mind && user.owns_soul() && !is_devil(user))
|
||||
var/mob/living/U = user
|
||||
U.visible_message("<span class='warning'>As [U] picks [src] up, [U]'s arms briefly catch fire.</span>", \
|
||||
"<span class='warning'>\"As you pick up [src] your arms ignite, reminding you of all your past sins.\"</span>")
|
||||
if(ishuman(U))
|
||||
var/mob/living/carbon/human/H = U
|
||||
H.apply_damage(rand(force/2, force), BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
else
|
||||
U.adjustFireLoss(rand(force/2,force))
|
||||
|
||||
/obj/item/pitchfork/demonic/attack(mob/target, mob/living/carbon/human/user)
|
||||
if(user.mind && user.owns_soul() && !is_devil(user))
|
||||
to_chat(user, "<span class='warning'>[src] burns in your hands.</span>")
|
||||
user.apply_damage(rand(force/2, force), BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
..()
|
||||
|
||||
/obj/item/pitchfork/demonic/ascended/afterattack(atom/target, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity || !wielded)
|
||||
return
|
||||
if(iswallturf(target))
|
||||
var/turf/closed/wall/W = target
|
||||
user.visible_message("<span class='danger'>[user] blasts \the [target] with \the [src]!</span>")
|
||||
playsound(target, 'sound/magic/disintegrate.ogg', 100, TRUE)
|
||||
W.break_wall()
|
||||
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return
|
||||
@@ -140,7 +140,8 @@
|
||||
if(jsonlist["icon_state"])
|
||||
icon_state = jsonlist["icon_state"]
|
||||
item_state = jsonlist["item_state"]
|
||||
icon = 'config/plushies/sprites.dmi'
|
||||
var/static/config_sprites = file("config/plushies/sprites.dmi")
|
||||
icon = config_sprites
|
||||
if(jsonlist["attack_verb"])
|
||||
attack_verb = jsonlist["attack_verb"]
|
||||
if(jsonlist["squeak_override"])
|
||||
@@ -436,13 +437,13 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
/obj/item/toy/plush/random/Initialize()
|
||||
var/newtype
|
||||
var/list/snowflake_list = CONFIG_GET(keyed_list/snowflake_plushies)
|
||||
|
||||
|
||||
/// If there are no snowflake plushies we'll default to base plush, so we grab from the valid list
|
||||
if (snowflake_list.len)
|
||||
newtype = prob(CONFIG_GET(number/snowflake_plushie_prob)) ? /obj/item/toy/plush/random_snowflake : pick(GLOB.valid_plushie_paths)
|
||||
else
|
||||
else
|
||||
newtype = pick(GLOB.valid_plushie_paths)
|
||||
|
||||
|
||||
new newtype(loc)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
item_flags = NEEDS_PERMIT | NO_COMBAT_MODE_FORCE_MODIFIER //To avoid ambushing and oneshotting healthy crewmembers on force setting 3.
|
||||
attack_verb = list("whacked", "fisted", "power-punched")
|
||||
force = 20
|
||||
throwforce = 10
|
||||
@@ -13,7 +14,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 40)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/click_delay = 1.5
|
||||
click_delay = CLICK_CD_MELEE * 1.5
|
||||
var/fisto_setting = 1
|
||||
var/gasperfist = 3
|
||||
var/obj/item/tank/internals/tank = null //Tank used for the gauntlet's piston-ram.
|
||||
@@ -70,42 +71,46 @@
|
||||
|
||||
|
||||
/obj/item/melee/powerfist/attack(mob/living/target, mob/living/user)
|
||||
if(!tank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
|
||||
return
|
||||
var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
T.assume_air(gasused)
|
||||
T.air_update_turf()
|
||||
if(!gasused)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s tank is empty!</span>")
|
||||
target.apply_damage((force / 5), BRUTE)
|
||||
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>[user]'s punches you!</span>")
|
||||
return
|
||||
if(gasused.total_moles() < gasperfist * fisto_setting)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
|
||||
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
target.apply_damage((force / 2), BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>[user]'s punch strikes with force!</span>")
|
||||
return
|
||||
target.apply_damage(force * fisto_setting, BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
|
||||
new /obj/effect/temp_visual/kinetic_blast(target.loc)
|
||||
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return FALSE
|
||||
if(!tank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
|
||||
return FALSE
|
||||
var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
var/totalitemdamage = target.pre_attacked_by(src, user)
|
||||
T.assume_air(gasused)
|
||||
T.air_update_turf()
|
||||
if(!gasused)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s tank is empty!</span>")
|
||||
target.apply_damage((totalitemdamage / 5), BRUTE)
|
||||
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>[user]'s punches you!</span>")
|
||||
return
|
||||
if(gasused.total_moles() < gasperfist * fisto_setting)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
|
||||
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
target.apply_damage((totalitemdamage / 2), BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>[user]'s punch strikes with force!</span>")
|
||||
return
|
||||
target.apply_damage(totalitemdamage * fisto_setting, BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
|
||||
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
|
||||
new /obj/effect/temp_visual/kinetic_blast(target.loc)
|
||||
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
|
||||
|
||||
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
|
||||
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
|
||||
target.throw_at(throw_target, 5 * fisto_setting, 0.5 + (fisto_setting / 2))
|
||||
|
||||
target.throw_at(throw_target, 5 * fisto_setting, 0.5 + (fisto_setting / 2))
|
||||
log_combat(user, target, "power fisted", src)
|
||||
|
||||
log_combat(user, target, "power fisted", src)
|
||||
|
||||
user.changeNext_move(CLICK_CD_MELEE * click_delay)
|
||||
|
||||
return
|
||||
var/weight = getweight(user, STAM_COST_ATTACK_MOB_MULT)
|
||||
if(weight)
|
||||
user.adjustStaminaLossBuffered(weight)
|
||||
return TRUE
|
||||
|
||||
@@ -215,8 +215,9 @@
|
||||
/obj/item/clothing/head/helmet/plate/crusader/prophet
|
||||
name = "Prophet's Hat"
|
||||
desc = "A religious-looking hat."
|
||||
icon_state = "prophet"
|
||||
mob_overlay_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
|
||||
flags_1 = 0
|
||||
flags_1 = NONE
|
||||
armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 50, "bomb" = 70, "bio" = 50, "rad" = 50, "fire" = 60, "acid" = 60) //religion protects you from disease and radiation, honk.
|
||||
worn_x_dimension = 64
|
||||
worn_y_dimension = 64
|
||||
|
||||
@@ -355,9 +355,11 @@
|
||||
emaggedhitdamage = 0
|
||||
|
||||
/obj/item/borg/lollipop/equipped()
|
||||
. = ..()
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/dropped(mob/user)
|
||||
. = ..()
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/proc/check_amount() //Doesn't even use processing ticks.
|
||||
@@ -419,7 +421,7 @@
|
||||
A.BB.damage = hitdamage
|
||||
if(hitdamage)
|
||||
A.BB.nodamage = FALSE
|
||||
A.BB.speed = 0.5
|
||||
A.BB.pixels_per_second = TILES_TO_PIXELS(20)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
A.fire_casing(target, user, params, 0, 0, null, 0, src)
|
||||
user.visible_message("<span class='warning'>[user] blasts a flying lollipop at [target]!</span>")
|
||||
@@ -434,7 +436,7 @@
|
||||
A.BB.damage = hitdamage
|
||||
if(hitdamage)
|
||||
A.BB.nodamage = FALSE
|
||||
A.BB.speed = 0.5
|
||||
A.BB.pixels_per_second = TILES_TO_PIXELS(20)
|
||||
A.BB.color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
|
||||
playsound(src.loc, 'sound/weapons/bulletflyby3.ogg', 50, 1)
|
||||
A.fire_casing(target, user, params, 0, 0, null, 0, src)
|
||||
@@ -671,13 +673,13 @@
|
||||
if(track_projectile)
|
||||
tracked[P] = P.damage
|
||||
P.damage *= projectile_damage_coefficient
|
||||
P.speed *= projectile_speed_coefficient
|
||||
P.pixels_per_second *= projectile_speed_coefficient
|
||||
P.add_overlay(projectile_effect)
|
||||
|
||||
/obj/item/borg/projectile_dampen/proc/restore_projectile(obj/item/projectile/P)
|
||||
tracked -= P
|
||||
P.damage *= (1/projectile_damage_coefficient)
|
||||
P.speed *= (1/projectile_speed_coefficient)
|
||||
P.pixels_per_second *= (1/projectile_speed_coefficient)
|
||||
P.cut_overlay(projectile_effect)
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
/obj/item/borg/upgrade/defib/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
var/obj/item/twohanded/shockpaddles/cyborg/S = locate() in R.module
|
||||
var/obj/item/shockpaddles/cyborg/S = locate() in R.module
|
||||
R.module.remove_module(S, TRUE)
|
||||
|
||||
/obj/item/borg/upgrade/processor
|
||||
@@ -545,7 +545,7 @@
|
||||
to_chat(usr, "<span class='notice'>This unit already has an expand module installed!</span>")
|
||||
return FALSE
|
||||
|
||||
R.notransform = TRUE
|
||||
R.mob_transforming = TRUE
|
||||
var/prev_locked_down = R.locked_down
|
||||
R.SetLockdown(1)
|
||||
R.anchored = TRUE
|
||||
@@ -559,7 +559,7 @@
|
||||
if(!prev_locked_down)
|
||||
R.SetLockdown(0)
|
||||
R.anchored = FALSE
|
||||
R.notransform = FALSE
|
||||
R.mob_transforming = FALSE
|
||||
R.resize = 2
|
||||
R.hasExpanded = TRUE
|
||||
R.update_transform()
|
||||
|
||||
@@ -24,24 +24,22 @@
|
||||
if(istype(I, /obj/item/melee/transforming/energy))
|
||||
to_chat(user, "<span class='warning'>You don't think \the [I] will be the thing getting modified if you use it on \the [src]!</span>")
|
||||
return
|
||||
if(istype(I, /obj/item/twohanded))//some twohanded items should still be sharpenable, but handle force differently. therefore i need this stuff
|
||||
var/obj/item/twohanded/TH = I
|
||||
if(TH.force_wielded >= max)
|
||||
to_chat(user, "<span class='warning'>[TH] is much too powerful to sharpen further!</span>")
|
||||
return
|
||||
if(TH.wielded)
|
||||
to_chat(user, "<span class='warning'>[TH] must be unwielded before it can be sharpened!</span>")
|
||||
return
|
||||
if(TH.force_wielded > initial(TH.force_wielded))
|
||||
to_chat(user, "<span class='warning'>[TH] has already been refined before. It cannot be sharpened further!</span>")
|
||||
return
|
||||
TH.force_wielded = clamp(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay
|
||||
if(I.force > initial(I.force))
|
||||
|
||||
var/signal_out = SEND_SIGNAL(I, COMSIG_ITEM_SHARPEN_ACT, increment, max)
|
||||
if(signal_out & COMPONENT_BLOCK_SHARPEN_MAXED)
|
||||
to_chat(user, "<span class='warning'>[I] is much too powerful to sharpen further!</span>")
|
||||
return
|
||||
if(signal_out & COMPONENT_BLOCK_SHARPEN_BLOCKED)
|
||||
to_chat(user, "<span class='warning'>[I] is not able to be sharpened right now!</span>")
|
||||
return
|
||||
if((signal_out & COMPONENT_BLOCK_SHARPEN_ALREADY) || (I.force > initial(I.force) && !signal_out))
|
||||
to_chat(user, "<span class='warning'>[I] has already been refined before. It cannot be sharpened further!</span>")
|
||||
return
|
||||
if(!(signal_out & COMPONENT_BLOCK_SHARPEN_APPLIED))
|
||||
I.force = clamp(I.force + increment, 0, max)
|
||||
|
||||
user.visible_message("<span class='notice'>[user] sharpens [I] with [src]!</span>", "<span class='notice'>You sharpen [I], making it much more deadly than before.</span>")
|
||||
I.sharpness = IS_SHARP_ACCURATE
|
||||
I.force = clamp(I.force + increment, 0, max)
|
||||
I.throwforce = clamp(I.throwforce + increment, 0, max)
|
||||
I.name = "[prefix] [I.name]"
|
||||
name = "worn out [name]"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/obj/item/shield
|
||||
name = "shield"
|
||||
icon = 'icons/obj/shields.dmi'
|
||||
block_chance = 50
|
||||
item_flags = ITEM_CAN_BLOCK
|
||||
block_parry_data = /datum/block_parry_data/shield
|
||||
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
|
||||
/// Shield flags
|
||||
var/shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
@@ -22,6 +23,18 @@
|
||||
/// Shield bashing push distance
|
||||
var/shieldbash_push_distance = 1
|
||||
|
||||
/datum/block_parry_data/shield
|
||||
block_damage_multiplier = 0.25
|
||||
block_stamina_efficiency = 2.5
|
||||
block_stamina_cost_per_second = 2.5
|
||||
block_slowdown = 0
|
||||
block_lock_attacking = FALSE
|
||||
block_lock_sprinting = TRUE
|
||||
block_start_delay = 1.5
|
||||
block_damage_absorption = 5
|
||||
block_resting_stamina_penalty_multiplier = 2
|
||||
block_projectile_mitigation = 75
|
||||
|
||||
/obj/item/shield/examine(mob/user)
|
||||
. = ..()
|
||||
if(shield_flags & SHIELD_CAN_BASH)
|
||||
@@ -107,7 +120,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/shield/proc/user_shieldbash(mob/living/user, atom/target, harmful)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //Combat mode has to be enabled for shield bashing
|
||||
if(!SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) //Combat mode has to be enabled for shield bashing
|
||||
return FALSE
|
||||
if(!(shield_flags & SHIELD_CAN_BASH))
|
||||
to_chat(user, "<span class='warning'>[src] can't be used to shield bash!</span>")
|
||||
@@ -154,6 +167,22 @@
|
||||
icon_state = "shield_bash"
|
||||
duration = 3
|
||||
|
||||
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(ismovable(object))
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
final_block_chance = 100
|
||||
. = ..()
|
||||
if(. & BLOCK_SUCCESS)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
|
||||
/obj/item/shield/on_active_block(mob/living/owner, atom/object, damage, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance)
|
||||
|
||||
/obj/item/shield/riot
|
||||
name = "riot shield"
|
||||
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
|
||||
@@ -172,20 +201,7 @@
|
||||
var/repair_material = /obj/item/stack/sheet/mineral/titanium
|
||||
var/can_shatter = TRUE
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_TRANSPARENT
|
||||
max_integrity = 75
|
||||
|
||||
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(ismovable(object))
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
final_block_chance = 100
|
||||
. = ..()
|
||||
if(. & BLOCK_SUCCESS)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
max_integrity = 450
|
||||
|
||||
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/melee/baton))
|
||||
@@ -197,10 +213,10 @@
|
||||
if(obj_integrity >= max_integrity)
|
||||
to_chat(user, "<span class='warning'>[src] is already in perfect condition.</span>")
|
||||
else
|
||||
var/obj/item/stack/sheet/mineral/titanium/T = W
|
||||
T.use(1)
|
||||
var/obj/item/stack/S = W
|
||||
S.use(1)
|
||||
obj_integrity = max_integrity
|
||||
to_chat(user, "<span class='notice'>You repair [src] with [T].</span>")
|
||||
to_chat(user, "<span class='notice'>You repair [src] with [S].</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -238,13 +254,13 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 55 //Weak
|
||||
max_integrity = 300
|
||||
|
||||
obj/item/shield/riot/bullet_proof
|
||||
name = "bullet resistant shield"
|
||||
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
|
||||
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
max_integrity = 55 //Weaker
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/shield/riot/roman
|
||||
name = "\improper Roman shield"
|
||||
@@ -255,13 +271,13 @@ obj/item/shield/riot/bullet_proof
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 65
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/roman/fake
|
||||
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
|
||||
block_chance = 0
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
max_integrity = 30
|
||||
max_integrity = 40
|
||||
|
||||
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/grillehit.ogg', 100)
|
||||
@@ -274,12 +290,12 @@ obj/item/shield/riot/bullet_proof
|
||||
item_state = "buckler"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
custom_materials = null
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 10)
|
||||
resistance_flags = FLAMMABLE
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
block_chance = 30
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 55
|
||||
max_integrity = 150
|
||||
|
||||
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/bang.ogg', 50)
|
||||
@@ -297,13 +313,16 @@ obj/item/shield/riot/bullet_proof
|
||||
throw_speed = 3
|
||||
throw_range = 4
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/active = 0
|
||||
var/active = FALSE
|
||||
|
||||
/obj/item/shield/riot/tele/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!active)
|
||||
return BLOCK_NONE
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/riot/tele/can_active_block()
|
||||
return ..() && active
|
||||
|
||||
/obj/item/shield/riot/tele/attack_self(mob/living/user)
|
||||
active = !active
|
||||
icon_state = "teleriot[active]"
|
||||
@@ -335,8 +354,7 @@ obj/item/shield/riot/bullet_proof
|
||||
icon_state = "makeshift_shield"
|
||||
custom_materials = list(/datum/material/iron = 18000)
|
||||
slot_flags = null
|
||||
block_chance = 35
|
||||
max_integrity = 100 //Made of metal welded together its strong but not unkillable
|
||||
max_integrity = 300 //Made of metal welded together its strong but not unkillable
|
||||
force = 10
|
||||
throwforce = 7
|
||||
|
||||
@@ -346,7 +364,6 @@ obj/item/shield/riot/bullet_proof
|
||||
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
block_chance = 75 //1/4 shots will hit*
|
||||
force = 16
|
||||
slowdown = 2
|
||||
throwforce = 15 //Massive pice of metal
|
||||
@@ -357,21 +374,19 @@ obj/item/shield/riot/bullet_proof
|
||||
/obj/item/shield/riot/tower/swat
|
||||
name = "swat shield"
|
||||
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
|
||||
max_integrity = 175
|
||||
block_chance = 50
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/implant
|
||||
name = "telescoping shield implant"
|
||||
desc = "A compact, arm-mounted telescopic shield. While nigh-indestructible when powered by a host user, it will eventually overload from damage. Recharges while inside its implant."
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
block_chance = 50
|
||||
slowdown = 1
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 60
|
||||
obj_integrity = 60
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
can_shatter = FALSE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
item_flags = SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
var/recharge_timerid
|
||||
var/recharge_delay = 15 SECONDS
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/obj/item/shrapnel // frag grenades
|
||||
name = "shrapnel shard"
|
||||
embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=4, embed_chance_turf_mod=-100)
|
||||
custom_materials = list(/datum/material/iron=50)
|
||||
armour_penetration = -20
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "large"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
item_flags = DROPDEL
|
||||
|
||||
/obj/item/shrapnel/stingball // stingbang grenades
|
||||
name = "stingball"
|
||||
embedding = list(embed_chance=90, fall_chance=3, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=5, jostle_pain_mult=6, rip_time=15, embed_chance_turf_mod=-100)
|
||||
icon_state = "tiny"
|
||||
|
||||
/obj/item/shrapnel/bullet // bullets
|
||||
name = "bullet"
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "s-casing"
|
||||
item_flags = NONE
|
||||
|
||||
/obj/item/shrapnel/bullet/c38 // .38 round
|
||||
name = "\improper .38 bullet"
|
||||
|
||||
/obj/item/shrapnel/bullet/c38/dumdum // .38 DumDum round
|
||||
name = "\improper .38 DumDum bullet"
|
||||
embedding = list(embed_chance=70, fall_chance=7, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10, embed_chance_turf_mod=-100)
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel
|
||||
name = "flying shrapnel shard"
|
||||
damage = 9
|
||||
range = 10
|
||||
armour_penetration = -30
|
||||
dismemberment = 5
|
||||
ricochets_max = 2
|
||||
ricochet_chance = 40
|
||||
shrapnel_type = /obj/item/shrapnel
|
||||
ricochet_incidence_leeway = 60
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel/mega
|
||||
name = "flying shrapnel hunk"
|
||||
range = 25
|
||||
dismemberment = 10
|
||||
ricochets_max = 4
|
||||
ricochet_chance = 90
|
||||
ricochet_decay_chance = 0.9
|
||||
|
||||
/obj/item/projectile/bullet/pellet/stingball
|
||||
name = "stingball pellet"
|
||||
damage = 3
|
||||
stamina = 8
|
||||
ricochets_max = 4
|
||||
ricochet_chance = 66
|
||||
ricochet_decay_chance = 1
|
||||
ricochet_decay_damage = 0.9
|
||||
ricochet_auto_aim_angle = 10
|
||||
ricochet_auto_aim_range = 2
|
||||
ricochet_incidence_leeway = 0
|
||||
shrapnel_type = /obj/item/shrapnel/stingball
|
||||
|
||||
/obj/item/projectile/bullet/pellet/stingball/mega
|
||||
name = "megastingball pellet"
|
||||
ricochets_max = 6
|
||||
ricochet_chance = 110
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/item/twohanded/singularityhammer
|
||||
/obj/item/singularityhammer
|
||||
name = "singularity hammer"
|
||||
desc = "The pinnacle of close combat technology, the hammer harnesses the power of a miniaturized singularity to deal crushing blows."
|
||||
icon_state = "mjollnir0"
|
||||
@@ -7,35 +7,47 @@
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
force = 5
|
||||
force_unwielded = 5
|
||||
force_wielded = 20
|
||||
throwforce = 15
|
||||
throw_range = 1
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/charged = 5
|
||||
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
force_string = "LORD SINGULOTH HIMSELF"
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
var/charged = 5
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/twohanded/singularityhammer/New()
|
||||
/obj/item/singularityhammer/New()
|
||||
..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/twohanded/singularityhammer/Destroy()
|
||||
/obj/item/singularityhammer/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=4, icon_wielded="mjollnir1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/singularityhammer/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/singularityhammer/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/singularityhammer/update_icon_state()
|
||||
icon_state = "mjollnir0"
|
||||
|
||||
/obj/item/singularityhammer/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/singularityhammer/process()
|
||||
/obj/item/singularityhammer/process()
|
||||
if(charged < 5)
|
||||
charged++
|
||||
return
|
||||
|
||||
/obj/item/twohanded/singularityhammer/update_icon_state() //Currently only here to fuck with the on-mob icons.
|
||||
icon_state = "mjollnir[wielded]"
|
||||
return
|
||||
|
||||
/obj/item/twohanded/singularityhammer/proc/vortex(turf/pull, mob/wielder)
|
||||
/obj/item/singularityhammer/proc/vortex(turf/pull, mob/wielder)
|
||||
for(var/atom/X in orange(5,pull))
|
||||
if(ismovable(X))
|
||||
var/atom/movable/A = X
|
||||
@@ -55,9 +67,8 @@
|
||||
step_towards(H,pull)
|
||||
step_towards(H,pull)
|
||||
step_towards(H,pull)
|
||||
return
|
||||
|
||||
/obj/item/twohanded/singularityhammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
|
||||
/obj/item/singularityhammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
@@ -71,7 +82,7 @@
|
||||
var/turf/target = get_turf(A)
|
||||
vortex(target,user)
|
||||
|
||||
/obj/item/twohanded/mjollnir
|
||||
/obj/item/mjollnir
|
||||
name = "Mjolnir"
|
||||
desc = "A weapon worthy of a god, able to strike with the force of a lightning bolt. It crackles with barely contained energy."
|
||||
icon_state = "mjollnir0"
|
||||
@@ -80,14 +91,33 @@
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
force = 5
|
||||
force_unwielded = 5
|
||||
force_wielded = 25
|
||||
throwforce = 30
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/twohanded/mjollnir/proc/shock(mob/living/target)
|
||||
/obj/item/mjollnir/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/mjollnir/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=5, icon_wielded="mjollnir1", attacksound="sparks")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/mjollnir/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/mjollnir/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/mjollnir/update_icon_state()
|
||||
icon_state = "mjollnir0"
|
||||
|
||||
/obj/item/mjollnir/proc/shock(mob/living/target)
|
||||
target.Stun(60)
|
||||
var/datum/effect_system/lightning_spread/s = new /datum/effect_system/lightning_spread
|
||||
s.set_up(5, 1, target.loc)
|
||||
@@ -99,17 +129,12 @@
|
||||
target.throw_at(throw_target, 200, 4)
|
||||
return
|
||||
|
||||
/obj/item/twohanded/mjollnir/attack(mob/living/M, mob/user)
|
||||
/obj/item/mjollnir/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
if(wielded)
|
||||
playsound(src.loc, "sparks", 50, 1)
|
||||
shock(M)
|
||||
|
||||
/obj/item/twohanded/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
/obj/item/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
. = ..()
|
||||
if(isliving(hit_atom))
|
||||
shock(hit_atom)
|
||||
|
||||
/obj/item/twohanded/mjollnir/update_icon_state() //Currently only here to fuck with the on-mob icons.
|
||||
icon_state = "mjollnir[wielded]"
|
||||
return
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
//spears
|
||||
/obj/item/spear
|
||||
icon_state = "spearglass0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "spear"
|
||||
desc = "A haphazardly-constructed yet still deadly weapon of ancient design."
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
embedding = list("impact_pain_mult" = 3)
|
||||
armour_penetration = 10
|
||||
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=2075)
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
|
||||
sharpness = IS_SHARP
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
|
||||
var/obj/item/grenade/explosive = null
|
||||
var/war_cry = "AAAAARGH!!!"
|
||||
var/icon_prefix = "spearglass"
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/spear/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/spear/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 100, 70) //decent in a pinch, but pretty bad.
|
||||
AddComponent(/datum/component/jousting)
|
||||
AddElement(/datum/element/sword_point)
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=10, force_wielded=18, icon_wielded="[icon_prefix]1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/spear/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/spear/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/spear/rightclick_attack_self(mob/user)
|
||||
if(explosive)
|
||||
explosive.attack_self(user)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/spear/update_icon_state()
|
||||
icon_state = "[icon_prefix]0"
|
||||
|
||||
/obj/item/spear/update_overlays()
|
||||
. = ..()
|
||||
if(explosive)
|
||||
. += "spearbomb_overlay"
|
||||
|
||||
/obj/item/spear/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins to sword-swallow \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(explosive) //Citadel Edit removes qdel and explosive.forcemove(AM)
|
||||
user.say("[war_cry]", forced="spear warcry")
|
||||
explosive.prime()
|
||||
user.gib()
|
||||
return BRUTELOSS
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/spear/examine(mob/user)
|
||||
. = ..()
|
||||
if(explosive)
|
||||
. += "<span class='notice'>Alt-click to set your war cry.</span>"
|
||||
. += "<span class='notice'>Right-click in combat mode to activate the attached explosive.</span>"
|
||||
|
||||
/obj/item/spear/afterattack(atom/movable/AM, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
if(isopenturf(AM)) //So you can actually melee with it
|
||||
return
|
||||
if(explosive && wielded) //Citadel edit removes qdel and explosive.forcemove(AM)
|
||||
user.say("[war_cry]", forced="spear warcry")
|
||||
explosive.prime()
|
||||
|
||||
/obj/item/spear/grenade_prime_react(obj/item/grenade/nade) //Citadel edit, removes throw_impact because memes
|
||||
nade.forceMove(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spear/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
..()
|
||||
if(!explosive)
|
||||
return
|
||||
if(istype(user) && loc == user)
|
||||
var/input = stripped_input(user,"What do you want your war cry to be? You will shout it when you hit someone in melee.", ,"", 50)
|
||||
if(input)
|
||||
src.war_cry = input
|
||||
return TRUE
|
||||
|
||||
/obj/item/spear/CheckParts(list/parts_list)
|
||||
var/obj/item/shard/tip = locate() in parts_list
|
||||
if (istype(tip, /obj/item/shard/plasma))
|
||||
throwforce = 21
|
||||
embedding = list(embed_chance = 75, pain_mult = 1.5) //plasmaglass spears are sharper
|
||||
updateEmbedding()
|
||||
icon_prefix = "spearplasma"
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=11, force_wielded=19, icon_wielded="[icon_prefix]1")
|
||||
qdel(tip)
|
||||
var/obj/item/spear/S = locate() in parts_list
|
||||
if(S)
|
||||
if(S.explosive)
|
||||
S.explosive.forceMove(get_turf(src))
|
||||
S.explosive = null
|
||||
parts_list -= S
|
||||
qdel(S)
|
||||
..()
|
||||
var/obj/item/grenade/G = locate() in contents
|
||||
if(G)
|
||||
explosive = G
|
||||
name = "explosive lance"
|
||||
embedding = list(embed_chance = 0, pain_mult = 1)//elances should not be embeddable
|
||||
updateEmbedding()
|
||||
desc = "A makeshift spear with \a [G] attached to it."
|
||||
update_icon()
|
||||
|
||||
//GREY TIDE
|
||||
/obj/item/spear/grey_tide
|
||||
icon_state = "spearglass0"
|
||||
name = "\improper Grey Tide"
|
||||
desc = "Recovered from the aftermath of a revolt aboard Defense Outpost Theta Aegis, in which a seemingly endless tide of Assistants caused heavy casualities among Nanotrasen military forces."
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
attack_verb = list("gored")
|
||||
var/clonechance = 50
|
||||
var/clonedamage = 12
|
||||
var/clonespeed = 0
|
||||
var/clone_replication_chance = 30
|
||||
var/clone_lifespan = 100
|
||||
|
||||
/obj/item/spear/grey_tide/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=15, force_wielded=25, icon_wielded="[icon_prefix]1")
|
||||
|
||||
/obj/item/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
user.faction |= "greytide([REF(user)])"
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(istype (L, /mob/living/simple_animal/hostile/illusion))
|
||||
return
|
||||
if(!L.stat && prob(clonechance))
|
||||
var/mob/living/simple_animal/hostile/illusion/M = new(user.loc)
|
||||
M.faction = user.faction.Copy()
|
||||
M.set_varspeed(clonespeed)
|
||||
M.Copy_Parent(user, clone_lifespan, user.health/2.5, clonedamage, clone_replication_chance)
|
||||
M.GiveTarget(L)
|
||||
|
||||
/*
|
||||
* Bone Spear
|
||||
*/
|
||||
/obj/item/spear/bonespear //Blatant imitation of spear, but made out of bone. Not valid for explosive modification.
|
||||
icon_state = "bone_spear0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "bone spear"
|
||||
desc = "A haphazardly-constructed yet still deadly weapon. The pinnacle of modern technology."
|
||||
force = 11
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
reach = 2
|
||||
throwforce = 22
|
||||
embedding = list("embedded_impact_pain_multiplier" = 3)
|
||||
armour_penetration = 15 //Enhanced armor piercing
|
||||
custom_materials = null
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
|
||||
sharpness = IS_SHARP
|
||||
icon_prefix = "bone_spear"
|
||||
|
||||
/obj/item/spear/bonespear/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=11, force_wielded=20, icon_wielded="[icon_prefix]1")
|
||||
@@ -71,3 +71,9 @@
|
||||
icon_state = "spacecash1000"
|
||||
singular_name = "one thousand credit bill"
|
||||
value = 1000
|
||||
|
||||
/obj/item/stack/spacecash/c10000
|
||||
icon_state = "spacecash10000"
|
||||
singular_name = "ten thousand credit bill"
|
||||
value = 10000
|
||||
|
||||
|
||||
@@ -13,18 +13,33 @@
|
||||
novariants = FALSE
|
||||
item_flags = NOBLUDGEON
|
||||
var/self_delay = 50
|
||||
var/other_delay = 0
|
||||
var/repeating = FALSE
|
||||
|
||||
/obj/item/stack/medical/attack(mob/living/M, mob/user)
|
||||
. = ..()
|
||||
try_heal(M, user)
|
||||
|
||||
|
||||
/obj/item/stack/medical/proc/try_heal(mob/living/M, mob/user, silent = FALSE)
|
||||
if(!M.can_inject(user, TRUE))
|
||||
return
|
||||
if(M == user)
|
||||
user.visible_message("<span class='notice'>[user] starts to apply \the [src] on [user.p_them()]self...</span>", "<span class='notice'>You begin applying \the [src] on yourself...</span>")
|
||||
if(!silent)
|
||||
user.visible_message("<span class='notice'>[user] starts to apply \the [src] on [user.p_them()]self...</span>", "<span class='notice'>You begin applying \the [src] on yourself...</span>")
|
||||
if(!do_mob(user, M, self_delay, extra_checks=CALLBACK(M, /mob/living/proc/can_inject, user, TRUE)))
|
||||
return
|
||||
else if(other_delay)
|
||||
if(!silent)
|
||||
user.visible_message("<span class='notice'>[user] starts to apply \the [src] on [M].</span>", "<span class='notice'>You begin applying \the [src] on [M]...</span>")
|
||||
if(!do_mob(user, M, other_delay, extra_checks=CALLBACK(M, /mob/living/proc/can_inject, user, TRUE)))
|
||||
return
|
||||
|
||||
if(heal(M, user))
|
||||
log_combat(user, M, "healed", src.name)
|
||||
use(1)
|
||||
if(repeating && amount > 0)
|
||||
try_heal(M, user, TRUE)
|
||||
|
||||
|
||||
/obj/item/stack/medical/proc/heal(mob/living/M, mob/user)
|
||||
@@ -96,7 +111,7 @@
|
||||
var/stop_bleeding = 1800
|
||||
var/heal_brute = 5
|
||||
self_delay = 10
|
||||
custom_price = 100
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
|
||||
/obj/item/stack/medical/gauze/heal(mob/living/M, mob/user)
|
||||
if(ishuman(M))
|
||||
@@ -174,3 +189,108 @@
|
||||
/obj/item/stack/medical/ointment/suicide_act(mob/living/user)
|
||||
user.visible_message("<span class='suicide'>[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?</span>")
|
||||
return TOXLOSS
|
||||
|
||||
/obj/item/stack/medical/suture
|
||||
name = "suture"
|
||||
desc = "Sterile sutures used to seal up cuts and lacerations."
|
||||
gender = PLURAL
|
||||
singular_name = "suture"
|
||||
icon_state = "suture"
|
||||
self_delay = 30
|
||||
other_delay = 10
|
||||
amount = 15
|
||||
max_amount = 15
|
||||
repeating = TRUE
|
||||
var/heal_brute = 10
|
||||
grind_results = list(/datum/reagent/medicine/spaceacillin = 2)
|
||||
|
||||
/obj/item/stack/medical/suture/one
|
||||
amount = 1
|
||||
|
||||
/obj/item/stack/medical/suture/heal(mob/living/M, mob/user)
|
||||
. = ..()
|
||||
if(M.stat == DEAD)
|
||||
to_chat(user, "<span class='warning'>[M] is dead! You can not help [M.p_them()].</span>")
|
||||
return
|
||||
if(iscarbon(M))
|
||||
return heal_carbon(M, user, heal_brute, 0)
|
||||
if(isanimal(M))
|
||||
var/mob/living/simple_animal/critter = M
|
||||
if (!(critter.healable))
|
||||
to_chat(user, "<span class='warning'>You cannot use \the [src] on [M]!</span>")
|
||||
return FALSE
|
||||
else if (critter.health == critter.maxHealth)
|
||||
to_chat(user, "<span class='notice'>[M] is at full health.</span>")
|
||||
return FALSE
|
||||
user.visible_message("<span class='green'>[user] applies \the [src] on [M].</span>", "<span class='green'>You apply \the [src] on [M].</span>")
|
||||
M.heal_bodypart_damage(heal_brute)
|
||||
return TRUE
|
||||
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
|
||||
|
||||
/obj/item/stack/medical/mesh
|
||||
name = "regenerative mesh"
|
||||
desc = "A bacteriostatic mesh used to dress burns."
|
||||
gender = PLURAL
|
||||
singular_name = "regenerative mesh"
|
||||
icon_state = "regen_mesh"
|
||||
self_delay = 30
|
||||
other_delay = 10
|
||||
amount = 15
|
||||
max_amount = 15
|
||||
repeating = TRUE
|
||||
var/heal_burn = 10
|
||||
var/is_open = TRUE ///This var determines if the sterile packaging of the mesh has been opened.
|
||||
grind_results = list(/datum/reagent/medicine/spaceacillin = 2)
|
||||
|
||||
/obj/item/stack/medical/mesh/one
|
||||
amount = 1
|
||||
|
||||
/obj/item/stack/medical/mesh/Initialize()
|
||||
. = ..()
|
||||
if(amount == max_amount) //only seal full mesh packs
|
||||
is_open = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/stack/medical/mesh/update_icon_state()
|
||||
if(!is_open)
|
||||
icon_state = "regen_mesh_closed"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/medical/mesh/heal(mob/living/M, mob/user)
|
||||
. = ..()
|
||||
if(M.stat == DEAD)
|
||||
to_chat(user, "<span class='warning'>[M] is dead! You can not help [M.p_them()].</span>")
|
||||
return
|
||||
if(iscarbon(M))
|
||||
return heal_carbon(M, user, 0, heal_burn)
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
|
||||
|
||||
|
||||
/obj/item/stack/medical/mesh/try_heal(mob/living/M, mob/user, silent = FALSE)
|
||||
if(!is_open)
|
||||
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/medical/mesh/AltClick(mob/living/user)
|
||||
if(!is_open)
|
||||
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/medical/mesh/attack_hand(mob/user)
|
||||
if(!is_open & user.get_inactive_held_item() == src)
|
||||
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/medical/mesh/attack_self(mob/user)
|
||||
if(!is_open)
|
||||
is_open = TRUE
|
||||
to_chat(user, "<span class='notice'>You open the sterile mesh package.</span>")
|
||||
update_icon()
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 20, TRUE)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -17,10 +17,10 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
custom_materials = list(/datum/material/iron=1000)
|
||||
mats_per_stack = 1000
|
||||
max_amount = 50
|
||||
attack_verb = list("hit", "bludgeoned", "whacked")
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg'
|
||||
embedding = list()
|
||||
novariants = TRUE
|
||||
|
||||
/obj/item/stack/rods/suicide_act(mob/living/carbon/user)
|
||||
@@ -89,3 +89,19 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
|
||||
/obj/item/stack/rods/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/rods/lava
|
||||
name = "heat resistant rod"
|
||||
desc = "Treated, specialized metal rods. When exposed to the vaccum of space their coating breaks off, but they can hold up against the extreme heat of active lava."
|
||||
singular_name = "heat resistant rod"
|
||||
icon_state = "rods"
|
||||
item_state = "rods"
|
||||
color = "#5286b9ff"
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
custom_materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000)
|
||||
max_amount = 30
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
/obj/item/stack/rods/lava/thirty
|
||||
amount = 30
|
||||
|
||||
@@ -69,7 +69,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
if (get_amount() < 1 || CC.get_amount() < 5)
|
||||
to_chat(user, "<span class='warning>You need five lengths of coil and one sheet of glass to make wired glass!</span>")
|
||||
return
|
||||
CC.use_tool(src, user, 0, 5, max_level = JOB_SKILL_BASIC)
|
||||
CC.use_tool(src, user, 0, 5, skill_gain_mult = TRIVIAL_USE_TOOL_MULT)
|
||||
use(1)
|
||||
to_chat(user, "<span class='notice'>You attach wire to the [name].</span>")
|
||||
var/obj/item/stack/light_w/new_tile = new(user.loc)
|
||||
@@ -291,6 +291,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
max_integrity = 40
|
||||
sharpness = IS_SHARP
|
||||
var/icon_prefix
|
||||
embedding = list("embed_chance" = 65)
|
||||
|
||||
|
||||
/obj/item/shard/suicide_act(mob/user)
|
||||
|
||||
@@ -39,9 +39,11 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
|
||||
item_state = "sheet-sandstone"
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
custom_materials = list(/datum/material/glass=MINERAL_MATERIAL_AMOUNT)
|
||||
custom_materials = list(/datum/material/sandstone=MINERAL_MATERIAL_AMOUNT)
|
||||
sheettype = "sandstone"
|
||||
merge_type = /obj/item/stack/sheet/mineral/sandstone
|
||||
walltype = /turf/closed/wall/mineral/sandstone
|
||||
material_type = /datum/material/sandstone
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -107,6 +109,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
|
||||
point_value = 25
|
||||
merge_type = /obj/item/stack/sheet/mineral/diamond
|
||||
material_type = /datum/material/diamond
|
||||
walltype = /turf/closed/wall/mineral/diamond
|
||||
|
||||
GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -135,6 +138,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/uranium
|
||||
material_type = /datum/material/uranium
|
||||
walltype = /turf/closed/wall/mineral/uranium
|
||||
|
||||
GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -163,6 +167,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/plasma
|
||||
material_type = /datum/material/plasma
|
||||
walltype = /turf/closed/wall/mineral/plasma
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins licking \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -205,6 +210,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/gold
|
||||
material_type = /datum/material/gold
|
||||
walltype = /turf/closed/wall/mineral/gold
|
||||
|
||||
GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -236,6 +242,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
merge_type = /obj/item/stack/sheet/mineral/silver
|
||||
material_type = /datum/material/silver
|
||||
tableVariant = /obj/structure/table/optable
|
||||
walltype = /turf/closed/wall/mineral/silver
|
||||
|
||||
GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -266,6 +273,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
point_value = 50
|
||||
merge_type = /obj/item/stack/sheet/mineral/bananium
|
||||
material_type = /datum/material/bananium
|
||||
walltype = /turf/closed/wall/mineral/bananium
|
||||
|
||||
GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
|
||||
@@ -294,6 +302,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/titanium
|
||||
material_type = /datum/material/titanium
|
||||
walltype = /turf/closed/wall/mineral/titanium
|
||||
|
||||
GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \
|
||||
@@ -324,6 +333,7 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 45
|
||||
merge_type = /obj/item/stack/sheet/mineral/plastitanium
|
||||
walltype = /turf/closed/wall/mineral/plastitanium
|
||||
|
||||
/obj/item/stack/sheet/mineral/plastitanium/fifty
|
||||
amount = 50
|
||||
@@ -390,11 +400,14 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
|
||||
name = "snow"
|
||||
icon_state = "sheet-snow"
|
||||
item_state = "sheet-snow"
|
||||
custom_materials = list(/datum/material/snow = MINERAL_MATERIAL_AMOUNT)
|
||||
singular_name = "snow block"
|
||||
force = 1
|
||||
throwforce = 2
|
||||
grind_results = list(/datum/reagent/consumable/ice = 20)
|
||||
merge_type = /obj/item/stack/sheet/mineral/snow
|
||||
walltype = /turf/closed/wall/mineral/snow
|
||||
material_type = /datum/material/snow
|
||||
|
||||
GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -417,6 +430,7 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
singular_name = "alien alloy sheet"
|
||||
sheettype = "abductor"
|
||||
merge_type = /obj/item/stack/sheet/mineral/abductor
|
||||
walltype = /turf/closed/wall/mineral/abductor
|
||||
|
||||
GLOBAL_LIST_INIT(abductor_recipes, list ( \
|
||||
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* Wood
|
||||
* Bamboo
|
||||
* Cloth
|
||||
* Silk
|
||||
* Durathread
|
||||
* Cardboard
|
||||
* Runed Metal (cult)
|
||||
@@ -63,7 +62,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
|
||||
new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
|
||||
new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
|
||||
null, \
|
||||
new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \
|
||||
null, \
|
||||
new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
@@ -206,7 +205,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
|
||||
desc = "This sheet is an alloy of iron and plasma."
|
||||
icon_state = "sheet-plasteel"
|
||||
item_state = "sheet-metal"
|
||||
custom_materials = list(/datum/material/iron=2000, /datum/material/plasma=2000)
|
||||
custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT)
|
||||
throwforce = 10
|
||||
flags_1 = CONDUCT_1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80)
|
||||
@@ -241,7 +240,8 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
new /datum/stack_recipe("pew (right)", /obj/structure/chair/pew/right, 3, one_per_turf = TRUE, on_floor = TRUE),\
|
||||
)),
|
||||
null, \
|
||||
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \
|
||||
new/datum/stack_recipe("wooden firearm body", /obj/item/weaponcrafting/improvised_parts/wooden_body, 10, time = 20), \
|
||||
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 20), \
|
||||
new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wood, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \
|
||||
@@ -268,6 +268,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\
|
||||
null, \
|
||||
new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\
|
||||
new/datum/stack_recipe("painting frame", /obj/item/wallframe/painting, 1, time = 10),\
|
||||
new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar, 3), \
|
||||
new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\
|
||||
))
|
||||
@@ -279,12 +280,15 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
icon_state = "sheet-wood"
|
||||
item_state = "sheet-wood"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/wood=MINERAL_MATERIAL_AMOUNT)
|
||||
sheettype = "wood"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/mineral/wood
|
||||
novariants = TRUE
|
||||
material_type = /datum/material/wood
|
||||
grind_results = list(/datum/reagent/carbon = 20)
|
||||
walltype = /turf/closed/wall/mineral/wood
|
||||
|
||||
/obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there.
|
||||
// Taken from /obj/item/stack/rods/attackby in [rods.dm]
|
||||
@@ -340,11 +344,13 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
|
||||
icon_state = "sheet-bamboo"
|
||||
item_state = "sheet-bamboo"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/bamboo = MINERAL_MATERIAL_AMOUNT)
|
||||
throwforce = 15
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/mineral/bamboo
|
||||
grind_results = list(/datum/reagent/carbon = 5)
|
||||
material_type = /datum/material/bamboo
|
||||
|
||||
/obj/item/stack/sheet/mineral/bamboo/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -375,6 +381,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
new/datum/stack_recipe("chemistry bag", /obj/item/storage/bag/chemistry, 4), \
|
||||
new/datum/stack_recipe("bio bag", /obj/item/storage/bag/bio, 4), \
|
||||
null, \
|
||||
new/datum/stack_recipe("string", /obj/item/weaponcrafting/string, 1, time = 10), \
|
||||
new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/gauze/improvised, 1, 2, 6), \
|
||||
new/datum/stack_recipe("rag", /obj/item/reagent_containers/rag, 1), \
|
||||
new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \
|
||||
@@ -388,6 +395,9 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
null, \
|
||||
new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 2), \
|
||||
null, \
|
||||
new/datum/stack_recipe("19x19 canvas", /obj/item/canvas/nineteenXnineteen, 3), \
|
||||
new/datum/stack_recipe("23x19 canvas", /obj/item/canvas/twentythreeXnineteen, 4), \
|
||||
new/datum/stack_recipe("23x23 canvas", /obj/item/canvas/twentythreeXtwentythree, 5), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/cloth
|
||||
@@ -399,9 +409,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
resistance_flags = FLAMMABLE
|
||||
force = 0
|
||||
throwforce = 0
|
||||
pull_effort = 90
|
||||
is_fabric = TRUE
|
||||
loom_result = /obj/item/stack/sheet/silk
|
||||
merge_type = /obj/item/stack/sheet/cloth
|
||||
|
||||
/obj/item/stack/sheet/cloth/get_main_recipes()
|
||||
@@ -414,30 +421,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
/obj/item/stack/sheet/cloth/thirty
|
||||
amount = 30
|
||||
|
||||
/*
|
||||
* Silk
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(silk_recipes, list ( \
|
||||
new/datum/stack_recipe("white jumpsuit", /obj/item/clothing/under/color/white, 4, time = 40), \
|
||||
new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 2, time = 40), \
|
||||
null, \
|
||||
new/datum/stack_recipe("silk string", /obj/item/weaponcrafting/silkstring, 1, time = 40), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/silk
|
||||
name = "silk"
|
||||
desc = "A long, soft material. Made out of refined cotton, instead of relying on the habits of spiders or silkworms."
|
||||
singular_name = "silk sheet"
|
||||
icon_state = "sheet-silk"
|
||||
item_state = "sheet-cloth"
|
||||
novariants = TRUE
|
||||
merge_type = /obj/item/stack/sheet/silk
|
||||
|
||||
/obj/item/stack/sheet/silk/get_main_recipes()
|
||||
. = ..()
|
||||
. += GLOB.silk_recipes
|
||||
|
||||
/*
|
||||
* Durathread
|
||||
*/
|
||||
@@ -532,12 +515,14 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
|
||||
desc = "Large sheets of card, like boxes folded flat."
|
||||
singular_name = "cardboard sheet"
|
||||
icon_state = "sheet-card"
|
||||
custom_materials = list(/datum/material/cardboard = MINERAL_MATERIAL_AMOUNT)
|
||||
item_state = "sheet-card"
|
||||
resistance_flags = FLAMMABLE
|
||||
force = 0
|
||||
throwforce = 0
|
||||
merge_type = /obj/item/stack/sheet/cardboard
|
||||
novariants = TRUE
|
||||
material_type = /datum/material/cardboard
|
||||
|
||||
/obj/item/stack/sheet/cardboard/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -577,10 +562,12 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
icon_state = "sheet-runed"
|
||||
item_state = "sheet-runed"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/runedmetal = MINERAL_MATERIAL_AMOUNT)
|
||||
sheettype = "runed"
|
||||
merge_type = /obj/item/stack/sheet/runed_metal
|
||||
novariants = TRUE
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/blood = 15)
|
||||
material_type = /datum/material/runedmetal
|
||||
|
||||
/obj/item/stack/sheet/runed_metal/ratvar_act()
|
||||
new /obj/item/stack/tile/brass(loc, amount)
|
||||
@@ -699,6 +686,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
icon_state = "sheet-brass"
|
||||
item_state = "sheet-brass"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/bronze = MINERAL_MATERIAL_AMOUNT)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
throwforce = 10
|
||||
max_amount = 50
|
||||
@@ -709,6 +697,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/copper = 3) //we have no "tin" reagent so this is the closest thing
|
||||
merge_type = /obj/item/stack/tile/bronze
|
||||
tableVariant = /obj/structure/table/bronze
|
||||
material_type = /datum/material/bronze
|
||||
|
||||
/obj/item/stack/tile/bronze/attack_self(mob/living/user)
|
||||
if(is_servant_of_ratvar(user)) //still lets them build with it, just gives a message
|
||||
@@ -756,6 +745,7 @@ GLOBAL_LIST_INIT(bone_recipes, list(
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "bone"
|
||||
item_state = "sheet-bone"
|
||||
custom_materials = list(/datum/material/bone = MINERAL_MATERIAL_AMOUNT)
|
||||
singular_name = "bone"
|
||||
desc = "Someone's been drinking their milk."
|
||||
force = 7
|
||||
@@ -766,6 +756,7 @@ GLOBAL_LIST_INIT(bone_recipes, list(
|
||||
throw_range = 3
|
||||
grind_results = list(/datum/reagent/carbon = 10)
|
||||
merge_type = /obj/item/stack/sheet/bone
|
||||
material_type = /datum/material/bone
|
||||
|
||||
/obj/item/stack/sheet/bone/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -793,11 +784,15 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
|
||||
custom_materials = list(/datum/material/plastic=MINERAL_MATERIAL_AMOUNT)
|
||||
throwforce = 7
|
||||
grind_results = list(/datum/reagent/glitter/white = 60)
|
||||
material_type = /datum/material/plastic
|
||||
merge_type = /obj/item/stack/sheet/plastic
|
||||
|
||||
/obj/item/stack/sheet/plastic/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/sheet/plastic/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/sheet/plastic/five
|
||||
amount = 5
|
||||
|
||||
@@ -815,9 +810,11 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
singular_name = "paper frame"
|
||||
icon_state = "sheet-paper"
|
||||
item_state = "sheet-paper"
|
||||
custom_materials = list(/datum/material/paper = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/paperframes
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/paperframes
|
||||
material_type = /datum/material/paper
|
||||
|
||||
/obj/item/stack/sheet/paperframes/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -837,13 +834,12 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
max_amount = 80
|
||||
singular_name = "raw cotton ball"
|
||||
icon_state = "sheet-cotton"
|
||||
is_fabric = TRUE
|
||||
resistance_flags = FLAMMABLE
|
||||
force = 0
|
||||
throwforce = 0
|
||||
merge_type = /obj/item/stack/sheet/cotton
|
||||
pull_effort = 30
|
||||
loom_result = /obj/item/stack/sheet/cloth
|
||||
var/pull_effort = 30
|
||||
var/loom_result = /obj/item/stack/sheet/cloth
|
||||
|
||||
/obj/item/stack/sheet/cotton/ten
|
||||
amount = 10
|
||||
@@ -859,3 +855,55 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
merge_type = /obj/item/stack/sheet/cotton/durathread
|
||||
pull_effort = 70
|
||||
loom_result = /obj/item/stack/sheet/durathread
|
||||
|
||||
/obj/item/stack/sheet/meat
|
||||
name = "meat sheets"
|
||||
desc = "Something's bloody meat compressed into a nice solid sheet"
|
||||
singular_name = "meat sheet"
|
||||
icon_state = "sheet-meat"
|
||||
material_flags = MATERIAL_COLOR
|
||||
custom_materials = list(/datum/material/meat = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/meat
|
||||
material_type = /datum/material/meat
|
||||
material_modifier = 1 //None of that wussy stuff
|
||||
|
||||
/obj/item/stack/sheet/meat/fifty
|
||||
amount = 50
|
||||
/obj/item/stack/sheet/meat/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/meat/five
|
||||
amount = 5
|
||||
|
||||
/obj/item/stack/sheet/pizza
|
||||
name = "pepperoni sheetzzas"
|
||||
desc = "It's a delicious pepperoni sheetzza!"
|
||||
singular_name = "pepperoni sheetzza"
|
||||
icon_state = "sheet-pizza"
|
||||
custom_materials = list(/datum/material/pizza = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/pizza
|
||||
material_type = /datum/material/pizza
|
||||
material_modifier = 1
|
||||
|
||||
/obj/item/stack/sheet/pizza/fifty
|
||||
amount = 50
|
||||
/obj/item/stack/sheet/pizza/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/pizza/five
|
||||
amount = 5
|
||||
|
||||
/obj/item/stack/sheet/sandblock
|
||||
name = "blocks of sand"
|
||||
desc = "You're too old to be playing with sandcastles. Now you build... sandstations."
|
||||
singular_name = "block of sand"
|
||||
icon_state = "sheet-sandstone"
|
||||
custom_materials = list(/datum/material/sand = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/sandblock
|
||||
material_type = /datum/material/sand
|
||||
material_modifier = 1
|
||||
|
||||
/obj/item/stack/sheet/sandblock/fifty
|
||||
amount = 50
|
||||
/obj/item/stack/sheet/sandblock/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/sandblock/five
|
||||
amount = 5
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
throw_range = 3
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
|
||||
novariants = FALSE
|
||||
mats_per_stack = MINERAL_MATERIAL_AMOUNT
|
||||
var/sheettype = null //this is used for girders in the creation of walls/false walls
|
||||
var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity
|
||||
var/is_fabric = FALSE //is this a valid material for the loom?
|
||||
var/loom_result //result from pulling on the loom
|
||||
var/pull_effort = 0 //amount of delay when pulling on the loom
|
||||
var/shard_type // the shard debris typepath left over by solar panels and windows etc.
|
||||
///this is used for girders in the creation of walls/false walls
|
||||
var/sheettype = null
|
||||
///turn-in value for the gulag stacker - loosely relative to its rarity
|
||||
var/point_value = 0
|
||||
/// the shard debris typepath left over by solar panels and windows etc.
|
||||
var/shard_type
|
||||
///What type of wall does this sheet spawn
|
||||
var/walltype
|
||||
|
||||
/obj/item/stack/sheet/Initialize(mapload, new_amount, merge)
|
||||
. = ..()
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/merge_type = null // This path and its children should merge with this stack, defaults to src.type
|
||||
var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount
|
||||
var/novariants = TRUE //Determines whether the item should update it's sprites based on amount.
|
||||
var/mats_per_stack = 0
|
||||
var/list/mats_per_unit //list that tells you how much is in a single unit.
|
||||
///Datum material type that this stack is made of
|
||||
var/material_type
|
||||
//NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind()
|
||||
@@ -47,8 +47,11 @@
|
||||
if(!merge_type)
|
||||
merge_type = type
|
||||
if(custom_materials && custom_materials.len)
|
||||
mats_per_unit = list()
|
||||
var/in_process_mat_list = custom_materials.Copy()
|
||||
for(var/i in custom_materials)
|
||||
custom_materials[SSmaterials.GetMaterialRef(i)] = mats_per_stack * amount
|
||||
mats_per_unit[SSmaterials.GetMaterialRef(i)] = in_process_mat_list[i]
|
||||
custom_materials[i] *= amount
|
||||
. = ..()
|
||||
if(merge)
|
||||
for(var/obj/item/stack/S in loc)
|
||||
@@ -60,7 +63,7 @@
|
||||
var/datum/material/M = SSmaterials.GetMaterialRef(material_type) //First/main material
|
||||
for(var/i in M.categories)
|
||||
switch(i)
|
||||
if(MAT_CATEGORY_RIGID)
|
||||
if(MAT_CATEGORY_BASE_RECIPES)
|
||||
var/list/temp = SSmaterials.rigid_stack_recipes.Copy()
|
||||
recipes += temp
|
||||
update_weight()
|
||||
@@ -201,8 +204,13 @@
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
if (R.time)
|
||||
var/adjusted_time = 0
|
||||
usr.visible_message("<span class='notice'>[usr] starts building [R.title].</span>", "<span class='notice'>You start building [R.title]...</span>")
|
||||
if (!do_after(usr, R.time, target = usr))
|
||||
if(HAS_TRAIT(usr, R.trait_booster))
|
||||
adjusted_time = (R.time * R.trait_modifier)
|
||||
else
|
||||
adjusted_time = R.time
|
||||
if (!do_after(usr, adjusted_time, target = usr))
|
||||
return
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
@@ -310,10 +318,13 @@
|
||||
if (amount < used)
|
||||
return FALSE
|
||||
amount -= used
|
||||
if(check)
|
||||
zero_amount()
|
||||
for(var/i in custom_materials)
|
||||
custom_materials[i] = amount * mats_per_stack
|
||||
if(check && zero_amount())
|
||||
return TRUE
|
||||
if(length(mats_per_unit))
|
||||
var/temp_materials = custom_materials.Copy()
|
||||
for(var/i in mats_per_unit)
|
||||
temp_materials[i] = mats_per_unit[i] * src.amount
|
||||
set_custom_materials(temp_materials)
|
||||
update_icon()
|
||||
update_weight()
|
||||
return TRUE
|
||||
@@ -345,10 +356,11 @@
|
||||
source.add_charge(amount * cost)
|
||||
else
|
||||
src.amount += amount
|
||||
if(custom_materials && custom_materials.len)
|
||||
for(var/i in custom_materials)
|
||||
custom_materials[SSmaterials.GetMaterialRef(i)] = MINERAL_MATERIAL_AMOUNT * src.amount
|
||||
set_custom_materials() //Refresh
|
||||
if(length(mats_per_unit))
|
||||
var/temp_materials = custom_materials.Copy()
|
||||
for(var/i in mats_per_unit)
|
||||
temp_materials[i] = mats_per_unit[i] * src.amount
|
||||
set_custom_materials(temp_materials)
|
||||
update_icon()
|
||||
update_weight()
|
||||
|
||||
@@ -457,8 +469,10 @@
|
||||
var/window_checks = FALSE
|
||||
var/placement_checks = FALSE
|
||||
var/applies_mats = FALSE
|
||||
var/trait_booster = null
|
||||
var/trait_modifier = 1
|
||||
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE)
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1)
|
||||
|
||||
|
||||
src.title = title
|
||||
@@ -472,6 +486,8 @@
|
||||
src.window_checks = window_checks
|
||||
src.placement_checks = placement_checks
|
||||
src.applies_mats = applies_mats
|
||||
src.trait_booster = trait_booster
|
||||
src.trait_modifier = trait_modifier
|
||||
/*
|
||||
* Recipe list datum
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
|
||||
/obj/item/stack/sticky_tape
|
||||
name = "sticky tape"
|
||||
singular_name = "sticky tape"
|
||||
desc = "Used for sticking to things for sticking said things to people."
|
||||
icon = 'icons/obj/tapes.dmi'
|
||||
icon_state = "tape_w"
|
||||
var/prefix = "sticky"
|
||||
item_flags = NOBLUDGEON
|
||||
amount = 5
|
||||
max_amount = 5
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
var/list/conferred_embed = EMBED_HARMLESS
|
||||
var/overwrite_existing = FALSE
|
||||
|
||||
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
|
||||
if(!istype(I))
|
||||
return
|
||||
|
||||
if(I.embedding && I.embedding == conferred_embed)
|
||||
to_chat(user, "<span class='warning'>[I] is already coated in [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] begins wrapping [I] with [src].</span>", "<span class='notice'>You begin wrapping [I] with [src].</span>")
|
||||
|
||||
if(do_after(user, 30, target=I))
|
||||
I.embedding = conferred_embed
|
||||
I.updateEmbedding()
|
||||
to_chat(user, "<span class='notice'>You finish wrapping [I] with [src].</span>")
|
||||
use(1)
|
||||
I.name = "[prefix] [I.name]"
|
||||
|
||||
if(istype(I, /obj/item/grenade))
|
||||
var/obj/item/grenade/sticky_bomb = I
|
||||
sticky_bomb.sticky = TRUE
|
||||
|
||||
/obj/item/stack/sticky_tape/super
|
||||
name = "super sticky tape"
|
||||
singular_name = "super sticky tape"
|
||||
desc = "Quite possibly the most mischevious substance in the galaxy. Use with extreme lack of caution."
|
||||
icon_state = "tape_y"
|
||||
prefix = "super sticky"
|
||||
conferred_embed = EMBED_HARMLESS_SUPERIOR
|
||||
|
||||
/obj/item/stack/sticky_tape/pointy
|
||||
name = "pointy tape"
|
||||
singular_name = "pointy tape"
|
||||
desc = "Used for sticking to things for sticking said things inside people."
|
||||
icon_state = "tape_evil"
|
||||
prefix = "pointy"
|
||||
conferred_embed = EMBED_POINTY
|
||||
|
||||
/obj/item/stack/sticky_tape/pointy/super
|
||||
name = "super pointy tape"
|
||||
singular_name = "super pointy tape"
|
||||
desc = "You didn't know tape could look so sinister. Welcome to Space Station 13."
|
||||
icon_state = "tape_spikes"
|
||||
prefix = "super pointy"
|
||||
conferred_embed = EMBED_POINTY_SUPERIOR
|
||||
@@ -9,16 +9,35 @@
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
max_amount = 60
|
||||
mats_per_stack = 500
|
||||
var/turf_type = null
|
||||
var/mineralType = null
|
||||
novariants = TRUE
|
||||
var/human_maxHealth = 100
|
||||
|
||||
/obj/item/stack/tile/Initialize(mapload, amount)
|
||||
. = ..()
|
||||
pixel_x = rand(-3, 3)
|
||||
pixel_y = rand(-3, 3) //randomize a little
|
||||
|
||||
/obj/item/stack/tile/examine(mob/user)
|
||||
. = ..()
|
||||
if(throwforce && !is_cyborg) //do not want to divide by zero or show the message to borgs who can't throw
|
||||
var/verb
|
||||
switch(CEILING(human_maxHealth / throwforce, 1)) //throws to crit a human
|
||||
if(1 to 3)
|
||||
verb = "superb"
|
||||
if(4 to 6)
|
||||
verb = "great"
|
||||
if(7 to 9)
|
||||
verb = "good"
|
||||
if(10 to 12)
|
||||
verb = "fairly decent"
|
||||
if(13 to 15)
|
||||
verb = "mediocre"
|
||||
if(!verb)
|
||||
return
|
||||
. += "<span class='notice'>Those could work as a [verb] throwing weapon.</span>"
|
||||
|
||||
/obj/item/stack/tile/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
if (istype(W, /obj/item/weldingtool))
|
||||
@@ -266,6 +285,9 @@
|
||||
/obj/item/stack/tile/carpet/blackred/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/blackred/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/blackred/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -275,6 +297,9 @@
|
||||
/obj/item/stack/tile/carpet/monochrome/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/monochrome/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -284,6 +309,9 @@
|
||||
/obj/item/stack/tile/carpet/blue/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/blue/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/blue/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -293,6 +321,9 @@
|
||||
/obj/item/stack/tile/carpet/cyan/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/cyan/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/cyan/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -302,6 +333,9 @@
|
||||
/obj/item/stack/tile/carpet/green/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/green/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/green/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -311,6 +345,9 @@
|
||||
/obj/item/stack/tile/carpet/orange/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/orange/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/orange/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -320,6 +357,9 @@
|
||||
/obj/item/stack/tile/carpet/purple/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/purple/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/purple/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -329,6 +369,9 @@
|
||||
/obj/item/stack/tile/carpet/red/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/red/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/red/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -338,6 +381,9 @@
|
||||
/obj/item/stack/tile/carpet/royalblack/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/royalblack/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -347,6 +393,9 @@
|
||||
/obj/item/stack/tile/carpet/royalblue/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/royalblue/thirty
|
||||
amount = 30
|
||||
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty
|
||||
amount = 50
|
||||
|
||||
@@ -440,7 +489,7 @@
|
||||
/obj/item/stack/tile/plasteel
|
||||
name = "floor tile"
|
||||
singular_name = "floor tile"
|
||||
desc = "Those could work as a pretty decent throwing weapon."
|
||||
desc = "The ground you walk on."
|
||||
icon_state = "tile"
|
||||
force = 6
|
||||
custom_materials = list(/datum/material/iron=500)
|
||||
@@ -452,7 +501,15 @@
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/stack/tile/plasteel/cyborg
|
||||
desc = "The ground you walk on." //Not the usual floor tile desc as that refers to throwing, Cyborgs can't do that - RR
|
||||
custom_materials = null // All other Borg versions of items have no Metal or Glass - RR
|
||||
is_cyborg = 1
|
||||
cost = 125
|
||||
|
||||
/obj/item/stack/tile/material
|
||||
name = "floor tile"
|
||||
singular_name = "floor tile"
|
||||
desc = "The ground you walk on."
|
||||
throwforce = 10
|
||||
icon_state = "material_tile"
|
||||
turf_type = /turf/open/floor/material
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
/obj/item/storage/backpack/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 21
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_items = 21
|
||||
STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
|
||||
STR.max_volume = STORAGE_VOLUME_BACKPACK
|
||||
STR.max_w_class = MAX_WEIGHT_CLASS_BACKPACK
|
||||
|
||||
/*
|
||||
* Backpack Types
|
||||
@@ -64,9 +64,9 @@
|
||||
/obj/item/storage/backpack/holding/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.allow_big_nesting = TRUE
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY
|
||||
STR.max_combined_w_class = 35
|
||||
STR.max_w_class = MAX_WEIGHT_CLASS_BAG_OF_HOLDING
|
||||
STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
|
||||
STR.max_volume = STORAGE_VOLUME_BAG_OF_HOLDING
|
||||
|
||||
/obj/item/storage/backpack/holding/suicide_act(mob/living/user)
|
||||
user.visible_message("<span class='suicide'>[user] is jumping into [src]! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
@@ -344,7 +344,7 @@
|
||||
/obj/item/storage/backpack/duffelbag/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 30
|
||||
STR.max_volume = STORAGE_VOLUME_DUFFLEBAG
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/captain
|
||||
name = "captain's duffel bag"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
switch(contents.len)
|
||||
if(0)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
if(0 to 11)
|
||||
if(1 to 11)
|
||||
icon_state = "[initial(icon_state)]1"
|
||||
if(11 to 20)
|
||||
icon_state = "[initial(icon_state)]2"
|
||||
@@ -326,6 +326,7 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
custom_materials = list(/datum/material/iron=3000)
|
||||
var/max_items = 7
|
||||
|
||||
/obj/item/storage/bag/tray/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -333,6 +334,7 @@
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food, /obj/item/reagent_containers/glass, /datum/reagent/consumable, /obj/item/kitchen/knife, /obj/item/kitchen/rollingpin, /obj/item/kitchen/fork, /obj/item/storage/box)) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Kitchen Tools, and ingredient boxes.
|
||||
STR.insert_preposition = "on"
|
||||
STR.max_items = max_items
|
||||
|
||||
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
|
||||
. = ..()
|
||||
@@ -373,6 +375,14 @@
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
//bluespace tray, holds more items
|
||||
/obj/item/storage/bag/tray/bluespace
|
||||
name = "bluespace tray"
|
||||
icon_state = "bluespace_tray"
|
||||
desc = "A tray created using bluespace technology to fit more food on it."
|
||||
max_items = 30 // far more items
|
||||
custom_materials = list(/datum/material/iron = 2000, /datum/material/bluespace = 500)
|
||||
|
||||
/*
|
||||
* Chemistry bag
|
||||
*/
|
||||
@@ -382,16 +392,16 @@
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "bag"
|
||||
desc = "A bag for storing pills, patches, and bottles."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_BELT|ITEM_SLOT_POCKET
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/chemistry/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 50
|
||||
STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
|
||||
STR.max_volume = STORAGE_VOLUME_CHEMISTRY_BAG
|
||||
STR.insert_preposition = "in"
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/syringe/dart))
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/syringe/dart, /obj/item/reagent_containers/chem_pack))
|
||||
|
||||
/*
|
||||
* Biowaste bag (mostly for xenobiologists)
|
||||
@@ -402,7 +412,7 @@
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "biobag"
|
||||
desc = "A bag for the safe transportation and disposal of biowaste and other biological materials."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_BELT|ITEM_SLOT_POCKET
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/bio/ComponentInitialize()
|
||||
@@ -427,3 +437,39 @@
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = INFINITY
|
||||
STR.max_items = 100
|
||||
|
||||
/obj/item/storage/bag/ammo
|
||||
name = "ammo pouch"
|
||||
desc = "A pouch for your ammo that goes in your pocket."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "ammopouch"
|
||||
slot_flags = ITEM_SLOT_POCKET
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/ammo/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 30
|
||||
STR.max_items = 3
|
||||
STR.display_numerical_stacking = FALSE
|
||||
STR.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing))
|
||||
|
||||
/obj/item/storage/bag/material
|
||||
name = "material pouch"
|
||||
desc = "A pouch for sheets and RCD ammunition that manages to hang where you would normally put things in your pocket."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "materialpouch"
|
||||
slot_flags = ITEM_SLOT_POCKET
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/material/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = INFINITY
|
||||
STR.max_items = 2
|
||||
STR.display_numerical_stacking = TRUE
|
||||
STR.can_hold = typecacheof(list(/obj/item/rcd_ammo, /obj/item/stack/sheet))
|
||||
|
||||
@@ -180,7 +180,8 @@
|
||||
/obj/item/implantcase,
|
||||
/obj/item/implant,
|
||||
/obj/item/implanter,
|
||||
/obj/item/pinpointer/crew
|
||||
/obj/item/pinpointer/crew,
|
||||
/obj/item/reagent_containers/chem_pack
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/medical/surgery_belt_adv
|
||||
@@ -512,16 +513,16 @@
|
||||
new /obj/item/grenade/smokebomb(src)
|
||||
new /obj/item/grenade/empgrenade(src)
|
||||
new /obj/item/grenade/empgrenade(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/frag(src)
|
||||
new /obj/item/grenade/gluon(src)
|
||||
new /obj/item/grenade/gluon(src)
|
||||
new /obj/item/grenade/gluon(src)
|
||||
@@ -585,7 +586,7 @@
|
||||
/obj/item/key/janitor,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/melee/flyswatter,
|
||||
/obj/item/twohanded/broom,
|
||||
/obj/item/broom,
|
||||
/obj/item/paint/paint_remover,
|
||||
/obj/item/assembly/mousetrap,
|
||||
/obj/item/screwdriver,
|
||||
@@ -713,7 +714,7 @@
|
||||
icon_state = "fannypack_leather"
|
||||
item_state = "fannypack_leather"
|
||||
dying_key = DYE_REGISTRY_FANNYPACK
|
||||
custom_price = 100
|
||||
custom_price = PRICE_ALMOST_CHEAP
|
||||
|
||||
/obj/item/storage/belt/fannypack/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -173,12 +173,12 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
var/unholy2clean = A.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
|
||||
A.reagents.del_reagent(/datum/reagent/fuel/unholywater)
|
||||
A.reagents.add_reagent(/datum/reagent/water/holywater,unholy2clean)
|
||||
if(istype(A, /obj/item/twohanded/required/cult_bastard) || istype(A, /obj/item/melee/cultblade) && !iscultist(user))
|
||||
if(istype(A, /obj/item/cult_bastard) || istype(A, /obj/item/melee/cultblade) && !iscultist(user))
|
||||
to_chat(user, "<span class='notice'>You begin to exorcise [A].</span>")
|
||||
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
|
||||
if(do_after(user, 40, target = A))
|
||||
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
|
||||
if(istype(A, /obj/item/twohanded/required/cult_bastard))
|
||||
if(istype(A, /obj/item/cult_bastard))
|
||||
for(var/obj/item/soulstone/SS in A.contents)
|
||||
SS.usability = TRUE
|
||||
for(var/mob/living/simple_animal/shade/EX in SS)
|
||||
|
||||
@@ -275,6 +275,16 @@
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/grenade/flashbang(src)
|
||||
|
||||
obj/item/storage/box/stingbangs
|
||||
name = "box of stingbangs (WARNING)"
|
||||
desc = "<B>WARNING: These devices are extremely dangerous and can cause severe injuries or death in repeated use.</B>"
|
||||
icon_state = "secbox"
|
||||
illustration = "flashbang"
|
||||
|
||||
/obj/item/storage/box/stingbangs/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/grenade/stingbang(src)
|
||||
|
||||
/obj/item/storage/box/flashes
|
||||
name = "box of flashbulbs"
|
||||
desc = "<B>WARNING: Flashes can cause serious eye damage, protective eyewear is required.</B>"
|
||||
@@ -434,6 +444,7 @@
|
||||
desc = "<B>Instructions:</B> <I>Heat in microwave. Product will cool if not eaten within seven minutes.</I>"
|
||||
icon_state = "donkpocketbox"
|
||||
illustration=null
|
||||
custom_premium_price = PRICE_ABOVE_NORMAL // git gud
|
||||
|
||||
/obj/item/storage/box/donkpockets/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -622,7 +633,7 @@
|
||||
item_state = "zippo"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_price = 20
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
|
||||
/obj/item/storage/box/matches/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -744,8 +755,8 @@
|
||||
|
||||
//////
|
||||
/obj/item/storage/box/hug/medical/PopulateContents()
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
|
||||
// Clown survival box
|
||||
@@ -1343,6 +1354,7 @@
|
||||
name = "box of marshmallows"
|
||||
desc = "A box of marshmallows."
|
||||
illustration = "marshmallow"
|
||||
custom_premium_price = PRICE_BELOW_NORMAL
|
||||
|
||||
/obj/item/storage/box/marshmallow/PopulateContents()
|
||||
for (var/i in 1 to 5)
|
||||
|
||||
@@ -106,10 +106,10 @@
|
||||
/obj/item/storage/briefcase/medical
|
||||
name = "medical briefcase"
|
||||
icon_state = "medbriefcase"
|
||||
desc = "A white with a blue cross brieface, this is ment to hold medical gear that would not be able to normally fit in a bag."
|
||||
desc = "A white with a blue cross brieface, this is meant to hold medical gear that would not be able to normally fit in a bag."
|
||||
|
||||
/obj/item/storage/briefcase/medical/PopulateContents()
|
||||
new /obj/item/clothing/neck/stethoscope(src)
|
||||
new /obj/item/healthanalyzer(src)
|
||||
..() //In case of paperwork
|
||||
..() //Incase of paperwork
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
name = "donut box"
|
||||
spawn_type = /obj/item/reagent_containers/food/snacks/donut
|
||||
fancy_open = TRUE
|
||||
custom_price = PRICE_NORMAL
|
||||
|
||||
/obj/item/storage/fancy/donut_box/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -136,7 +137,23 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
icon_type = "cigarette"
|
||||
spawn_type = /obj/item/clothing/mask/cigarette/space_cigarette
|
||||
custom_price = 75
|
||||
custom_price = PRICE_ALMOST_CHEAP
|
||||
var/spawn_coupon = TRUE
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/attack_self(mob/user)
|
||||
if(contents.len == 0 && spawn_coupon)
|
||||
to_chat(user, "<span class='notice'>You rip the back off \the [src] and get a coupon!</span>")
|
||||
var/obj/item/coupon/attached_coupon = new
|
||||
user.put_in_hands(attached_coupon)
|
||||
attached_coupon.generate()
|
||||
attached_coupon = null
|
||||
spawn_coupon = FALSE
|
||||
name = "discarded cigarette packet"
|
||||
desc = "An old cigarette packet with the back torn off, worth less than nothing now."
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 0
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -147,6 +164,8 @@
|
||||
/obj/item/storage/fancy/cigarettes/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click to extract contents.</span>"
|
||||
if(spawn_coupon)
|
||||
. += "<span class='notice'>There's a coupon on the back of the pack! You can tear it off once it's empty.</span>"
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/AltClick(mob/living/carbon/user)
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
@@ -188,18 +207,18 @@
|
||||
cig_position++
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(!ismob(M))
|
||||
return
|
||||
if(M != user || !istype(M))
|
||||
return ..()
|
||||
var/obj/item/clothing/mask/cigarette/cig = locate(/obj/item/clothing/mask/cigarette) in contents
|
||||
if(cig)
|
||||
if(M == user && contents.len > 0 && !user.wear_mask)
|
||||
if(!user.wear_mask && !(SLOT_WEAR_MASK in M.check_obscured_slots()))
|
||||
var/obj/item/clothing/mask/cigarette/W = cig
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, W, M)
|
||||
M.equip_to_slot_if_possible(W, SLOT_WEAR_MASK)
|
||||
contents -= W
|
||||
to_chat(user, "<span class='notice'>You take \a [W] out of the pack.</span>")
|
||||
else
|
||||
..()
|
||||
return ..()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no [icon_type]s left in the pack.</span>")
|
||||
|
||||
@@ -278,7 +297,7 @@
|
||||
///The value in here has NOTHING to do with icons. It needs to be this for the proper examine.
|
||||
icon_type = "rolling paper"
|
||||
spawn_type = /obj/item/rollingpaper
|
||||
custom_price = 25
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
|
||||
/obj/item/storage/fancy/rollingpapers/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -307,6 +326,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
icon_type = "premium cigar"
|
||||
spawn_type = /obj/item/clothing/mask/cigarette/cigar
|
||||
spawn_coupon = FALSE
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigars/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/healthanalyzer(src)
|
||||
|
||||
@@ -52,12 +52,12 @@
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
|
||||
/obj/item/storage/firstaid/fire
|
||||
name = "burn treatment kit"
|
||||
@@ -223,6 +223,8 @@
|
||||
/obj/item/storage/pill_bottle/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
|
||||
STR.max_volume = STORAGE_VOLUME_PILL_BOTTLE
|
||||
STR.allow_quick_gather = TRUE
|
||||
STR.click_gather = TRUE
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice))
|
||||
@@ -244,7 +246,7 @@
|
||||
desc = "Contains pills used to counter radiation poisoning."
|
||||
|
||||
/obj/item/storage/pill_bottle/anitrad/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/pill/antirad(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/epinephrine
|
||||
@@ -276,7 +278,7 @@
|
||||
desc = "Guaranteed to give you that extra burst of energy during a long shift!"
|
||||
|
||||
/obj/item/storage/pill_bottle/stimulant/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/pill/stimulant(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mining
|
||||
@@ -368,6 +370,14 @@
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/breast_enlargement(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/neurine
|
||||
name = "bottle of neurine pills"
|
||||
desc = "Contains pills to treat non-severe mental traumas."
|
||||
|
||||
/obj/item/storage/pill_bottle/neurine/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/pill/neurine(src)
|
||||
|
||||
/////////////
|
||||
//Organ Box//
|
||||
/////////////
|
||||
@@ -416,7 +426,8 @@
|
||||
/obj/item/circuitboard/computer/crew,
|
||||
/obj/item/stack/sheet/glass,
|
||||
/obj/item/stack/sheet/mineral/silver,
|
||||
/obj/item/organ_storage
|
||||
/obj/item/organ_storage,
|
||||
/obj/item/reagent_containers/chem_pack
|
||||
))
|
||||
|
||||
//hijacking the minature first aids for hypospray boxes. <3
|
||||
@@ -430,8 +441,8 @@
|
||||
throw_range = 7
|
||||
var/empty = FALSE
|
||||
item_state = "firstaid"
|
||||
custom_price = 300
|
||||
custom_premium_price = 500
|
||||
custom_price = PRICE_ABOVE_NORMAL
|
||||
custom_premium_price = PRICE_EXPENSIVE
|
||||
|
||||
/obj/item/storage/hypospraykit/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -188,19 +188,52 @@
|
||||
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
|
||||
|
||||
/obj/item/storage/lockbox/medal/engineering
|
||||
name = "engineering medal box"
|
||||
desc = "A locked box used to store medals to be given to the members of the engineering department."
|
||||
req_access = list(ACCESS_CE)
|
||||
name = "engineering medal box"
|
||||
desc = "A locked box used to store medals to be given to the members of the engineering department."
|
||||
req_access = list(ACCESS_CE)
|
||||
|
||||
/obj/item/storage/lockbox/medal/engineering/PopulateContents()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/accessory/medal/engineer(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/accessory/medal/engineer(src)
|
||||
|
||||
/obj/item/storage/lockbox/medal/medical
|
||||
name = "medical medal box"
|
||||
desc = "A locked box used to store medals to be given to the members of the medical department."
|
||||
req_access = list(ACCESS_CMO)
|
||||
name = "medical medal box"
|
||||
desc = "A locked box used to store medals to be given to the members of the medical department."
|
||||
req_access = list(ACCESS_CMO)
|
||||
|
||||
/obj/item/storage/lockbox/medal/medical/PopulateContents()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/accessory/medal/ribbon/medical_doctor(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/accessory/medal/ribbon/medical_doctor(src)
|
||||
|
||||
/obj/item/storage/lockbox/order
|
||||
name = "order lockbox"
|
||||
desc = "A box used to secure small cargo orders from being looted by those who didn't order it. Yeah, cargo tech, that means you."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "secure"
|
||||
item_state = "sec-case"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/briefcase_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/datum/bank_account/buyer_account
|
||||
var/privacy_lock = TRUE
|
||||
|
||||
/obj/item/storage/lockbox/order/Initialize(datum/bank_account/_buyer_account)
|
||||
. = ..()
|
||||
buyer_account = _buyer_account
|
||||
|
||||
/obj/item/storage/lockbox/order/attackby(obj/item/W, mob/user, params)
|
||||
if(!istype(W, /obj/item/card/id))
|
||||
return ..()
|
||||
|
||||
var/obj/item/card/id/id_card = W
|
||||
if(iscarbon(user))
|
||||
add_fingerprint(user)
|
||||
|
||||
if(id_card.registered_account != buyer_account)
|
||||
to_chat(user, "<span class='notice'>Bank account does not match with buyer!</span")
|
||||
return
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !privacy_lock)
|
||||
privacy_lock = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
user.visible_message("<span class='notice'>[user] [privacy_lock ? "" : "un"]locks [src]'s privacy lock.</span>",
|
||||
"<span class='notice'>You [privacy_lock ? "" : "un"]lock [src]'s privacy lock.</span>")
|
||||
|
||||
@@ -105,10 +105,7 @@
|
||||
if (length(code) > 5)
|
||||
code = "ERROR"
|
||||
add_fingerprint(usr)
|
||||
for(var/mob/M in viewers(1, loc))
|
||||
if ((M.client && M.machine == src))
|
||||
attack_self(M)
|
||||
return
|
||||
attack_self(usr)
|
||||
return
|
||||
|
||||
|
||||
@@ -150,6 +147,35 @@
|
||||
for(var/i = 0, i < STR.max_items - 2, i++)
|
||||
new /obj/item/stack/spacecash/c1000(src)
|
||||
|
||||
/obj/item/storage/secure/briefcase/mws_pack
|
||||
name = "\improper \'MWS\' gun kit"
|
||||
desc = "A storage case for a multi-purpose handgun. Variety hour!"
|
||||
|
||||
/obj/item/storage/secure/briefcase/mws_pack/PopulateContents()
|
||||
new /obj/item/gun/ballistic/revolver/mws(src)
|
||||
new /obj/item/ammo_box/magazine/mws_mag(src)
|
||||
for(var/path in subtypesof(/obj/item/ammo_casing/mws_batt))
|
||||
new path(src)
|
||||
|
||||
/obj/item/storage/secure/briefcase/hos/mws_pack_hos
|
||||
name = "\improper \'MWS\' gun kit"
|
||||
desc = "A storage case for a multi-purpose handgun. Variety hour!"
|
||||
|
||||
/obj/item/storage/secure/briefcase/hos/mws_pack_hos/PopulateContents()
|
||||
new /obj/item/gun/ballistic/revolver/mws(src)
|
||||
new /obj/item/ammo_box/magazine/mws_mag(src)
|
||||
new /obj/item/ammo_casing/mws_batt/lethal(src)
|
||||
new /obj/item/ammo_casing/mws_batt/lethal(src)
|
||||
new /obj/item/ammo_casing/mws_batt/stun(src)
|
||||
new /obj/item/ammo_casing/mws_batt/stun(src)
|
||||
new /obj/item/ammo_casing/mws_batt/ion(src)
|
||||
|
||||
/obj/item/storage/secure/briefcase/hos/multiphase_box
|
||||
name = "\improper X-01 Multiphase energy gun box"
|
||||
desc = "A storage case for a high-tech energy firearm."
|
||||
|
||||
/obj/item/storage/secure/briefcase/hos/multiphase_box/PopulateContents()
|
||||
new /obj/item/gun/energy/e_gun/hos(src)
|
||||
|
||||
// -----------------------------
|
||||
// Secure Safe
|
||||
@@ -158,6 +184,7 @@
|
||||
/obj/item/storage/secure/safe
|
||||
name = "secure safe"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
plane = ABOVE_WALL_PLANE
|
||||
icon_state = "safe"
|
||||
icon_opened = "safe0"
|
||||
icon_locking = "safeb"
|
||||
|
||||
@@ -16,12 +16,17 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
attack_verb = list("robusted")
|
||||
hitsound = 'sound/weapons/smash.ogg'
|
||||
custom_materials = list(/datum/material/iron = 500)
|
||||
material_flags = MATERIAL_COLOR
|
||||
var/latches = "single_latch"
|
||||
var/has_latches = TRUE
|
||||
var/can_rubberify = TRUE
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //very protecc too
|
||||
|
||||
/obj/item/storage/toolbox/greyscale
|
||||
icon_state = "toolbox_default"
|
||||
item_state = "toolbox_default"
|
||||
can_rubberify = FALSE
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
|
||||
/obj/item/storage/toolbox/Initialize(mapload)
|
||||
if(has_latches)
|
||||
if(prob(10))
|
||||
@@ -48,7 +53,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
name = "emergency toolbox"
|
||||
icon_state = "red"
|
||||
item_state = "toolbox_red"
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/emergency/PopulateContents()
|
||||
new /obj/item/crowbar/red(src)
|
||||
@@ -73,7 +77,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
name = "mechanical toolbox"
|
||||
icon_state = "blue"
|
||||
item_state = "toolbox_blue"
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/PopulateContents()
|
||||
new /obj/item/screwdriver(src)
|
||||
@@ -102,7 +105,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
name = "electrical toolbox"
|
||||
icon_state = "yellow"
|
||||
item_state = "toolbox_yellow"
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/electrical/PopulateContents()
|
||||
var/pickedcolor = pick("red","yellow","green","blue","pink","orange","cyan","white")
|
||||
@@ -124,7 +126,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
desc = "A toolbox painted black with a red stripe. It looks more heavier than normal toolboxes."
|
||||
force = 15
|
||||
throwforce = 18
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/syndicate/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -144,7 +145,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
name = "mechanical toolbox"
|
||||
icon_state = "blue"
|
||||
item_state = "toolbox_blue"
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/drone/PopulateContents()
|
||||
var/pickedcolor = pick("red","yellow","green","blue","pink","orange","cyan","white")
|
||||
@@ -166,7 +166,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
attack_verb = list("robusted", "crushed", "smashed")
|
||||
can_rubberify = FALSE
|
||||
material_flags = NONE
|
||||
var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab
|
||||
|
||||
/obj/item/storage/toolbox/brass/ComponentInitialize()
|
||||
@@ -209,7 +208,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
w_class = WEIGHT_CLASS_HUGE //heyo no bohing this!
|
||||
force = 18 //spear damage
|
||||
can_rubberify = FALSE
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/plastitanium/afterattack(atom/A, mob/user, proximity)
|
||||
. = ..()
|
||||
@@ -225,7 +223,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
icon_state = "green"
|
||||
item_state = "toolbox_green"
|
||||
w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox!
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/artistic/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -302,7 +299,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
icon_state = "gold"
|
||||
item_state = "toolbox_gold"
|
||||
has_latches = FALSE
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/gold_real/PopulateContents()
|
||||
new /obj/item/screwdriver/nuke(src)
|
||||
@@ -328,7 +324,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
force = 0
|
||||
throwforce = 0
|
||||
can_rubberify = FALSE
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/proc/rubberify()
|
||||
name = "rubber [name]"
|
||||
@@ -364,7 +359,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
throwforce = 15
|
||||
attack_verb = list("robusted", "bounced")
|
||||
can_rubberify = FALSE //we are already the future.
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/rubber/Initialize()
|
||||
icon_state = pick("blue", "red", "yellow", "green")
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
new /obj/item/pizzabox/bomb
|
||||
|
||||
if("darklord") //20 tc + tk + summon item close enough for now
|
||||
new /obj/item/twohanded/dualsaber(src)
|
||||
new /obj/item/dualsaber(src)
|
||||
new /obj/item/dnainjector/telemut/darkbundle(src)
|
||||
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
|
||||
new /obj/item/card/id/syndicate(src)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
|
||||
var/stamforce = 35
|
||||
var/status = FALSE
|
||||
var/turned_on = FALSE
|
||||
var/knockdown = TRUE
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/hitcost = 750
|
||||
@@ -49,7 +49,7 @@
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
//Only mob/living types have stun handling
|
||||
if(status && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
baton_stun(hit_atom)
|
||||
|
||||
/obj/item/melee/baton/loaded //this one starts with a cell pre-installed.
|
||||
@@ -66,16 +66,16 @@
|
||||
copper_top.use(min(chrgdeductamt, copper_top.charge), explode)
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
if(status && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY))))
|
||||
if(turned_on && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY))))
|
||||
//we're below minimum, turn off
|
||||
switch_status(FALSE)
|
||||
|
||||
/obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE)
|
||||
if(status != new_status)
|
||||
status = new_status
|
||||
if(turned_on != new_status)
|
||||
turned_on = new_status
|
||||
if(!silent)
|
||||
playsound(loc, "sparks", 75, 1, -1)
|
||||
if(status)
|
||||
if(turned_on)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -85,7 +85,7 @@
|
||||
deductcharge(round(hitcost * STUNBATON_DEPLETION_RATE), FALSE, FALSE)
|
||||
|
||||
/obj/item/melee/baton/update_icon_state()
|
||||
if(status)
|
||||
if(turned_on)
|
||||
icon_state = "[initial(name)]_active"
|
||||
else if(!cell)
|
||||
icon_state = "[initial(name)]_nocell"
|
||||
@@ -134,14 +134,14 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is out of charge.</span>")
|
||||
else
|
||||
switch_status(!status)
|
||||
to_chat(user, "<span class='notice'>[src] is now [status ? "on" : "off"].</span>")
|
||||
switch_status(!turned_on)
|
||||
to_chat(user, "<span class='notice'>[src] is now [turned_on ? "on" : "off"].</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
|
||||
var/interrupt = common_baton_melee(M, user, FALSE)
|
||||
if(!interrupt)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params)
|
||||
. = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-disarming.
|
||||
@@ -151,16 +151,16 @@
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
|
||||
return FALSE
|
||||
if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
if(turned_on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
clowning_around(user)
|
||||
if(IS_STAMCRIT(user)) //CIT CHANGE - makes it impossible to baton in stamina softcrit
|
||||
to_chat(user, "<span class='danger'>You're too exhausted for that.</span>")
|
||||
to_chat(user, "<span class='danger'>You're too exhausted to use [src] properly.</span>")
|
||||
return TRUE
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/L = M
|
||||
if(check_martial_counter(L, user))
|
||||
return TRUE
|
||||
if(status)
|
||||
if(turned_on)
|
||||
if(baton_stun(M, user, disarming))
|
||||
user.do_attack_animation(M)
|
||||
user.adjustStaminaLossBuffered(getweight(user, STAM_COST_BATON_MOB_MULT))
|
||||
@@ -170,10 +170,12 @@
|
||||
return disarming || (user.a_intent != INTENT_HARM)
|
||||
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user, disarming = FALSE)
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
var/list/return_list = list()
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
var/stunpwr = stamforce
|
||||
stunpwr = block_calculate_resultant_damage(stunpwr, return_list)
|
||||
var/obj/item/stock_parts/cell/our_cell = get_cell()
|
||||
if(!our_cell)
|
||||
switch_status(FALSE)
|
||||
@@ -292,6 +294,48 @@
|
||||
sparkler?.activate()
|
||||
. = ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang
|
||||
name = "\improper OZtek Boomerang"
|
||||
desc = "A device invented in 2486 for the great Space Emu War by the confederacy of Australicus, these high-tech boomerangs also work exceptionally well at stunning crewmembers. Just be careful to catch it when thrown!"
|
||||
throw_speed = 1
|
||||
icon_state = "boomerang"
|
||||
item_state = "boomerang"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_range = 5
|
||||
hitcost = 2000
|
||||
throw_hit_chance = 99 //Have you prayed today?
|
||||
custom_materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000)
|
||||
|
||||
/obj/item/melee/baton/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
|
||||
if(turned_on)
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.throw_mode_off() //so they can catch it on the return.
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(turned_on)
|
||||
var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum)
|
||||
if(ishuman(hit_atom) && !caught && prob(throw_hit_chance))//if they are a carbon and they didn't catch it
|
||||
baton_stun(hit_atom)
|
||||
if(thrownby && !caught)
|
||||
sleep(1)
|
||||
if(!QDELETED(src))
|
||||
throw_at(thrownby, throw_range+2, throw_speed, null, TRUE)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang/update_icon()
|
||||
if(turned_on)
|
||||
icon_state = "[initial(icon_state)]_active"
|
||||
else if(!cell)
|
||||
icon_state = "[initial(icon_state)]_nocell"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/melee/baton/boomerang/loaded //Same as above, comes with a cell.
|
||||
preload_cell_type = /obj/item/stock_parts/cell/high
|
||||
|
||||
#undef STUNBATON_CHARGE_LENIENCY
|
||||
#undef STUNBATON_DEPLETION_RATE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user