Merge remote-tracking branch 'citadel/master' into auxtools-atmos
This commit is contained in:
@@ -375,12 +375,14 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
|
||||
. = TRUE
|
||||
|
||||
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
|
||||
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, destroy_speed, target = A))
|
||||
activate()
|
||||
qdel(A)
|
||||
return
|
||||
var/obj/item/pipe/P = A
|
||||
if(!istype(P) || P.disposable)
|
||||
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, destroy_speed, target = A))
|
||||
activate()
|
||||
qdel(A)
|
||||
return
|
||||
|
||||
if((mode & PAINT_MODE))
|
||||
if(istype(A, /obj/machinery/atmospherics/pipe) && !istype(A, /obj/machinery/atmospherics/pipe/layer_manifold))
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/* BALLS - GLORIOUS BALLS
|
||||
//
|
||||
// Includes:-
|
||||
// 1) Tennis balls, lines 10 - 92
|
||||
//
|
||||
//
|
||||
//
|
||||
*/
|
||||
|
||||
/obj/item/toy/tennis
|
||||
name = "tennis ball"
|
||||
desc = "A classical tennis ball. It appears to have faint bite marks scattered all over its surface."
|
||||
icon = 'modular_citadel/icons/obj/balls.dmi'
|
||||
icon_state = "tennis_classic"
|
||||
lefthand_file = 'modular_citadel/icons/mob/inhands/balls_left.dmi'
|
||||
righthand_file = 'modular_citadel/icons/mob/inhands/balls_right.dmi'
|
||||
item_state = "tennis_classic"
|
||||
mob_overlay_icon = 'modular_citadel/icons/mob/mouthball.dmi'
|
||||
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS //Fluff item, put it wherever you want!
|
||||
throw_range = 14
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/toy/tennis/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/tennis/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] waggles [src] at [target].</span>", "<span class='notice'>You waggle [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/tennis/rainbow
|
||||
name = "pseudo-euclidean interdimensional tennis sphere"
|
||||
desc = "A tennis ball from another plane of existance. Really groovy."
|
||||
icon_state = "tennis_rainbow"
|
||||
item_state = "tennis_rainbow"
|
||||
actions_types = list(/datum/action/item_action/squeeze) //Giving the masses easy access to unilimted honks would be annoying
|
||||
|
||||
/obj/item/toy/tennis/rainbow/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak)
|
||||
|
||||
/obj/item/toy/tennis/rainbow/izzy //izzyinbox's donator item
|
||||
name = "Katlin's Ball"
|
||||
desc = "A tennis ball that's seen a good bit of love, being covered in a few black and white hairs and slobber."
|
||||
icon_state = "tennis_izzy"
|
||||
item_state = "tennis_izzy"
|
||||
|
||||
/obj/item/toy/tennis/red //da red wuns go fasta
|
||||
name = "red tennis ball"
|
||||
desc = "A red tennis ball. It goes three times faster!"
|
||||
icon_state = "tennis_red"
|
||||
item_state = "tennis_red"
|
||||
throw_speed = 9
|
||||
|
||||
/obj/item/toy/tennis/yellow //because yellow is hot I guess
|
||||
name = "yellow tennis ball"
|
||||
desc = "A yellow tennis ball. It seems to have a flame-retardant coating."
|
||||
icon_state = "tennis_yellow"
|
||||
item_state = "tennis_yellow"
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/toy/tennis/green //pestilence
|
||||
name = "green tennis ball"
|
||||
desc = "A green tennis ball. It seems to have an impermeable coating."
|
||||
icon_state = "tennis_green"
|
||||
item_state = "tennis_green"
|
||||
permeability_coefficient = 0.9
|
||||
|
||||
/obj/item/toy/tennis/cyan //electric
|
||||
name = "cyan tennis ball"
|
||||
desc = "A cyan tennis ball. It seems to have odd electrical properties."
|
||||
icon_state = "tennis_cyan"
|
||||
item_state = "tennis_cyan"
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
/obj/item/toy/tennis/blue //reliability
|
||||
name = "blue tennis ball"
|
||||
desc = "A blue tennis ball. It seems ever so slightly more robust than normal."
|
||||
icon_state = "tennis_blue"
|
||||
item_state = "tennis_blue"
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/toy/tennis/purple //because purple dyes have high pH and would neutralize acids I guess
|
||||
name = "purple tennis ball"
|
||||
desc = "A purple tennis ball. It seems to have an acid-resistant coating."
|
||||
icon_state = "tennis_purple"
|
||||
item_state = "tennis_purple"
|
||||
resistance_flags = ACID_PROOF
|
||||
|
||||
/datum/action/item_action/squeeze
|
||||
name = "Squeak!"
|
||||
@@ -16,6 +16,9 @@
|
||||
if(isopenturf(target))
|
||||
deploy_bodybag(user, target)
|
||||
|
||||
/obj/item/bodybag/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return (user in src)
|
||||
|
||||
/obj/item/bodybag/proc/deploy_bodybag(mob/user, atom/location)
|
||||
var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location)
|
||||
R.open(user)
|
||||
|
||||
@@ -549,6 +549,7 @@
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/configure_machine(obj/machinery/computer/cargo/machine)
|
||||
if(!istype(machine))
|
||||
@@ -565,10 +566,12 @@
|
||||
build_path = /obj/machinery/computer/cargo/express
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
|
||||
. = ..()
|
||||
if(!(obj_flags & EMAGGED))
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You change the routing protocols, allowing the Drop Pod to land anywhere on the station.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
|
||||
if (!(obj_flags & EMAGGED))
|
||||
|
||||
@@ -472,7 +472,7 @@
|
||||
build_path = /obj/machinery/holopad
|
||||
secure = FALSE
|
||||
else
|
||||
build_path = /obj/machinery/holopad //secure
|
||||
build_path = /obj/machinery/holopad/secure //secure
|
||||
secure = TRUE
|
||||
to_chat(user, "<span class='notice'>You [secure? "en" : "dis"]able the security on the [src]</span>")
|
||||
. = ..()
|
||||
@@ -609,6 +609,7 @@
|
||||
/obj/machinery/vending/cigarette = "ShadyCigs Deluxe",
|
||||
/obj/machinery/vending/games = "\improper Good Clean Fun",
|
||||
/obj/machinery/vending/kink = "KinkMate",
|
||||
/obj/machinery/vending/barkbox = "Bark Box",
|
||||
/obj/machinery/vending/autodrobe = "AutoDrobe",
|
||||
/obj/machinery/vending/wardrobe/sec_wardrobe = "SecDrobe",
|
||||
/obj/machinery/vending/wardrobe/det_wardrobe = "DetDrobe",
|
||||
|
||||
@@ -443,7 +443,7 @@
|
||||
// Check area validity.
|
||||
// Reject space, player-created areas, and non-station z-levels.
|
||||
var/area/A = get_base_area(target)
|
||||
if(!A || (!is_station_level(A.z)) || !A.valid_territory)
|
||||
if(!A || (!is_station_level(A.z)) || !(A.area_flags & VALID_TERRITORY))
|
||||
to_chat(user, "<span class='warning'>[A] is unsuitable for tagging.</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -721,24 +721,24 @@
|
||||
|
||||
/obj/item/disk/medical/defib_heal
|
||||
name = "Defibrillator Healing Disk"
|
||||
desc = "An upgrade which increases the healing power of the defibrillator"
|
||||
desc = "An upgrade which increases the healing power of the defibrillator."
|
||||
icon_state = "heal_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 6000, /datum/material/silver = 6000)
|
||||
|
||||
/obj/item/disk/medical/defib_shock
|
||||
name = "Defibrillator Anti-Shock Disk"
|
||||
desc = "A safety upgrade that guarantees only the patient will get shocked"
|
||||
desc = "A safety upgrade that guarantees only the patient will get shocked."
|
||||
icon_state = "zap_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 6000, /datum/material/silver = 6000)
|
||||
|
||||
/obj/item/disk/medical/defib_decay
|
||||
name = "Defibrillator Body-Decay Extender Disk"
|
||||
desc = "An upgrade allowing the defibrillator to work on more decayed bodies"
|
||||
desc = "An upgrade allowing the defibrillator to work on bodies that have decayed further."
|
||||
icon_state = "body_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 16000, /datum/material/silver = 6000, /datum/material/titanium = 2000)
|
||||
|
||||
/obj/item/disk/medical/defib_speed
|
||||
name = "Defibrillator Fast Charge Disk"
|
||||
desc = "An upgrade to the defibrillator capacitors, which let it charge faster"
|
||||
desc = "An upgrade to the defibrillator capacitors, which lets it charge faster."
|
||||
icon_state = "fast_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 8000, /datum/material/gold = 26000, /datum/material/silver = 26000)
|
||||
|
||||
@@ -69,8 +69,7 @@ effective or pretty fucking useless.
|
||||
*/
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser
|
||||
custom_materials = list(/datum/material/iron=400)
|
||||
var/irradiate = 1
|
||||
var/irradiate = TRUE
|
||||
var/intensity = 10 // how much damage the radiation does
|
||||
var/wavelength = 10 // time it takes for the radiation to kick in, in seconds
|
||||
var/used = 0 // is it cooling down?
|
||||
@@ -92,16 +91,16 @@ effective or pretty fucking useless.
|
||||
addtimer(VARSET_CALLBACK(src, used, FALSE), cooldown)
|
||||
addtimer(VARSET_CALLBACK(src, icon_state, "health"), cooldown)
|
||||
to_chat(user, "<span class='warning'>Successfully irradiated [M].</span>")
|
||||
addtimer(CALLBACK(src, .proc/radiation_aftereffect, M), (wavelength+(intensity*4))*5)
|
||||
addtimer(CALLBACK(src, .proc/radiation_aftereffect, M, intensity), (wavelength+(intensity*4))*5)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The radioactive microlaser is still recharging.</span>")
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M)
|
||||
if(QDELETED(M))
|
||||
/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M, passed_intensity)
|
||||
if(QDELETED(M) || !ishuman(M) || HAS_TRAIT(M, TRAIT_RADIMMUNE))
|
||||
return
|
||||
if(intensity >= 5)
|
||||
M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS)
|
||||
M.rad_act(intensity*10)
|
||||
if(passed_intensity >= 5)
|
||||
M.apply_effect(round(passed_intensity/0.075), EFFECT_UNCONSCIOUS) //to save you some math, this is a round(intensity * (4/3)) second long knockout
|
||||
M.rad_act(passed_intensity*10)
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/get_cooldown()
|
||||
return round(max(10, (stealth*30 + intensity*5 - wavelength/4)))
|
||||
|
||||
@@ -210,8 +210,7 @@
|
||||
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.set_last_attacker(user)
|
||||
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")
|
||||
@@ -237,8 +236,7 @@
|
||||
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.set_last_attacker(user)
|
||||
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")
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/* Balls, Bones, and Bountiful Fun
|
||||
//
|
||||
// Includes:-
|
||||
// 1) Fluff Content, lines 12 - 131
|
||||
//
|
||||
// 1) Tennis balls, lines 39 - 99
|
||||
// 2) Chew bones, lines 101 - 138
|
||||
// 3) Frisbee, lines 140 - 166
|
||||
*/
|
||||
|
||||
/obj/item/toy/fluff
|
||||
name = "Fluff Item"
|
||||
desc = "You shouldn't be seeing this."
|
||||
icon = 'icons/obj/barkbox_fluff.dmi'
|
||||
icon_state = "poly_tennis"
|
||||
item_state = "poly_tennis"
|
||||
lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
|
||||
mob_overlay_icon = 'icons/mob/mouthfluff.dmi'
|
||||
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS
|
||||
var/poly_states = 0
|
||||
var/poly_colors = list()
|
||||
|
||||
/obj/item/toy/fluff/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/fluff/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] waggles [src] at [target].</span>", "<span class='notice'>You waggle [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/fluff/ComponentInitialize()
|
||||
. = ..()
|
||||
if(!poly_states)
|
||||
return
|
||||
AddElement(/datum/element/polychromic, poly_colors, poly_states, _flags = POLYCHROMIC_ACTION)
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly
|
||||
name = "polychromic tennis ball"
|
||||
desc = "A polychromic tennis ball. There's a half torn tag read: WARNIN-, surely it means nothing. Right?"
|
||||
throw_range = 14
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
poly_states = 2
|
||||
poly_colors = list("#CCFF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/red
|
||||
poly_colors = list("#FF4C00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/yellow
|
||||
poly_colors = list("#FFCC00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/green
|
||||
poly_colors = list("#99FF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/cyan
|
||||
poly_colors = list("#00FFB2", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/blue
|
||||
poly_colors = list("#007FFF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/purple
|
||||
poly_colors = list("#CC00FF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri
|
||||
name = "tricolor-polychromic tennis ball"
|
||||
desc = "A tricolor-polychromic tennis ball. Triple the shocking!"
|
||||
icon_state = "tripoly_tennis"
|
||||
item_state = "tripoly_tennis"
|
||||
poly_states = 3
|
||||
poly_colors = list("#FFFFFF", "#FFFFFF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak
|
||||
name = "tricolor-polychromic tennis sphere"
|
||||
desc = "A tricolor-polychromic tennis ball. This one seems to emit a squeak when squeezed."
|
||||
actions_types = list(/datum/action/item_action/squeeze)
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak/izzy //izzyinbox's donator item
|
||||
name = "Katlin's Ball"
|
||||
desc = "A tennis ball that's seen a good bit of love, being covered in a few black and white hairs and slobber."
|
||||
poly_colors = list("#8FED56", "#51cfde", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow
|
||||
name = "pseudo-euclidean interdimensional tennis sphere"
|
||||
desc = "A tennis ball from another plane of existance. Really groovy."
|
||||
icon_state = "tennis_rainbow"
|
||||
item_state = "tennis_rainbow"
|
||||
poly_states = 0
|
||||
actions_types = list(/datum/action/item_action/squeeze)
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak)
|
||||
|
||||
/obj/item/toy/fluff/bone_poly
|
||||
name = "polychromic bone"
|
||||
desc = "A polychromic chew bone. Nothing like a good bone to chew on."
|
||||
icon_state = "poly_bone"
|
||||
item_state = "poly_bone"
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
poly_states = 1
|
||||
poly_colors = list("#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/red
|
||||
poly_colors = list("#FF4C00")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/yellow
|
||||
poly_colors = list("#FFCC00")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/green
|
||||
poly_colors = list("#99FF00")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/cyan
|
||||
poly_colors = list("#00FFB2")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/blue
|
||||
poly_colors = list("#007FFF")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/purple
|
||||
poly_colors = list("#CC00FF")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/squeak
|
||||
name = "polychromic bone"
|
||||
desc = "A polychromic chew bone. Makes a small squeak when squeezed."
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/squeak/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak)
|
||||
|
||||
/datum/action/item_action/squeeze
|
||||
name = "Squeak!"
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly
|
||||
name = "polychromic frisbee"
|
||||
desc = "A polychromic frisbee. Warning: May induce shock."
|
||||
icon_state = "poly_frisbee"
|
||||
item_state = "poly_frisbee"
|
||||
throw_range = 14
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
poly_states = 2
|
||||
poly_colors = list("#CCFF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/red
|
||||
poly_colors = list("#FF4C00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/yellow
|
||||
poly_colors = list("#FFCC00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/green
|
||||
poly_colors = list("#99FF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/cyan
|
||||
poly_colors = list("#00FFB2", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/blue
|
||||
poly_colors = list("#007FFF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/purple
|
||||
poly_colors = list("#CC00FF", "#FFFFFF")
|
||||
@@ -312,7 +312,7 @@
|
||||
trap_damage = 0
|
||||
item_flags = DROPDEL
|
||||
flags_1 = NONE
|
||||
breakouttime = 50
|
||||
breakouttime = 25
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap/energy/New()
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/datum/deathrattle_group
|
||||
var/name
|
||||
var/list/datum/weakref/implant_refs = list()
|
||||
|
||||
/datum/deathrattle_group/New()
|
||||
// Give the group a unique name for debugging, and possible future
|
||||
// use for making custom linked groups.
|
||||
name = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
|
||||
/datum/deathrattle_group/proc/rattle(obj/item/implant/deathrattle/origin, mob/living/owner)
|
||||
var/name = owner.mind ? owner.mind.name : owner.real_name
|
||||
var/area = get_area_name(get_turf(owner))
|
||||
|
||||
for(var/r in implant_refs)
|
||||
var/datum/weakref/R = r
|
||||
|
||||
var/obj/item/implant/deathrattle/implant = R.resolve()
|
||||
if(!implant || implant == origin)
|
||||
continue
|
||||
|
||||
// Not all the implants may be actually implanted in people.
|
||||
if(!implant.imp_in)
|
||||
continue
|
||||
|
||||
// Deliberately the same message framing as nanite message + ghost deathrattle
|
||||
var/mob/living/recipient = implant.imp_in
|
||||
to_chat(recipient, "<i>You hear a strange, robotic voice in your head...</i> \"<span class='robot'><b>[name]</b> has died at <b>[area]</b>.</span>\"")
|
||||
SEND_SOUND(recipient, pick(
|
||||
'sound/items/knell1.ogg',
|
||||
'sound/items/knell2.ogg',
|
||||
'sound/items/knell3.ogg',
|
||||
'sound/items/knell4.ogg',
|
||||
))
|
||||
|
||||
/datum/deathrattle_group/proc/register(obj/item/implant/deathrattle/implant)
|
||||
implant.group = src
|
||||
implant_refs += WEAKREF(implant)
|
||||
|
||||
|
||||
/obj/item/implant/deathrattle
|
||||
name = "deathrattle implant"
|
||||
desc = "Hope no one else dies, prepare for when they do."
|
||||
|
||||
activated = FALSE
|
||||
|
||||
var/datum/deathrattle_group/group = null
|
||||
|
||||
/obj/item/implant/deathrattle/Destroy()
|
||||
group = null
|
||||
return ..()
|
||||
|
||||
/obj/item/implant/deathrattle/can_be_implanted_in(mob/living/target)
|
||||
// Can be implanted in anything that's a mob. Syndicate cyborgs, talking fish, humans...
|
||||
return TRUE
|
||||
|
||||
/obj/item/implant/deathrattle/proc/on_predeath(datum/source, gibbed)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(group)
|
||||
group.rattle(origin = src, owner = source)
|
||||
|
||||
/obj/item/implant/deathrattle/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
RegisterSignal(target, COMSIG_LIVING_PREDEATH, .proc/on_predeath)
|
||||
|
||||
if(!group)
|
||||
to_chat(target, "<i>You hear a strange, robotic voice in your head...</i> \"<span class='robot'>Warning: No other linked implants detected.</span>\"")
|
||||
|
||||
|
||||
/obj/item/implantcase/deathrattle
|
||||
name = "implant case - 'Deathrattle'"
|
||||
desc = "A glass case containing a deathrattle implant."
|
||||
imp_type = /obj/item/implant/deathrattle
|
||||
@@ -139,14 +139,25 @@
|
||||
name = "health implant"
|
||||
activated = 0
|
||||
var/healthstring = ""
|
||||
var/list/raw_data = list()
|
||||
|
||||
/obj/item/implant/health/proc/sensehealth()
|
||||
/obj/item/implant/health/proc/sensehealth(get_list = FALSE)
|
||||
if (!imp_in)
|
||||
return "ERROR"
|
||||
else
|
||||
if(isliving(imp_in))
|
||||
var/mob/living/L = imp_in
|
||||
healthstring = "<small>Oxygen Deprivation Damage => [round(L.getOxyLoss())]<br />Fire Damage => [round(L.getFireLoss())]<br />Toxin Damage => [round(L.getToxLoss())]<br />Brute Force Damage => [round(L.getBruteLoss())]</small>"
|
||||
if (!healthstring)
|
||||
raw_data = list() //Reset list
|
||||
raw_data["oxy"] = list("[round(L.getOxyLoss())]") //Suffocation
|
||||
raw_data["burn"] = list("[round(L.getFireLoss())]") //Burn
|
||||
raw_data["tox"] = list("[round(L.getToxLoss())]") //Tox
|
||||
raw_data["brute"] = list("[round(L.getBruteLoss())]") //Brute
|
||||
if(!healthstring) //I have no idea who made it go this order but okay.
|
||||
healthstring = "ERROR"
|
||||
return healthstring
|
||||
if(!length(raw_data))
|
||||
raw_data = list("ERROR")
|
||||
if(!get_list)
|
||||
return healthstring
|
||||
else
|
||||
return raw_data
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
|
||||
/obj/item/melee/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user)
|
||||
if(target.check_martial_melee_block())
|
||||
target.visible_message("<span class='danger'>[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!</span>",
|
||||
target.visible_message("<span class='danger'>[target.name] blocks your attack!</span>",
|
||||
"<span class='userdanger'>You block the attack!</span>")
|
||||
user.Stun(40)
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/chainofcommand
|
||||
@@ -272,11 +271,14 @@
|
||||
var/force_on // Damage when on - not stunning
|
||||
var/force_off // Damage when off - not stunning
|
||||
var/weight_class_on // What is the new size class when turned on
|
||||
var/sword_point = TRUE
|
||||
|
||||
wound_bonus = 15
|
||||
|
||||
/obj/item/melee/classic_baton/Initialize()
|
||||
. = ..()
|
||||
if(sword_point)
|
||||
AddElement(/datum/element/sword_point)
|
||||
|
||||
// Description for trying to stun when still on cooldown.
|
||||
/obj/item/melee/classic_baton/proc/get_wait_description()
|
||||
@@ -403,6 +405,8 @@
|
||||
weight_class_on = WEIGHT_CLASS_BULKY
|
||||
total_mass = TOTAL_MASS_NORMAL_ITEM
|
||||
bare_wound_bonus = 5
|
||||
sword_point = FALSE
|
||||
var/silent = FALSE
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/suicide_act(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
@@ -432,6 +436,9 @@
|
||||
w_class = weight_class_on
|
||||
force = force_on
|
||||
attack_verb = list("smacked", "struck", "cracked", "beaten")
|
||||
AddElement(/datum/element/sword_point)
|
||||
if(!silent)
|
||||
user?.visible_message("<span class='warning'>[user] extends [src] with a flick of their wrist!</span>")
|
||||
else
|
||||
to_chat(user, desc["local_off"])
|
||||
icon_state = off_icon_state
|
||||
@@ -440,6 +447,9 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = force_off
|
||||
attack_verb = list("hit", "poked")
|
||||
RemoveElement(/datum/element/sword_point)
|
||||
if(!silent)
|
||||
user?.visible_message("<span class='warning'>[user] collapses [src] back down!</span>")
|
||||
playsound(src.loc, on_sound, 50, 1)
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -466,6 +476,7 @@
|
||||
force_on = 16
|
||||
force_off = 5
|
||||
weight_class_on = WEIGHT_CLASS_NORMAL
|
||||
silent = TRUE
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/contractor_baton/get_wait_description()
|
||||
return "<span class='danger'>The baton is still charging!</span>"
|
||||
|
||||
@@ -332,6 +332,7 @@
|
||||
to_chat(occupant, "You pop out of the [src], slightly dazed!")
|
||||
occupant.Stun(5 SECONDS)
|
||||
|
||||
|
||||
/obj/item/pet_carrier/bluespace/return_air()
|
||||
if(!occupant_gas_supply)
|
||||
occupant_gas_supply = new
|
||||
@@ -353,4 +354,14 @@
|
||||
if(..())
|
||||
name = "[initial(name)] ([target])"
|
||||
|
||||
/obj/item/pet_carrier/bluespace/single_use
|
||||
desc = "A jar, that seems to be bigger on the inside, somehow allowing lifeforms to fit through its narrow entrance. This one looks exceptionally fragile."
|
||||
|
||||
/obj/item/pet_carrier/bluespace/single_use/remove_occupant(mob/living/occupant)
|
||||
. = ..()
|
||||
|
||||
if(!QDELETED(src))
|
||||
playsound(src, "shatter", 70, 1)
|
||||
qdel(src)
|
||||
|
||||
#undef pet_carrier_full
|
||||
|
||||
@@ -174,6 +174,10 @@
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_NO_RANGED) && (attack_type & ATTACK_TYPE_PROJECTILE))
|
||||
return BLOCK_NONE
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_NO_MELEE) && (attack_type & ATTACK_TYPE_MELEE))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
@@ -238,30 +242,75 @@
|
||||
new /obj/item/shard((get_turf(src)))
|
||||
|
||||
/obj/item/shield/riot/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
var/final_damage = damage
|
||||
|
||||
if(attack_type & ATTACK_TYPE_MELEE)
|
||||
var/obj/hittingthing = object
|
||||
if(hittingthing.damtype == BURN)
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(hittingthing.damtype == BRUTE)
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY)
|
||||
final_damage = 0
|
||||
|
||||
if(attack_type & ATTACK_TYPE_PROJECTILE)
|
||||
var/obj/item/projectile/shootingthing = object
|
||||
if(is_energy_reflectable_projectile(shootingthing))
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(!is_energy_reflectable_projectile(object))
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(shootingthing.damage_type == STAMINA)
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_DISABLER_DISRUPTED))
|
||||
final_damage *= 3 //disablers melt these kinds of shields. Really meant more for holoshields.
|
||||
else
|
||||
final_damage = 0
|
||||
|
||||
if(shootingthing.damage_type == TOX || shootingthing.damage_type == CLONE || shootingthing.damage_type == BRAIN || shootingthing.damage_type == OXY)
|
||||
final_damage = 0
|
||||
|
||||
if(can_shatter && (obj_integrity <= damage))
|
||||
var/turf/T = get_turf(owner)
|
||||
T.visible_message("<span class='warning'>[attack_text] destroys [src]!</span>")
|
||||
shatter(owner)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
take_damage(damage)
|
||||
take_damage(final_damage)
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/riot/laser_proof
|
||||
name = "laser resistant shield"
|
||||
desc = "A far more frail shield made of dark glass meant to block lasers but suffers from being being weak to ballistic projectiles."
|
||||
/obj/item/shield/riot/energy_proof
|
||||
name = "energy resistant shield"
|
||||
desc = "An ablative shield designed to absorb and disperse energy attacks. This comes at significant cost to its ability to withstand ballistics and kinetics, breaking apart easily."
|
||||
armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
icon_state = "riot_laser"
|
||||
item_state = "riot_laser"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_ENERGY_STRONG | SHIELD_KINETIC_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."
|
||||
/obj/item/shield/riot/kinetic_proof
|
||||
name = "kinetic resistant shield"
|
||||
desc = "A polymer and ceramic shield designed to absorb ballistic projectiles and kinetic force. It doesn't do very well into energy attacks, especially from weapons that inflict burns."
|
||||
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
icon_state = "riot_bullet"
|
||||
item_state = "riot_bullet"
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_ENERGY_WEAK
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/shield/riot/roman
|
||||
@@ -277,8 +326,8 @@
|
||||
|
||||
/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)
|
||||
shield_flags = SHIELD_ENERGY_WEAK | SHIELD_KINETIC_WEAK | SHIELD_NO_RANGED
|
||||
max_integrity = 40
|
||||
|
||||
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
|
||||
@@ -295,14 +344,80 @@
|
||||
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
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_ENERGY_WEAK
|
||||
max_integrity = 150
|
||||
|
||||
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/bang.ogg', 50)
|
||||
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
|
||||
|
||||
/obj/item/shield/riot/flash
|
||||
name = "strobe shield"
|
||||
desc = "A shield with a built in, high intensity light capable of blinding and disorienting suspects. Takes regular handheld flashes as bulbs."
|
||||
icon_state = "flashshield"
|
||||
item_state = "flashshield"
|
||||
var/obj/item/assembly/flash/handheld/embedded_flash
|
||||
|
||||
/obj/item/shield/riot/flash/Initialize()
|
||||
. = ..()
|
||||
embedded_flash = new(src)
|
||||
|
||||
/obj/item/shield/riot/flash/ComponentInitialize()
|
||||
. = .. ()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/obj/item/shield/riot/flash/attack(mob/living/M, mob/user)
|
||||
. = embedded_flash.attack(M, user)
|
||||
update_icon()
|
||||
|
||||
/obj/item/shield/riot/flash/attack_self(mob/living/carbon/user)
|
||||
. = embedded_flash.attack_self(user)
|
||||
update_icon()
|
||||
|
||||
/obj/item/shield/riot/flash/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
. = ..()
|
||||
if (. && !embedded_flash.crit_fail)
|
||||
embedded_flash.activate()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/shield/riot/flash/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/assembly/flash/handheld))
|
||||
var/obj/item/assembly/flash/handheld/flash = W
|
||||
if(flash.crit_fail)
|
||||
to_chat(user, "<span class='warning'>No sense replacing it with a broken bulb!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin to replace the bulb...</span>")
|
||||
if(do_after(user, 20, target = user))
|
||||
if(flash.crit_fail || !flash || QDELETED(flash))
|
||||
return
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
qdel(embedded_flash)
|
||||
embedded_flash = flash
|
||||
flash.forceMove(src)
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/shield/riot/flash/emp_act(severity)
|
||||
. = ..()
|
||||
embedded_flash.emp_act(severity)
|
||||
update_icon()
|
||||
|
||||
/obj/item/shield/riot/flash/update_icon_state()
|
||||
if(!embedded_flash || embedded_flash.crit_fail)
|
||||
icon_state = "riot"
|
||||
item_state = "riot"
|
||||
else
|
||||
icon_state = "flashshield"
|
||||
item_state = "flashshield"
|
||||
|
||||
/obj/item/shield/riot/flash/examine(mob/user)
|
||||
. = ..()
|
||||
if (embedded_flash?.crit_fail)
|
||||
. += "<span class='info'>The mounted bulb has burnt out. You can try replacing it with a new one.</span>"
|
||||
|
||||
/obj/item/shield/riot/tele
|
||||
name = "telescopic shield"
|
||||
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
|
||||
@@ -348,7 +463,7 @@
|
||||
|
||||
/obj/item/shield/makeshift
|
||||
name = "metal shield"
|
||||
desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather making it unwieldy."
|
||||
desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather, making it unwieldy."
|
||||
armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80)
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
@@ -362,33 +477,34 @@
|
||||
|
||||
/obj/item/shield/riot/tower
|
||||
name = "tower shield"
|
||||
desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking."
|
||||
desc = "An immense tower shield. Designed to ensure maximum protection to the user, at the expense of mobility."
|
||||
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"
|
||||
force = 16
|
||||
slowdown = 2
|
||||
throwforce = 15 //Massive pice of metal
|
||||
throwforce = 15 //Massive piece of metal
|
||||
max_integrity = 600
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
item_flags = SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
|
||||
/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 = 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"
|
||||
name = "hardlight shield implant"
|
||||
desc = "A hardlight plane of force projected from the implant. While it is capable of withstanding immense amounts of abuse, it will eventually overload from sustained impacts, especially against energy attacks. Recharges while retracted."
|
||||
item_state = "holoshield"
|
||||
icon_state = "holoshield"
|
||||
slowdown = 1
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
can_shatter = FALSE
|
||||
item_flags = SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
item_flags = ITEM_CAN_BLOCK
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_DISABLER_DISRUPTED
|
||||
var/recharge_timerid
|
||||
var/recharge_delay = 15 SECONDS
|
||||
|
||||
@@ -400,7 +516,7 @@
|
||||
if(obj_integrity == 0)
|
||||
if(ismob(loc))
|
||||
var/mob/living/L = loc
|
||||
playsound(src, 'sound/effects/glassbr3.ogg', 100)
|
||||
playsound(src, "sparks", 100, TRUE)
|
||||
L.visible_message("<span class='boldwarning'>[src] overloads from the damage sustained!</span>")
|
||||
L.dropItemToGround(src) //implant component catch hook will grab it.
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
. = ..()
|
||||
. += GLOB.plastitaniumglass_recipes
|
||||
|
||||
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
|
||||
/obj/item/stack/sheet/plastitaniumglass/on_solar_construction(obj/machinery/power/solar/S)
|
||||
S.max_integrity *= 2
|
||||
S.efficiency *= 2
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
|
||||
// new/datum/stack_recipe("diamond brick", /obj/item/ingot/diamond, 6, time = 100), \ not yet
|
||||
))
|
||||
new/datum/stack_recipe("diamond ingot", /obj/item/ingot/diamond, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/get_main_recipes()
|
||||
. = ..()
|
||||
|
||||
@@ -592,7 +592,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
return
|
||||
var/turf/T = get_turf(user) //we may have moved. adjust as needed...
|
||||
var/area/A = get_area(user)
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !A.blob_allowed))
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !(A.flags_1 & CULT_PERMITTED_1)))
|
||||
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -459,8 +459,8 @@
|
||||
|
||||
/obj/item/stack/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
|
||||
return
|
||||
// if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
|
||||
// return
|
||||
if(is_cyborg || !user.canUseTopic(src, BE_CLOSE, TRUE, FALSE) || zero_amount()) //, !iscyborg(user)
|
||||
return
|
||||
//get amount from user
|
||||
|
||||
@@ -351,6 +351,75 @@
|
||||
if(!contents.len)
|
||||
. += "[icon_state]_empty"
|
||||
|
||||
//Derringer "Cigarettes"//
|
||||
/obj/item/storage/fancy/cigarettes/derringer
|
||||
name = "\improper Robust packet"
|
||||
desc = "Smoked by the robust."
|
||||
icon_state = "robust"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer/traitor
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette, /obj/item/lighter, /obj/item/gun/ballistic/derringer, /obj/item/ammo_casing/c38, /obj/item/ammo_casing/a357, /obj/item/ammo_casing/g4570))
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/AltClick(mob/living/carbon/user)
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
var/obj/item/W = (locate(/obj/item/ammo_casing/a357) in contents) || (locate(/obj/item/clothing/mask/cigarette) in contents) || locate(/obj/item/ammo_casing/g4570) //Easy access smokes and bullets
|
||||
if(W && contents.len > 0)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, W, user)
|
||||
user.put_in_hands(W)
|
||||
contents -= W
|
||||
to_chat(user, "<span class='notice'>You take \a [W] out of the pack.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no items left in the pack.</span>")
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/PopulateContents()
|
||||
new spawn_type(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/clothing/mask/cigarette/syndicate(src)
|
||||
|
||||
//For traitors with luck/class
|
||||
/obj/item/storage/fancy/cigarettes/derringer/gold
|
||||
name = "\improper Robust Gold packet"
|
||||
desc = "Smoked by the truly robust."
|
||||
icon_state = "robustg"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer/gold
|
||||
|
||||
//For operatives, bound in a ka-tet.
|
||||
/obj/item/storage/fancy/cigarettes/derringer/midworld
|
||||
name = "\improper Midworld's Lime Bend"
|
||||
desc = "The wheel of Ka turns, Gunslinger."
|
||||
icon_state = "slime"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer/nukeop
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/midworld/PopulateContents()
|
||||
new spawn_type(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/clothing/mask/cigarette/xeno(src)
|
||||
|
||||
//For Cargomen, looking for a good deal on arms, with no quarrels as to where they're from.
|
||||
/obj/item/storage/fancy/cigarettes/derringer/smuggled
|
||||
name = "\improper Shady Jim's Super Slims packet"
|
||||
desc = "If you get caught with this, we don't know you, capiche?"
|
||||
icon_state = "shadyjim"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/smuggled/PopulateContents()
|
||||
new spawn_type(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/clothing/mask/cigarette/shadyjims (src)
|
||||
/////////////
|
||||
//CIGAR BOX//
|
||||
/////////////
|
||||
@@ -435,6 +504,20 @@
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/nugget))
|
||||
|
||||
/obj/item/storage/fancy/treat_box
|
||||
name = "treat box"
|
||||
desc = "A cardboard box used for holding dog treats."
|
||||
icon = 'icons/obj/food/containers.dmi'
|
||||
icon_state = "treatbox"
|
||||
icon_type = "treat"
|
||||
spawn_type = /obj/item/reagent_containers/food/snacks/dogtreat
|
||||
|
||||
/obj/item/storage/fancy/treat_box/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/dogtreat))
|
||||
|
||||
/obj/item/storage/fancy/cracker_pack
|
||||
name = "cracker pack"
|
||||
desc = "A pack of delicious crackers. Keep away from parrots!"
|
||||
|
||||
@@ -394,15 +394,15 @@
|
||||
desc = "You want penis enlargement pills?"
|
||||
|
||||
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/reagent_containers/pill/penis_enlargement(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/breast_enlargement
|
||||
name = "breast enlargement pills"
|
||||
desc = "Made by Fermichem - They have a woman with breasts larger than she is on them. The warming states not to take more than 10u at a time."
|
||||
desc = "Made by Fermichem - The bottle shows a woman with breasts larger than she is on them. The warning states to not take more than 10 units at a time."
|
||||
|
||||
/obj/item/storage/pill_bottle/breast_enlargement/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/reagent_containers/pill/breast_enlargement(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/neurine
|
||||
@@ -469,7 +469,7 @@
|
||||
//hijacking the minature first aids for hypospray boxes. <3
|
||||
/obj/item/storage/hypospraykit
|
||||
name = "hypospray kit"
|
||||
desc = "It's a kit containing a hypospray and specific treatment chemical-filled vials."
|
||||
desc = "It's a kit designed for containing a hypospray and specific treatment chemical-filled vials."
|
||||
icon_state = "firstaid-mini"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/storage/box/syndicate
|
||||
|
||||
/obj/item/storage/box/syndicate/PopulateContents()
|
||||
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "baseball" = 1, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1)))
|
||||
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "baseball" = 1, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1, "ancient" = 1)))
|
||||
if("bloodyspai") // 30 tc now this is more right
|
||||
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
|
||||
new /obj/item/clothing/mask/chameleon(src) // Goes with above
|
||||
@@ -62,7 +62,7 @@
|
||||
new /obj/item/clothing/glasses/phantomthief/syndicate(src)
|
||||
new /obj/item/reagent_containers/syringe/stimulants(src)
|
||||
|
||||
if("baseball") // 42~ tc
|
||||
if("baseball") // 44~ tc
|
||||
new /obj/item/melee/baseball_bat/ablative/syndi(src) //Lets say 12 tc, lesser sleeping carp
|
||||
new /obj/item/clothing/glasses/sunglasses/garb(src) //Lets say 2 tc
|
||||
new /obj/item/card/emag(src) //6 tc
|
||||
@@ -72,6 +72,7 @@
|
||||
new /obj/item/clothing/under/syndicate/baseball(src) //3tc
|
||||
new /obj/item/clothing/head/soft/baseball(src) //Lets say 4 tc
|
||||
new /obj/item/reagent_containers/hypospray/medipen/stimulants/baseball(src) //lets say 5tc
|
||||
new /obj/item/melee/baseball_bat/telescopic(src) // 2 tc
|
||||
|
||||
if("implant") // 67+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it?
|
||||
new /obj/item/implanter/freedom(src)
|
||||
@@ -155,6 +156,20 @@
|
||||
new /obj/item/card/id/syndicate(src) // 2 tc
|
||||
new /obj/item/chameleon(src) // 7 tc
|
||||
|
||||
if("ancient") //A kit so old, it's probably older than you. //This bundle is filled with the entire unlink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code.
|
||||
new /obj/item/storage/toolbox/emergency/old/ancientbundle(src) //Items fit neatly into a classic toolbox just to remind you what the theme is.
|
||||
|
||||
/obj/item/storage/toolbox/emergency/old/ancientbundle //So the subtype works
|
||||
|
||||
/obj/item/storage/toolbox/emergency/old/ancientbundle/PopulateContents()
|
||||
new /obj/item/card/emag(src)
|
||||
new /obj/item/pen/sleepy(src)
|
||||
new /obj/item/reagent_containers/pill/cyanide(src)
|
||||
new /obj/item/chameleon(src) //its not the original cloaking device, but it will do.
|
||||
new /obj/item/gun/ballistic/revolver(src)
|
||||
new /obj/item/implanter/freedom(src)
|
||||
new /obj/item/stack/telecrystal(src) //The failsafe/self destruct isn't an item we can physically include in the kit, but 1 TC is technically enough to buy the equivalent.
|
||||
|
||||
/obj/item/storage/box/syndie_kit
|
||||
name = "box"
|
||||
desc = "A sleek, sturdy box."
|
||||
@@ -531,3 +546,21 @@
|
||||
. = ..()
|
||||
new /obj/item/cardpack/syndicate(src)
|
||||
new /obj/item/cardpack/syndicate(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_deathrattle
|
||||
name = "deathrattle implant box"
|
||||
desc = "Contains eight linked deathrattle implants."
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_deathrattle/PopulateContents()
|
||||
new /obj/item/implanter(src)
|
||||
|
||||
var/datum/deathrattle_group/group = new
|
||||
|
||||
var/implants = list()
|
||||
for(var/j in 1 to 8)
|
||||
var/obj/item/implantcase/deathrattle/case = new (src)
|
||||
implants += case.imp
|
||||
|
||||
for(var/i in implants)
|
||||
group.register(i)
|
||||
desc += " The implants are registered to the \"[group.name]\" group."
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
/obj/item/instrument/harmonica,
|
||||
/obj/item/mining_voucher,
|
||||
/obj/item/suit_voucher,
|
||||
/obj/item/reagent_containers/pill))
|
||||
/obj/item/reagent_containers/pill,
|
||||
/obj/item/gun/ballistic/derringer))
|
||||
|
||||
/obj/item/storage/wallet/Exited(atom/movable/AM)
|
||||
. = ..()
|
||||
|
||||
@@ -16,17 +16,21 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
attack_speed = CLICK_CD_MELEE
|
||||
|
||||
var/stamforce = 35
|
||||
var/stamina_loss_amount = 35
|
||||
var/turned_on = FALSE
|
||||
var/knockdown = TRUE
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/hitcost = 750
|
||||
var/throw_hit_chance = 35
|
||||
var/preload_cell_type //if not empty the baton starts with this type of cell
|
||||
var/cooldown_duration = 5 SECONDS //How long our baton rightclick goes on cooldown for after applying a knockdown
|
||||
var/status_duration = 5 SECONDS //how long our status effects last for otherwise
|
||||
COOLDOWN_DECLARE(shove_cooldown)
|
||||
|
||||
/obj/item/melee/baton/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Right click attack while in combat mode to disarm instead of stun.</span>"
|
||||
. += "<span class='notice'>Right click attack while in combat mode to knockdown, but only once per [cooldown_duration / 10] seconds.</span>"
|
||||
. += "<span class='notice'>This knockdown will also put them off balance for [status_duration / 20] seconds, allowing you to shove a weapon out of their hand with a right click in Disarm intent.</span>"
|
||||
|
||||
/obj/item/melee/baton/get_cell()
|
||||
. = cell
|
||||
@@ -53,8 +57,8 @@
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
//Only mob/living types have stun handling
|
||||
if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
baton_stun(hit_atom)
|
||||
if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom) && thrownby)
|
||||
baton_stun(hit_atom, thrownby, shoving = TRUE)
|
||||
|
||||
/obj/item/melee/baton/loaded //this one starts with a cell pre-installed.
|
||||
preload_cell_type = /obj/item/stock_parts/cell/high/plus
|
||||
@@ -74,6 +78,16 @@
|
||||
//we're below minimum, turn off
|
||||
switch_status(FALSE)
|
||||
|
||||
///Check for our cell to determine how much penetration our weapon does.
|
||||
/obj/item/melee/baton/proc/get_cell_zap_pen()
|
||||
var/obj/item/stock_parts/cell/copper_top = get_cell()
|
||||
if(copper_top)
|
||||
var/chargepower = copper_top.maxcharge
|
||||
var/zap_penetration = (chargepower/1000) //This is our effective penetration. Every 1000 max charge, we get 1 pen power. A high capacity cell is equal to 10 armor pen, as an example.
|
||||
return zap_penetration
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE)
|
||||
if(turned_on != new_status)
|
||||
turned_on = new_status
|
||||
@@ -101,6 +115,7 @@
|
||||
var/obj/item/stock_parts/cell/copper_top = get_cell()
|
||||
if(copper_top)
|
||||
. += "<span class='notice'>\The [src] is [round(copper_top.percent())]% charged.</span>"
|
||||
. += "<span class='notice'>\The [src] currently can penetrate [round(copper_top.maxcharge/1000)]% of enemy armor thanks to it's loaded cell.</span>"
|
||||
else
|
||||
. += "<span class='warning'>\The [src] does not have a power source installed.</span>"
|
||||
|
||||
@@ -150,10 +165,10 @@
|
||||
/obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params)
|
||||
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
. = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-disarming.
|
||||
. = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-shoving.
|
||||
|
||||
//return TRUE to interrupt attack chain.
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, shoving = FALSE)
|
||||
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
|
||||
return FALSE
|
||||
if(turned_on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
@@ -167,21 +182,26 @@
|
||||
if(check_martial_counter(L, user))
|
||||
return TRUE
|
||||
if(turned_on)
|
||||
if(baton_stun(M, user, disarming))
|
||||
if(baton_stun(M, user, shoving))
|
||||
user.do_attack_animation(M)
|
||||
else if(user.a_intent != INTENT_HARM) //they'll try to bash in the last proc.
|
||||
M.visible_message("<span class='warning'>[user] has prodded [M] with [src]. Luckily it was off.</span>", \
|
||||
"<span class='warning'>[user] has prodded you with [src]. Luckily it was off</span>")
|
||||
return disarming || (user.a_intent != INTENT_HARM)
|
||||
return shoving || (user.a_intent != INTENT_HARM)
|
||||
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user, disarming = FALSE)
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user, shoving = FALSE)
|
||||
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/final_stamina_loss_amount = stamina_loss_amount //Our stunning power for the baton
|
||||
var/shoved = FALSE //Did we succeed on knocking our target over?
|
||||
var/zap_penetration = get_cell_zap_pen() //Find out what kind of cell we have, and calculating the resultant armor pen we get from it
|
||||
var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, "melee", null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack
|
||||
final_stamina_loss_amount = block_calculate_resultant_damage(final_stamina_loss_amount, return_list)
|
||||
|
||||
var/obj/item/stock_parts/cell/our_cell = get_cell()
|
||||
|
||||
if(!our_cell)
|
||||
switch_status(FALSE)
|
||||
return FALSE
|
||||
@@ -194,26 +214,31 @@
|
||||
L.visible_message("<span class='warning'>[user] has prodded [L] with [src]. Luckily it was out of charge.</span>", \
|
||||
"<span class='warning'>[user] has prodded you with [src]. Luckily it was out of charge.</span>")
|
||||
return FALSE
|
||||
stunpwr *= round(stuncharge/hitcost, 0.1)
|
||||
final_stamina_loss_amount *= round(stuncharge/hitcost, 0.1)
|
||||
|
||||
if(user && !user.UseStaminaBuffer(getweight(user, STAM_COST_BATON_MOB_MULT), warn = TRUE))
|
||||
return FALSE
|
||||
|
||||
if(!disarming)
|
||||
if(knockdown)
|
||||
L.DefaultCombatKnockdown(50, override_stamdmg = 0) //knockdown
|
||||
L.adjustStaminaLoss(stunpwr)
|
||||
else
|
||||
L.drop_all_held_items() //no knockdown/stamina damage, instead disarm.
|
||||
if(shoving && COOLDOWN_FINISHED(src, shove_cooldown) && !HAS_TRAIT(L, TRAIT_IWASBATONED)) //Rightclicking applies a knockdown, but only once every couple of seconds, based on the cooldown_duration var. If they were recently knocked down, they can't be knocked down again by a baton.
|
||||
L.DefaultCombatKnockdown(50, override_stamdmg = 0)
|
||||
L.apply_status_effect(STATUS_EFFECT_TASED_WEAK, status_duration) //Even if they shove themselves up, they're still slowed.
|
||||
L.apply_status_effect(STATUS_EFFECT_OFF_BALANCE, status_duration) //They're very likely to drop items if shoved briefly after a knockdown.
|
||||
shoved = TRUE
|
||||
COOLDOWN_START(src, shove_cooldown, cooldown_duration)
|
||||
ADD_TRAIT(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT) //Prevents swapping to a new baton to avoid the cooldown by just acquiring more batons
|
||||
addtimer(TRAIT_CALLBACK_REMOVE(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT), cooldown_duration)
|
||||
playsound(loc, 'sound/weapons/zapbang.ogg', 50, 1, -1)
|
||||
else //If we cannot/don't knock down the target, we apply a stagger, which keeps them from just running off
|
||||
L.apply_status_effect(STATUS_EFFECT_STAGGERED, status_duration)
|
||||
|
||||
L.apply_effect(EFFECT_STUTTER, stamforce)
|
||||
L.apply_damage (final_stamina_loss_amount, STAMINA, BODY_ZONE_CHEST, zap_block)
|
||||
L.apply_effect(EFFECT_STUTTER, stamina_loss_amount)
|
||||
SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
L.lastattacker = user.real_name
|
||||
L.lastattackerckey = user.ckey
|
||||
L.visible_message("<span class='danger'>[user] has [disarming? "disarmed" : "stunned"] [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [disarming? "disarmed" : "stunned"] you with [src]!</span>")
|
||||
log_combat(user, L, disarming? "disarmed" : "stunned")
|
||||
L.set_last_attacker(user)
|
||||
L.visible_message("<span class='danger'>[user] has [shoved ? "brutally stunned" : "stunned"] [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [shoved ? "brutally stunnned" : "stunned"] you with [src]!</span>")
|
||||
log_combat(user, L, shoved ? "stunned and attempted knockdown" : "stunned")
|
||||
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
|
||||
@@ -228,7 +253,7 @@
|
||||
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)
|
||||
user.DefaultCombatKnockdown(stamforce*6)
|
||||
user.DefaultCombatKnockdown(stamina_loss_amount*6)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
deductcharge(hitcost)
|
||||
|
||||
@@ -306,18 +331,20 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 3
|
||||
throwforce = 5
|
||||
stamforce = 25
|
||||
stamina_loss_amount = 25
|
||||
hitcost = 1000
|
||||
throw_hit_chance = 10
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
cooldown_duration = 7 SECONDS //It's a little on the weak side
|
||||
status_duration = 3 //Slows someone for a tiny bit
|
||||
var/obj/item/assembly/igniter/sparkler
|
||||
|
||||
/obj/item/melee/baton/cattleprod/Initialize()
|
||||
. = ..()
|
||||
sparkler = new (src)
|
||||
sparkler.activate_cooldown = 5
|
||||
sparkler.activate_cooldown = 7 //Helps visualize the knockdown
|
||||
|
||||
/obj/item/melee/baton/cattleprod/baton_stun()
|
||||
/obj/item/melee/baton/cattleprod/baton_stun(mob/living/L, mob/living/carbon/user, shoving = FALSE)
|
||||
sparkler?.activate()
|
||||
. = ..()
|
||||
|
||||
@@ -344,8 +371,8 @@
|
||||
/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(ishuman(hit_atom) && !caught && prob(throw_hit_chance) && thrownby)//if they are a carbon and they didn't catch it
|
||||
baton_stun(hit_atom, thrownby, shoving = TRUE)
|
||||
if(thrownby && !caught)
|
||||
sleep(1)
|
||||
if(!QDELETED(src))
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var/datum/effect_system/trail_follow/ion/ion_trail
|
||||
|
||||
/obj/item/tank/jetpack/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
ion_trail = new
|
||||
ion_trail.set_up(src)
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank/jetpack/suicide_act(mob/user)
|
||||
if (istype(user, /mob/living/carbon/human/))
|
||||
if (ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
|
||||
H.visible_message("<span class='suicide'>[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!</span>")
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
/obj/item/tank/internals/air
|
||||
name = "air tank"
|
||||
desc = "Mixed anyone?"
|
||||
icon_state = "air"
|
||||
item_state = "air"
|
||||
force = 10
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
@@ -139,14 +139,14 @@
|
||||
/obj/item/hand_tele/attack_self(mob/user)
|
||||
var/turf/current_location = get_turf(user)//What turf is the user on?
|
||||
var/area/current_area = current_location.loc
|
||||
if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
|
||||
if(!current_location || (current_area.area_flags & NOTELEPORT) || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
return
|
||||
var/list/L = list( )
|
||||
for(var/obj/machinery/computer/teleporter/com in GLOB.machines)
|
||||
if(com.target)
|
||||
var/area/A = get_area(com.target)
|
||||
if(!A || A.noteleport)
|
||||
if(!A || (A.area_flags & NOTELEPORT))
|
||||
continue
|
||||
if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged)
|
||||
L["[get_area(com.target)] (Active)"] = com.target
|
||||
@@ -159,7 +159,7 @@
|
||||
if(T.y>world.maxy-8 || T.y<8)
|
||||
continue
|
||||
var/area/A = T.loc
|
||||
if(A.noteleport)
|
||||
if(A.area_flags & NOTELEPORT)
|
||||
continue
|
||||
turfs += T
|
||||
if(turfs.len)
|
||||
@@ -172,12 +172,12 @@
|
||||
return
|
||||
var/atom/T = L[t1]
|
||||
var/area/A = get_area(T)
|
||||
if(A.noteleport)
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
if (A.area_flags & NOTELEPORT)
|
||||
to_chat(user, "<span class='notice'>[src] is malfunctioning.</span>")
|
||||
return
|
||||
current_location = get_turf(user) //Recheck.
|
||||
current_area = current_location.loc
|
||||
if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
|
||||
if (!current_location || (current_area.area_flags & NOTELEPORT) || is_away_level(current_location.z) || !isturf(user.loc))
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
return
|
||||
user.show_message("<span class='notice'>Locked In.</span>", MSG_AUDIBLE)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
item_state = "teleprod"
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user)//handles making things teleport when hit
|
||||
/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user, shoving = FALSE)//handles making things teleport when hit
|
||||
. = ..()
|
||||
if(!. || L.anchored)
|
||||
return
|
||||
@@ -16,7 +16,7 @@
|
||||
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)
|
||||
user.DefaultCombatKnockdown(stamforce * 6)
|
||||
user.DefaultCombatKnockdown(stamina_loss_amount * 6)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE))
|
||||
deductcharge(hitcost)
|
||||
|
||||
@@ -911,6 +911,16 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
var/homerun_ready = 0
|
||||
var/homerun_able = 0
|
||||
total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google
|
||||
var/on_sound
|
||||
var/on = TRUE // Are we on or off
|
||||
var/on_icon_state // What is our sprite when turned on
|
||||
var/off_icon_state // What is our sprite when turned off
|
||||
var/on_item_state // What is our in-hand sprite when turned on
|
||||
var/force_on // Damage when on
|
||||
var/force_off // Damage when off
|
||||
var/throwforce_on // Damage when on
|
||||
var/throwforce_off // Damage when off
|
||||
var/weight_class_on // What is the new size class when turned on
|
||||
|
||||
/obj/item/melee/baseball_bat/Initialize()
|
||||
. = ..()
|
||||
@@ -992,6 +1002,58 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
force = 18 //Spear damage...
|
||||
throwforce = 30
|
||||
|
||||
/obj/item/melee/baseball_bat/proc/get_on_description()
|
||||
. = list()
|
||||
.["local_on"] = "<span class ='warning'>You extend the bat.</span>"
|
||||
.["local_off"] = "<span class ='notice'>You collapse the bat.</span>"
|
||||
return .
|
||||
|
||||
/obj/item/melee/baseball_bat/telescopic
|
||||
name = "telescopic baseball bat"
|
||||
desc = "A stealthy telescopic bat that can fit in a pocket when collapsed."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "baseball_bat_telescopic_0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = NONE
|
||||
force = 5
|
||||
throwforce = 10
|
||||
on = FALSE
|
||||
on_sound = 'sound/weapons/batonextend.ogg'
|
||||
on_icon_state = "baseball_bat_telescopic_1"
|
||||
off_icon_state = "baseball_bat_telescopic_0"
|
||||
on_item_state = "baseball_bat_telescopic"
|
||||
force_on = 15
|
||||
force_off = 5
|
||||
throwforce_on = 20
|
||||
throwforce_off = 10
|
||||
weight_class_on = WEIGHT_CLASS_HUGE
|
||||
total_mass = TOTAL_MASS_NORMAL_ITEM
|
||||
|
||||
/obj/item/melee/baseball_bat/telescopic/attack_self(mob/user)
|
||||
on = !on
|
||||
var/list/desc = get_on_description()
|
||||
if(on)
|
||||
to_chat(user, desc["local_on"])
|
||||
icon_state = on_icon_state
|
||||
item_state = on_item_state
|
||||
w_class = weight_class_on
|
||||
force = force_on
|
||||
throwforce = throwforce_on
|
||||
attack_verb = list("beat", "smacked")
|
||||
else
|
||||
to_chat(user, desc["local_off"])
|
||||
icon_state = off_icon_state
|
||||
item_state = null //no sprite for concealment even when in hand
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = force_off
|
||||
throwforce = throwforce_off
|
||||
attack_verb = list("drubbed", "beaned")
|
||||
playsound(src.loc, on_sound, 50, 1)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/melee/flyswatter
|
||||
name = "flyswatter"
|
||||
desc = "Useful for killing pests of all sizes."
|
||||
|
||||
Reference in New Issue
Block a user