Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into DRAKEBORG
This commit is contained in:
@@ -238,24 +238,22 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1)
|
||||
return(BRUTELOSS)
|
||||
|
||||
/obj/item/pipe_dispenser/ui_base_html(html)
|
||||
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
|
||||
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
|
||||
/obj/item/pipe_dispenser/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/pipes),
|
||||
)
|
||||
|
||||
/obj/item/pipe_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/pipe_dispenser/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
|
||||
assets.send(user)
|
||||
|
||||
ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state)
|
||||
ui = new(user, src, "RapidPipeDispenser", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/pipe_dispenser/ui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"category" = category,
|
||||
"piping_layer" = piping_layer,
|
||||
// "ducting_layer" = ducting_layer, //uhh is this for chem thing?
|
||||
"preview_rows" = recipe.get_preview(p_dir),
|
||||
"categories" = list(),
|
||||
"selected_color" = paint_color,
|
||||
@@ -284,7 +282,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
/obj/item/pipe_dispenser/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
if(!usr.canUseTopic(src))
|
||||
if(!usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
var/playeffect = TRUE
|
||||
switch(action)
|
||||
@@ -304,6 +302,9 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
if("piping_layer")
|
||||
piping_layer = text2num(params["piping_layer"])
|
||||
playeffect = FALSE
|
||||
// if("ducting_layer")
|
||||
// ducting_layer = text2num(params["ducting_layer"])
|
||||
// playeffect = FALSE
|
||||
if("pipe_type")
|
||||
var/static/list/recipes
|
||||
if(!recipes)
|
||||
@@ -320,11 +321,9 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
mode &= ~n
|
||||
else
|
||||
mode |= n
|
||||
|
||||
if(playeffect && world.time >= effectcooldown)
|
||||
if(playeffect)
|
||||
spark_system.start()
|
||||
effectcooldown = world.time + 100
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, FALSE)
|
||||
return TRUE
|
||||
|
||||
/obj/item/pipe_dispenser/pre_attack(atom/A, mob/user)
|
||||
|
||||
@@ -26,6 +26,7 @@ RSF
|
||||
/obj/item/rsf/cyborg
|
||||
matter = 30
|
||||
|
||||
|
||||
/obj/item/rsf/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/rcd_ammo))
|
||||
if((matter + 10) > 30)
|
||||
@@ -64,15 +65,16 @@ RSF
|
||||
return
|
||||
if (!(istype(A, /obj/structure/table) || isfloorturf(A)))
|
||||
return
|
||||
|
||||
if(matter < 1)
|
||||
to_chat(user, "<span class='warning'>\The [src] doesn't have enough matter left.</span>")
|
||||
return
|
||||
if(iscyborg(user))
|
||||
matter = 30 //borgs dont actually use the matter so this is mostly just so it doesnt fail the next check incase of shennanigans
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(!R.cell || R.cell.charge < 200)
|
||||
to_chat(user, "<span class='warning'>You do not have enough power to use [src].</span>")
|
||||
return
|
||||
if(matter < 1)
|
||||
to_chat(user, "<span class='warning'>\The [src] doesn't have enough matter left.</span>")
|
||||
return
|
||||
|
||||
|
||||
var/turf/T = get_turf(A)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
|
||||
@@ -91,7 +93,7 @@ RSF
|
||||
use_matter(50, user)
|
||||
if(4)
|
||||
to_chat(user, "Dispensing Dice Pack...")
|
||||
new /obj/item/storage/pill_bottle/dice(T)
|
||||
new /obj/item/storage/box/dice(T)
|
||||
use_matter(200, user)
|
||||
if(5)
|
||||
to_chat(user, "Dispensing Cigarette...")
|
||||
|
||||
@@ -180,10 +180,10 @@
|
||||
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)
|
||||
/obj/item/airlock_painter/decal/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state)
|
||||
ui = new(user, src, "DecalPainter", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_data(mob/user)
|
||||
@@ -233,4 +233,4 @@
|
||||
|
||||
/obj/item/airlock_painter/decal/debug/Initialize()
|
||||
. = ..()
|
||||
ink = new /obj/item/toner/extreme(src)
|
||||
ink = new /obj/item/toner/extreme(src)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Armor kits! Reinforcing uniforms to maintain fashion and also armor capabilities.
|
||||
|
||||
/obj/item/armorkit
|
||||
name = "durathread armor kit"
|
||||
desc = "A glorified sewing kit with durathread sheets, thread, and a titanium needle, for reinforcing jumpsuits and uniforms."
|
||||
icon = 'icons/obj/clothing/reinf_kits.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon_state = "durathread_kit" // shoutout to my guy Toriate for being good at sprites tho
|
||||
|
||||
/obj/item/armorkit/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
// yeah have fun making subtypes and modifying the afterattack if you want to make variants
|
||||
// idiot
|
||||
// - hatter
|
||||
var/used = FALSE
|
||||
|
||||
if(isobj(target) && istype(target, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/C = target
|
||||
if(C.armor.melee < 10)
|
||||
C.armor.melee = 10
|
||||
used = TRUE
|
||||
if(C.armor.laser < 10)
|
||||
C.armor.laser = 10
|
||||
used = TRUE
|
||||
if(C.armor.fire < 40)
|
||||
C.armor.fire = 40
|
||||
used = TRUE
|
||||
if(C.armor.acid < 10)
|
||||
C.armor.acid = 10
|
||||
used = TRUE
|
||||
if(C.armor.bomb < 5)
|
||||
C.armor.bomb = 5
|
||||
used = TRUE
|
||||
|
||||
if(used)
|
||||
user.visible_message("<span class = 'notice'>[user] uses [src] on [C], reinforcing it and tossing the empty case away afterwards.</span>", \
|
||||
"<span class = 'notice'>You reinforce [C] with [src], making it a little more protective! You toss the empty casing away afterwards.</span>")
|
||||
C.name = "durathread [C.name]" // this disappears if it gets repaired, which is annoying
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class = 'notice'>You stare at [src] and [C], coming to the conclusion that you probably don't need to reinforce it any further.")
|
||||
return
|
||||
else
|
||||
return
|
||||
@@ -71,8 +71,6 @@
|
||||
if(user.incapacitated())
|
||||
to_chat(user, "<span class='warning'>You can't get out while you're restrained like this!</span>")
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You claw at the fabric of [src], trying to tear it open...</span>")
|
||||
to_chat(loc, "<span class='warning'>Someone starts trying to break free of [src]!</span>")
|
||||
if(!do_after(user, 200, target = src))
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
icon_state = "cutout_basic"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
resistance_flags = FLAMMABLE
|
||||
attack_hand_speed = CLICK_CD_MELEE
|
||||
attack_hand_is_action = TRUE
|
||||
/// Possible restyles for the cutout, add an entry in change_appearance() if you add to here
|
||||
var/static/list/possible_appearances
|
||||
/// If the cutout is pushed over and has to be righted
|
||||
@@ -43,8 +45,7 @@
|
||||
"Monkey" = image(icon = src.icon, icon_state = "cutout_monky"),
|
||||
))
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/cardboard_cutout/attack_hand(mob/living/user)
|
||||
/obj/item/cardboard_cutout/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(user.a_intent == INTENT_HELP || pushed_over)
|
||||
return ..()
|
||||
user.visible_message("<span class='warning'>[user] pushes over [src]!</span>", "<span class='danger'>You push over [src]!</span>")
|
||||
@@ -81,7 +82,6 @@
|
||||
else if(I.hitsound)
|
||||
playsound(loc, I.hitsound, get_clamped_volume(), 1, -1)
|
||||
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
|
||||
if(I.force)
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
switch(var_name)
|
||||
if("assignment","registered_name")
|
||||
if(NAMEOF(src, assignment),NAMEOF(src, registered_name)) //,NAMEOF(src, registered_age))
|
||||
update_label()
|
||||
|
||||
/obj/item/card/id/attack_self(mob/user)
|
||||
@@ -250,15 +250,13 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/proc/insert_money(obj/item/I, mob/user, physical_currency)
|
||||
if(!registered_account)
|
||||
to_chat(user, "<span class='warning'>[src] doesn't have a linked account to deposit [I] into!</span>")
|
||||
return
|
||||
var/cash_money = I.get_item_credit_value()
|
||||
if(!cash_money)
|
||||
to_chat(user, "<span class='warning'>[I] doesn't seem to be worth anything!</span>")
|
||||
return
|
||||
|
||||
if(!registered_account)
|
||||
to_chat(user, "<span class='warning'>[src] doesn't have a linked account to deposit [I] into!</span>")
|
||||
return
|
||||
|
||||
registered_account.adjust_money(cash_money)
|
||||
if(physical_currency)
|
||||
to_chat(user, "<span class='notice'>You stuff [I] into [src]. It disappears in a small puff of bluespace smoke, adding [cash_money] credits to the linked account.</span>")
|
||||
@@ -269,17 +267,20 @@
|
||||
qdel(I)
|
||||
|
||||
/obj/item/card/id/proc/mass_insert_money(list/money, mob/user)
|
||||
if(!registered_account)
|
||||
to_chat(user, "<span class='warning'>[src] doesn't have a linked account to deposit into!</span>")
|
||||
return FALSE
|
||||
|
||||
if (!money || !money.len)
|
||||
return FALSE
|
||||
|
||||
var/total = 0
|
||||
|
||||
for (var/obj/item/physical_money in money)
|
||||
var/cash_money = physical_money.get_item_credit_value()
|
||||
total += physical_money.get_item_credit_value()
|
||||
CHECK_TICK
|
||||
|
||||
total += cash_money
|
||||
|
||||
registered_account.adjust_money(cash_money)
|
||||
registered_account.adjust_money(total)
|
||||
|
||||
QDEL_LIST(money)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
custom_materials = list(/datum/material/iron=13000)
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = "swing_hit"
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
actions_types = list(/datum/action/item_action/startchainsaw)
|
||||
tool_behaviour = TOOL_SAW
|
||||
toolspeed = 0.5
|
||||
@@ -71,10 +71,6 @@
|
||||
/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>"
|
||||
|
||||
@@ -53,32 +53,32 @@
|
||||
|
||||
/obj/item/chromosome/stabilizer
|
||||
name = "stabilizer chromosome"
|
||||
desc = "A chromosome that adjusts to the body to reduce genetic damage by 20%."
|
||||
desc = "A chromosome that reduces mutation instability by 20%."
|
||||
icon_state = "stabilizer"
|
||||
stabilizer_coeff = 0.8
|
||||
weight = 1
|
||||
|
||||
/obj/item/chromosome/synchronizer
|
||||
name = "synchronizer chromosome"
|
||||
desc = "A chromosome that gives the mind more controle over the mutation, reducing knockback and downsides by 50%."
|
||||
desc = "A chromosome that reduces mutation knockback and downsides by 50%."
|
||||
icon_state = "synchronizer"
|
||||
synchronizer_coeff = 0.5
|
||||
|
||||
/obj/item/chromosome/power
|
||||
name = "power chromosome"
|
||||
desc = "A power chromosome for boosting certain mutation's power by 50%."
|
||||
desc = "A chromosome that increases mutation power by 50%."
|
||||
icon_state = "power"
|
||||
power_coeff = 1.5
|
||||
|
||||
/obj/item/chromosome/energy
|
||||
name = "energetic chromosome"
|
||||
desc = "A chromosome that reduces cooldown on action based mutations by 50%."
|
||||
desc = "A chromosome that reduces action based mutation cooldowns by by 50%."
|
||||
icon_state = "energy"
|
||||
energy_coeff = 0.5
|
||||
|
||||
/obj/item/chromosome/reinforcer
|
||||
name = "reinforcement chromosome"
|
||||
desc = "Renders the mutation immune to mutadone."
|
||||
desc = "A chromosome that renders mutations immune to mutadone."
|
||||
icon_state = "reinforcer"
|
||||
weight = 3
|
||||
|
||||
|
||||
@@ -188,4 +188,4 @@
|
||||
else
|
||||
..()
|
||||
else
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -32,6 +32,6 @@
|
||||
if(istype(I, /obj/item/gavelhammer))
|
||||
playsound(loc, 'sound/items/gavel.ogg', 100, 1)
|
||||
user.visible_message("<span class='warning'>[user] strikes [src] with [I].</span>")
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -147,23 +147,23 @@
|
||||
to_chat(user, "<span class='warning'>There is not enough of [src] left!</span>")
|
||||
. = TRUE
|
||||
|
||||
/obj/item/toy/crayon/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
// tgui is a plague upon this codebase
|
||||
/obj/item/toy/crayon/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/toy/crayon/ui_interact(mob/user, datum/tgui/ui)
|
||||
// tgui is a plague upon this codebase
|
||||
// no u
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "crayon", name, 600, 600,
|
||||
master_ui, state)
|
||||
ui = new(user, src, "Crayon", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
if(has_cap)
|
||||
is_capped = !is_capped
|
||||
to_chat(user, "<span class='notice'>The cap on [src] is now [is_capped ? "on" : "off"].</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/crayon/CtrlClick(mob/user)
|
||||
if(can_change_colour && !isturf(loc) && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
@@ -273,7 +273,9 @@
|
||||
. = ..()
|
||||
if(!proximity || !check_allowed_items(target))
|
||||
return
|
||||
draw_on(target, user, proximity, params)
|
||||
|
||||
/obj/item/toy/crayon/proc/draw_on(atom/target, mob/user, proximity, params)
|
||||
var/static/list/punctuation = list("!","?",".",",","/","+","-","=","%","#","&")
|
||||
|
||||
var/cost = 1
|
||||
@@ -568,9 +570,9 @@
|
||||
dye_color = DYE_RAINBOW
|
||||
charges = -1
|
||||
|
||||
/obj/item/toy/crayon/rainbow/afterattack(atom/target, mob/user, proximity, params)
|
||||
/obj/item/toy/crayon/rainbow/draw_on(atom/target, mob/user, proximity, params)
|
||||
paint_color = rgb(rand(0,255), rand(0,255), rand(0,255))
|
||||
. = ..()
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Crayon Box
|
||||
@@ -693,7 +695,7 @@
|
||||
. += "It is empty."
|
||||
. += "<span class='notice'>Alt-click [src] to [ is_capped ? "take the cap off" : "put the cap on"].</span>"
|
||||
|
||||
/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user, proximity, params)
|
||||
/obj/item/toy/crayon/spraycan/draw_on(atom/target, mob/user, proximity, params)
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
@@ -766,7 +768,7 @@
|
||||
desc = "A metallic container containing shiny synthesised paint."
|
||||
charges = -1
|
||||
|
||||
/obj/item/toy/crayon/spraycan/borg/afterattack(atom/target,mob/user,proximity, params)
|
||||
/obj/item/toy/crayon/spraycan/borg/draw_on(atom/target,mob/user,proximity, params)
|
||||
var/diff = ..()
|
||||
if(!iscyborg(user))
|
||||
to_chat(user, "<span class='notice'>How did you get this?</span>")
|
||||
|
||||
@@ -77,8 +77,7 @@
|
||||
/obj/item/defibrillator/ui_action_click()
|
||||
toggle_paddles()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/defibrillator/attack_hand(mob/user)
|
||||
/obj/item/defibrillator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user)
|
||||
if(slot_flags == ITEM_SLOT_BACK)
|
||||
if(user.get_item_by_slot(SLOT_BACK) == src)
|
||||
|
||||
@@ -1027,6 +1027,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
else if(is_type_in_list(C, contained_item)) //Checks if there is a pen
|
||||
if(inserted_item)
|
||||
to_chat(user, "<span class='warning'>There is already \a [inserted_item] in \the [src]!</span>")
|
||||
return ..()
|
||||
else
|
||||
if(!user.transferItemToLoc(C, src))
|
||||
return
|
||||
|
||||
@@ -54,18 +54,20 @@
|
||||
name = initial(name)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/aicard/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/aicard/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
/obj/item/aicard/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "intellicard", name, 500, 500, master_ui, state)
|
||||
ui = new(user, src, "Intellicard", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/aicard/ui_data()
|
||||
var/list/data = list()
|
||||
if(AI)
|
||||
data["name"] = AI.name
|
||||
data["laws"] = AI.laws.get_law_list(include_zeroth = 1)
|
||||
data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE)
|
||||
data["health"] = (AI.health + 100) / 2
|
||||
data["wireless"] = !AI.control_disabled //todo disabled->enabled
|
||||
data["radio"] = AI.radio_enabled
|
||||
@@ -86,19 +88,19 @@
|
||||
if(confirm == "Yes" && !..())
|
||||
flush = TRUE
|
||||
if(AI && AI.loc == src)
|
||||
to_chat(AI, "Your core files are being wiped!")
|
||||
to_chat(AI, "<span class='userdanger'>Your core files are being wiped!</span>")
|
||||
while(AI.stat != DEAD && flush)
|
||||
AI.adjustOxyLoss(1)
|
||||
AI.adjustOxyLoss(5)
|
||||
AI.updatehealth()
|
||||
sleep(5)
|
||||
flush = FALSE
|
||||
. = TRUE
|
||||
if("wireless")
|
||||
AI.control_disabled = !AI.control_disabled
|
||||
to_chat(AI, "[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!")
|
||||
to_chat(AI, "<span class='warning'>[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!</span>")
|
||||
. = TRUE
|
||||
if("radio")
|
||||
AI.radio_enabled = !AI.radio_enabled
|
||||
to_chat(AI, "Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!")
|
||||
to_chat(AI, "<span class='warning'>Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!</span>")
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -132,8 +132,7 @@
|
||||
/obj/effect/dummy/chameleon/attackby()
|
||||
master.disrupt()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/dummy/chameleon/attack_hand()
|
||||
/obj/effect/dummy/chameleon/on_attack_hand()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_animal()
|
||||
|
||||
@@ -116,8 +116,6 @@
|
||||
if(!hound)
|
||||
go_out(user)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
return
|
||||
var/voracious = TRUE
|
||||
@@ -165,12 +163,13 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/dogborg/sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
/obj/item/dogborg/sleeper/ui_state(mob/user)
|
||||
return GLOB.notcontained_state
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/dogborg/sleeper/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "dogborg_sleeper", name, 375, 550, master_ui, state)
|
||||
ui = new(user, src, "dogborg_sleeper", name, 375, 550) //UI DOES NOT EXIST
|
||||
ui.open()
|
||||
|
||||
/obj/item/dogborg/sleeper/ui_data()
|
||||
|
||||
@@ -183,9 +183,21 @@
|
||||
var/T = get_turf(target)
|
||||
if(locate(/mob/living) in T)
|
||||
new /obj/effect/temp_visual/medical_holosign(T,user) //produce a holographic glow
|
||||
holo_cooldown = world.time + 100
|
||||
holo_cooldown = world.time + 10 SECONDS
|
||||
return
|
||||
|
||||
// see: [/datum/wound/burn/proc/uv()]
|
||||
/obj/item/flashlight/pen/paramedic
|
||||
name = "paramedic penlight"
|
||||
desc = "A high-powered UV penlight intended to help stave off infection in the field on serious burned patients. Probably really bad to look into."
|
||||
icon_state = "penlight_surgical"
|
||||
/// Our current UV cooldown
|
||||
var/uv_cooldown = 0
|
||||
/// How long between UV fryings
|
||||
var/uv_cooldown_length = 1 MINUTES
|
||||
/// How much sanitization to apply to the burn wound
|
||||
var/uv_power = 1
|
||||
|
||||
/obj/effect/temp_visual/medical_holosign
|
||||
name = "medical holosign"
|
||||
desc = "A small holographic glow that indicates a medic is coming to treat a patient."
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
user.visible_message("<span class='warning'>[user] projects a forcefield!</span>","<span class='notice'>You project a forcefield.</span>")
|
||||
var/obj/structure/projected_forcefield/F = new(T, src)
|
||||
current_fields += F
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
|
||||
/obj/item/forcefield_projector/attack_self(mob/user)
|
||||
if(LAZYLEN(current_fields))
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
rad_flags = RAD_NO_CONTAMINATE
|
||||
custom_materials = list(/datum/material/iron = 150, /datum/material/glass = 150)
|
||||
|
||||
var/grace = RAD_GRACE_PERIOD
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
GLOBAL_LIST_EMPTY(GPS_list)
|
||||
|
||||
/obj/item/gps
|
||||
name = "global positioning system"
|
||||
desc = "Helping lost spacemen find their way through the planets since 2016."
|
||||
@@ -8,138 +8,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
obj_flags = UNIQUE_RENAME
|
||||
var/gpstag = "COM0"
|
||||
var/emped = FALSE
|
||||
var/tracking = TRUE
|
||||
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
|
||||
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
|
||||
|
||||
/obj/item/gps/examine(mob/user)
|
||||
. = ..()
|
||||
var/turf/curr = get_turf(src)
|
||||
. += "The screen says: [get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
|
||||
. += "<span class='notice'>Alt-click to switch it [tracking ? "off":"on"].</span>"
|
||||
|
||||
/obj/item/gps/Initialize()
|
||||
. = ..()
|
||||
GLOB.GPS_list += src
|
||||
name = "global positioning system ([gpstag])"
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/gps/Destroy()
|
||||
GLOB.GPS_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/gps/emp_act(severity)
|
||||
. = ..()
|
||||
if (. & EMP_PROTECT_SELF)
|
||||
return
|
||||
emped = TRUE
|
||||
cut_overlay("working")
|
||||
add_overlay("emp")
|
||||
addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_UNIQUE|TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
|
||||
SStgui.close_uis(src) //Close the UI control if it is open.
|
||||
|
||||
/obj/item/gps/proc/reboot()
|
||||
emped = FALSE
|
||||
cut_overlay("emp")
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/gps/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
toggletracking(user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gps/proc/toggletracking(mob/user)
|
||||
if(!user.canUseTopic(src, BE_CLOSE))
|
||||
return //user not valid to use gps
|
||||
if(emped)
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
if(tracking)
|
||||
cut_overlay("working")
|
||||
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
|
||||
tracking = FALSE
|
||||
else
|
||||
add_overlay("working")
|
||||
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
|
||||
tracking = TRUE
|
||||
|
||||
|
||||
/obj/item/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
|
||||
if(emped)
|
||||
to_chat(user, "[src] fizzles weakly.")
|
||||
return
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// Variable window height, depending on how many GPS units there are
|
||||
// to show, clamped to relatively safe range.
|
||||
var/gps_window_height = clamp(325 + GLOB.GPS_list.len * 14, 325, 700)
|
||||
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
|
||||
ui.open()
|
||||
|
||||
ui.set_autoupdate(state = updating)
|
||||
|
||||
|
||||
/obj/item/gps/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = tracking
|
||||
data["tag"] = gpstag
|
||||
data["updating"] = updating
|
||||
data["globalmode"] = global_mode
|
||||
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
|
||||
return data
|
||||
|
||||
var/turf/curr = get_turf(src)
|
||||
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
|
||||
data["currentArea"] = "[get_area_name(curr, TRUE)]"
|
||||
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
|
||||
|
||||
var/list/signals = list()
|
||||
data["signals"] = list()
|
||||
|
||||
for(var/gps in GLOB.GPS_list)
|
||||
var/obj/item/gps/G = gps
|
||||
if(G.emped || !G.tracking || G == src)
|
||||
continue
|
||||
var/turf/pos = get_turf(G)
|
||||
if(!global_mode && pos.z != curr.z)
|
||||
continue
|
||||
var/list/signal = list()
|
||||
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
|
||||
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
|
||||
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
|
||||
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
|
||||
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
|
||||
|
||||
signals += list(signal) //Add this signal to the list of signals
|
||||
data["signals"] = signals
|
||||
return data
|
||||
|
||||
|
||||
|
||||
/obj/item/gps/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = copytext(sanitize(a), 1, 20)
|
||||
gpstag = a
|
||||
. = TRUE
|
||||
name = "global positioning system ([gpstag])"
|
||||
|
||||
if("power")
|
||||
toggletracking(usr)
|
||||
. = TRUE
|
||||
if("updating")
|
||||
updating = !updating
|
||||
. = TRUE
|
||||
if("globalmode")
|
||||
global_mode = !global_mode
|
||||
. = TRUE
|
||||
|
||||
AddComponent(/datum/component/gps/item, gpstag)
|
||||
|
||||
/obj/item/gps/science
|
||||
icon_state = "gps-s"
|
||||
|
||||
@@ -263,3 +263,11 @@
|
||||
icon = 'icons/obj/advancedtools.dmi'
|
||||
icon_state = "multitool"
|
||||
toolspeed = 0.2
|
||||
|
||||
/obj/item/multitool/advanced/brass
|
||||
name = "clockwork multitool"
|
||||
desc = "A brass...multitool? With three prongs arcing electricity between them. It vibrates subtly in your hand."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "clockitool"
|
||||
toolspeed = 0.2
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/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)
|
||||
/obj/item/stack/circuit_stack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!user.get_inactive_held_item() == src)
|
||||
return ..()
|
||||
|
||||
@@ -97,10 +97,7 @@ GLOBAL_LIST_EMPTY(power_sinks)
|
||||
/obj/item/powersink/attack_ai()
|
||||
return
|
||||
|
||||
/obj/item/powersink/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/powersink/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
switch(mode)
|
||||
if(DISCONNECTED)
|
||||
..()
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
var/on = TRUE
|
||||
var/shock_cooldown = FALSE
|
||||
|
||||
var/ui_x = 260
|
||||
var/ui_y = 137
|
||||
|
||||
/obj/item/electropack/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (FIRELOSS)
|
||||
@@ -26,10 +29,9 @@
|
||||
|
||||
/obj/item/electropack/Destroy()
|
||||
SSradio.remove_object(src, frequency)
|
||||
. = ..()
|
||||
return ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/electropack/attack_hand(mob/user)
|
||||
/obj/item/electropack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
if(src == C.back)
|
||||
@@ -37,7 +39,7 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/electropack/attackby(obj/item/W, mob/living/user, params)
|
||||
/obj/item/electropack/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/clothing/head/helmet))
|
||||
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user)
|
||||
A.icon = 'icons/obj/assemblies.dmi'
|
||||
@@ -57,56 +59,12 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/electropack/Topic(href, href_list)
|
||||
var/mob/living/carbon/C = usr
|
||||
if(usr.stat || usr.restrained() || C.back == src)
|
||||
return
|
||||
|
||||
if(!usr.canUseTopic(src, BE_CLOSE))
|
||||
usr << browse(null, "window=radio")
|
||||
onclose(usr, "radio")
|
||||
return
|
||||
|
||||
if(href_list["set"])
|
||||
if(href_list["set"] == "freq")
|
||||
var/new_freq = input(usr, "Input a new receiving frequency", "Electropack Frequency", format_frequency(frequency)) as num|null
|
||||
if(!usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
new_freq = unformat_frequency(new_freq)
|
||||
new_freq = sanitize_frequency(new_freq, TRUE)
|
||||
set_frequency(new_freq)
|
||||
|
||||
if(href_list["set"] == "code")
|
||||
var/new_code = input(usr, "Input a new receiving code", "Electropack Code", code) as num|null
|
||||
if(!usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
new_code = round(new_code)
|
||||
new_code = clamp(new_code, 1, 100)
|
||||
code = new_code
|
||||
|
||||
if(href_list["set"] == "power")
|
||||
if(!usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
on = !(on)
|
||||
icon_state = "electropack[on]"
|
||||
|
||||
if(usr)
|
||||
attack_self(usr)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/electropack/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
SSradio.add_object(src, frequency, RADIO_SIGNALER)
|
||||
return
|
||||
|
||||
/obj/item/electropack/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.data["code"] != code)
|
||||
return
|
||||
|
||||
if(isliving(loc) && on)
|
||||
if(shock_cooldown == TRUE)
|
||||
if(shock_cooldown)
|
||||
return
|
||||
shock_cooldown = TRUE
|
||||
addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100)
|
||||
@@ -122,28 +80,59 @@
|
||||
|
||||
if(master)
|
||||
master.receive_signal()
|
||||
return
|
||||
|
||||
/obj/item/electropack/ui_interact(mob/user)
|
||||
if(!ishuman(user))
|
||||
/obj/item/electropack/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
SSradio.add_object(src, frequency, RADIO_SIGNALER)
|
||||
|
||||
/obj/item/electropack/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
/obj/item/electropack/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Electropack", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/electropack/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = on
|
||||
data["frequency"] = frequency
|
||||
data["code"] = code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
data["maxFrequency"] = MAX_FREE_FREQ
|
||||
return data
|
||||
|
||||
/obj/item/electropack/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<TT>
|
||||
Turned [on ? "On" : "Off"] - <A href='?src=[REF(src)];set=power'>Toggle</A><BR>
|
||||
<B>Frequency/Code</B> for electropack:<BR>
|
||||
Frequency:
|
||||
[format_frequency(src.frequency)]
|
||||
<A href='byond://?src=[REF(src)];set=freq'>Set</A><BR>
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
icon_state = "electropack[on]"
|
||||
. = TRUE
|
||||
if("freq")
|
||||
var/value = unformat_frequency(params["freq"])
|
||||
if(value)
|
||||
frequency = sanitize_frequency(value, TRUE)
|
||||
set_frequency(frequency)
|
||||
. = TRUE
|
||||
if("code")
|
||||
var/value = text2num(params["code"])
|
||||
if(value)
|
||||
value = round(value)
|
||||
code = clamp(value, 1, 100)
|
||||
. = TRUE
|
||||
if("reset")
|
||||
if(params["reset"] == "freq")
|
||||
frequency = initial(frequency)
|
||||
. = TRUE
|
||||
else if(params["reset"] == "code")
|
||||
code = initial(code)
|
||||
. = TRUE
|
||||
|
||||
Code:
|
||||
[src.code]
|
||||
<A href='byond://?src=[REF(src)];set=code'>Set</A><BR>
|
||||
</TT>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
/obj/item/electropack/shockcollar
|
||||
name = "shock collar"
|
||||
@@ -153,7 +142,7 @@ Code:
|
||||
icon_state = "shockcollar"
|
||||
item_state = "shockcollar"
|
||||
body_parts_covered = NECK
|
||||
slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers
|
||||
slot_flags = ITEM_SLOT_NECK //no more pocket shockers. Now done without lazyness
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
strip_delay = 60
|
||||
equip_delay_other = 60
|
||||
@@ -169,22 +158,24 @@ Code:
|
||||
materials = list(/datum/material/iron = 5000, /datum/material/glass =2000)
|
||||
category = list("hacked", "Misc")
|
||||
|
||||
/obj/item/electropack/shockcollar/attack_hand(mob/user)
|
||||
/obj/item/electropack/shockcollar/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.get_item_by_slot(SLOT_NECK))
|
||||
to_chat(user, "<span class='warning'>The collar is fastened tight! You'll need help taking this off!</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal)
|
||||
/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) //we have to override this because of text
|
||||
if(!signal || signal.data["code"] != code)
|
||||
return
|
||||
|
||||
if(isliving(loc) && on)
|
||||
if(isliving(loc) && on) //the "on" arg is currently useless
|
||||
var/mob/living/L = loc
|
||||
if(!L.get_item_by_slot(SLOT_NECK)) //**properly** stops pocket shockers
|
||||
return
|
||||
if(shock_cooldown == TRUE)
|
||||
return
|
||||
shock_cooldown = TRUE
|
||||
addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100)
|
||||
var/mob/living/L = loc
|
||||
step(L, pick(GLOB.cardinals))
|
||||
|
||||
to_chat(L, "<span class='danger'>You feel a sharp shock from the collar!</span>")
|
||||
@@ -204,10 +195,13 @@ Code:
|
||||
if(t)
|
||||
tagname = t
|
||||
name = "[initial(name)] - [t]"
|
||||
return
|
||||
if(istype(W, /obj/item/clothing/head/helmet)) //lazy method of denying this
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
|
||||
/obj/item/electropack/shockcollar/ui_interact(mob/user) //note to src: use tgooey
|
||||
var/dat = {"
|
||||
<TT>
|
||||
<B>Frequency/Code</B> for shock collar:<BR>
|
||||
|
||||
@@ -86,10 +86,7 @@
|
||||
/obj/item/radio/intercom/attack_ai(mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/item/radio/intercom/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/radio/intercom/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
interact(user)
|
||||
|
||||
/obj/item/radio/intercom/interact(mob/user)
|
||||
|
||||
@@ -107,19 +107,15 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/radio/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
|
||||
. = ..()
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/radio/ui_state(mob/user)
|
||||
return GLOB.inventory_state
|
||||
|
||||
/obj/item/radio/ui_interact(mob/user, datum/tgui/ui, datum/ui_state/state)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
var/ui_width = 360
|
||||
var/ui_height = 106
|
||||
if(subspace_transmission)
|
||||
if(channels.len > 0)
|
||||
ui_height += 6 + channels.len * 21
|
||||
else
|
||||
ui_height += 24
|
||||
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
|
||||
ui = new(user, src, "Radio", name)
|
||||
if(state)
|
||||
ui.set_state(state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/radio/ui_data(mob/user)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
to_chat(loc, "<span class='userdanger'>*ding*</span>")
|
||||
addtimer(CALLBACK(src, .proc/snap), 2)
|
||||
|
||||
/obj/item/reverse_bear_trap/attack_hand(mob/user)
|
||||
/obj/item/reverse_bear_trap/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.get_item_by_slot(SLOT_HEAD) == src)
|
||||
|
||||
@@ -10,6 +10,14 @@ NANITE SCANNER
|
||||
GENETICS SCANNER
|
||||
|
||||
*/
|
||||
|
||||
// Describes the three modes of scanning available for health analyzers
|
||||
#define SCANMODE_HEALTH 0
|
||||
#define SCANMODE_CHEMICAL 1
|
||||
#define SCANMODE_WOUND 2
|
||||
#define SCANNER_CONDENSED 0
|
||||
#define SCANNER_VERBOSE 1
|
||||
|
||||
/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."
|
||||
@@ -80,7 +88,7 @@ GENETICS SCANNER
|
||||
throw_range = 7
|
||||
custom_materials = list(/datum/material/iron=200)
|
||||
var/mode = 1
|
||||
var/scanmode = 0
|
||||
var/scanmode = SCANMODE_HEALTH
|
||||
var/advanced = FALSE
|
||||
|
||||
/obj/item/healthanalyzer/suicide_act(mob/living/carbon/user)
|
||||
@@ -88,37 +96,40 @@ GENETICS SCANNER
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/healthanalyzer/attack_self(mob/user)
|
||||
if(!scanmode)
|
||||
to_chat(user, "<span class='notice'>You switch the health analyzer to scan chemical contents.</span>")
|
||||
scanmode = 1
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You switch the health analyzer to check physical health.</span>")
|
||||
scanmode = 0
|
||||
scanmode = (scanmode + 1) % 3
|
||||
switch(scanmode)
|
||||
if(SCANMODE_HEALTH)
|
||||
to_chat(user, "<span class='notice'>You switch the health analyzer to check physical health.</span>")
|
||||
if(SCANMODE_CHEMICAL)
|
||||
to_chat(user, "<span class='notice'>You switch the health analyzer to scan chemical contents.</span>")
|
||||
if(SCANMODE_WOUND)
|
||||
to_chat(user, "<span class='notice'>You switch the health analyzer to report extra info on wounds.</span>")
|
||||
|
||||
/obj/item/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
|
||||
flick("[icon_state]-scan", src) //makes it so that it plays the scan animation upon scanning, including clumsy scanning
|
||||
|
||||
// Clumsiness/brain damage check
|
||||
if ((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50))
|
||||
to_chat(user, "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
|
||||
user.visible_message("<span class='warning'>[user] has analyzed the floor's vitals!</span>")
|
||||
var/msg = "<span class='info'>*---------*\nAnalyzing results for The floor:\n\tOverall status: <b>Healthy</b>\n"
|
||||
msg += "Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font>\n"
|
||||
msg += "\tDamage specifics: <font color='blue'>0</font>-<font color='green'>0</font>-<font color='#FF8000'>0</font>-<font color='red'>0</font>\n"
|
||||
msg += "Body temperature: ???\n"
|
||||
msg += "*---------*</span>"
|
||||
to_chat(user, msg)
|
||||
user.visible_message("<span class='warning'>[user] analyzes the floor's vitals!</span>", \
|
||||
"<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
|
||||
to_chat(user, "<span class='info'>Analyzing results for The floor:\n\tOverall status: <b>Healthy</b></span>\
|
||||
\n<span class='info'>Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font></span>\
|
||||
\n<span class='info'>\tDamage specifics: <font color='blue'>0</font>-<font color='green'>0</font>-<font color='#FF8000'>0</font>-<font color='red'>0</font></span>\
|
||||
\n<span class='info'>Body temperature: ???</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>")
|
||||
user.visible_message("<span class='notice'>[user] analyzes [M]'s vitals.</span>", \
|
||||
"<span class='notice'>You analyze [M]'s vitals.</span>")
|
||||
|
||||
if(scanmode == 0)
|
||||
if(scanmode == SCANMODE_HEALTH)
|
||||
healthscan(user, M, mode, advanced)
|
||||
else if(scanmode == 1)
|
||||
else if(scanmode == SCANMODE_CHEMICAL)
|
||||
chemscan(user, M)
|
||||
else
|
||||
woundscan(user, M, src)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
// Used by the PDA medical scanner too
|
||||
/proc/healthscan(mob/user, mob/living/M, mode = 1, advanced = FALSE)
|
||||
if(isliving(user) && (user.incapacitated() || user.eye_blind))
|
||||
@@ -402,6 +413,17 @@ GENETICS SCANNER
|
||||
msg += "<span class='danger'> Intervention recommended.</span>\n"
|
||||
else
|
||||
msg += "\n"
|
||||
// Wounds
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
var/list/wounded_parts = C.get_wounded_bodyparts()
|
||||
for(var/i in wounded_parts)
|
||||
var/obj/item/bodypart/wounded_part = i
|
||||
msg += "<span class='alert ml-1'><b>Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]</b>"
|
||||
for(var/k in wounded_part.wounds)
|
||||
var/datum/wound/W = k
|
||||
msg += "<div class='ml-2'>Type: [W.name]\nSeverity: [W.severity_text()]\nRecommended Treatment: [W.treat_text]</div>\n" // less lines than in woundscan() so we don't overload people trying to get basic med info
|
||||
msg += "</span>\n"
|
||||
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
@@ -414,7 +436,7 @@ GENETICS SCANNER
|
||||
var/blood_typepath = C.get_blood_id()
|
||||
if(blood_typepath)
|
||||
if(ishuman(C))
|
||||
if(H.bleed_rate)
|
||||
if(H.is_bleeding())
|
||||
msg += "<span class='danger'>Subject is bleeding!</span>\n"
|
||||
var/blood_percent = round((C.scan_blood_volume() / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
|
||||
var/blood_type = C.dna.blood_type
|
||||
@@ -505,6 +527,67 @@ GENETICS SCANNER
|
||||
desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
|
||||
advanced = TRUE
|
||||
|
||||
/// Displays wounds with extended information on their status vs medscanners
|
||||
/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/wound/scanner)
|
||||
if(!istype(patient))
|
||||
return
|
||||
|
||||
var/render_list = ""
|
||||
for(var/i in patient.get_wounded_bodyparts())
|
||||
var/obj/item/bodypart/wounded_part = i
|
||||
render_list += "<span class='alert ml-1'><b>Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]</b>"
|
||||
for(var/k in wounded_part.wounds)
|
||||
var/datum/wound/W = k
|
||||
render_list += "<div class='ml-2'>[W.get_scanner_description()]</div>\n"
|
||||
render_list += "</span>"
|
||||
|
||||
if(render_list == "")
|
||||
if(istype(scanner))
|
||||
// Only emit the cheerful scanner message if this scan came from a scanner
|
||||
playsound(scanner, 'sound/machines/ping.ogg', 50, FALSE)
|
||||
to_chat(user, "<span class='notice'>\The [scanner] makes a happy ping and briefly displays a smiley face with several exclamation points! It's really excited to report that [patient] has no wounds!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice ml-1'>No wounds detected in subject.</span>")
|
||||
else
|
||||
to_chat(user, jointext(render_list, ""))
|
||||
|
||||
/obj/item/healthanalyzer/wound
|
||||
name = "first aid analyzer"
|
||||
icon_state = "adv_spectrometer"
|
||||
desc = "A prototype MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds, but offers no further insight into the patient's health. You hope the final version is less annoying to read!"
|
||||
var/next_encouragement
|
||||
var/greedy
|
||||
|
||||
/obj/item/healthanalyzer/wound/attack_self(mob/user)
|
||||
if(next_encouragement < world.time)
|
||||
playsound(src, 'sound/machines/ping.ogg', 50, FALSE)
|
||||
var/list/encouragements = list("briefly displays a happy face, gazing emptily at you", "briefly displays a spinning cartoon heart", "displays an encouraging message about eating healthy and exercising", \
|
||||
"reminds you that everyone is doing their best", "displays a message wishing you well", "displays a sincere thank-you for your interest in first-aid", "formally absolves you of all your sins")
|
||||
to_chat(user, "<span class='notice'>\The [src] makes a happy ping and [pick(encouragements)]!</span>")
|
||||
next_encouragement = world.time + 10 SECONDS
|
||||
greedy = FALSE
|
||||
else if(!greedy)
|
||||
to_chat(user, "<span class='warning'>\The [src] displays an eerily high-definition frowny face, chastizing you for asking it for too much encouragement.</span>")
|
||||
greedy = TRUE
|
||||
else
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
to_chat(L, "<span class='warning'>\The [src] makes a disappointed buzz and pricks your finger for being greedy. Ow!</span>")
|
||||
L.adjustBruteLoss(4)
|
||||
L.dropItemToGround(src)
|
||||
|
||||
/obj/item/healthanalyzer/wound/attack(mob/living/carbon/patient, mob/living/carbon/human/user)
|
||||
add_fingerprint(user)
|
||||
user.visible_message("<span class='notice'>[user] scans [patient] for serious injuries.</span>", "<span class='notice'>You scan [patient] for serious injuries.</span>")
|
||||
|
||||
if(!istype(patient))
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
to_chat(user, "<span class='notice'>\The [src] makes a sad buzz and briefly displays a frowny face, indicating it can't scan [patient].</span>")
|
||||
return
|
||||
|
||||
woundscan(user, patient, src)
|
||||
|
||||
/obj/item/analyzer
|
||||
desc = "A hand-held environmental scanner which reports current gas levels. Alt-Click to use the built in barometer function."
|
||||
name = "analyzer"
|
||||
@@ -541,54 +624,13 @@ GENETICS SCANNER
|
||||
if (user.stat || user.eye_blind)
|
||||
return
|
||||
|
||||
var/turf/location = user.loc
|
||||
//Functionality moved down to proc/scan_turf()
|
||||
var/turf/location = get_turf(user)
|
||||
if(!istype(location))
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
|
||||
to_chat(user, "<span class='info'><B>Results:</B></span>")
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
to_chat(user, "<span class='info'>Pressure: [round(pressure, 0.01)] kPa</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
|
||||
if(total_moles)
|
||||
|
||||
var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
|
||||
var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
|
||||
var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
|
||||
var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
|
||||
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
|
||||
|
||||
if(abs(o2_concentration - O2STANDARD) < 2)
|
||||
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
|
||||
|
||||
if(co2_concentration > 0.01)
|
||||
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
|
||||
|
||||
if(plasma_concentration > 0.005)
|
||||
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
|
||||
|
||||
for(var/id in environment.get_gases())
|
||||
if(id in GLOB.hardcoded_gases)
|
||||
continue
|
||||
var/gas_concentration = environment.get_moles(id)/total_moles
|
||||
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)</span>")
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)</span>")
|
||||
|
||||
|
||||
scan_turf(user, location)
|
||||
|
||||
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
|
||||
. = ..()
|
||||
|
||||
@@ -666,7 +708,7 @@ GENETICS SCANNER
|
||||
|
||||
var/total_moles = air_contents.total_moles()
|
||||
var/pressure = air_contents.return_pressure()
|
||||
var/volume = air_contents.return_volume()
|
||||
var/volume = air_contents.return_volume() //could just do mixture.volume... but safety, I guess?
|
||||
var/temperature = air_contents.return_temperature()
|
||||
var/cached_scan_results = air_contents.analyzer_results
|
||||
|
||||
@@ -693,6 +735,73 @@ GENETICS SCANNER
|
||||
to_chat(user, "<span class='notice'>Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.</span>")
|
||||
return
|
||||
|
||||
/obj/item/analyzer/proc/scan_turf(mob/user, turf/location)
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
var/cached_scan_results = environment.analyzer_results
|
||||
|
||||
to_chat(user, "<span class='info'><B>Results:</B></span>")
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
to_chat(user, "<span class='info'>Pressure: [round(pressure, 0.01)] kPa</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
|
||||
if(total_moles)
|
||||
|
||||
var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
|
||||
var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
|
||||
var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
|
||||
var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
|
||||
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
|
||||
|
||||
if(abs(o2_concentration - O2STANDARD) < 2)
|
||||
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
|
||||
|
||||
if(co2_concentration > 0.01)
|
||||
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
|
||||
|
||||
if(plasma_concentration > 0.005)
|
||||
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
|
||||
|
||||
for(var/id in environment.get_gases())
|
||||
if(id in GLOB.hardcoded_gases)
|
||||
continue
|
||||
var/gas_concentration = environment.get_moles(id)/total_moles
|
||||
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)</span>")
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)</span>")
|
||||
|
||||
if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected
|
||||
var/fusion_power = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = fusionpower2text(fusion_power)
|
||||
to_chat(user, "<span class='boldnotice'>Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.</span>")
|
||||
to_chat(user, "<span class='notice'>Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.</span>")
|
||||
|
||||
/obj/item/analyzer/ranged
|
||||
desc = "A hand-held scanner which uses advanced spectroscopy and infrared readings to analyze gases as a distance. Alt-Click to use the built in barometer function."
|
||||
name = "long-range analyzer"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "ranged_analyzer"
|
||||
|
||||
/obj/item/analyzer/ranged/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(target.tool_act(user, src, tool_behaviour))
|
||||
return
|
||||
// Tool act didn't scan it, so let's get it's turf.
|
||||
var/turf/location = get_turf(target)
|
||||
scan_turf(user, location)
|
||||
|
||||
//slime scanner
|
||||
|
||||
/obj/item/slime_scanner
|
||||
@@ -878,3 +987,9 @@ GENETICS SCANNER
|
||||
return "[HM.name] ([HM.alias])"
|
||||
else
|
||||
return HM.alias
|
||||
|
||||
#undef SCANMODE_HEALTH
|
||||
#undef SCANMODE_CHEMICAL
|
||||
#undef SCANMODE_WOUND
|
||||
#undef SCANNER_CONDENSED
|
||||
#undef SCANNER_VERBOSE
|
||||
@@ -54,8 +54,7 @@
|
||||
mytape.ruin() //Fires destroy the tape
|
||||
..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/taperecorder/attack_hand(mob/user)
|
||||
/obj/item/taperecorder/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user)
|
||||
if(mytape)
|
||||
if(!user.is_holding(src))
|
||||
|
||||
@@ -76,6 +76,9 @@ effective or pretty fucking useless.
|
||||
var/used = 0 // is it cooling down?
|
||||
var/stealth = FALSE
|
||||
|
||||
var/ui_x = 320
|
||||
var/ui_y = 335
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/attack(mob/living/M, mob/living/user)
|
||||
if(!stealth || !irradiate)
|
||||
..()
|
||||
@@ -83,93 +86,102 @@ effective or pretty fucking useless.
|
||||
return
|
||||
if(!used)
|
||||
log_combat(user, M, "irradiated", src)
|
||||
var/cooldown = GetCooldown()
|
||||
used = 1
|
||||
var/cooldown = get_cooldown()
|
||||
used = TRUE
|
||||
icon_state = "health1"
|
||||
handle_cooldown(cooldown) // splits off to handle the cooldown while handling wavelength
|
||||
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>")
|
||||
spawn((wavelength+(intensity*4))*5)
|
||||
if(M)
|
||||
if(intensity >= 5)
|
||||
M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS)
|
||||
M.rad_act(intensity*10)
|
||||
addtimer(CALLBACK(src, .proc/radiation_aftereffect, M), (wavelength+(intensity*4))*5)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The radioactive microlaser is still recharging.</span>")
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/handle_cooldown(cooldown)
|
||||
spawn(cooldown)
|
||||
used = 0
|
||||
icon_state = "health"
|
||||
/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M)
|
||||
if(QDELETED(M))
|
||||
return
|
||||
if(intensity >= 5)
|
||||
M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS)
|
||||
M.rad_act(intensity*10)
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/get_cooldown()
|
||||
return round(max(10, (stealth*30 + intensity*5 - wavelength/4)))
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/attack_self(mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/GetCooldown()
|
||||
return round(max(10, (stealth*30 + intensity*5 - wavelength/4)))
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/interact(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user)
|
||||
. = ..()
|
||||
/obj/item/healthanalyzer/rad_laser/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
var/dat = "Irradiation: <A href='?src=[REF(src)];rad=1'>[irradiate ? "On" : "Off"]</A><br>"
|
||||
dat += "Stealth Mode (NOTE: Deactivates automatically while Irradiation is off): <A href='?src=[REF(src)];stealthy=[TRUE]'>[stealth ? "On" : "Off"]</A><br>"
|
||||
dat += "Scan Mode: <a href='?src=[REF(src)];mode=1'>"
|
||||
if(!scanmode)
|
||||
dat += "Scan Health"
|
||||
else if(scanmode == 1)
|
||||
dat += "Scan Reagents"
|
||||
else
|
||||
dat += "Disabled"
|
||||
dat += "</a><br><br>"
|
||||
/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "RadioactiveMicrolaser")
|
||||
ui.open()
|
||||
|
||||
dat += {"
|
||||
Radiation Intensity:
|
||||
<A href='?src=[REF(src)];radint=-5'>-</A><A href='?src=[REF(src)];radint=-1'>-</A>
|
||||
[intensity]
|
||||
<A href='?src=[REF(src)];radint=1'>+</A><A href='?src=[REF(src)];radint=5'>+</A><BR>
|
||||
/obj/item/healthanalyzer/rad_laser/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["irradiate"] = irradiate
|
||||
data["stealth"] = stealth
|
||||
data["scanmode"] = scanmode
|
||||
data["intensity"] = intensity
|
||||
data["wavelength"] = wavelength
|
||||
data["on_cooldown"] = used
|
||||
data["cooldown"] = DisplayTimeText(get_cooldown())
|
||||
return data
|
||||
|
||||
Radiation Wavelength:
|
||||
<A href='?src=[REF(src)];radwav=-5'>-</A><A href='?src=[REF(src)];radwav=-1'>-</A>
|
||||
[(wavelength+(intensity*4))]
|
||||
<A href='?src=[REF(src)];radwav=1'>+</A><A href='?src=[REF(src)];radwav=5'>+</A><BR>
|
||||
Laser Cooldown: [DisplayTimeText(GetCooldown())]<BR>
|
||||
"}
|
||||
/obj/item/healthanalyzer/rad_laser/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
var/datum/browser/popup = new(user, "radlaser", "Radioactive Microlaser Interface", 400, 240)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(src))
|
||||
return 1
|
||||
|
||||
usr.set_machine(src)
|
||||
if(href_list["rad"])
|
||||
irradiate = !irradiate
|
||||
|
||||
else if(href_list["stealthy"])
|
||||
stealth = !stealth
|
||||
|
||||
else if(href_list["mode"])
|
||||
scanmode += 1
|
||||
if(scanmode > 2)
|
||||
scanmode = 0
|
||||
|
||||
else if(href_list["radint"])
|
||||
var/amount = text2num(href_list["radint"])
|
||||
amount += intensity
|
||||
intensity = max(1,(min(20,amount)))
|
||||
|
||||
else if(href_list["radwav"])
|
||||
var/amount = text2num(href_list["radwav"])
|
||||
amount += wavelength
|
||||
wavelength = max(0,(min(120,amount)))
|
||||
|
||||
attack_self(usr)
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
switch(action)
|
||||
if("irradiate")
|
||||
irradiate = !irradiate
|
||||
. = TRUE
|
||||
if("stealth")
|
||||
stealth = !stealth
|
||||
. = TRUE
|
||||
if("scanmode")
|
||||
scanmode = !scanmode
|
||||
. = TRUE
|
||||
if("radintensity")
|
||||
var/target = params["target"]
|
||||
var/adjust = text2num(params["adjust"])
|
||||
if(target == "min")
|
||||
target = 1
|
||||
. = TRUE
|
||||
else if(target == "max")
|
||||
target = 20
|
||||
. = TRUE
|
||||
else if(adjust)
|
||||
target = intensity + adjust
|
||||
. = TRUE
|
||||
else if(text2num(target) != null)
|
||||
target = text2num(target)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target = round(target)
|
||||
intensity = clamp(target, 1, 20)
|
||||
if("radwavelength")
|
||||
var/target = params["target"]
|
||||
var/adjust = text2num(params["adjust"])
|
||||
if(target == "min")
|
||||
target = 0
|
||||
. = TRUE
|
||||
else if(target == "max")
|
||||
target = 120
|
||||
. = TRUE
|
||||
else if(adjust)
|
||||
target = wavelength + adjust
|
||||
. = TRUE
|
||||
else if(text2num(target) != null)
|
||||
target = text2num(target)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target = round(target)
|
||||
wavelength = clamp(target, 0, 120)
|
||||
|
||||
/obj/item/shadowcloak
|
||||
name = "cloaker belt"
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
var/mob/attacher = null
|
||||
var/valve_open = FALSE
|
||||
var/toggle = 1
|
||||
var/ui_x = 310
|
||||
var/ui_y = 320
|
||||
|
||||
/obj/item/transfer_valve/IsAssemblyHolder()
|
||||
return TRUE
|
||||
@@ -77,7 +79,7 @@
|
||||
if(attached_device)
|
||||
attached_device.Crossed(AM)
|
||||
|
||||
/obj/item/transfer_valve/attack_hand()//Triggers mousetraps
|
||||
/obj/item/transfer_valve/on_attack_hand()//Triggers mousetraps
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
@@ -186,11 +188,10 @@
|
||||
tank_one.air_contents.merge(temp)
|
||||
tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
|
||||
|
||||
/*
|
||||
/*
|
||||
Exadv1: I know this isn't how it's going to work, but this was just to check
|
||||
it explodes properly when it gets a signal (and it does).
|
||||
*/
|
||||
|
||||
*/
|
||||
/obj/item/transfer_valve/proc/toggle_valve()
|
||||
if(!valve_open && tank_one && tank_two)
|
||||
valve_open = TRUE
|
||||
@@ -231,7 +232,60 @@
|
||||
valve_open = FALSE
|
||||
update_icon()
|
||||
|
||||
// this doesn't do anything but the timer etc. expects it to be here
|
||||
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
|
||||
/*
|
||||
This doesn't do anything but the timer etc. expects it to be here
|
||||
eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
|
||||
*/
|
||||
/obj/item/transfer_valve/proc/c_state()
|
||||
return
|
||||
|
||||
/obj/item/transfer_valve/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
/obj/item/transfer_valve/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "TransferValve", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/transfer_valve/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["tank_one"] = tank_one
|
||||
data["tank_two"] = tank_two
|
||||
data["attached_device"] = attached_device
|
||||
data["valve"] = valve_open
|
||||
return data
|
||||
|
||||
/obj/item/transfer_valve/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("tankone")
|
||||
if(tank_one)
|
||||
split_gases()
|
||||
valve_open = FALSE
|
||||
tank_one.forceMove(drop_location())
|
||||
tank_one = null
|
||||
. = TRUE
|
||||
if("tanktwo")
|
||||
if(tank_two)
|
||||
split_gases()
|
||||
valve_open = FALSE
|
||||
tank_two.forceMove(drop_location())
|
||||
tank_two = null
|
||||
. = TRUE
|
||||
if("toggle")
|
||||
toggle_valve()
|
||||
. = TRUE
|
||||
if("device")
|
||||
if(attached_device)
|
||||
attached_device.attack_self(usr)
|
||||
. = TRUE
|
||||
if("remove_device")
|
||||
if(attached_device)
|
||||
attached_device.on_detach()
|
||||
attached_device = null
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/obj/item/storage/pill_bottle/dice
|
||||
/obj/item/storage/box/dice
|
||||
name = "bag of dice"
|
||||
desc = "Contains all the luck you'll ever need."
|
||||
icon = 'icons/obj/dice.dmi'
|
||||
icon_state = "dicebag"
|
||||
|
||||
/obj/item/storage/pill_bottle/dice/Initialize()
|
||||
/obj/item/storage/box/dice/Initialize()
|
||||
. = ..()
|
||||
var/special_die = pick("1","2","fudge","space","00","8bd20","4dd6","100")
|
||||
if(special_die == "1")
|
||||
@@ -30,7 +30,7 @@
|
||||
if(special_die == "100")
|
||||
new /obj/item/dice/d100(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/dice/suicide_act(mob/user)
|
||||
/obj/item/storage/box/dice/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (OXYLOSS)
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
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
|
||||
wound_bonus = -110
|
||||
bare_wound_bonus = 20
|
||||
block_parry_data = /datum/block_parry_data/dual_esword
|
||||
var/hacked = FALSE
|
||||
/// Can this reflect all energy projectiles?
|
||||
@@ -103,7 +105,7 @@
|
||||
to_chat(user, "<span class='warning'>You lack the grace to wield this!</span>")
|
||||
return COMPONENT_TWOHANDED_BLOCK_WIELD
|
||||
wielded = TRUE
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
w_class = w_class_on
|
||||
total_mass = total_mass_on
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
@@ -340,12 +342,30 @@
|
||||
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
|
||||
block_parry_data = /datum/block_parry_data/chaplain
|
||||
var/chaplain_spawnable = TRUE
|
||||
can_reflect = FALSE
|
||||
obj_flags = UNIQUE_RENAME
|
||||
|
||||
/datum/block_parry_data/chaplain
|
||||
parry_stamina_cost = 12
|
||||
parry_time_windup = 2
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 3
|
||||
// parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK
|
||||
parry_time_perfect = 1
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 7.5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 80
|
||||
parry_efficiency_perfect = 120
|
||||
parry_efficiency_perfect_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 30,
|
||||
)
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = 2 SECONDS
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/chaplain/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=20, \
|
||||
|
||||
@@ -192,11 +192,13 @@
|
||||
|
||||
return top_vote
|
||||
|
||||
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.always_state)
|
||||
/obj/item/toy/eightball/haunted/ui_state(mob/user)
|
||||
return GLOB.observer_state
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/toy/eightball/haunted/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "eightball", name, 400, 600, master_ui, state)
|
||||
ui = new(user, src, "EightBallVote", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/toy/eightball/haunted/ui_data(mob/user)
|
||||
@@ -229,4 +231,4 @@
|
||||
else
|
||||
votes[selected_answer] += 1
|
||||
voted[user.ckey] = selected_answer
|
||||
. = TRUE
|
||||
. = TRUE
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
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
|
||||
attack_speed = CLICK_CD_MELEE
|
||||
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
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
. += "The safety is [safety ? "on" : "off"]."
|
||||
|
||||
if(reagents.total_volume)
|
||||
. += "<span class='notice'>You can loose its <b>screws</b> to empty it.</span>"
|
||||
. += "<span class='notice'>Alt-click to empty it.</span>"
|
||||
|
||||
/obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user)
|
||||
if(istype(target, tanktype) && target.Adjacent(user))
|
||||
@@ -230,7 +230,7 @@
|
||||
repetition++
|
||||
addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_chair, B, movementdirection, repetition), timer_seconds)
|
||||
|
||||
/obj/item/extinguisher/screwdriver_act(mob/user, obj/item/tool)
|
||||
/obj/item/extinguisher/AltClick(mob/user)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
EmptyExtinguisher(user)
|
||||
@@ -244,7 +244,7 @@
|
||||
var/turf/open/theturf = T
|
||||
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
|
||||
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by loosing the release valve's screws.</span>")
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by using its release valve.</span>")
|
||||
|
||||
//firebot assembly
|
||||
/obj/item/extinguisher/attackby(obj/O, mob/user, params)
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
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
|
||||
wound_bonus = -15
|
||||
bare_wound_bonus = 20
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/fireaxe/Initialize()
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
/obj/item/flamethrower/analyzer_act(mob/living/user, obj/item/I)
|
||||
if(ptank)
|
||||
ptank.analyzer_act(user, I)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/flamethrower/attack_self(mob/user)
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
ADD_TRAIT(user, granted_trait, BOOK_TRAIT)
|
||||
|
||||
/obj/item/book/granter/trait/rifleman
|
||||
name = "\proper the Neo-Russian Rifleman\'s Primer"
|
||||
name = "The Neo-Russian Rifleman\'s Primer"
|
||||
desc = "A book with stains of vodka and...blood? The back is hard to read, but says something about bolt-actions. Or pump-actions. Both, maybe."
|
||||
oneuse = FALSE
|
||||
granted_trait = TRAIT_FAST_PUMP
|
||||
@@ -477,6 +477,23 @@
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
|
||||
/obj/item/book/granter/martial/krav_maga
|
||||
martial = /datum/martial_art/krav_maga
|
||||
name = "parchment scroll"
|
||||
martialname = "krav maga"
|
||||
desc = "A worn parchment scrap written in an ancient language. Somehow you can still understand the lessons!"
|
||||
greet = "<span class='sciradio'>You have learned the ancient martial art of Krav Maga. You have special attacks with which to take down your foes.</span>"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
remarks = list("Sweep the legs...", "Chop the throat...", "Punch the lungs...", "Get the gold...", "Where are my sick gloves..?")
|
||||
|
||||
/obj/item/book/granter/martial/krav_maga/onlearned(mob/living/carbon/user)
|
||||
. = ..()
|
||||
if(oneuse == TRUE)
|
||||
desc = "It's completely blank."
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
|
||||
// I did not include mushpunch's grant, it is not a book and the item does it just fine.
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +60,14 @@
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/mega
|
||||
shrapnel_radius = 12
|
||||
|
||||
/obj/item/grenade/stingbang/breaker
|
||||
name = "breakbang"
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/breaker
|
||||
|
||||
/obj/item/grenade/stingbang/shred
|
||||
name = "shredbang"
|
||||
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/shred
|
||||
|
||||
/obj/item/grenade/stingbang/prime(mob/living/lanced_by)
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
@@ -116,9 +124,11 @@
|
||||
/obj/item/grenade/primer/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(!user.CheckActionCooldown())
|
||||
return
|
||||
user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
rots++
|
||||
user.changeNext_move(CLICK_CD_RAPID)
|
||||
user.DelayNextAction(CLICK_CD_RAPID)
|
||||
|
||||
/obj/item/grenade/primer/prime(mob/living/lanced_by)
|
||||
shrapnel_radius = round(rots / rots_per_mag)
|
||||
|
||||
@@ -320,7 +320,7 @@
|
||||
do_sparks(1, TRUE, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user)
|
||||
/obj/item/restraints/legcuffs/beartrap/energy/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
Crossed(user) //honk
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@
|
||||
throwforce = 10
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
obj_flags = UNIQUE_RENAME
|
||||
wound_bonus = -10
|
||||
var/chaplain_spawnable = TRUE
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
|
||||
@@ -351,7 +352,7 @@
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
|
||||
block_chance = 30
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
|
||||
@@ -451,7 +452,7 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
armour_penetration = 35
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("chopped", "sliced", "cut", "reaped")
|
||||
|
||||
/obj/item/nullrod/scythe/Initialize()
|
||||
@@ -574,7 +575,7 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
item_flags = ABSTRACT
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = 'sound/weapons/chainsawhit.ogg'
|
||||
total_mass = TOTAL_MASS_HAND_REPLACEMENT
|
||||
@@ -593,7 +594,7 @@
|
||||
name = "clown dagger"
|
||||
desc = "Used for absolutely hilarious sacrifices."
|
||||
hitsound = 'sound/items/bikehorn.ogg'
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
|
||||
/obj/item/nullrod/pride_hammer
|
||||
@@ -644,7 +645,7 @@
|
||||
throw_speed = 4
|
||||
throw_range = 7
|
||||
throwforce = 30
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("enlightened", "redpilled")
|
||||
|
||||
/obj/item/nullrod/armblade
|
||||
@@ -656,7 +657,9 @@
|
||||
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
|
||||
item_flags = ABSTRACT
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
wound_bonus = -20
|
||||
bare_wound_bonus = 25
|
||||
total_mass = TOTAL_MASS_HAND_REPLACEMENT
|
||||
|
||||
/obj/item/nullrod/armblade/Initialize()
|
||||
@@ -696,7 +699,7 @@
|
||||
force = 15
|
||||
block_chance = 40
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
sharpness = IS_BLUNT
|
||||
sharpness = SHARP_NONE
|
||||
hitsound = "swing_hit"
|
||||
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
@@ -751,7 +754,7 @@
|
||||
name = "arrhythmic knife"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
desc = "They say fear is the true mind killer, but stabbing them in the head works too. Honour compels you to not sheathe it once drawn."
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
slot_flags = null
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
@@ -779,7 +782,7 @@
|
||||
desc = "Holding this makes you look absolutely devilish."
|
||||
attack_verb = list("poked", "impaled", "pierced", "jabbed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/obj/item/nullrod/egyptian
|
||||
name = "egyptian staff"
|
||||
|
||||
@@ -38,6 +38,23 @@
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/implant/warp
|
||||
name = "warp implant"
|
||||
desc = "Saves your position somewhere, and then warps you back to it after five seconds."
|
||||
icon_state = "warp"
|
||||
uses = 15
|
||||
|
||||
/obj/item/implant/warp/activate()
|
||||
. = ..()
|
||||
uses--
|
||||
imp_in.do_adrenaline(20, TRUE, 0, 0, TRUE, list(/datum/reagent/fermi/eigenstate = 1.2), "<span class='boldnotice'>You feel an internal prick as as the bluespace starts ramping up!</span>")
|
||||
to_chat(imp_in, "<span class='notice'>You feel an internal prick as as the bluespace starts ramping up!</span>")
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/implanter/warp
|
||||
name = "implanter (warp)"
|
||||
imp_type = /obj/item/implant/warp
|
||||
|
||||
/obj/item/implant/emp
|
||||
name = "emp implant"
|
||||
@@ -69,4 +86,4 @@
|
||||
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)
|
||||
healthstring = "ERROR"
|
||||
return healthstring
|
||||
return healthstring
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/obj/item/implant/radio/activate()
|
||||
. = ..()
|
||||
// needs to be GLOB.deep_inventory_state otherwise it won't open
|
||||
radio.ui_interact(usr, "main", null, FALSE, null, GLOB.deep_inventory_state)
|
||||
radio.ui_interact(usr, state = GLOB.deep_inventory_state)
|
||||
|
||||
/obj/item/implant/radio/implant(mob/living/target, mob/user, silent = FALSE)
|
||||
. = ..()
|
||||
|
||||
@@ -26,14 +26,15 @@
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/ui_state(mob/user)
|
||||
return GLOB.notcontained_state
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui = new(user, src, "ImplantChair", name)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
@@ -121,8 +122,6 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
@@ -191,4 +190,4 @@
|
||||
brainwash(C, objective)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.")
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
name = "fork"
|
||||
desc = "Pointy."
|
||||
icon_state = "fork"
|
||||
force = 5
|
||||
force = 4
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
@@ -28,6 +28,7 @@
|
||||
attack_verb = list("attacked", "stabbed", "poked")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
|
||||
sharpness = SHARP_POINTY
|
||||
var/datum/reagent/forkload //used to eat omelette
|
||||
|
||||
/obj/item/kitchen/fork/suicide_act(mob/living/carbon/user)
|
||||
@@ -54,6 +55,14 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/kitchen/fork/throwing
|
||||
name = "throwing fork"
|
||||
desc = "A fork, sharpened to perfection, making it a great weapon for throwing."
|
||||
throwforce = 15
|
||||
throw_speed = 4
|
||||
throw_range = 6
|
||||
embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/obj/item/kitchen/knife
|
||||
name = "kitchen knife"
|
||||
@@ -68,9 +77,11 @@
|
||||
throw_range = 6
|
||||
custom_materials = list(/datum/material/iron=12000)
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
sharpness = SHARP_POINTY
|
||||
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?
|
||||
wound_bonus = -5
|
||||
bare_wound_bonus = 10
|
||||
custom_price = PRICE_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/Initialize()
|
||||
|
||||
@@ -54,5 +54,5 @@
|
||||
var/obj/item/tank/T = W
|
||||
blow(T, user)
|
||||
return
|
||||
if (W.get_sharpness() || W.get_temperature() || is_pointed(W))
|
||||
if (W.get_sharpness() || W.get_temperature())
|
||||
burst()
|
||||
|
||||
@@ -506,7 +506,9 @@
|
||||
if(prob(50))
|
||||
step(W, pick(GLOB.alldirs))
|
||||
ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC)
|
||||
H.bleed_rate = 5
|
||||
for(var/i in H.bodyparts)
|
||||
var/obj/item/bodypart/BP = i
|
||||
BP.generic_bleedstacks += 5
|
||||
H.gib_animation()
|
||||
sleep(3)
|
||||
H.adjustBruteLoss(1000) //to make the body super-bloody
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
attack_verb_off = list("tapped", "poked")
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
|
||||
armour_penetration = 35
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
@@ -147,6 +147,12 @@
|
||||
return NONE
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
. = ..()
|
||||
if(parry_efficiency >= 80) // perfect parry
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER
|
||||
. |= BLOCK_SHOULD_REDIRECT
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cyborg
|
||||
sword_color = "red"
|
||||
light_color = "#ff0000"
|
||||
@@ -174,7 +180,7 @@
|
||||
sword_color = null //stops icon from breaking when turned on.
|
||||
hitcost = 75 //Costs more than a standard cyborg esword
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
light_color = "#40ceff"
|
||||
tool_behaviour = TOOL_SAW
|
||||
toolspeed = 0.7
|
||||
@@ -249,7 +255,7 @@
|
||||
throw_range = 1
|
||||
w_class = WEIGHT_CLASS_BULKY//So you can't hide it in your pocket or some such.
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
|
||||
/obj/item/melee/transforming/energy/blade/Initialize()
|
||||
@@ -285,7 +291,7 @@
|
||||
attack_verb_off = list("tapped", "poked")
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
|
||||
armour_penetration = 10
|
||||
block_chance = 35
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 14
|
||||
throwforce = 10
|
||||
wound_bonus = 15
|
||||
bare_wound_bonus = 10
|
||||
reach = 2
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
|
||||
@@ -42,7 +44,7 @@
|
||||
throwforce = 10
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "impaled", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
total_mass = TOTAL_MASS_HAND_REPLACEMENT
|
||||
|
||||
/obj/item/melee/synthetic_arm_blade/Initialize()
|
||||
@@ -62,7 +64,7 @@
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
armour_penetration = 75
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("slashed", "cut")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
custom_materials = list(/datum/material/iron = 1000)
|
||||
@@ -166,7 +168,7 @@
|
||||
flags_1 = CONDUCT_1
|
||||
obj_flags = UNIQUE_RENAME
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
|
||||
sharpness = SHARP_POINTY //It cant be sharpend cook -_-
|
||||
attack_verb = list("stabs", "punctures", "pierces", "pokes")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
total_mass = 0.4
|
||||
@@ -268,6 +270,8 @@
|
||||
var/force_off // Damage when off - not stunning
|
||||
var/weight_class_on // What is the new size class when turned on
|
||||
|
||||
wound_bonus = 15
|
||||
|
||||
/obj/item/melee/classic_baton/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -371,6 +375,7 @@
|
||||
var/wait_desc = get_wait_description()
|
||||
if(wait_desc)
|
||||
to_chat(user, wait_desc)
|
||||
return DISCARD_LAST_ACTION
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic
|
||||
name = "telescopic baton"
|
||||
@@ -393,6 +398,7 @@
|
||||
force_off = 0
|
||||
weight_class_on = WEIGHT_CLASS_BULKY
|
||||
total_mass = TOTAL_MASS_NORMAL_ITEM
|
||||
bare_wound_bonus = 5
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/suicide_act(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
@@ -621,7 +627,7 @@
|
||||
to_chat(user, "<span class='warning'>[target] doesn't seem to want to get on [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/melee/roastingstick/attack_hand(mob/user)
|
||||
/obj/item/melee/roastingstick/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
..()
|
||||
if (held_sausage)
|
||||
user.put_in_hands(held_sausage)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/melee/transforming
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
var/active = FALSE
|
||||
var/force_on = 30 //force when active
|
||||
var/faction_bonus_force = 0 //Bonus force dealt against certain factions
|
||||
@@ -84,4 +84,4 @@
|
||||
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
|
||||
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
|
||||
user.take_bodypart_damage(5,5)
|
||||
user.take_bodypart_damage(5,5)
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gangtool-blue"
|
||||
item_state = "radio"
|
||||
var/list/stored_options
|
||||
var/force_refresh = FALSE //if set to true, the beacon will recalculate its display options whenever opened
|
||||
|
||||
/obj/item/choice_beacon/attack_self(mob/user)
|
||||
if(canUseBeacon(user))
|
||||
@@ -34,14 +36,15 @@
|
||||
return FALSE
|
||||
|
||||
/obj/item/choice_beacon/proc/generate_options(mob/living/M)
|
||||
var/list/display_names = generate_display_names()
|
||||
if(!display_names.len)
|
||||
if(!stored_options || force_refresh)
|
||||
stored_options = generate_display_names()
|
||||
if(!stored_options.len)
|
||||
return
|
||||
var/choice = input(M,"Which item would you like to order?","Select an Item") as null|anything in display_names
|
||||
var/choice = input(M,"Which item would you like to order?","Select an Item") as null|anything in stored_options
|
||||
if(!choice || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
|
||||
spawn_option(display_names[choice],M)
|
||||
spawn_option(stored_options[choice],M)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/proc/spawn_option(obj/choice,mob/living/M)
|
||||
@@ -153,6 +156,51 @@
|
||||
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/choice_beacon/box
|
||||
name = "choice box (default)"
|
||||
desc = "Think really hard about what you want, and then rip it open!"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "deliverypackage3"
|
||||
item_state = "deliverypackage3"
|
||||
|
||||
/obj/item/choice_beacon/box/spawn_option(obj/choice,mob/living/M)
|
||||
to_chat(M, "<span class='hear'>The box opens, revealing the [choice]!</span>")
|
||||
playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1)
|
||||
M.temporarilyRemoveItemFromInventory(src, TRUE)
|
||||
M.put_in_hands(new choice)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/box/plushie
|
||||
name = "choice box (plushie)"
|
||||
desc = "Using the power of quantum entanglement, this box contains every plush, until the moment it is opened!"
|
||||
icon = 'icons/obj/plushes.dmi'
|
||||
icon_state = "box"
|
||||
item_state = "box"
|
||||
|
||||
/obj/item/choice_beacon/box/spawn_option(choice,mob/living/M)
|
||||
if(ispath(choice, /obj/item/toy/plush))
|
||||
..() //regular plush, spawn it naturally
|
||||
else
|
||||
//snowflake plush
|
||||
var/obj/item/toy/plush/snowflake_plushie = new(get_turf(M))
|
||||
snowflake_plushie.set_snowflake_from_config(choice)
|
||||
M.temporarilyRemoveItemFromInventory(src, TRUE)
|
||||
M.put_in_hands(new choice)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/choice_beacon/box/plushie/generate_display_names()
|
||||
var/list/plushie_list = list()
|
||||
//plushie set 1: just subtypes of /obj/item/toy/plush
|
||||
var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox)
|
||||
for(var/V in plushies_set_one)
|
||||
var/atom/A = V
|
||||
plushie_list[initial(A.name)] = A
|
||||
//plushie set 2: snowflake plushies
|
||||
var/list/plushies_set_two = CONFIG_GET(keyed_list/snowflake_plushies)
|
||||
for(var/V in plushies_set_two)
|
||||
plushie_list[V] = V //easiest way to do this which works with how selecting options works, despite being snowflakey to have the key equal the value
|
||||
return plushie_list
|
||||
|
||||
/obj/item/skub
|
||||
desc = "It's skub."
|
||||
name = "skub"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
if(T)
|
||||
user.visible_message("[user] cleans \the [T] with [src].", "<span class='notice'>You clean \the [T] with [src].</span>")
|
||||
clean(T)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(T, used_item = src)
|
||||
if(istype(L))
|
||||
L.adjustStaminaLossBuffered(stamusage)
|
||||
@@ -128,4 +128,4 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/mop/advanced/cyborg
|
||||
insertable = FALSE
|
||||
insertable = FALSE
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
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/alternate_escape_time = 0 //how long it takes for mobs to escape when the entrance is open
|
||||
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?
|
||||
@@ -106,8 +107,9 @@
|
||||
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
|
||||
if((ishostile(target) && (!allows_hostiles || !istype(target, /mob/living/simple_animal/hostile/carp/cayenne))) || target.move_resist >= MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers, but let cayenne in!
|
||||
to_chat(user, "<span class='warning'>You have a feeling you shouldn't keep this as a pet.</span>")
|
||||
return
|
||||
load_occupant(user, target)
|
||||
|
||||
/obj/item/pet_carrier/relaymove(mob/living/user, direction)
|
||||
@@ -128,13 +130,18 @@
|
||||
/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
|
||||
if(alternate_escape_time > 0)
|
||||
loc.visible_message("<span class='notice'>The [src] begins to shake!</span>")
|
||||
if(do_after(user, alternate_escape_time, target = user))
|
||||
loc.visible_message("<span class='notice'>[user] jumps out of [src]</span>")
|
||||
remove_occupant(user)
|
||||
return
|
||||
else //instant escape, different message
|
||||
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 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>")
|
||||
@@ -147,7 +154,7 @@
|
||||
update_icon()
|
||||
else
|
||||
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>")
|
||||
to_chat(user, "<span class='notice'>You start pushing out of [src]... (This will take about [escape_time/10] seconds.)</span>")
|
||||
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)
|
||||
@@ -180,21 +187,22 @@
|
||||
/obj/item/pet_carrier/proc/load_occupant(mob/living/user, mob/living/target)
|
||||
if(pet_carrier_full(src))
|
||||
to_chat(user, "<span class='warning'>[src] is already carrying too much!</span>")
|
||||
return
|
||||
return FALSE
|
||||
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, load_time))
|
||||
return
|
||||
return FALSE
|
||||
if(target in occupants)
|
||||
return
|
||||
return FALSE
|
||||
if(pet_carrier_full(src)) //Run the checks again, just in case
|
||||
to_chat(user, "<span class='warning'>[src] is already carrying too much!</span>")
|
||||
return
|
||||
return FALSE
|
||||
user.visible_message("<span class='notice'>[user] loads [target] into [src]!</span>", \
|
||||
"<span class='notice'>You load [target] into [src].</span>", null, null, target)
|
||||
to_chat(target, "<span class='userdanger'>[user] loads you into [user.p_their()] [name]!</span>")
|
||||
add_occupant(target)
|
||||
return TRUE
|
||||
|
||||
/obj/item/pet_carrier/proc/add_occupant(mob/living/occupant)
|
||||
if(occupant in occupants || !istype(occupant))
|
||||
@@ -230,7 +238,8 @@
|
||||
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
|
||||
escape_time = 200 //equal to the time of a bluespace bodybag
|
||||
alternate_escape_time = 100
|
||||
var/datum/gas_mixture/occupant_gas_supply
|
||||
|
||||
/obj/item/pet_carrier/bluespace/update_icon_state()
|
||||
@@ -253,7 +262,8 @@
|
||||
occupant_gas_supply = new
|
||||
if(isanimal(occupant))
|
||||
var/mob/living/simple_animal/animal = occupant
|
||||
occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature when their turf isnt a location
|
||||
occupant_gas_supply[/datum/gas/oxygen] = 0.0064 //make sure it has some gas in so it isn't depressurized
|
||||
occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature/pressure 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")
|
||||
@@ -270,10 +280,15 @@
|
||||
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")
|
||||
name = initial(name)
|
||||
|
||||
/obj/item/pet_carrier/bluespace/return_air()
|
||||
if(!occupant_gas_supply)
|
||||
occupant_gas_supply = new
|
||||
return occupant_gas_supply
|
||||
|
||||
/obj/item/pet_carrier/bluespace/load_occupant(mob/living/user, mob/living/target)
|
||||
if(..())
|
||||
name = "[initial(name)] ([target])"
|
||||
|
||||
#undef pet_carrier_full
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
attack_verb = list("attacked", "impaled", "pierced")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
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
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
var/list/squeak_override //Weighted list; If you want your plush to have different squeak sounds use this
|
||||
var/stuffed = TRUE //If the plushie has stuffing in it
|
||||
var/unstuffable = FALSE //for plushies that can't be stuffed
|
||||
var/obj/item/grenade/grenade //You can remove the stuffing from a plushie and add a grenade to it for *nefarious uses*
|
||||
//--love ~<3--
|
||||
gender = NEUTER
|
||||
@@ -174,6 +175,9 @@
|
||||
/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params)
|
||||
if(I.get_sharpness())
|
||||
if(!grenade)
|
||||
if(unstuffable)
|
||||
to_chat(user, "<span class='notice'>Nothing to do here.</span>")
|
||||
return
|
||||
if(!stuffed)
|
||||
to_chat(user, "<span class='warning'>You already murdered it!</span>")
|
||||
return
|
||||
@@ -187,6 +191,13 @@
|
||||
grenade = null
|
||||
return
|
||||
if(istype(I, /obj/item/grenade))
|
||||
if(unstuffable)
|
||||
to_chat(user, "<span class='warning'>No... you should destroy it now!</span>")
|
||||
sleep(10)
|
||||
if(QDELETED(user) || QDELETED(src))
|
||||
return
|
||||
SEND_SOUND(user, 'sound/weapons/armbomb.ogg')
|
||||
return
|
||||
if(stuffed)
|
||||
to_chat(user, "<span class='warning'>You need to remove some stuffing first!</span>")
|
||||
return
|
||||
@@ -755,3 +766,14 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
attack_verb = list("headbutt", "scritched", "bit")
|
||||
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
|
||||
/obj/item/toy/plush/hairball
|
||||
name = "Hairball"
|
||||
desc = "A bundle of undigested fibers and scales. Yuck."
|
||||
icon_state = "Hairball"
|
||||
unstuffable = TRUE
|
||||
young = TRUE // Your own mouth-baby.
|
||||
squeak_override = list('sound/misc/splort.ogg'=1)
|
||||
attack_verb = list("sploshed", "splorted", "slushed")
|
||||
can_random_spawn = FALSE
|
||||
|
||||
@@ -14,12 +14,11 @@
|
||||
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
|
||||
click_delay = CLICK_CD_MELEE * 1.5
|
||||
attack_speed = 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.
|
||||
|
||||
|
||||
/obj/item/melee/powerfist/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src))
|
||||
@@ -98,7 +97,7 @@
|
||||
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.apply_damage(totalitemdamage * fisto_setting, BRUTE, wound_bonus = -25*fisto_setting**2)
|
||||
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)
|
||||
|
||||
@@ -746,8 +746,8 @@
|
||||
***********************************************************************/
|
||||
|
||||
/obj/item/weapon/gripper
|
||||
name = "circuit gripper"
|
||||
desc = "A simple grasping tool for inserting circuitboards into machinary."
|
||||
name = "engineering gripper"
|
||||
desc = "A simple grasping tool for interacting with various engineering related items, such as circuits, gas tanks, conveyer belts and more. Alt click to drop instead of use."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gripper"
|
||||
|
||||
@@ -755,18 +755,36 @@
|
||||
|
||||
//Has a list of items that it can hold.
|
||||
var/list/can_hold = list(
|
||||
/obj/item/circuitboard
|
||||
/obj/item/circuitboard,
|
||||
/obj/item/light,
|
||||
/obj/item/electronics,
|
||||
/obj/item/tank,
|
||||
/obj/item/conveyor_switch_construct,
|
||||
/obj/item/stack/conveyor,
|
||||
/obj/item/wallframe,
|
||||
/obj/item/vending_refill,
|
||||
/obj/item/stack/sheet,
|
||||
/obj/item/stack/tile,
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stock_parts
|
||||
)
|
||||
//Basically a blacklist for any subtypes above we dont want
|
||||
var/list/cannot_hold = list(
|
||||
/obj/item/stack/sheet/mineral/plasma,
|
||||
/obj/item/stack/sheet/plasteel
|
||||
)
|
||||
|
||||
var/obj/item/wrapped = null // Item currently being held.
|
||||
|
||||
/obj/item/weapon/gripper/attack_self()
|
||||
//Used to interact with UI's of held items, such as gas tanks and airlock electronics.
|
||||
/obj/item/weapon/gripper/AltClick(mob/user)
|
||||
if(wrapped)
|
||||
wrapped.forceMove(get_turf(wrapped))
|
||||
to_chat(user, "<span class='notice'>You drop the [wrapped].</span>")
|
||||
wrapped = null
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params)
|
||||
/obj/item/weapon/gripper/pre_attack(var/atom/target, var/mob/living/silicon/robot/user, proximity, params)
|
||||
|
||||
if(!proximity)
|
||||
return
|
||||
@@ -792,18 +810,21 @@
|
||||
return
|
||||
|
||||
else if(istype(target,/obj/item))
|
||||
|
||||
var/obj/item/I = target
|
||||
|
||||
var/grab = 0
|
||||
|
||||
for(var/typepath in can_hold)
|
||||
if(istype(I,typepath))
|
||||
grab = 1
|
||||
break
|
||||
for(var/badpath in cannot_hold)
|
||||
if(istype(I,badpath))
|
||||
if(!user.emagged)
|
||||
grab = 0
|
||||
continue
|
||||
|
||||
//We can grab the item, finally.
|
||||
if(grab)
|
||||
to_chat(user, "You collect \the [I].")
|
||||
to_chat(user, "<span class='notice'>You collect \the [I].</span>")
|
||||
I.loc = src
|
||||
wrapped = I
|
||||
return
|
||||
@@ -812,18 +833,24 @@
|
||||
|
||||
/obj/item/weapon/gripper/mining
|
||||
name = "shelter capsule deployer"
|
||||
desc = "A simple grasping tool for carrying and deploying shelter capsules."
|
||||
desc = "A simple grasping tool for carrying and deploying shelter capsules. Alt click to drop instead of use."
|
||||
icon_state = "gripper_mining"
|
||||
can_hold = list(
|
||||
/obj/item/survivalcapsule
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/mining/attack_self()
|
||||
if(wrapped)
|
||||
wrapped.forceMove(get_turf(wrapped))
|
||||
wrapped.attack_self()
|
||||
wrapped = null
|
||||
return
|
||||
/obj/item/weapon/gripper/medical
|
||||
name = "medical gripper"
|
||||
desc = "A simple grasping tool for interacting with medical equipment, such as beakers, blood bags, chem bags and more. Alt click to drop instead of use."
|
||||
icon_state = "gripper_medical"
|
||||
can_hold = list(
|
||||
/obj/item/storage/bag/bio,
|
||||
/obj/item/storage/bag/chemistry,
|
||||
/obj/item/storage/pill_bottle,
|
||||
/obj/item/reagent_containers/glass,
|
||||
/obj/item/reagent_containers/pill,
|
||||
/obj/item/reagent_containers/blood
|
||||
)
|
||||
|
||||
/obj/item/gun/energy/plasmacutter/cyborg
|
||||
name = "cyborg plasma cutter"
|
||||
@@ -907,6 +934,9 @@
|
||||
icon_state = "data_1"
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Dogborg stuff
|
||||
***********************************************************************/
|
||||
///Mere cosmetic dogborg items, remnants of what were once the most annoying cyborg modules.
|
||||
/obj/item/dogborg_tongue
|
||||
name = "synthetic tongue"
|
||||
|
||||
@@ -6,21 +6,24 @@
|
||||
desc = "Protected by FRM."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "cyborg_upgrade"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/locked = FALSE
|
||||
var/installed = 0
|
||||
var/require_module = 0
|
||||
var/list/module_type
|
||||
/// Bitflags listing module compatibility. Used in the exosuit fabricator for creating sub-categories.
|
||||
var/module_flags = NONE
|
||||
// if true, is not stored in the robot to be ejected
|
||||
// if module is reset
|
||||
var/one_use = FALSE
|
||||
|
||||
/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R, user = usr)
|
||||
if(R.stat == DEAD)
|
||||
to_chat(user, "<span class='notice'>[src] will not function on a deceased cyborg.</span>")
|
||||
to_chat(user, "<span class='warning'>[src] will not function on a deceased cyborg.</span>")
|
||||
return FALSE
|
||||
if(module_type && !is_type_in_list(R.module, module_type))
|
||||
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
|
||||
to_chat(user, "There's no mounting point for the module!")
|
||||
to_chat(R, "<span class='alert'>Upgrade mounting error! No suitable hardpoint detected.</span>")
|
||||
to_chat(user, "<span class='warning'>There's no mounting point for the module!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -37,7 +40,7 @@
|
||||
one_use = TRUE
|
||||
|
||||
/obj/item/borg/upgrade/rename/attack_self(mob/user)
|
||||
heldname = stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN)
|
||||
heldname = sanitize_name(stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN))
|
||||
|
||||
/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R)
|
||||
. = ..()
|
||||
@@ -95,6 +98,7 @@
|
||||
desc = "Used to cool a mounted energy-based firearm, increasing the potential current in it and thus its recharge rate."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
module_flags = BORG_MODULE_SECURITY
|
||||
|
||||
/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -147,6 +151,7 @@
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/miner)
|
||||
module_flags = BORG_MODULE_MINER
|
||||
|
||||
/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -207,6 +212,7 @@
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/butler)
|
||||
module_flags = BORG_MODULE_JANITOR
|
||||
|
||||
/obj/item/borg/upgrade/tboh/action(mob/living/silicon/robot/R)
|
||||
. = ..()
|
||||
@@ -234,6 +240,7 @@
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/butler)
|
||||
module_flags = BORG_MODULE_JANITOR
|
||||
|
||||
/obj/item/borg/upgrade/amop/action(mob/living/silicon/robot/R)
|
||||
. = ..()
|
||||
@@ -241,9 +248,9 @@
|
||||
for(var/obj/item/mop/cyborg/M in R.module.modules)
|
||||
R.module.remove_module(M, TRUE)
|
||||
|
||||
var/obj/item/mop/advanced/cyborg/A = new /obj/item/mop/advanced/cyborg(R.module)
|
||||
R.module.basic_modules += A
|
||||
R.module.add_module(A, FALSE, TRUE)
|
||||
var/obj/item/mop/advanced/cyborg/A = new /obj/item/mop/advanced/cyborg(R.module)
|
||||
R.module.basic_modules += A
|
||||
R.module.add_module(A, FALSE, TRUE)
|
||||
|
||||
/obj/item/borg/upgrade/amop/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -283,6 +290,7 @@
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/miner)
|
||||
module_flags = BORG_MODULE_MINER
|
||||
|
||||
/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -402,6 +410,7 @@
|
||||
module_type = list(/obj/item/robot_module/medical,
|
||||
/obj/item/robot_module/syndicate_medical)
|
||||
var/list/additional_reagents = list()
|
||||
module_flags = BORG_MODULE_MEDICAL
|
||||
|
||||
/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -471,6 +480,7 @@
|
||||
require_module = 1
|
||||
module_type = list(/obj/item/robot_module/medical,
|
||||
/obj/item/robot_module/syndicate_medical)
|
||||
module_flags = BORG_MODULE_MEDICAL
|
||||
|
||||
/obj/item/borg/upgrade/processor/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -566,7 +576,7 @@
|
||||
|
||||
/obj/item/borg/upgrade/expand/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
if (. && R.hasExpanded)
|
||||
R.resize = 0.5
|
||||
R.hasExpanded = FALSE
|
||||
R.update_transform()
|
||||
@@ -578,6 +588,7 @@
|
||||
icon_state = "borg_BS_RPED"
|
||||
require_module = TRUE
|
||||
module_type = list(/obj/item/robot_module/engineering, /obj/item/robot_module/saboteur)
|
||||
module_flags = BORG_MODULE_ENGINEERING
|
||||
|
||||
/obj/item/borg/upgrade/rped/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
@@ -612,8 +623,8 @@
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer_crew"
|
||||
require_module = TRUE
|
||||
module_type = list(/obj/item/robot_module/medical,
|
||||
/obj/item/robot_module/syndicate_medical)
|
||||
module_type = list(/obj/item/robot_module/medical, /obj/item/robot_module/syndicate_medical)
|
||||
module_flags = BORG_MODULE_MEDICAL
|
||||
|
||||
/obj/item/borg/upgrade/pinpointer/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
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.sharpness = SHARP_POINTY
|
||||
I.throwforce = clamp(I.throwforce + increment, 0, max)
|
||||
I.name = "[prefix] [I.name]"
|
||||
name = "worn out [name]"
|
||||
|
||||
@@ -106,8 +106,8 @@
|
||||
var/disarming = (target_downed && (shield_flags & SHIELD_BASH_GROUND_SLAM_DISARM)) || (shield_flags & SHIELD_BASH_ALWAYS_DISARM) || (wallhit && (shield_flags & SHIELD_BASH_WALL_DISARM))
|
||||
var/knockdown = !target_downed && ((shield_flags & SHIELD_BASH_ALWAYS_KNOCKDOWN) || (wallhit && (shield_flags & SHIELD_BASH_WALL_KNOCKDOWN)))
|
||||
if(shieldbash_stagger_duration || knockdown)
|
||||
target.visible_message("<span class='warning'>[target] is knocked [knockdown? "to the floor" : "off balanace"]!</span>",
|
||||
"<span class='userdanger'>You are knocked [knockdown? "to the floor" : "off balanace"]!</span>")
|
||||
target.visible_message("<span class='warning'>[target] is knocked [knockdown? "to the floor" : "off balance"]!</span>",
|
||||
"<span class='userdanger'>You are knocked [knockdown? "to the floor" : "off balance"]!</span>")
|
||||
if(knockdown)
|
||||
target.KnockToFloor(disarming)
|
||||
else if(disarming)
|
||||
@@ -446,6 +446,12 @@ obj/item/shield/riot/bullet_proof
|
||||
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/energy/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
|
||||
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
|
||||
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
|
||||
|
||||
@@ -31,10 +31,7 @@
|
||||
to_chat(user, "<span class='notice'>You slice off [src]'s uneven chunks of aluminium and scorch marks.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/target/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/target/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(pinnedLoc)
|
||||
pinnedLoc.removeTarget(user)
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
icon_state = "large"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
item_flags = DROPDEL
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/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"
|
||||
sharpness = SHARP_NONE
|
||||
|
||||
/obj/item/shrapnel/bullet // bullets
|
||||
name = "bullet"
|
||||
@@ -28,21 +30,24 @@
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel
|
||||
name = "flying shrapnel shard"
|
||||
damage = 9
|
||||
range = 10
|
||||
damage = 14
|
||||
range = 20
|
||||
armour_penetration = -30
|
||||
dismemberment = 5
|
||||
ricochets_max = 2
|
||||
ricochet_chance = 40
|
||||
ricochet_chance = 70
|
||||
shrapnel_type = /obj/item/shrapnel
|
||||
ricochet_incidence_leeway = 60
|
||||
sharpness = SHARP_EDGED
|
||||
wound_bonus = 40
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel/mega
|
||||
name = "flying shrapnel hunk"
|
||||
range = 25
|
||||
dismemberment = 10
|
||||
ricochets_max = 4
|
||||
ricochet_chance = 90
|
||||
range = 45
|
||||
dismemberment = 15
|
||||
ricochets_max = 6
|
||||
ricochet_chance = 130
|
||||
ricochet_incidence_leeway = 0
|
||||
ricochet_decay_chance = 0.9
|
||||
|
||||
/obj/item/projectile/bullet/pellet/stingball
|
||||
@@ -62,3 +67,15 @@
|
||||
name = "megastingball pellet"
|
||||
ricochets_max = 6
|
||||
ricochet_chance = 110
|
||||
|
||||
/obj/item/projectile/bullet/pellet/stingball/breaker
|
||||
name = "breakbang pellet"
|
||||
damage = 10
|
||||
wound_bonus = 40
|
||||
sharpness = SHARP_NONE
|
||||
|
||||
/obj/item/projectile/bullet/pellet/stingball/shred
|
||||
name = "shredbang pellet"
|
||||
damage = 10
|
||||
wound_bonus = 30
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
@@ -40,4 +40,3 @@
|
||||
user.visible_message("<span class='warning'>[user] waves around \the \"[label]\" sign.</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] waves around blank sign.</span>")
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
@@ -15,13 +15,15 @@
|
||||
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
|
||||
sharpness = SHARP_EDGED
|
||||
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
|
||||
wound_bonus = -15
|
||||
bare_wound_bonus = 15
|
||||
|
||||
/obj/item/spear/Initialize()
|
||||
. = ..()
|
||||
@@ -177,7 +179,7 @@
|
||||
custom_materials = null
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
icon_prefix = "bone_spear"
|
||||
|
||||
/obj/item/spear/bonespear/ComponentInitialize()
|
||||
|
||||
@@ -74,8 +74,7 @@
|
||||
/obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening
|
||||
to_chat(user, "<span class='warning'>You cannot crush the polycrystal in-hand, try breaking one off.</span>")
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/stack/sheet/bluespace_crystal/attack_hand(mob/user)
|
||||
/obj/item/stack/sheet/bluespace_crystal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(user.get_inactive_held_item() == src)
|
||||
if(zero_amount())
|
||||
return
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
full_w_class = WEIGHT_CLASS_TINY
|
||||
resistance_flags = FLAMMABLE
|
||||
grind_results = list(/datum/reagent/cellulose = 10)
|
||||
var/value = 0
|
||||
|
||||
/obj/item/stack/spacecash/Initialize()
|
||||
|
||||
@@ -15,11 +15,20 @@
|
||||
var/self_delay = 50
|
||||
var/other_delay = 0
|
||||
var/repeating = FALSE
|
||||
/// How much brute we heal per application
|
||||
var/heal_brute
|
||||
/// How much burn we heal per application
|
||||
var/heal_burn
|
||||
/// How much we reduce bleeding per application on cut wounds
|
||||
var/stop_bleeding
|
||||
/// How much sanitization to apply to burns on application
|
||||
var/sanitization
|
||||
/// How much we add to flesh_healing for burn wounds on application
|
||||
var/flesh_regeneration
|
||||
|
||||
/obj/item/stack/medical/attack(mob/living/M, mob/user)
|
||||
. = ..()
|
||||
try_heal(M, user)
|
||||
|
||||
INVOKE_ASYNC(src, .proc/try_heal, M, user)
|
||||
|
||||
/obj/item/stack/medical/proc/try_heal(mob/living/M, mob/user, silent = FALSE)
|
||||
if(!M.can_inject(user, TRUE))
|
||||
@@ -70,8 +79,9 @@
|
||||
icon_state = "brutepack"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
var/heal_brute = 20
|
||||
self_delay = 20
|
||||
heal_brute = 40
|
||||
self_delay = 40
|
||||
other_delay = 20
|
||||
grind_results = list(/datum/reagent/medicine/styptic_powder = 10)
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/one
|
||||
@@ -95,7 +105,8 @@
|
||||
M.heal_bodypart_damage((heal_brute/2))
|
||||
return TRUE
|
||||
if(iscarbon(M))
|
||||
return heal_carbon(M, user, heal_brute, 0)
|
||||
return heal_carbon(M, user, heal_brute, heal_burn)
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with \the [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You can't heal [M] with the \the [src]!</span>")
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/suicide_act(mob/user)
|
||||
@@ -104,24 +115,51 @@
|
||||
|
||||
/obj/item/stack/medical/gauze
|
||||
name = "medical gauze"
|
||||
desc = "A roll of elastic cloth that is extremely effective at stopping bleeding, heals minor wounds."
|
||||
desc = "A roll of elastic cloth, perfect for stabilizing all kinds of wounds, from cuts and burns to broken bones."
|
||||
gender = PLURAL
|
||||
singular_name = "medical gauze"
|
||||
icon_state = "gauze"
|
||||
var/stop_bleeding = 1800
|
||||
var/heal_brute = 5
|
||||
self_delay = 10
|
||||
heal_brute = 5
|
||||
self_delay = 50
|
||||
other_delay = 20
|
||||
amount = 10
|
||||
max_amount = 10
|
||||
absorption_rate = 0.25
|
||||
absorption_capacity = 5
|
||||
splint_factor = 0.35
|
||||
custom_price = PRICE_REALLY_CHEAP
|
||||
|
||||
/obj/item/stack/medical/gauze/heal(mob/living/M, mob/user)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.bleedsuppress && H.bleed_rate) //so you can't stack bleed suppression
|
||||
H.suppress_bloodloss(stop_bleeding)
|
||||
to_chat(user, "<span class='notice'>You stop the bleeding of [M]!</span>")
|
||||
H.adjustBruteLoss(-(heal_brute))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You can not use \the [src] on [M]!</span>")
|
||||
// gauze is only relevant for wounds, which are handled in the wounds themselves
|
||||
/obj/item/stack/medical/gauze/try_heal(mob/living/M, mob/user, silent)
|
||||
var/obj/item/bodypart/limb = M.get_bodypart(check_zone(user.zone_selected))
|
||||
if(!limb)
|
||||
to_chat(user, "<span class='notice'>There's nothing there to bandage!</span>")
|
||||
return
|
||||
if(!LAZYLEN(limb.wounds))
|
||||
to_chat(user, "<span class='notice'>There's no wounds that require bandaging on [user==M ? "your" : "[M]'s"] [limb.name]!</span>") // good problem to have imo
|
||||
return
|
||||
|
||||
var/gauzeable_wound = FALSE
|
||||
for(var/i in limb.wounds)
|
||||
var/datum/wound/woundies = i
|
||||
if(woundies.wound_flags & ACCEPTS_GAUZE)
|
||||
gauzeable_wound = TRUE
|
||||
break
|
||||
if(!gauzeable_wound)
|
||||
to_chat(user, "<span class='notice'>There's no wounds that require bandaging on [user==M ? "your" : "[M]'s"] [limb.name]!</span>") // good problem to have imo
|
||||
return
|
||||
|
||||
if(limb.current_gauze && (limb.current_gauze.absorption_capacity * 0.8 > absorption_capacity)) // ignore if our new wrap is < 20% better than the current one, so someone doesn't bandage it 5 times in a row
|
||||
to_chat(user, "<span class='warning'>The bandage currently on [user==M ? "your" : "[M]'s"] [limb.name] is still in good condition!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='warning'>[user] begins wrapping the wounds on [M]'s [limb.name] with [src]...</span>", "<span class='warning'>You begin wrapping the wounds on [user == M ? "your" : "[M]'s"] [limb.name] with [src]...</span>")
|
||||
|
||||
if(!do_after(user, (user == M ? self_delay : other_delay), target=M))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='green'>[user] applies [src] to [M]'s [limb.name].</span>", "<span class='green'>You bandage the wounds on [user == M ? "yourself" : "[M]'s"] [limb.name].</span>")
|
||||
limb.apply_gauze(src)
|
||||
|
||||
/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness())
|
||||
@@ -133,6 +171,14 @@
|
||||
"<span class='notice'>You cut [src] into pieces of cloth with [I].</span>", \
|
||||
"<span class='italics'>You hear cutting.</span>")
|
||||
use(2)
|
||||
else if(I.is_drainable() && I.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine))
|
||||
if(!I.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine, 10))
|
||||
to_chat(user, "<span class='warning'>There's not enough sterilizine in [I] to sterilize [src]!</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] pours the contents of [I] onto [src], sterilizing it.</span>", "<span class='notice'>You pour the contents of [I] onto [src], sterilizing it.</span>")
|
||||
I.reagents.remove_reagent(/datum/reagent/space_cleaner/sterilizine, 10)
|
||||
new /obj/item/stack/medical/gauze/adv/one(user.drop_location())
|
||||
use(1)
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -143,15 +189,22 @@
|
||||
/obj/item/stack/medical/gauze/improvised
|
||||
name = "improvised gauze"
|
||||
singular_name = "improvised gauze"
|
||||
desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
|
||||
stop_bleeding = 900
|
||||
heal_brute = 0
|
||||
desc = "A roll of cloth roughly cut from something that does a decent job of stabilizing wounds, but less efficiently than real medical gauze."
|
||||
self_delay = 60
|
||||
other_delay = 30
|
||||
absorption_rate = 0.15
|
||||
absorption_capacity = 4
|
||||
|
||||
/obj/item/stack/medical/gauze/adv
|
||||
name = "sterilized medical gauze"
|
||||
desc = "A roll of elastic sterilized cloth that is extremely effective at stopping bleeding, heals minor wounds and cleans them."
|
||||
singular_name = "sterilized medical gauze"
|
||||
self_delay = 5
|
||||
desc = "A roll of elastic sterilized cloth that is extremely effective at stopping bleeding and covering burns."
|
||||
heal_brute = 6
|
||||
self_delay = 45
|
||||
other_delay = 15
|
||||
absorption_rate = 0.4
|
||||
absorption_capacity = 6
|
||||
|
||||
/obj/item/stack/medical/gauze/adv/one
|
||||
amount = 1
|
||||
@@ -161,38 +214,9 @@
|
||||
is_cyborg = 1
|
||||
cost = 250
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
name = "ointment"
|
||||
desc = "Used to treat those nasty burn wounds."
|
||||
gender = PLURAL
|
||||
singular_name = "ointment"
|
||||
icon_state = "ointment"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
var/heal_burn = 20
|
||||
self_delay = 20
|
||||
grind_results = list(/datum/reagent/medicine/silver_sulfadiazine = 10)
|
||||
|
||||
/obj/item/stack/medical/ointment/one
|
||||
amount = 1
|
||||
|
||||
/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user)
|
||||
if(M.stat == DEAD)
|
||||
to_chat(user, "<span class='notice'> [M] is dead. You can not help [M.p_them()]!</span>")
|
||||
return
|
||||
if(iscarbon(M))
|
||||
return heal_carbon(M, user, 0, heal_burn)
|
||||
if(AmBloodsucker(M))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You can't heal [M] with the \the [src]!</span>")
|
||||
|
||||
/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."
|
||||
desc = "Basic sterile sutures used to seal up cuts and lacerations and stop bleeding."
|
||||
gender = PLURAL
|
||||
singular_name = "suture"
|
||||
icon_state = "suture"
|
||||
@@ -201,9 +225,30 @@
|
||||
amount = 15
|
||||
max_amount = 15
|
||||
repeating = TRUE
|
||||
var/heal_brute = 10
|
||||
heal_brute = 10
|
||||
stop_bleeding = 0.6
|
||||
grind_results = list(/datum/reagent/medicine/spaceacillin = 2)
|
||||
|
||||
/obj/item/stack/medical/suture/emergency
|
||||
name = "emergency suture"
|
||||
desc = "A value pack of cheap sutures, not very good at repairing damage, but still decent at stopping bleeding."
|
||||
heal_brute = 5
|
||||
amount = 5
|
||||
max_amount = 5
|
||||
|
||||
/obj/item/stack/medical/suture/one
|
||||
amount = 1
|
||||
|
||||
/obj/item/stack/medical/suture/five
|
||||
amount = 5
|
||||
|
||||
/obj/item/stack/medical/suture/medicated
|
||||
name = "medicated suture"
|
||||
icon_state = "suture_purp"
|
||||
desc = "A suture infused with drugs that speed up wound healing of the treated laceration."
|
||||
heal_brute = 15
|
||||
grind_results = list(/datum/reagent/medicine/polypyr = 2)
|
||||
|
||||
/obj/item/stack/medical/suture/one
|
||||
amount = 1
|
||||
|
||||
@@ -223,10 +268,39 @@
|
||||
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
|
||||
return heal_carbon(M, user, heal_brute, heal_burn)
|
||||
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with \the [src]!</span>")
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
name = "ointment"
|
||||
desc = "Basic burn ointment, rated effective for second degree burns with proper bandaging, though it's still an effective stabilizer for worse burns. Not terribly good at outright healing burns though."
|
||||
gender = PLURAL
|
||||
singular_name = "ointment"
|
||||
icon_state = "ointment"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
amount = 12
|
||||
max_amount = 12
|
||||
self_delay = 40
|
||||
other_delay = 20
|
||||
|
||||
heal_burn = 5
|
||||
flesh_regeneration = 2.5
|
||||
sanitization = 0.3
|
||||
grind_results = list(/datum/reagent/medicine/kelotane = 10)
|
||||
|
||||
/obj/item/stack/medical/ointment/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, heal_burn)
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with \the [src]!</span>")
|
||||
|
||||
/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/mesh
|
||||
name = "regenerative mesh"
|
||||
@@ -238,20 +312,43 @@
|
||||
other_delay = 10
|
||||
amount = 15
|
||||
max_amount = 15
|
||||
heal_burn = 10
|
||||
repeating = TRUE
|
||||
var/heal_burn = 10
|
||||
sanitization = 0.75
|
||||
flesh_regeneration = 3
|
||||
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/five
|
||||
amount = 5
|
||||
|
||||
/obj/item/stack/medical/mesh/advanced
|
||||
name = "advanced regenerative mesh"
|
||||
desc = "An advanced mesh made with aloe extracts and sterilizing chemicals, used to treat burns."
|
||||
gender = PLURAL
|
||||
singular_name = "advanced regenerative mesh"
|
||||
icon_state = "aloe_mesh"
|
||||
heal_burn = 15
|
||||
grind_results = list(/datum/reagent/consumable/aloejuice = 1)
|
||||
|
||||
/obj/item/stack/medical/mesh/advanced/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/advanced/update_icon_state()
|
||||
if(!is_open)
|
||||
icon_state = "aloe_mesh_closed"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/medical/mesh/update_icon_state()
|
||||
if(!is_open)
|
||||
icon_state = "regen_mesh_closed"
|
||||
@@ -264,8 +361,8 @@
|
||||
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>")
|
||||
return heal_carbon(M, user, heal_brute, heal_burn)
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with \the [src]!</span>")
|
||||
|
||||
|
||||
/obj/item/stack/medical/mesh/try_heal(mob/living/M, mob/user, silent = FALSE)
|
||||
@@ -280,7 +377,7 @@
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/medical/mesh/attack_hand(mob/user)
|
||||
/obj/item/stack/medical/mesh/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!is_open & user.get_inactive_held_item() == src)
|
||||
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
|
||||
return
|
||||
@@ -294,3 +391,83 @@
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 20, TRUE)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/medical/bone_gel
|
||||
name = "bone gel"
|
||||
singular_name = "bone gel"
|
||||
desc = "A potent medical gel that, when applied to a damaged bone in a proper surgical setting, triggers an intense melding reaction to repair the wound. Can be directly applied alongside surgical sticky tape to a broken bone in dire circumstances, though this is very harmful to the patient and not recommended."
|
||||
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "bone-gel"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
|
||||
amount = 4
|
||||
self_delay = 20
|
||||
grind_results = list(/datum/reagent/medicine/bicaridine = 10)
|
||||
novariants = TRUE
|
||||
|
||||
/obj/item/stack/medical/bone_gel/attack(mob/living/M, mob/user)
|
||||
to_chat(user, "<span class='warning'>Bone gel can only be used on fractured limbs while aggressively holding someone!</span>")
|
||||
return
|
||||
|
||||
/obj/item/stack/medical/bone_gel/suicide_act(mob/user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='suicide'>[C] is squirting all of \the [src] into [C.p_their()] mouth! That's not proper procedure! It looks like [C.p_theyre()] trying to commit suicide!</span>")
|
||||
if(do_after(C, 2 SECONDS))
|
||||
C.emote("scream")
|
||||
for(var/i in C.bodyparts)
|
||||
var/obj/item/bodypart/bone = i
|
||||
var/datum/wound/blunt/severe/oof_ouch = new
|
||||
oof_ouch.apply_wound(bone)
|
||||
var/datum/wound/blunt/critical/oof_OUCH = new
|
||||
oof_OUCH.apply_wound(bone)
|
||||
|
||||
for(var/i in C.bodyparts)
|
||||
var/obj/item/bodypart/bone = i
|
||||
bone.receive_damage(brute=60)
|
||||
use(1)
|
||||
return (BRUTELOSS)
|
||||
else
|
||||
C.visible_message("<span class='suicide'>[C] screws up like an idiot and still dies anyway!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/stack/medical/bone_gel/cyborg
|
||||
custom_materials = null
|
||||
is_cyborg = 1
|
||||
cost = 250
|
||||
|
||||
/obj/item/stack/medical/aloe
|
||||
name = "aloe cream"
|
||||
desc = "A healing paste you can apply on wounds."
|
||||
|
||||
icon_state = "aloe_paste"
|
||||
self_delay = 20
|
||||
other_delay = 10
|
||||
novariants = TRUE
|
||||
amount = 20
|
||||
max_amount = 20
|
||||
var/heal = 3
|
||||
grind_results = list(/datum/reagent/consumable/aloejuice = 1)
|
||||
|
||||
/obj/item/stack/medical/aloe/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 FALSE
|
||||
if(iscarbon(M))
|
||||
return heal_carbon(M, user, heal, heal)
|
||||
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, heal)
|
||||
return TRUE
|
||||
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
|
||||
|
||||
@@ -289,7 +289,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
resistance_flags = ACID_PROOF
|
||||
armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100)
|
||||
max_integrity = 40
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
var/icon_prefix
|
||||
embedding = list("embed_chance" = 65)
|
||||
|
||||
|
||||
@@ -184,13 +184,13 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
|
||||
new /datum/stack_recipe("trash cart", /obj/structure/closet/crate/trashcart, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("medical crate", /obj/structure/closet/crate/medical, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("freezer crate", /obj/structure/closet/crate/freezer, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("blood bag crate", /obj/structure/closet/crate/freezer/blood, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("surplus limbs crate", /obj/structure/closet/crate/freezer/surplus_limbs, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("blood bag crate", /obj/structure/closet/crate/freezer/blood/fake, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("surplus limbs crate", /obj/structure/closet/crate/freezer/surplus_limbs/fake, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("radiation containment crate", /obj/structure/closet/crate/radiation, 8, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("hydroponics crate", /obj/structure/closet/crate/hydroponics, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("engineering crate", /obj/structure/closet/crate/engineering, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("eletrical crate", /obj/structure/closet/crate/engineering/electrical, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("RCD storage crate", /obj/structure/closet/crate/rcd, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("RCD storage crate", /obj/structure/closet/crate/rcd/fake, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("science crate", /obj/structure/closet/crate/science, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
)), \
|
||||
new /datum/stack_recipe_list("airlock assemblies", list( \
|
||||
@@ -244,8 +244,10 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
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("painting frame", /obj/item/wallframe/painting, 1, time = 10),\
|
||||
new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \
|
||||
new/datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),\
|
||||
new/datum/stack_recipe("training bokken", /obj/item/melee/bokken, 10, time = 15),\
|
||||
null, \
|
||||
new/datum/stack_recipe("wooden chair", /obj/structure/chair/wood/, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("winged wooden chair", /obj/structure/chair/wood/wings, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
@@ -287,7 +289,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
merge_type = /obj/item/stack/sheet/mineral/wood
|
||||
novariants = TRUE
|
||||
material_type = /datum/material/wood
|
||||
grind_results = list(/datum/reagent/carbon = 20)
|
||||
grind_results = list(/datum/reagent/cellulose = 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.
|
||||
@@ -349,7 +351,7 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
|
||||
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)
|
||||
grind_results = list(/datum/reagent/cellulose = 10)
|
||||
material_type = /datum/material/bamboo
|
||||
|
||||
/obj/item/stack/sheet/mineral/bamboo/get_main_recipes()
|
||||
|
||||
@@ -25,9 +25,18 @@
|
||||
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
|
||||
max_integrity = 100
|
||||
//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()
|
||||
var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack)
|
||||
|
||||
// The following are all for medical treatment, they're here instead of /stack/medical because sticky tape can be used as a makeshift bandage or splint
|
||||
/// If set and this used as a splint for a broken bone wound, this is used as a multiplier for applicable slowdowns (lower = better) (also for speeding up burn recoveries)
|
||||
var/splint_factor
|
||||
/// How much blood flow this stack can absorb if used as a bandage on a cut wound, note that absorption is how much we lower the flow rate, not the raw amount of blood we suck up
|
||||
var/absorption_capacity
|
||||
/// How quickly we lower the blood flow on a cut wound we're bandaging. Expected lifetime of this bandage in ticks is thus absorption_capacity/absorption_rate, or until the cut heals, whichever comes first
|
||||
var/absorption_rate
|
||||
|
||||
/obj/item/stack/on_grind()
|
||||
for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists
|
||||
grind_results[grind_results[i]] *= get_amount() //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size
|
||||
@@ -224,7 +233,7 @@
|
||||
return
|
||||
T.PlaceOnTop(R.result_type, flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
O = new R.result_type(usr.drop_location())
|
||||
O = new R.result_type(get_turf(usr))
|
||||
if(O)
|
||||
O.setDir(usr.dir)
|
||||
log_craft("[O] crafted by [usr] at [loc_name(O.loc)]")
|
||||
@@ -389,8 +398,7 @@
|
||||
merge(AM)
|
||||
. = ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/stack/attack_hand(mob/user)
|
||||
/obj/item/stack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(user.get_inactive_held_item() == src)
|
||||
if(zero_amount())
|
||||
return
|
||||
|
||||
@@ -7,14 +7,21 @@
|
||||
icon = 'icons/obj/tapes.dmi'
|
||||
icon_state = "tape_w"
|
||||
var/prefix = "sticky"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
full_w_class = WEIGHT_CLASS_TINY
|
||||
item_flags = NOBLUDGEON
|
||||
amount = 5
|
||||
max_amount = 5
|
||||
resistance_flags = FLAMMABLE
|
||||
splint_factor = 0.8
|
||||
grind_results = list(/datum/reagent/cellulose = 5)
|
||||
|
||||
var/list/conferred_embed = EMBED_HARMLESS
|
||||
var/overwrite_existing = FALSE
|
||||
|
||||
var/endless = FALSE
|
||||
var/apply_time = 30
|
||||
|
||||
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
|
||||
if(!istype(I))
|
||||
return
|
||||
@@ -25,17 +32,24 @@
|
||||
|
||||
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))
|
||||
if(do_after(user, apply_time, target=I))
|
||||
I.embedding = conferred_embed
|
||||
I.updateEmbedding()
|
||||
to_chat(user, "<span class='notice'>You finish wrapping [I] with [src].</span>")
|
||||
use(1)
|
||||
if(!endless)
|
||||
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/infinite //endless tape that applies far faster, for maximum honks
|
||||
name = "endless sticky tape"
|
||||
desc = "This roll of sticky tape somehow has no end."
|
||||
endless = TRUE
|
||||
apply_time = 10
|
||||
|
||||
/obj/item/stack/sticky_tape/super
|
||||
name = "super sticky tape"
|
||||
singular_name = "super sticky tape"
|
||||
@@ -43,6 +57,7 @@
|
||||
icon_state = "tape_y"
|
||||
prefix = "super sticky"
|
||||
conferred_embed = EMBED_HARMLESS_SUPERIOR
|
||||
splint_factor = 0.6
|
||||
|
||||
/obj/item/stack/sticky_tape/pointy
|
||||
name = "pointy tape"
|
||||
@@ -58,4 +73,14 @@
|
||||
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
|
||||
conferred_embed = EMBED_POINTY_SUPERIOR
|
||||
|
||||
/obj/item/stack/sticky_tape/surgical
|
||||
name = "surgical tape"
|
||||
singular_name = "surgical tape"
|
||||
desc = "Made for patching broken bones back together alongside bone gel, not for playing pranks."
|
||||
//icon_state = "tape_spikes"
|
||||
prefix = "surgical"
|
||||
conferred_embed = list("embed_chance" = 30, "pain_mult" = 0, "jostle_pain_mult" = 0, "ignore_throwspeed_threshold" = TRUE)
|
||||
splint_factor = 0.4
|
||||
custom_price = 500
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/obj/item/stack/arcadeticket
|
||||
name = "arcade tickets"
|
||||
desc = "Wow! With enough of these, you could buy a bike! ...Pssh, yeah right."
|
||||
singular_name = "arcade ticket"
|
||||
icon_state = "arcade-ticket"
|
||||
item_state = "tickets"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_amount = 30
|
||||
|
||||
/obj/item/stack/arcadeticket/Initialize(mapload, new_amount, merge = TRUE)
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/stack/arcadeticket/update_icon()
|
||||
var/amount = get_amount()
|
||||
if((amount >= 12) && (amount > 0))
|
||||
icon_state = "arcade-ticket_4"
|
||||
else if((amount >= 6) && (amount > 0))
|
||||
icon_state = "arcade-ticket_3"
|
||||
else if((amount >= 2) && (amount > 0))
|
||||
icon_state = "arcade-ticket_2"
|
||||
else
|
||||
icon_state = "arcade-ticket"
|
||||
|
||||
/obj/item/stack/arcadeticket/proc/pay_tickets()
|
||||
amount -= 2
|
||||
if (amount == 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/stack/arcadeticket/thirty
|
||||
amount = 30
|
||||
@@ -35,6 +35,7 @@
|
||||
amount = 25
|
||||
max_amount = 25
|
||||
resistance_flags = FLAMMABLE
|
||||
grind_results = list(/datum/reagent/cellulose = 5)
|
||||
|
||||
/obj/item/stack/packageWrap/suicide_act(mob/living/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins wrapping [user.p_them()]self in \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/storage/contents_explosion(severity, target)
|
||||
var/in_storage = istype(loc, /obj/item/storage)? (max(0, severity - 1)) : (severity)
|
||||
for(var/atom/A in contents)
|
||||
A.ex_act(severity, target)
|
||||
A.ex_act(in_storage, target)
|
||||
CHECK_TICK
|
||||
|
||||
//Cyberboss says: "USE THIS TO FILL IT, NOT INITIALIZE OR NEW"
|
||||
|
||||
@@ -369,6 +369,7 @@
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/reagent_containers/medspray/sterilizine(src)
|
||||
@@ -391,6 +392,7 @@
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/reagent_containers/medspray/sterilizine(src)
|
||||
@@ -485,6 +487,7 @@
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/suit/straight_jacket(src)
|
||||
new /obj/item/clothing/mask/muzzle(src)
|
||||
@@ -501,8 +504,8 @@
|
||||
new /obj/item/scalpel/advanced(src)
|
||||
new /obj/item/retractor/advanced(src)
|
||||
new /obj/item/surgicaldrill/advanced(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/storage/firstaid/tactical(src)
|
||||
new /obj/item/clothing/suit/straight_jacket(src)
|
||||
new /obj/item/clothing/mask/muzzle(src)
|
||||
new /obj/item/mmi/syndie(src)
|
||||
@@ -648,3 +651,9 @@ obj/item/storage/backpack/duffelbag/syndie/shredderbundle
|
||||
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
|
||||
new /obj/item/storage/belt/military(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
|
||||
|
||||
/obj/item/storage/backpack/snail
|
||||
name = "snail shell"
|
||||
desc = "Worn by snails as armor and storage compartment."
|
||||
icon_state = "snailshell"
|
||||
item_state = "snailshell"
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
STR.max_combined_w_class = 30
|
||||
STR.max_items = 30
|
||||
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear))
|
||||
STR.can_hold_extra = typecacheof(list(/obj/item/organ/lungs, /obj/item/organ/liver, /obj/item/organ/stomach, /obj/item/clothing/shoes)) - typesof(/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/clown_shoes, /obj/item/clothing/shoes/jackboots, /obj/item/clothing/shoes/workboots)
|
||||
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/storage/wallet, /obj/item/organ/brain))
|
||||
STR.limited_random_access = TRUE
|
||||
STR.limited_random_access_stack_position = 3
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
new /obj/item/multitool(src)
|
||||
new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange"))
|
||||
new /obj/item/extinguisher/mini(src)
|
||||
new /obj/item/analyzer(src)
|
||||
new /obj/item/analyzer/ranged(src)
|
||||
//much roomier now that we've managed to remove two tools
|
||||
|
||||
/obj/item/storage/belt/utility/full/PopulateContents()
|
||||
@@ -120,7 +120,7 @@
|
||||
new /obj/item/wrench/brass(src)
|
||||
new /obj/item/crowbar/brass(src)
|
||||
new /obj/item/weldingtool/experimental/brass(src)
|
||||
new /obj/item/multitool(src)
|
||||
new /obj/item/multitool/advanced/brass(src)
|
||||
new /obj/item/stack/cable_coil(src, 30, "yellow")
|
||||
|
||||
/obj/item/storage/belt/medical
|
||||
@@ -162,6 +162,7 @@
|
||||
/obj/item/surgical_drapes, //for true paramedics
|
||||
/obj/item/scalpel,
|
||||
/obj/item/circular_saw,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/retractor,
|
||||
/obj/item/cautery,
|
||||
@@ -181,7 +182,8 @@
|
||||
/obj/item/implant,
|
||||
/obj/item/implanter,
|
||||
/obj/item/pinpointer/crew,
|
||||
/obj/item/reagent_containers/chem_pack
|
||||
/obj/item/reagent_containers/chem_pack,
|
||||
/obj/item/stack/sticky_tape //surgical tape
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/medical/surgery_belt_adv
|
||||
@@ -444,10 +446,11 @@
|
||||
|
||||
/obj/item/storage/belt/durathread
|
||||
name = "durathread toolbelt"
|
||||
desc = "A toolbelt made out of durathread, it seems resistant enough to hold even big tools like an RCD, it also has higher capacity."
|
||||
desc = "A toolbelt made out of durathread, it seems robust enough to hold bigger tools like RCDs or RPDs, with enough pouches to hold more gear than a normal belt."
|
||||
icon_state = "webbing-durathread"
|
||||
item_state = "webbing-durathread"
|
||||
resistance_flags = FIRE_PROOF
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //If normal belts get this, the upgraded version should too
|
||||
|
||||
/obj/item/storage/belt/durathread/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -467,7 +470,7 @@
|
||||
/obj/item/t_scanner,
|
||||
/obj/item/analyzer,
|
||||
/obj/item/geiger_counter,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/radio,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/holosign_creator,
|
||||
@@ -488,7 +491,8 @@
|
||||
desc = "A belt for holding grenades."
|
||||
icon_state = "grenadebeltnew"
|
||||
item_state = "security"
|
||||
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
|
||||
/obj/item/storage/belt/grenade/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
@@ -811,4 +815,3 @@
|
||||
attack_verb = list("bashed", "slashes", "prods", "pokes")
|
||||
fitting_swords = list(/obj/item/melee/rapier)
|
||||
starting_sword = /obj/item/melee/rapier
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "blessing", /datum/mood_event/blessing)
|
||||
return 1
|
||||
|
||||
/obj/item/storage/book/bible/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE)
|
||||
/obj/item/storage/book/bible/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1, heal_mode = TRUE)
|
||||
|
||||
if (!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
@@ -238,11 +238,10 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
var/ownername = H.real_name
|
||||
desc += "<span class='warning'>The name [ownername] is written in blood inside the cover.</span>"
|
||||
|
||||
/obj/item/storage/book/bible/syndicate/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE)
|
||||
if (user.a_intent == INTENT_HELP)
|
||||
return ..()
|
||||
else
|
||||
return ..(M,user,heal_mode = FALSE)
|
||||
/obj/item/storage/book/bible/syndicate/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1, heal_mode = TRUE)
|
||||
if(user.a_intent != INTENT_HELP)
|
||||
heal_mode = FALSE //args pass over
|
||||
return ..() // to ..()
|
||||
|
||||
/obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna)
|
||||
return FALSE
|
||||
|
||||
@@ -726,9 +726,9 @@ obj/item/storage/box/stingbangs
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/storage/box/hug/attack_self(mob/user)
|
||||
..()
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
playsound(loc, "rustle", 50, 1, -5)
|
||||
. = ..()
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
playsound(src, "rustle", 50, 1, -5)
|
||||
user.visible_message("<span class='notice'>[user] hugs \the [src].</span>","<span class='notice'>You hug \the [src].</span>")
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"hugbox", /datum/mood_event/hugbox)
|
||||
|
||||
@@ -1418,3 +1418,9 @@ obj/item/storage/box/stingbangs
|
||||
new /obj/item/reagent_containers/glass/beaker/meta(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/noreact(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/bluespace(src)
|
||||
|
||||
/obj/item/storage/box/strange_seeds_5pack
|
||||
|
||||
/obj/item/storage/box/strange_seeds_5pack/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/seeds/random(src)
|
||||
|
||||
@@ -47,6 +47,6 @@
|
||||
if(INTENT_HARM)
|
||||
user.visible_message("<span class='danger'>[user] punches the [name]!</span>")
|
||||
playsound(src, 'sound/effects/shieldbash.ogg', 50, 1)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
|
||||
////////////////////////////
|
||||
|
||||
@@ -168,13 +168,19 @@
|
||||
. += "<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)))
|
||||
return
|
||||
var/obj/item/clothing/mask/cigarette/W = locate(/obj/item/clothing/mask/cigarette) in contents
|
||||
var/obj/item/lighter/L = locate() in contents
|
||||
if(L)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, L, user)
|
||||
user.put_in_hands(L)
|
||||
to_chat(user, "<span class='notice'>You take \a [L] out of the pack.</span>")
|
||||
return TRUE
|
||||
var/obj/item/clothing/mask/cigarette/W = locate() in contents
|
||||
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 [icon_type]s left in the pack.</span>")
|
||||
@@ -398,6 +404,20 @@
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/nugget))
|
||||
|
||||
/obj/item/storage/fancy/cracker_pack
|
||||
name = "cracker pack"
|
||||
desc = "A pack of delicious crackers. Keep away from parrots!"
|
||||
icon = 'icons/obj/food/containers.dmi'
|
||||
icon_state = "crackerbox"
|
||||
icon_type = "cracker"
|
||||
spawn_type = /obj/item/reagent_containers/food/snacks/cracker
|
||||
|
||||
/obj/item/storage/fancy/cracker_pack/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/cracker))
|
||||
|
||||
/*
|
||||
* Ring Box
|
||||
*/
|
||||
|
||||
@@ -41,9 +41,25 @@
|
||||
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/reagent_containers/hypospray/medipen/ekit(src)
|
||||
new /obj/item/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/emergency
|
||||
icon_state = "medbriefcase"
|
||||
name = "emergency first-aid kit"
|
||||
desc = "A very simple first aid kit meant to secure and stabilize serious wounds for later treatment."
|
||||
|
||||
/obj/item/storage/firstaid/emergency/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
var/static/items_inside = list(
|
||||
/obj/item/healthanalyzer/wound = 1,
|
||||
/obj/item/stack/medical/gauze = 1,
|
||||
/obj/item/stack/medical/suture/emergency = 1,
|
||||
/obj/item/stack/medical/ointment = 1,
|
||||
/obj/item/reagent_containers/hypospray/medipen/ekit = 2)
|
||||
generate_items_inside(items_inside,src)
|
||||
|
||||
/obj/item/storage/firstaid/ancient
|
||||
icon_state = "firstaid"
|
||||
desc = "A first aid kit with the ability to heal common types of injuries."
|
||||
@@ -229,6 +245,25 @@
|
||||
STR.click_gather = TRUE
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice))
|
||||
|
||||
/obj/item/storage/pill_bottle/AltClick(mob/living/carbon/user)
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
if(!length(user.get_empty_held_indexes()))
|
||||
to_chat(user, "<span class='warning'>Your hands are full!</span>")
|
||||
return
|
||||
var/obj/item/reagent_containers/pill/P = locate() in contents
|
||||
if(P)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, P, user)
|
||||
if(!user.put_in_hands(P))
|
||||
P.forceMove(user.drop_location()) // make sure it's not stuck in the user if the put in hands somehow fails
|
||||
to_chat(user, "<span class='warning'>[P] drops to the floor!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You take \a [P] out of [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no pills left in the bottle.</span>")
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/storage/pill_bottle/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (TOXLOSS)
|
||||
@@ -416,6 +451,7 @@
|
||||
/obj/item/retractor,
|
||||
/obj/item/cautery,
|
||||
/obj/item/surgical_drapes,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/autosurgeon,
|
||||
/obj/item/organ,
|
||||
/obj/item/implant,
|
||||
|
||||
@@ -205,10 +205,7 @@
|
||||
new /obj/item/paper(src)
|
||||
new /obj/item/pen(src)
|
||||
|
||||
/obj/item/storage/secure/safe/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/storage/secure/safe/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
return attack_self(user)
|
||||
|
||||
/obj/item/storage/secure/safe/HoS
|
||||
|
||||
@@ -20,6 +20,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
var/has_latches = TRUE
|
||||
var/can_rubberify = TRUE
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //very protecc too
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 5
|
||||
|
||||
/obj/item/storage/toolbox/greyscale
|
||||
icon_state = "toolbox_default"
|
||||
|
||||
@@ -169,6 +169,14 @@
|
||||
O.imp = new /obj/item/implant/freedom(O)
|
||||
O.update_icon()
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_warp
|
||||
name = "boxed warp implant (with injector)"
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_warp/PopulateContents()
|
||||
var/obj/item/implanter/O = new(src)
|
||||
O.imp = new /obj/item/implant/warp(O)
|
||||
O.update_icon()
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_microbomb
|
||||
name = "Microbomb Implant (with injector)"
|
||||
|
||||
@@ -327,6 +335,7 @@
|
||||
new /obj/item/reagent_containers/glass/bottle/romerol(src)
|
||||
new /obj/item/reagent_containers/syringe(src)
|
||||
new /obj/item/reagent_containers/dropper(src)
|
||||
new /obj/item/paper/guides/antag/romerol_instructions(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/ez_clean/PopulateContents()
|
||||
for(var/i in 1 to 3)
|
||||
@@ -401,7 +410,7 @@
|
||||
/obj/item/storage/box/syndie_kit/revolver
|
||||
|
||||
/obj/item/storage/box/syndie_kit/revolver/PopulateContents()
|
||||
new /obj/item/gun/ballistic/revolver(src)
|
||||
new /obj/item/gun/ballistic/revolver/syndicate(src)
|
||||
new /obj/item/ammo_box/a357(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/pistol
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("beaten")
|
||||
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/turned_on = FALSE
|
||||
@@ -144,8 +145,9 @@
|
||||
return ..()
|
||||
|
||||
/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.
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
//return TRUE to interrupt attack chain.
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
@@ -156,6 +158,7 @@
|
||||
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>")
|
||||
return TRUE
|
||||
user.DelayNextAction()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/L = M
|
||||
if(check_martial_counter(L, user))
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
|
||||
/obj/item/tank/analyzer_act(mob/living/user, obj/item/I)
|
||||
atmosanalyzer_scan(air_contents, user, src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank/deconstruct(disassembled = TRUE)
|
||||
if(!disassembled)
|
||||
@@ -143,7 +144,6 @@
|
||||
if(prob(50))
|
||||
step(W, pick(GLOB.alldirs))
|
||||
ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC)
|
||||
H.bleed_rate = 5
|
||||
H.gib_animation()
|
||||
sleep(3)
|
||||
H.adjustBruteLoss(1000) //to make the body super-bloody
|
||||
@@ -164,11 +164,13 @@
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/tank/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/tank/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
/obj/item/tank/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state)
|
||||
ui = new(user, src, "Tank", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/tank/ui_data(mob/user)
|
||||
@@ -205,10 +207,6 @@
|
||||
else if(pressure == "max")
|
||||
pressure = TANK_MAX_RELEASE_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New release pressure ([TANK_MIN_RELEASE_PRESSURE]-[TANK_MAX_RELEASE_PRESSURE] kPa):", name, distribute_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
QDEL_NULL(noz)
|
||||
return ..()
|
||||
|
||||
/obj/item/watertank/attack_hand(mob/user)
|
||||
/obj/item/watertank/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if (user.get_item_by_slot(user.getBackSlot()) == src)
|
||||
toggle_mister(user)
|
||||
else
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#define SOURCE_PORTAL 1
|
||||
#define DESTINATION_PORTAL 2
|
||||
|
||||
@@ -25,90 +24,72 @@
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
custom_materials = list(/datum/material/iron=400)
|
||||
var/tracking_range = 20
|
||||
|
||||
/obj/item/locator/attack_self(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat
|
||||
if (temp)
|
||||
dat = "[temp]<BR><BR><A href='byond://?src=[REF(src)];temp=1'>Clear</A>"
|
||||
else
|
||||
dat = {"
|
||||
<B>Persistent Signal Locator</B><HR>
|
||||
<A href='?src=[REF(src)];refresh=1'>Refresh</A>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
/obj/item/locator/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "BluespaceLocator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/locator/Topic(href, href_list)
|
||||
..()
|
||||
if (usr.stat || usr.restrained())
|
||||
return
|
||||
var/turf/current_location = get_turf(usr)//What turf is the user on?
|
||||
if(!current_location || is_centcom_level(current_location.z))//If turf was not found or they're on CentCom
|
||||
to_chat(usr, "[src] is malfunctioning.")
|
||||
return
|
||||
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)))
|
||||
usr.set_machine(src)
|
||||
if (href_list["refresh"])
|
||||
temp = "<B>Persistent Signal Locator</B><HR>"
|
||||
var/turf/sr = get_turf(src)
|
||||
/obj/item/locator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if (sr)
|
||||
temp += "<B>Beacon Signals:</B><BR>"
|
||||
for(var/obj/item/beacon/W in GLOB.teleportbeacons)
|
||||
if (!W.renamed)
|
||||
continue
|
||||
var/turf/tr = get_turf(W)
|
||||
if (tr.z == sr.z && tr)
|
||||
var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
|
||||
if (direct < 5)
|
||||
direct = "very strong"
|
||||
else
|
||||
if (direct < 10)
|
||||
direct = "strong"
|
||||
else
|
||||
if (direct < 20)
|
||||
direct = "weak"
|
||||
else
|
||||
direct = "very weak"
|
||||
temp += "[W.name]-[dir2text(get_dir(sr, tr))]-[direct]<BR>"
|
||||
data["trackingrange"] = tracking_range
|
||||
|
||||
temp += "<B>Implant Signals:</B><BR>"
|
||||
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
|
||||
if (!isliving(W.imp_in))
|
||||
continue
|
||||
var/mob/living/M = W.imp_in
|
||||
if (M.stat == DEAD)
|
||||
if (M.timeofdeath + W.lifespan_postmortem < world.time)
|
||||
continue
|
||||
// Get our current turf location.
|
||||
var/turf/sr = get_turf(src)
|
||||
|
||||
var/turf/tr = get_turf(M)
|
||||
if (tr.z == sr.z && tr)
|
||||
var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
|
||||
if (direct < 20)
|
||||
if (direct < 5)
|
||||
direct = "very strong"
|
||||
else
|
||||
if (direct < 10)
|
||||
direct = "strong"
|
||||
else
|
||||
direct = "weak"
|
||||
temp += "[W.imp_in.name]-[dir2text(get_dir(sr, tr))]-[direct]<BR>"
|
||||
if (sr)
|
||||
// Check every teleport beacon.
|
||||
var/list/tele_beacons = list()
|
||||
for(var/obj/item/beacon/W in GLOB.teleportbeacons)
|
||||
|
||||
temp += "<B>You are at \[[sr.x],[sr.y],[sr.z]\]</B> in orbital coordinates.<BR><BR><A href='byond://?src=[REF(src)];refresh=1'>Refresh</A><BR>"
|
||||
// Get the tracking beacon's turf location.
|
||||
var/turf/tr = get_turf(W)
|
||||
|
||||
// Make sure it's on a turf and that its Z-level matches the tracker's Z-level
|
||||
if (tr && tr.z == sr.z)
|
||||
// Get the distance between the beacon's turf and our turf
|
||||
var/distance = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
|
||||
|
||||
// If the target is too far away, skip over this beacon.
|
||||
if(distance > tracking_range)
|
||||
continue
|
||||
|
||||
var/beacon_name
|
||||
|
||||
if(W.renamed)
|
||||
beacon_name = W.name
|
||||
else
|
||||
var/area/A = get_area(W)
|
||||
beacon_name = A.name
|
||||
|
||||
var/D = dir2text(get_dir(sr, tr))
|
||||
tele_beacons += list(list(name = beacon_name, direction = D, distance = distance))
|
||||
|
||||
data["telebeacons"] = tele_beacons
|
||||
|
||||
var/list/track_implants = list()
|
||||
|
||||
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
|
||||
if (!W.imp_in || !isliving(W.loc))
|
||||
continue
|
||||
else
|
||||
temp += "<B><FONT color='red'>Processing Error:</FONT></B> Unable to locate orbital position.<BR>"
|
||||
else
|
||||
if (href_list["temp"])
|
||||
temp = null
|
||||
if (ismob(src.loc))
|
||||
attack_self(src.loc)
|
||||
else
|
||||
for(var/mob/M in fov_viewers(1, src))
|
||||
if (M.client)
|
||||
src.attack_self(M)
|
||||
return
|
||||
var/mob/living/M = W.loc
|
||||
if (M.stat == DEAD)
|
||||
if (M.timeofdeath + W.lifespan_postmortem < world.time)
|
||||
continue
|
||||
var/turf/tr = get_turf(W)
|
||||
var/distance = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
|
||||
|
||||
if(distance > tracking_range)
|
||||
continue
|
||||
|
||||
var/D = dir2text(get_dir(sr, tr))
|
||||
track_implants += list(list(name = W.imp_in.name, direction = D, distance = distance))
|
||||
data["trackimplants"] = track_implants
|
||||
return data
|
||||
|
||||
/*
|
||||
* Hand-tele
|
||||
@@ -190,13 +171,8 @@
|
||||
user.show_message("<span class='notice'>\The [src] is recharging!</span>")
|
||||
return
|
||||
var/atom/T = L[t1]
|
||||
var/implantcheckmate = FALSE
|
||||
if(isliving(T))
|
||||
var/mob/living/M = T
|
||||
if(!locate(/obj/item/implant/tracking) in M.implants) //The user was too slow and let the target mob's tracking implant expire or get removed.
|
||||
implantcheckmate = TRUE
|
||||
var/area/A = get_area(T)
|
||||
if(A.noteleport || implantcheckmate)
|
||||
if(A.noteleport)
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
return
|
||||
current_location = get_turf(user) //Recheck.
|
||||
@@ -205,10 +181,12 @@
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
return
|
||||
user.show_message("<span class='notice'>Locked In.</span>", MSG_AUDIBLE)
|
||||
var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1, null, atmos_link_override)
|
||||
var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), 300, 1, null, atmos_link_override)
|
||||
if(!(LAZYLEN(created) == 2))
|
||||
return
|
||||
try_move_adjacent(created[1])
|
||||
RegisterSignal(created[1], COMSIG_PARENT_QDELETING, .proc/on_portal_destroy) //Gosh darn it kevinz.
|
||||
RegisterSignal(created[2], COMSIG_PARENT_QDELETING, .proc/on_portal_destroy)
|
||||
try_move_adjacent(created[1], user.dir)
|
||||
active_portal_pairs[created[1]] = created[2]
|
||||
var/obj/effect/portal/c1 = created[1]
|
||||
var/obj/effect/portal/c2 = created[2]
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
toolspeed = 1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
|
||||
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 5
|
||||
|
||||
/obj/item/crowbar/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
@@ -90,6 +93,7 @@
|
||||
/obj/item/crowbar/power/attack_self(mob/user)
|
||||
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
|
||||
var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power(drop_location())
|
||||
cutjaws.name = name
|
||||
to_chat(user, "<span class='notice'>You attach the cutting jaws to [src].</span>")
|
||||
qdel(src)
|
||||
user.put_in_active_hand(cutjaws)
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
"yellow" = rgb(255, 165, 0)
|
||||
)
|
||||
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 5
|
||||
|
||||
/obj/item/screwdriver/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return(BRUTELOSS)
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
heat = 3800
|
||||
tool_behaviour = TOOL_WELDER
|
||||
toolspeed = 1
|
||||
wound_bonus = 0
|
||||
bare_wound_bonus = 5
|
||||
|
||||
/obj/item/weldingtool/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
/obj/item/wirecutters/power/attack_self(mob/user)
|
||||
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
|
||||
var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power(drop_location())
|
||||
pryjaws.name = name
|
||||
to_chat(user, "<span class='notice'>You attach the pry jaws to [src].</span>")
|
||||
qdel(src)
|
||||
user.put_in_active_hand(pryjaws)
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
toolspeed = 1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
|
||||
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 5
|
||||
|
||||
/obj/item/wrench/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
|
||||
@@ -447,7 +447,7 @@
|
||||
block_parry_data = null
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
sharpness = IS_BLUNT
|
||||
sharpness = SHARP_NONE
|
||||
|
||||
/obj/item/dualsaber/toy/ComponentInitialize()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=0, wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
|
||||
@@ -466,7 +466,7 @@
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
slowdown_wielded = 0
|
||||
sharpness = IS_BLUNT
|
||||
sharpness = SHARP_NONE
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/toy/ComponentInitialize()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=0, wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
|
||||
@@ -574,10 +574,7 @@
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/prize/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/toy/prize/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user)
|
||||
attack_self(user)
|
||||
|
||||
@@ -811,9 +808,8 @@
|
||||
cards += "Ace of Clubs"
|
||||
cards += "Ace of Diamonds"
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
//ATTACK HAND NOT CALLING PARENT
|
||||
/obj/item/toy/cards/deck/attack_hand(mob/user)
|
||||
/obj/item/toy/cards/deck/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
draw_card(user)
|
||||
|
||||
/obj/item/toy/cards/deck/proc/draw_card(mob/user)
|
||||
@@ -1234,7 +1230,7 @@
|
||||
name = "steampunk watch"
|
||||
desc = "A stylish steampunk watch made out of thousands of tiny cogwheels."
|
||||
icon = 'icons/obj/clockwork_objects.dmi'
|
||||
icon_state = "dread_ipad"
|
||||
icon_state = "clockwork_slab"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/cooldown = 0
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
name = "syndi-cakes"
|
||||
icon_state = "syndi_cakes"
|
||||
|
||||
/obj/item/trash/energybar
|
||||
name = "energybar wrapper"
|
||||
icon_state = "energybar"
|
||||
|
||||
/obj/item/trash/waffles
|
||||
name = "waffles tray"
|
||||
icon_state = "waffles"
|
||||
|
||||
@@ -65,7 +65,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
block_chance = 50
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
@@ -231,7 +231,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
block_chance = 50
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
@@ -249,6 +249,174 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1)
|
||||
return(BRUTELOSS)
|
||||
|
||||
/obj/item/katana/timestop
|
||||
name = "temporal katana"
|
||||
desc = "Delicately balanced, this finely-crafted blade hums with barely-restrained potential."
|
||||
block_chance = 0 // oops
|
||||
force = 27.5 // oops
|
||||
item_flags = ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/bokken/quick_parry/proj
|
||||
|
||||
/obj/item/katana/timestop/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/flynn = owner
|
||||
flynn.emote("smirk")
|
||||
new /obj/effect/timestop/magic(get_turf(owner), 1, 50, list(owner)) // null roddies counter
|
||||
|
||||
/obj/item/melee/bokken // parrying stick
|
||||
name = "bokken"
|
||||
desc = "A space-Japanese training sword made of wood and shaped like a katana."
|
||||
icon_state = "bokken"
|
||||
item_state = "bokken"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 9
|
||||
throwforce = 10
|
||||
damtype = STAMINA
|
||||
attack_verb = list("whacked", "smacked", "struck")
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg' // no good wood thunk sounds
|
||||
var/harm = FALSE // TRUE = brute, FALSE = stam
|
||||
var/reinforced = FALSE
|
||||
var/burnt = FALSE
|
||||
var/burned_in // text you burned in (with a welder)
|
||||
var/quick_parry = FALSE // false = default parry, true = really small parry window
|
||||
item_flags = ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/bokken
|
||||
bare_wound_bonus = 0
|
||||
wound_bonus = 0
|
||||
|
||||
/datum/block_parry_data/bokken // fucked up parry data, emphasizing quicker, shorter parries
|
||||
parry_stamina_cost = 8 // be wise about when you parry, though, else you won't be able to fight enough to make it count
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 10 // small parry window
|
||||
parry_time_spindown = 0
|
||||
// parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // bokken users can no longer strike while parrying
|
||||
parry_time_perfect = 1.5
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 7.5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 65 // VERY generous
|
||||
parry_efficiency_perfect = 120
|
||||
parry_efficiency_perfect_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 30,
|
||||
)
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_data = list(
|
||||
PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 2.5, // 7*2.5 = 17.5, 8*2.5 = 20, 9*2.5 = 22.5, 10*2.5 = 25
|
||||
)
|
||||
|
||||
/datum/block_parry_data/bokken/quick_parry // emphasizing REALLY SHORT PARRIES
|
||||
parry_stamina_cost = 6 // still more costly than most parries, but less than a full bokken parry
|
||||
parry_time_active = 5 // REALLY small parry window
|
||||
parry_time_perfect = 2.5 // however...
|
||||
parry_time_perfect_leeway = 2.5 // the entire time, the parry is perfect
|
||||
parry_failed_stagger_duration = 1 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS // more forgiving punishments for missed parries
|
||||
// still, don't fucking miss your parries or you're down stamina and staggered to shit
|
||||
|
||||
/datum/block_parry_data/bokken/quick_parry/proj
|
||||
parry_efficiency_perfect_override = list()
|
||||
|
||||
/obj/item/melee/bokken/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/sword_point)
|
||||
|
||||
/obj/item/melee/bokken/attack_self(mob/user)
|
||||
harm = !harm
|
||||
if(harm)
|
||||
force -= 2
|
||||
damtype = BRUTE
|
||||
attack_verb = list("bashed", "smashed", "attacked")
|
||||
bare_wound_bonus = 15 // having your leg smacked by a wooden stick is probably not great for it if it's naked
|
||||
wound_bonus = 0
|
||||
else
|
||||
force += 2
|
||||
damtype = STAMINA
|
||||
attack_verb = list("whacked", "smacked", "struck")
|
||||
bare_wound_bonus = 0
|
||||
wound_bonus = 0
|
||||
to_chat(user, "<span class='notice'>[src] is now [harm ? "harmful" : "not quite as harmful"].</span>")
|
||||
|
||||
/obj/item/melee/bokken/AltClick(mob/user)
|
||||
. = ..()
|
||||
quick_parry = !quick_parry
|
||||
if(quick_parry)
|
||||
block_parry_data = /datum/block_parry_data/bokken/quick_parry
|
||||
else
|
||||
block_parry_data = /datum/block_parry_data/bokken
|
||||
to_chat(user, "<span class='notice'>[src] is now [quick_parry ? "emphasizing shorter parries, forcing you to riposte or be staggered" : "emphasizing longer parries, with a shorter window to riposte but more forgiving parries"].</span>")
|
||||
|
||||
/obj/item/melee/bokken/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/pen))
|
||||
var/new_name = stripped_input(user, "What do you wish to name [src]?", "New Name", "bokken", 30)
|
||||
if(new_name)
|
||||
name = new_name
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
var/new_burn = stripped_input(user, "What do you wish to burn into [src]?", "Burnt Inscription","", 140)
|
||||
if(new_burn)
|
||||
burned_in = new_burn
|
||||
if(!burnt)
|
||||
icon_state += "_burnt"
|
||||
item_state += "_burnt"
|
||||
burnt = TRUE
|
||||
update_icon()
|
||||
update_icon_state()
|
||||
if(istype(I, /obj/item/stack/rods))
|
||||
var/obj/item/stack/rods/R = I
|
||||
if(!reinforced)
|
||||
if(R.use(1))
|
||||
force++
|
||||
reinforced = TRUE
|
||||
to_chat(user, "<span class='notice'>You slide a metal rod into [src]\'s hilt. It feels a little heftier in your hands.")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] already has a weight slid into the hilt.")
|
||||
|
||||
/obj/item/melee/bokken/examine(mob/user)
|
||||
. = ..()
|
||||
if(quick_parry)
|
||||
. += " [src] is gripped in a way to emphasize quicker parries."
|
||||
if(reinforced)
|
||||
. += " There's a metal rod shoved into the base."
|
||||
if(burnt)
|
||||
. += " Burned into the \"blade\" is [burned_in]."
|
||||
|
||||
/obj/item/melee/bokken/debug
|
||||
name = "funny debug parrying stick"
|
||||
desc = "if you see this you've fucked up somewhere my good man"
|
||||
block_parry_data = /datum/block_parry_data/bokken/debug
|
||||
|
||||
/obj/item/melee/bokken/debug/AltClick(mob/user)
|
||||
quick_parry = !quick_parry
|
||||
if(quick_parry)
|
||||
block_parry_data = /datum/block_parry_data/bokken/quick_parry/debug
|
||||
else
|
||||
block_parry_data = /datum/block_parry_data/bokken/debug
|
||||
to_chat(user, "<span class='notice'>[src] is now [quick_parry ? "emphasizing shorter parries, forcing you to riposte or be staggered" : "emphasizing longer parries, with a shorter window to riposte but more forgiving parries"].</span>")
|
||||
|
||||
/datum/block_parry_data/bokken/debug
|
||||
parry_efficiency_perfect_override = list()
|
||||
parry_data = list(
|
||||
PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 2.5, // 7*2.5 = 17.5, 8*2.5 = 20, 9*2.5 = 22.5, 10*2.5 = 25
|
||||
PARRY_DISARM_ATTACKER = TRUE,
|
||||
PARRY_KNOCKDOWN_ATTACKER = 10,
|
||||
PARRY_STAGGER_ATTACKER = 10,
|
||||
PARRY_DAZE_ATTACKER = 10,
|
||||
)
|
||||
|
||||
/datum/block_parry_data/bokken/quick_parry/debug
|
||||
parry_efficiency_perfect_override = list()
|
||||
parry_data = list(
|
||||
PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 2.5, // 7*2.5 = 17.5, 8*2.5 = 20, 9*2.5 = 22.5, 10*2.5 = 25
|
||||
PARRY_DISARM_ATTACKER = TRUE,
|
||||
PARRY_KNOCKDOWN_ATTACKER = 10,
|
||||
PARRY_STAGGER_ATTACKER = 10,
|
||||
PARRY_DAZE_ATTACKER = 10,
|
||||
)
|
||||
|
||||
|
||||
/obj/item/wirerod
|
||||
name = "wired rod"
|
||||
desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit."
|
||||
@@ -260,6 +428,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=75)
|
||||
attack_verb = list("hit", "bludgeoned", "whacked", "bonked")
|
||||
wound_bonus = -10
|
||||
|
||||
/obj/item/wirerod/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/shard))
|
||||
@@ -297,13 +466,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
force = 2
|
||||
throwforce = 20 //This is never used on mobs since this has a 100% embed chance.
|
||||
throwforce = 10 //This is never used on mobs since this has a 100% embed chance.
|
||||
throw_speed = 4
|
||||
embedding = list("pain_mult" = 4, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
|
||||
armour_penetration = 40
|
||||
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
custom_materials = list(/datum/material/iron=500, /datum/material/glass=500)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
@@ -316,7 +485,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/throwing_star/toy
|
||||
name = "toy throwing star"
|
||||
desc = "An aerodynamic disc strapped with adhesive for sticking to people, good for playing pranks and getting yourself killed by security."
|
||||
sharpness = IS_BLUNT
|
||||
sharpness = SHARP_NONE
|
||||
force = 0
|
||||
throwforce = 0
|
||||
embedding = list("pain_mult" = 0, "jostle_pain_mult" = 0, "embed_chance" = 100, "fall_chance" = 0)
|
||||
@@ -353,7 +522,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
icon_state = extended_icon_state
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
else
|
||||
force = initial(force)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
@@ -361,7 +530,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
icon_state = retracted_icon_state
|
||||
attack_verb = list("stubbed", "poked")
|
||||
hitsound = 'sound/weapons/genhit.ogg'
|
||||
sharpness = IS_BLUNT
|
||||
sharpness = SHARP_NONE
|
||||
|
||||
/obj/item/switchblade/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -462,7 +631,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
throwforce = 0
|
||||
throw_range = 0
|
||||
throw_speed = 0
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = 'sound/weapons/chainsawhit.ogg'
|
||||
total_mass = TOTAL_MASS_HAND_REPLACEMENT
|
||||
@@ -574,6 +743,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
force = 10
|
||||
wound_bonus = -10
|
||||
throwforce = 12
|
||||
attack_verb = list("beat", "smacked")
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5)
|
||||
@@ -590,6 +760,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
obj_flags = UNIQUE_RENAME
|
||||
var/chaplain_spawnable = TRUE
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
wound_bonus = -5
|
||||
|
||||
/obj/item/melee/baseball_bat/chaplain/Initialize()
|
||||
. = ..()
|
||||
@@ -626,7 +797,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
homerun_ready = 0
|
||||
return
|
||||
else if(!target.anchored)
|
||||
target.throw_at(throw_target, rand(1,2), 7, user)
|
||||
var/whack_speed = (prob(60) ? 1 : 4)
|
||||
target.throw_at(throw_target, rand(1, 2), whack_speed, user) // sorry friends, 7 speed batting caused wounds to absolutely delete whoever you knocked your target into (and said target)
|
||||
|
||||
/obj/item/melee/baseball_bat/ablative
|
||||
name = "metal baseball bat"
|
||||
@@ -706,6 +878,92 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
item_flags = DROPDEL | ABSTRACT
|
||||
attack_verb = list("bopped")
|
||||
|
||||
/obj/item/circlegame/Initialize()
|
||||
. = ..()
|
||||
var/mob/living/owner = loc
|
||||
if(!istype(owner))
|
||||
return
|
||||
RegisterSignal(owner, COMSIG_PARENT_EXAMINE, .proc/ownerExamined)
|
||||
|
||||
/obj/item/circlegame/Destroy()
|
||||
var/mob/owner = loc
|
||||
if(istype(owner))
|
||||
UnregisterSignal(owner, COMSIG_PARENT_EXAMINE)
|
||||
return ..()
|
||||
|
||||
/obj/item/circlegame/dropped(mob/user)
|
||||
UnregisterSignal(user, COMSIG_PARENT_EXAMINE) //loc will have changed by the time this is called, so Destroy() can't catch it
|
||||
// this is a dropdel item.
|
||||
return ..()
|
||||
|
||||
/// Stage 1: The mistake is made
|
||||
/obj/item/circlegame/proc/ownerExamined(mob/living/owner, mob/living/sucker)
|
||||
if(!istype(sucker) || !in_range(owner, sucker))
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/waitASecond, owner, sucker), 4)
|
||||
|
||||
/// Stage 2: Fear sets in
|
||||
/obj/item/circlegame/proc/waitASecond(mob/living/owner, mob/living/sucker)
|
||||
if(QDELETED(sucker) || QDELETED(src) || QDELETED(owner))
|
||||
return
|
||||
|
||||
if(owner == sucker) // big mood
|
||||
to_chat(owner, "<span class='danger'>Wait a second... you just looked at your own [src.name]!</span>")
|
||||
addtimer(CALLBACK(src, .proc/selfGottem, owner), 10)
|
||||
else
|
||||
to_chat(sucker, "<span class='danger'>Wait a second... was that a-</span>")
|
||||
addtimer(CALLBACK(src, .proc/GOTTEM, owner, sucker), 6)
|
||||
|
||||
/// Stage 3A: We face our own failures
|
||||
/obj/item/circlegame/proc/selfGottem(mob/living/owner)
|
||||
if(QDELETED(src) || QDELETED(owner))
|
||||
return
|
||||
|
||||
playsound(get_turf(owner), 'sound/effects/hit_punch.ogg', 50, TRUE, -1)
|
||||
owner.visible_message("<span class='danger'>[owner] shamefully bops [owner.p_them()]self with [owner.p_their()] [src.name].</span>", "<span class='userdanger'>You shamefully bop yourself with your [src.name].</span>", \
|
||||
"<span class='hear'>You hear a dull thud!</span>")
|
||||
log_combat(owner, owner, "bopped", src.name, "(self)")
|
||||
owner.do_attack_animation(owner)
|
||||
owner.apply_damage(100, STAMINA)
|
||||
owner.Knockdown(10)
|
||||
qdel(src)
|
||||
|
||||
/// Stage 3B: We face our reckoning (unless we moved away or they're incapacitated)
|
||||
/obj/item/circlegame/proc/GOTTEM(mob/living/owner, mob/living/sucker)
|
||||
if(QDELETED(sucker))
|
||||
return
|
||||
|
||||
if(QDELETED(src) || QDELETED(owner))
|
||||
to_chat(sucker, "<span class='warning'>Nevermind... must've been your imagination...</span>")
|
||||
return
|
||||
|
||||
if(!in_range(owner, sucker) || !(owner.mobility_flags & MOBILITY_USE))
|
||||
to_chat(sucker, "<span class='notice'>Phew... you moved away before [owner] noticed you saw [owner.p_their()] [src.name]...</span>")
|
||||
return
|
||||
|
||||
to_chat(owner, "<span class='warning'>[sucker] looks down at your [src.name] before trying to avert [sucker.p_their()] eyes, but it's too late!</span>")
|
||||
to_chat(sucker, "<span class='danger'><b>[owner] sees the fear in your eyes as you try to look away from [owner.p_their()] [src.name]!</b></span>")
|
||||
|
||||
playsound(get_turf(owner), 'sound/effects/hit_punch.ogg', 50, TRUE, -1)
|
||||
owner.do_attack_animation(sucker)
|
||||
|
||||
if(HAS_TRAIT(owner, TRAIT_HULK))
|
||||
owner.visible_message("<span class='danger'>[owner] bops [sucker] with [owner.p_their()] [src.name] much harder than intended, sending [sucker.p_them()] flying!</span>", \
|
||||
"<span class='danger'>You bop [sucker] with your [src.name] much harder than intended, sending [sucker.p_them()] flying!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", ignored_mobs=list(sucker))
|
||||
to_chat(sucker, "<span class='userdanger'>[owner] bops you incredibly hard with [owner.p_their()] [src.name], sending you flying!</span>")
|
||||
sucker.apply_damage(50, STAMINA)
|
||||
sucker.Knockdown(50)
|
||||
log_combat(owner, sucker, "bopped", src.name, "(setup- Hulk)")
|
||||
var/atom/throw_target = get_edge_target_turf(sucker, owner.dir)
|
||||
sucker.throw_at(throw_target, 6, 3, owner)
|
||||
else
|
||||
owner.visible_message("<span class='danger'>[owner] bops [sucker] with [owner.p_their()] [src.name]!</span>", "<span class='danger'>You bop [sucker] with your [src.name]!</span>", \
|
||||
"<span class='hear'>You hear a dull thud!</span>", ignored_mobs=list(sucker))
|
||||
sucker.apply_damage(15, STAMINA)
|
||||
log_combat(owner, sucker, "bopped", src.name, "(setup)")
|
||||
to_chat(sucker, "<span class='userdanger'>[owner] bops you with [owner.p_their()] [src.name]!</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/slapper
|
||||
name = "slapper"
|
||||
desc = "This is how real men fight."
|
||||
@@ -772,7 +1030,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
block_chance = 40
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
attack_verb = list("cut", "sliced", "diced")
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
|
||||
Reference in New Issue
Block a user