Merge remote-tracking branch 'citadel/master' into shoelaces

This commit is contained in:
silicons
2020-07-23 16:23:34 -07:00
540 changed files with 11615 additions and 4656 deletions
+6 -1
View File
@@ -516,7 +516,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
used_environ += amount
/area/Entered(atom/movable/M)
/area/Entered(atom/movable/M, atom/OldLoc)
set waitfor = FALSE
SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M)
SEND_SIGNAL(M, COMSIG_ENTER_AREA, src) //The atom that enters the area
@@ -524,6 +524,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
return
var/mob/living/L = M
var/turf/oldTurf = get_turf(OldLoc)
var/area/A = oldTurf?.loc
if(A && (A.has_gravity != has_gravity))
L.update_gravity(L.mob_has_gravity())
if(!L.ckey)
return
+33
View File
@@ -994,6 +994,39 @@ Proc for attack log creation, because really why not
var/reverse_message = "has been [what_done] by [ssource][postfix]"
target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE)
/**
* log_wound() is for when someone is *attacked* and suffers a wound. Note that this only captures wounds from damage, so smites/forced wounds aren't logged, as well as demotions like cuts scabbing over
*
* Note that this has no info on the attack that dealt the wound: information about where damage came from isn't passed to the bodypart's damaged proc. When in doubt, check the attack log for attacks at that same time
* TODO later: Add logging for healed wounds, though that will require some rewriting of healing code to prevent admin heals from spamming the logs. Not high priority
*
* Arguments:
* * victim- The guy who got wounded
* * suffered_wound- The wound, already applied, that we're logging. It has to already be attached so we can get the limb from it
* * dealt_damage- How much damage is associated with the attack that dealt with this wound.
* * dealt_wound_bonus- The wound_bonus, if one was specified, of the wounding attack
* * dealt_bare_wound_bonus- The bare_wound_bonus, if one was specified *and applied*, of the wounding attack. Not shown if armor was present
* * base_roll- Base wounding ability of an attack is a random number from 1 to (dealt_damage ** WOUND_DAMAGE_EXPONENT). This is the number that was rolled in there, before mods
*/
/proc/log_wound(atom/victim, datum/wound/suffered_wound, dealt_damage, dealt_wound_bonus, dealt_bare_wound_bonus, base_roll)
if(QDELETED(victim) || !suffered_wound)
return
var/message = "has suffered: [suffered_wound][suffered_wound.limb ? " to [suffered_wound.limb.name]" : null]"// maybe indicate if it's a promote/demote?
if(dealt_damage)
message += " | Damage: [dealt_damage]"
// The base roll is useful since it can show how lucky someone got with the given attack. For example, dealing a cut
if(base_roll)
message += " (rolled [base_roll]/[dealt_damage ** WOUND_DAMAGE_EXPONENT])"
if(dealt_wound_bonus)
message += " | WB: [dealt_wound_bonus]"
if(dealt_bare_wound_bonus)
message += " | BWB: [dealt_bare_wound_bonus]"
victim.log_message(message, LOG_ATTACK, color="blue")
// Filter stuff
/atom/proc/add_filter(name,priority,list/params)
LAZYINITLIST(filter_data)
+2
View File
@@ -6,6 +6,7 @@
// To be removed on step_ conversion
// All this work to prevent a second bump
/atom/movable/Move(atom/newloc, direct=0)
set waitfor = FALSE //n o
. = FALSE
if(!newloc || newloc == loc)
return
@@ -52,6 +53,7 @@
////////////////////////////////////////
/atom/movable/Move(atom/newloc, direct)
set waitfor = FALSE //n o
var/atom/movable/pullee = pulling
var/turf/T = loc
if(!moving_from_pull)
+2
View File
@@ -543,6 +543,8 @@
/datum/game_mode/proc/get_remaining_days(client/C)
if(!C)
return 0
if(C.prefs?.db_flags & DB_FLAG_EXEMPT)
return 0
if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
return 0
if(!isnum(C.player_age))
+1 -1
View File
@@ -149,7 +149,7 @@
add_fingerprint(user)
return ..()
/obj/machinery/dominator/attack_hand(mob/user)
/obj/machinery/dominator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(operating || (stat & BROKEN))
examine(user)
return
+31
View File
@@ -845,6 +845,37 @@ GLOBAL_LIST_EMPTY(possible_items_special)
/datum/objective/destroy/internal
var/stolen = FALSE //Have we already eliminated this target?
/datum/objective/steal_five_of_type
name = "steal five of"
explanation_text = "Steal at least five items!"
var/list/wanted_items = list(/obj/item)
/datum/objective/steal_five_of_type/New()
..()
wanted_items = typecacheof(wanted_items)
/datum/objective/steal_five_of_type/summon_guns
name = "steal guns"
explanation_text = "Steal at least five guns!"
wanted_items = list(/obj/item/gun)
/datum/objective/steal_five_of_type/summon_magic
name = "steal magic"
explanation_text = "Steal at least five magical artefacts!"
wanted_items = list(/obj/item/spellbook, /obj/item/gun/magic, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/scrying, /obj/item/antag_spawner/contract, /obj/item/necromantic_stone)
/datum/objective/steal_five_of_type/check_completion()
var/list/datum/mind/owners = get_owners()
var/stolen_count = 0
for(var/datum/mind/M in owners)
if(!isliving(M.current))
continue
var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
for(var/obj/I in all_items) //Check for wanted items
if(is_type_in_typecache(I, wanted_items))
stolen_count++
return stolen_count >= 5
//Created by admin tools
/datum/objective/custom
name = "custom"
+1 -1
View File
@@ -107,7 +107,7 @@
stat |= BROKEN
update_icon()
/obj/machinery/pdapainter/attack_hand(mob/user)
/obj/machinery/pdapainter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+2 -2
View File
@@ -122,7 +122,7 @@
else
icon_state = "airlock_sensor_off"
/obj/machinery/airlock_sensor/attack_hand(mob/user)
/obj/machinery/airlock_sensor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -161,4 +161,4 @@
/obj/machinery/airlock_sensor/Destroy()
SSradio.remove_object(src,frequency)
return ..()
return ..()
+1 -1
View File
@@ -100,7 +100,7 @@
stat |= BROKEN
update_icon()
/obj/machinery/aug_manipulator/attack_hand(mob/user)
/obj/machinery/aug_manipulator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+11 -1
View File
@@ -79,7 +79,7 @@
charging = null
update_icon()
/obj/machinery/cell_charger/attack_hand(mob/user)
/obj/machinery/cell_charger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -103,8 +103,18 @@
removecell()
/obj/machinery/cell_charger/attack_ai(mob/user)
if(!charging)
return
charging.forceMove(loc)
to_chat(user, "<span class='notice'>You remotely disconnect the battery port and eject [charging] from [src].</span>")
removecell()
return
/obj/machinery/cell_charger/attack_robot(mob/user)
attack_ai(user)
/obj/machinery/cell_charger/emp_act(severity)
. = ..()
@@ -8,7 +8,7 @@
icon_state = "arcade"
circuit = /obj/item/circuitboard/computer/arcade/amputation
/obj/machinery/computer/arcade/amputation/attack_hand(mob/user)
/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!iscarbon(user))
return
var/mob/living/carbon/c_user = user
@@ -28,4 +28,4 @@
for(var/i=1; i<=rand(3,5); i++)
prizevend(user)
else
to_chat(c_user, "<span class='notice'>You (wisely) decide against putting your hand in the machine.</span>")
to_chat(c_user, "<span class='notice'>You (wisely) decide against putting your hand in the machine.</span>")
@@ -103,7 +103,7 @@
return FALSE
return ..()
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
/obj/machinery/computer/camera_advanced/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -662,7 +662,7 @@ What a mess.*/
GLOB.data_core.removeMajorCrime(active1.fields["id"], href_list["cdataid"])
if("notes")
if(istype(active2, /datum/data/record))
var/t1 = stripped_input(usr, "Please summarize notes:", "Secure. records", active2.fields["notes"], null)
var/t1 = stripped_multiline_input(usr, "Please summarize notes:", "Secure records", active2.fields["notes"], 8192)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
active2.fields["notes"] = t1
+1 -1
View File
@@ -59,7 +59,7 @@
return defib.get_cell()
//defib interaction
/obj/machinery/defibrillator_mount/attack_hand(mob/living/user)
/obj/machinery/defibrillator_mount/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!defib)
to_chat(user, "<span class='warning'>There's no defibrillator unit loaded!</span>")
return
+1 -1
View File
@@ -31,7 +31,7 @@
if(user.Adjacent(src))
. += "<span class='notice'>Alt-click it to beam its contents to any nearby disposal bins.</span>"
/obj/machinery/dish_drive/attack_hand(mob/living/user)
/obj/machinery/dish_drive/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!contents.len)
to_chat(user, "<span class='warning'>There's nothing in [src]!</span>")
return
+1 -1
View File
@@ -763,7 +763,7 @@
/obj/machinery/door/airlock/attack_paw(mob/user)
return attack_hand(user)
/obj/machinery/door/airlock/attack_hand(mob/user)
/obj/machinery/door/airlock/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+5 -1
View File
@@ -140,7 +140,7 @@
do_animate("deny")
return
/obj/machinery/door/attack_hand(mob/user)
/obj/machinery/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -343,6 +343,10 @@
/obj/machinery/door/proc/crush()
for(var/mob/living/L in get_turf(src))
L.visible_message("<span class='warning'>[src] closes on [L], crushing [L.p_them()]!</span>", "<span class='userdanger'>[src] closes on you and crushes you!</span>")
if(iscarbon(L))
var/mob/living/carbon/C = L
for(var/datum/wound/W in C.all_wounds)
W.crush(DOOR_CRUSH_DAMAGE)
if(isalien(L)) //For xenos
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans.
L.emote("roar")
+1 -1
View File
@@ -88,7 +88,7 @@
else
stat |= NOPOWER
/obj/machinery/door/firedoor/attack_hand(mob/user)
/obj/machinery/door/firedoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -141,7 +141,7 @@
if(user)
log_game("[user] reset a fire alarm at [COORD(src)]")
/obj/machinery/firealarm/attack_hand(mob/user)
/obj/machinery/firealarm/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(buildstage != 2)
return ..()
add_fingerprint(user)
+1 -1
View File
@@ -50,7 +50,7 @@
harvesting = FALSE
warming_up = FALSE
/obj/machinery/harvester/attack_hand(mob/user)
/obj/machinery/harvester/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(state_open)
close_machine()
else if(!harvesting)
+1 -1
View File
@@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(network_holopads)
new_disk.forceMove(src)
disk = new_disk
/obj/machinery/holopad/tutorial/attack_hand(mob/user)
/obj/machinery/holopad/tutorial/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!istype(user))
return
if(user.incapacitated() || !is_operational())
+1 -1
View File
@@ -26,7 +26,7 @@
on = TRUE
icon_state = "igniter1"
/obj/machinery/igniter/attack_hand(mob/user)
/obj/machinery/igniter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+8 -4
View File
@@ -158,12 +158,10 @@
attached.transfer_blood_to(beaker, amount)
update_icon()
/obj/machinery/iv_drip/attack_hand(mob/user)
/obj/machinery/iv_drip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!ishuman(user))
return
if(attached)
visible_message("[attached] is detached from [src]")
attached = null
@@ -174,7 +172,11 @@
else
toggle_mode()
/obj/machinery/iv_drip/verb/eject_beaker()
/obj/machinery/iv_drip/attack_robot(mob/user)
if(Adjacent(user))
attack_hand(user)
/obj/machinery/iv_drip/verb/eject_beaker(mob/user)
set category = "Object"
set name = "Remove IV Container"
set src in view(1)
@@ -189,6 +191,8 @@
if(usr && Adjacent(usr) && usr.can_hold_items())
if(!usr.put_in_hands(beaker))
beaker.forceMove(drop_location())
if(iscyborg(user))
beaker.forceMove(drop_location())
beaker = null
update_icon()
@@ -168,7 +168,7 @@
return ..()
/obj/machinery/porta_turret_construct/attack_hand(mob/user)
/obj/machinery/porta_turret_construct/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -31,7 +31,7 @@
return parent_turret.attack_ai(user)
/obj/machinery/porta_turret_cover/attack_hand(mob/user)
/obj/machinery/porta_turret_cover/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -108,7 +108,7 @@
return ..()
/obj/machinery/recharger/attack_hand(mob/user)
/obj/machinery/recharger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -68,7 +68,7 @@ GLOBAL_VAR_INIT(singularity_counter, 0)
/obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return
/obj/machinery/power/singularity_beacon/attack_hand(mob/user)
/obj/machinery/power/singularity_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+5 -4
View File
@@ -18,9 +18,6 @@
/obj/machinery/turnstile/CanAtmosPass(turf/T)
return TRUE
/obj/machinery/turnstile/bullet_act(obj/item/projectile/P, def_zone)
return BULLET_ACT_FORCE_PIERCE //Pass through!
/obj/machinery/turnstile/proc/allowed_access(var/mob/B)
if(B.pulledby && ismob(B.pulledby))
return allowed(B.pulledby) | allowed(B)
@@ -28,6 +25,8 @@
return allowed(B)
/obj/machinery/turnstile/CanPass(atom/movable/AM, turf/T)
if(istype(AM, /obj/item/projectile))
return TRUE
if(ismob(AM))
var/mob/B = AM
if(isliving(AM))
@@ -60,6 +59,8 @@
return FALSE
/obj/machinery/turnstile/CheckExit(atom/movable/AM as mob|obj, target)
if(istype(AM, /obj/item/projectile))
return TRUE
if(isliving(AM))
var/mob/living/M = AM
var/outdir = dir
@@ -81,4 +82,4 @@
M.last_bumped = world.time
return canexit
else
return TRUE
return TRUE
+1 -1
View File
@@ -297,7 +297,7 @@ GLOBAL_LIST_INIT(dye_registry, list(
else
return ..()
/obj/machinery/washing_machine/attack_hand(mob/user)
/obj/machinery/washing_machine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -54,7 +54,7 @@
. *= booster_damage_modifier
/obj/mecha/attack_hand(mob/living/user)
/obj/mecha/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -9,7 +9,7 @@
var/buckle_prevents_pull = FALSE
//Interaction
/atom/movable/attack_hand(mob/living/user)
/atom/movable/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -101,7 +101,7 @@
to_chat(user, "<span class='notice'>You carefully remove the poster from the wall.</span>")
roll_and_drop(user.loc)
/obj/structure/sign/poster/attack_hand(mob/user)
/obj/structure/sign/poster/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -137,7 +137,7 @@
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
beauty = -150
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user)
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -284,7 +284,7 @@
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user)
/obj/structure/foamedmetal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -60,7 +60,7 @@
/obj/effect/portal/attack_tk(mob/user)
return
/obj/effect/portal/attack_hand(mob/user)
/obj/effect/portal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -466,7 +466,7 @@
/obj/effect/spawner/lootdrop/cigars_cases/no_turf = 2,
/obj/effect/spawner/lootdrop/space_cash/no_turf = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/storage/box/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5
)
@@ -485,7 +485,7 @@
/obj/effect/spawner/lootdrop/cig_packs/no_turf = 10,
/obj/effect/spawner/lootdrop/cigars_cases/no_turf = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/storage/box/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5,
/obj/item/kitchen/knife = 5,
+2 -1
View File
@@ -69,6 +69,7 @@
if(prob(50))
to_chat(mover, "<span class='danger'>You get stuck in \the [src] for a moment.</span>")
return FALSE
return TRUE
else if(istype(mover, /obj/item/projectile))
return prob(30)
@@ -152,7 +153,7 @@
else
..()
/obj/structure/spider/spiderling/attack_hand(mob/user)
/obj/structure/spider/spiderling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(user.a_intent != INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
+2 -2
View File
@@ -313,7 +313,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
add_fingerprint(usr)
return ..()
/obj/item/attack_hand(mob/user)
/obj/item/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -1113,4 +1113,4 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
jostle_pain_mult = (!isnull(embedding["jostle_pain_mult"]) ? embedding["jostle_pain_mult"] : EMBEDDED_JOSTLE_PAIN_MULTIPLIER),\
pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\
embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD))
return TRUE
return TRUE
+7 -5
View File
@@ -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...")
+2 -2
View File
@@ -183,7 +183,7 @@
/obj/item/airlock_painter/decal/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state)
ui = new(user, src, ui_key, "DecalPainter", name, 500, 400, master_ui, state)
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)
+1 -1
View File
@@ -44,7 +44,7 @@
))
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/cardboard_cutout/attack_hand(mob/living/user)
/obj/item/cardboard_cutout/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>")
+1 -1
View File
@@ -78,7 +78,7 @@
toggle_paddles()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/defibrillator/attack_hand(mob/user)
/obj/item/defibrillator/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)
+13 -1
View File
@@ -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."
@@ -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
@@ -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/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 ..()
+1 -1
View File
@@ -97,7 +97,7 @@ GLOBAL_LIST_EMPTY(power_sinks)
/obj/item/powersink/attack_ai()
return
/obj/item/powersink/attack_hand(mob/user)
/obj/item/powersink/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -32,7 +32,7 @@
. = ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/electropack/attack_hand(mob/user)
/obj/item/electropack/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)
@@ -162,7 +162,7 @@
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/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
@@ -86,7 +86,7 @@
/obj/item/radio/intercom/attack_ai(mob/user)
interact(user)
/obj/item/radio/intercom/attack_hand(mob/user)
/obj/item/radio/intercom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -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/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)
+109 -20
View File
@@ -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"
@@ -878,3 +961,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
@@ -55,7 +55,7 @@
..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/taperecorder/attack_hand(mob/user)
/obj/item/taperecorder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(loc == user)
if(mytape)
if(!user.is_holding(src))
+3 -3
View File
@@ -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)
+2
View File
@@ -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?
+1
View File
@@ -17,6 +17,7 @@
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 = -20
var/wielded = FALSE // track wielded status on item
/obj/item/fireaxe/Initialize()
@@ -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
+1 -1
View File
@@ -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/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
Crossed(user) //honk
. = ..()
+3
View File
@@ -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
@@ -657,6 +658,8 @@
item_flags = ABSTRACT
w_class = WEIGHT_CLASS_HUGE
sharpness = IS_SHARP
wound_bonus = -20
bare_wound_bonus = 25
total_mass = TOTAL_MASS_HAND_REPLACEMENT
/obj/item/nullrod/armblade/Initialize()
+2
View File
@@ -79,6 +79,8 @@
sharpness = IS_SHARP_ACCURATE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
var/bayonet = FALSE //Can this be attached to a gun?
wound_bonus = -5
bare_wound_bonus = 10
custom_price = PRICE_NORMAL
/obj/item/kitchen/knife/Initialize()
+3 -1
View File
@@ -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
+6 -1
View File
@@ -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")
@@ -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()
. = ..()
@@ -393,6 +397,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 +626,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/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
..()
if (held_sausage)
user.put_in_hands(held_sausage)
+52 -4
View File
@@ -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"
+1 -1
View File
@@ -98,7 +98,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)
+46 -16
View File
@@ -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
View File
@@ -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>")
+1 -1
View File
@@ -31,7 +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)
/obj/item/target/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+17 -1
View File
@@ -7,11 +7,13 @@
icon_state = "large"
w_class = WEIGHT_CLASS_TINY
item_flags = DROPDEL
sharpness = TRUE
/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 = FALSE
/obj/item/shrapnel/bullet // bullets
name = "bullet"
@@ -28,7 +30,7 @@
/obj/item/projectile/bullet/shrapnel
name = "flying shrapnel shard"
damage = 9
damage = 8
range = 10
armour_penetration = -30
dismemberment = 5
@@ -36,6 +38,8 @@
ricochet_chance = 40
shrapnel_type = /obj/item/shrapnel
ricochet_incidence_leeway = 60
sharpness = TRUE
wound_bonus = 30
/obj/item/projectile/bullet/shrapnel/mega
name = "flying shrapnel hunk"
@@ -62,3 +66,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 = FALSE
/obj/item/projectile/bullet/pellet/stingball/shred
name = "shredbang pellet"
damage = 10
wound_bonus = 30
sharpness = TRUE
+2
View File
@@ -22,6 +22,8 @@
var/war_cry = "AAAAARGH!!!"
var/icon_prefix = "spearglass"
var/wielded = FALSE // track wielded status on item
wound_bonus = -25
bare_wound_bonus = 15
/obj/item/spear/Initialize()
. = ..()
+1 -1
View File
@@ -75,7 +75,7 @@
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/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user.get_inactive_held_item() == src)
if(zero_amount())
return
+1
View File
@@ -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()
+194 -58
View File
@@ -15,6 +15,16 @@
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)
. = ..()
@@ -70,8 +80,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 +106,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 +116,27 @@
/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 = 6
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)
if(limb.brute_dam > 40)
to_chat(user, "<span class='warning'>The bleeding on [user==M ? "your" : "[M]'s"] [limb.name] is from bruising, and cannot be treated with [src]!</span>")
else
to_chat(user, "<span class='warning'>There's no bleeding on [user==M ? "your" : "[M]'s"] [limb.name]</span>")
/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness())
@@ -143,9 +158,12 @@
/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 so 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"
@@ -161,49 +179,38 @@
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"
self_delay = 30
other_delay = 10
amount = 15
max_amount = 15
amount = 10
max_amount = 10
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/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 +230,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 = 10
max_amount = 10
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"
@@ -237,21 +273,41 @@
self_delay = 30
other_delay = 10
amount = 15
heal_burn = 10
max_amount = 15
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/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 +320,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 +336,7 @@
return
. = ..()
/obj/item/stack/medical/mesh/attack_hand(mob/user)
/obj/item/stack/medical/mesh/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 +350,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/brute/bone/severe/oof_ouch = new
oof_ouch.apply_wound(bone)
var/datum/wound/brute/bone/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>")
@@ -288,7 +288,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.
@@ -350,7 +350,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()
+10 -1
View File
@@ -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
@@ -390,7 +399,7 @@
. = ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/stack/attack_hand(mob/user)
/obj/item/stack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user.get_inactive_held_item() == src)
if(zero_amount())
return
+16 -1
View File
@@ -7,10 +7,14 @@
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
@@ -53,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"
@@ -68,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
+1
View File
@@ -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>")
+10 -1
View File
@@ -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"
+3 -2
View File
@@ -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
@@ -811,4 +813,3 @@
attack_verb = list("bashed", "slashes", "prods", "pokes")
fitting_swords = list(/obj/item/melee/rapier)
starting_sword = /obj/item/melee/rapier
+14
View File
@@ -398,6 +398,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
*/
+37 -1
View File
@@ -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,
+1 -1
View File
@@ -205,7 +205,7 @@
new /obj/item/paper(src)
new /obj/item/pen(src)
/obj/item/storage/secure/safe/attack_hand(mob/user)
/obj/item/storage/secure/safe/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -20,6 +20,7 @@ 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 = 5
/obj/item/storage/toolbox/greyscale
icon_state = "toolbox_default"
-1
View File
@@ -143,7 +143,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
+1 -1
View File
@@ -72,7 +72,7 @@
QDEL_NULL(noz)
return ..()
/obj/item/watertank/attack_hand(mob/user)
/obj/item/watertank/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
+2 -2
View File
@@ -574,7 +574,7 @@
else
. = ..()
/obj/item/toy/prize/attack_hand(mob/user)
/obj/item/toy/prize/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -813,7 +813,7 @@
//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/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)
+89 -1
View File
@@ -574,6 +574,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)
@@ -626,7 +627,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 +708,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."
+5
View File
@@ -10,6 +10,11 @@
var/damtype = BRUTE
var/force = 0
/// How good a given object is at causing wounds on carbons. Higher values equal better shots at creating serious wounds.
var/wound_bonus = 0
/// If this attacks a human with no wound armor on the affected body part, add this to the wound mod. Some attacks may be significantly worse at wounding if there's even a slight layer of armor to absorb some of it vs bare flesh
var/bare_wound_bonus = 0
var/datum/armor/armor
var/obj_integrity //defaults to max_integrity
var/max_integrity = 500
+1 -1
View File
@@ -28,7 +28,7 @@
queue_smooth_neighbors(src)
return ..()
/obj/structure/attack_hand(mob/user)
/obj/structure/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -249,7 +249,7 @@
/obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user)
return attack_hand(user)
/obj/structure/alien/egg/attack_hand(mob/living/user)
/obj/structure/alien/egg/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -52,7 +52,7 @@
/obj/structure/sign/barsign/attack_ai(mob/user)
return attack_hand(user)
/obj/structure/sign/barsign/attack_hand(mob/user)
/obj/structure/sign/barsign/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+1 -1
View File
@@ -311,7 +311,7 @@ LINEN BINS
/obj/structure/bedsheetbin/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/bedsheetbin/attack_hand(mob/user)
/obj/structure/bedsheetbin/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -458,7 +458,7 @@
return
container_resist(user)
/obj/structure/closet/attack_hand(mob/user)
/obj/structure/closet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -91,7 +91,7 @@
locked = TRUE
return ..()
/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user)
/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user.lying && get_dist(src, user) > 0)
return
@@ -114,4 +114,4 @@
return
..()
..()
@@ -41,7 +41,7 @@
if(manifest)
. += "manifest"
/obj/structure/closet/crate/attack_hand(mob/user)
/obj/structure/closet/crate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -8,7 +8,7 @@
delivery_icon = "deliverybox"
integrity_failure = 0 //Makes the crate break when integrity reaches 0, instead of opening and becoming an invisible sprite.
/obj/structure/closet/crate/large/attack_hand(mob/user)
/obj/structure/closet/crate/large/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
if(manifest)
tear_manifest(user)
@@ -40,4 +40,4 @@
else
to_chat(user, "<span class='warning'>You need a crowbar to pry this open!</span>")
return FALSE //Just stop. Do nothing. Don't turn into an invisible sprite. Don't open like a locker.
//The large crate has no non-attack interactions other than the crowbar, anyway.
//The large crate has no non-attack interactions other than the crowbar, anyway.
+1 -1
View File
@@ -157,7 +157,7 @@
/obj/structure/displaycase/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/displaycase/attack_hand(mob/user)
/obj/structure/displaycase/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+3 -3
View File
@@ -7,7 +7,7 @@
density = FALSE
can_buckle = 1
/obj/structure/sacrificealtar/attack_hand(mob/living/user)
/obj/structure/sacrificealtar/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -30,7 +30,7 @@
var/time_between_uses = 1800
var/last_process = 0
/obj/structure/healingfountain/attack_hand(mob/living/user)
/obj/structure/healingfountain/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -48,4 +48,4 @@
if(last_process + time_between_uses > world.time)
icon_state = "fountain"
else
icon_state = "fountain-red"
icon_state = "fountain-red"
+2 -2
View File
@@ -19,7 +19,7 @@
new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)
qdel(src)
/obj/structure/dresser/attack_hand(mob/user)
/obj/structure/dresser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(. || !ishuman(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
@@ -46,7 +46,7 @@
switch(choice)
if("Underwear")
var/new_undies = input(H, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list
if(H.underwear)
if(new_undies)
H.underwear = new_undies
H.saved_underwear = new_undies
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[new_undies]
+1 -1
View File
@@ -69,7 +69,7 @@
return ..()
/obj/structure/extinguisher_cabinet/attack_hand(mob/user)
/obj/structure/extinguisher_cabinet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
+2 -2
View File
@@ -41,7 +41,7 @@
new /obj/structure/falsewall/brass(loc)
qdel(src)
/obj/structure/falsewall/attack_hand(mob/user)
/obj/structure/falsewall/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(opening)
return
. = ..()
@@ -180,7 +180,7 @@
radiate()
return ..()
/obj/structure/falsewall/uranium/attack_hand(mob/user)
/obj/structure/falsewall/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
radiate()
. = ..()
@@ -32,7 +32,7 @@
if (LAZYLEN(buckled_mobs))
. += "Someone appears to be strapped in. You can help them unbuckle, or activate the femur breaker."
/obj/structure/femur_breaker/attack_hand(mob/user)
/obj/structure/femur_breaker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
// Currently being used
+2 -2
View File
@@ -120,7 +120,7 @@
open = TRUE
density = TRUE
/obj/structure/fence/door/attack_hand(mob/user)
/obj/structure/fence/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(can_open(user))
toggle(user)
@@ -156,4 +156,4 @@
#undef NO_HOLE
#undef MEDIUM_HOLE
#undef LARGE_HOLE
#undef MAX_HOLE_SIZE
#undef MAX_HOLE_SIZE

Some files were not shown because too many files have changed in this diff Show More