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

This commit is contained in:
silicons
2020-07-29 01:11:11 -07:00
660 changed files with 13702 additions and 6807 deletions
+42 -1
View File
@@ -70,6 +70,9 @@
/// A luminescence-shifted value of the last color calculated for chatmessage overlays
var/chat_color_darkened
///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy()
var/list/targeted_by
/atom/New(loc, ...)
//atom creation method that preloads variables at creation
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
@@ -144,6 +147,11 @@
LAZYCLEARLIST(overlays)
LAZYCLEARLIST(priority_overlays)
for(var/i in targeted_by)
var/mob/M = i
LAZYREMOVE(M.do_afters, src)
targeted_by = null
QDEL_NULL(light)
return ..()
@@ -219,7 +227,7 @@
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
if(does_attack_animation)
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
log_combat(user, src, "punched", "hulk powers")
user.do_attack_animation(src, ATTACK_EFFECT_SMASH)
@@ -986,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)
@@ -58,6 +58,7 @@
if(visualsOnly)
return
H.dna.add_mutation(SMILE)
H.faction |= "clown"
/datum/outfit/syndicate/clownop/leader
name = "Clown Operative Leader - Basic"
+1 -1
View File
@@ -149,7 +149,7 @@
add_fingerprint(user)
return ..()
/obj/machinery/dominator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/dominator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(operating || (stat & BROKEN))
examine(user)
return
+5
View File
@@ -94,6 +94,11 @@
targetitem = /obj/item/documents //Any set of secret documents. Doesn't have to be NT's
difficulty = 5
/datum/objective_item/steal/blackbox
name = "the black box from the onboard blackbox recording device. Take care to wear the proper safety equipment when extracting the black box as the telecommunications array is likely to be under inhospitable conditions."
targetitem = /obj/item/blackbox //steal the forbidden ssblackbox
difficulty = 10
/datum/objective_item/steal/nuke_core
name = "the heavily radioactive plutonium core from the onboard self-destruct. Take care to wear the proper safety equipment when extracting the core!"
targetitem = /obj/item/nuke_core
+1 -1
View File
@@ -7,7 +7,7 @@
/obj/structure/door_assembly
var/datum/airlock_maker/maker = null
/obj/structure/door_assembly/attack_hand()
/obj/structure/door_assembly/on_attack_hand()
. = ..()
if(.)
return
+1 -4
View File
@@ -107,10 +107,7 @@
stat |= BROKEN
update_icon()
/obj/machinery/pdapainter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/pdapainter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!storedpda)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
+1 -1
View File
@@ -313,7 +313,7 @@ Class Procs:
if(user.a_intent != INTENT_HARM)
return attack_hand(user)
else
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
user.visible_message("<span class='danger'>[user.name] smashes against \the [src.name] with its paws.</span>", null, null, COMBAT_MESSAGE_RANGE)
take_damage(4, BRUTE, "melee", 1)
+1 -4
View File
@@ -122,10 +122,7 @@
else
icon_state = "airlock_sensor_off"
/obj/machinery/airlock_sensor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/airlock_sensor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
var/datum/signal/signal = new(list(
"tag" = master_tag,
"command" = "cycle"
+1 -4
View File
@@ -100,10 +100,7 @@
stat |= BROKEN
update_icon()
/obj/machinery/aug_manipulator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/aug_manipulator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
if(storedpart)
+1 -1
View File
@@ -138,7 +138,7 @@
var/obj/item/assembly/control/A = device
A.id = "[idnum][id]"
/obj/machinery/button/attack_hand(mob/user)
/obj/machinery/button/on_attack_hand(mob/user)
. = ..()
if(.)
return
+1 -1
View File
@@ -235,7 +235,7 @@
itemname = P.name
info = P.notehtml
to_chat(U, "<span class='notice'>You hold \the [itemname] up to the camera...</span>")
U.changeNext_move(CLICK_CD_MELEE)
U.DelayNextAction(CLICK_CD_MELEE)
for(var/mob/O in GLOB.player_list)
if(isAI(O))
var/mob/living/silicon/ai/AI = O
+1 -4
View File
@@ -79,10 +79,7 @@
charging = null
update_icon()
/obj/machinery/cell_charger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/cell_charger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!charging)
return
@@ -8,7 +8,7 @@
icon_state = "arcade"
circuit = /obj/item/circuitboard/computer/arcade/amputation
/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/computer/arcade/amputation/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!iscarbon(user))
return
var/mob/living/carbon/c_user = user
@@ -103,10 +103,7 @@
return FALSE
return ..()
/obj/machinery/computer/camera_advanced/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/computer/camera_advanced/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(current_user)
to_chat(user, "The console is already in use!")
return
+1 -1
View File
@@ -59,7 +59,7 @@
return defib.get_cell()
//defib interaction
/obj/machinery/defibrillator_mount/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/defibrillator_mount/on_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, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/dish_drive/on_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
-2
View File
@@ -70,8 +70,6 @@
if(!locked)
open_machine()
return
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='hear'>You hear a metallic creaking from [src].</span>")
+3 -4
View File
@@ -763,10 +763,7 @@
/obj/machinery/door/airlock/attack_paw(mob/user)
return attack_hand(user)
/obj/machinery/door/airlock/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/door/airlock/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!(issilicon(user) || IsAdminGhost(user)))
if(src.isElectrified())
if(src.shock(user, 100))
@@ -783,6 +780,8 @@
H.apply_damage(10, BRUTE, BODY_ZONE_HEAD)
else
visible_message("<span class='danger'>[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.</span>")
else
return ..()
/obj/machinery/door/airlock/attempt_wire_interaction(mob/user)
if(security_level)
+5 -4
View File
@@ -140,10 +140,7 @@
do_animate("deny")
return
/obj/machinery/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
return try_to_activate_door(user)
/obj/machinery/door/attack_tk(mob/user)
@@ -343,6 +340,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")
+3 -7
View File
@@ -24,6 +24,8 @@
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70)
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
air_tight = TRUE
attack_hand_is_action = TRUE
attack_hand_speed = CLICK_CD_MELEE
var/emergency_close_timer = 0
var/nextstate = null
var/boltslocked = TRUE
@@ -80,7 +82,6 @@
return TRUE
return FALSE
/obj/machinery/door/firedoor/power_change()
if(powered(power_channel))
stat &= ~NOPOWER
@@ -88,11 +89,7 @@
else
stat |= NOPOWER
/obj/machinery/door/firedoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/door/firedoor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user)
if(density)
@@ -103,7 +100,6 @@
return TRUE
if(operating || !density)
return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] bangs on \the [src].",
"You bang on \the [src].")
+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, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/firealarm/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(buildstage != 2)
return ..()
add_fingerprint(user)
-2
View File
@@ -101,8 +101,6 @@ The console is located at computer/gulag_teleporter.dm
if(!locked)
open_machine()
return
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>")
+1 -1
View File
@@ -50,7 +50,7 @@
harvesting = FALSE
warming_up = FALSE
/obj/machinery/harvester/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/harvester/on_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, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/holopad/tutorial/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!istype(user))
return
if(user.incapacitated() || !is_operational())
-2
View File
@@ -178,8 +178,6 @@
icon_state += "_occupied"
/obj/machinery/hypnochair/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(600)].)</span>", \
"<span class='hear'>You hear a metallic creaking from [src].</span>")
+1 -4
View File
@@ -26,10 +26,7 @@
on = TRUE
icon_state = "igniter1"
/obj/machinery/igniter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/igniter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
use_power(50)
+8 -7
View File
@@ -158,12 +158,7 @@
attached.transfer_blood_to(beaker, amount)
update_icon()
/obj/machinery/iv_drip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!ishuman(user))
return
/obj/machinery/iv_drip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(attached)
visible_message("[attached] is detached from [src]")
attached = null
@@ -174,7 +169,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 +188,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()
@@ -17,6 +17,7 @@
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
req_access = list(ACCESS_SEC_DOORS)
power_channel = EQUIP //drains power from the EQUIPMENT channel
speed_process = TRUE
var/base_icon_state = "standard"
var/scan_range = 7
@@ -53,7 +54,7 @@
var/last_fired = 0 //world.time the turret last fired
var/shot_delay = 15 //ticks until next shot (1.5 ?)
var/shot_stagger = 0 // sleep() shots to stagger attacks
var/check_records = 1 //checks if it can use the security records
var/criminals = 1 //checks if it can shoot people on arrest
@@ -436,6 +437,9 @@
else if(!always_up)
popDown() // no valid targets, close the cover
/obj/machinery/porta_turret/proc/randomize_shot_stagger()
shot_stagger = rand(0, min(2 SECONDS, round(shot_delay/3, world.tick_lag)))
/obj/machinery/porta_turret/proc/tryToShootAt(list/atom/movable/targets)
while(targets.len > 0)
var/atom/movable/M = pick(targets)
@@ -443,7 +447,6 @@
if(target(M))
return 1
/obj/machinery/porta_turret/proc/popUp() //pops the turret up
if(!anchored)
return
@@ -525,11 +528,14 @@
if(target)
popUp() //pop the turret up if it's not already up.
setDir(get_dir(base, target))//even if you can't shoot, follow the target
shootAt(target)
INVOKE_ASYNC(src, .proc/shootAt, target)
return 1
return
/obj/machinery/porta_turret/proc/shootAt(atom/movable/target)
/obj/machinery/porta_turret/proc/shootAt(atom/movable/target, stagger_enabled = FALSE)
if(stagger_enabled)
randomize_shot_stagger()
sleep(shot_stagger)
if(!raised) //the turret has to be raised in order to fire - makes sense, right?
return
@@ -79,6 +79,9 @@
if(PTURRET_INTERNAL_ARMOUR_ON)
if(istype(I, /obj/item/gun/energy)) //the gun installation part
var/obj/item/gun/energy/E = I
if(!E.can_turret)
to_chat(user, "<span class='warning'>[src] can't be fit into turrets.</span>")
return
if(!user.transferItemToLoc(E, src))
return
installed_gun = E
@@ -168,10 +171,7 @@
return ..()
/obj/machinery/porta_turret_construct/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/porta_turret_construct/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
switch(build_step)
if(PTURRET_GUN_EQUIPPED)
build_step = PTURRET_INTERNAL_ARMOUR_ON
@@ -31,10 +31,7 @@
return parent_turret.attack_ai(user)
/obj/machinery/porta_turret_cover/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/porta_turret_cover/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
return parent_turret.attack_hand(user)
+1 -4
View File
@@ -108,10 +108,7 @@
return ..()
/obj/machinery/recharger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/recharger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
if(charging)
-2
View File
@@ -301,8 +301,6 @@
open_machine()
dump_contents()
return
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 doors of [src]!</span>", \
"<span class='notice'>You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a thump from [src].</span>")
+1 -4
View File
@@ -68,10 +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, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/power/singularity_beacon/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(anchored)
return active ? Deactivate(user) : Activate(user)
else
@@ -5,16 +5,73 @@
require the message server.
*/
// A decorational representation of SSblackbox, usually placed alongside the message server.
// A decorational representation of SSblackbox, usually placed alongside the message server. Also contains a traitor theft item.
/obj/machinery/blackbox_recorder
icon = 'icons/obj/stationobjs.dmi'
icon_state = "blackbox"
name = "Blackbox Recorder"
name = "blackbox recorder"
density = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 100
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
var/obj/item/stored
/obj/machinery/blackbox_recorder/Initialize()
. = ..()
stored = new /obj/item/blackbox(src)
/obj/machinery/blackbox_recorder/attack_hand(mob/living/user)
. = ..()
if(stored)
to_chat(user, "<span class='notice'>You start struggling to pry the [stored] from the [src]...</span>")
if(!do_after(user, 30 SECONDS, TRUE, src))
to_chat(user, "<span class='warning'>Your fingers slip as you fail to pry the [stored] from the [src], clicking it right back into the slot!</span>")
return
if(user.put_in_hands(stored))
stored.forceMove(user.drop_location())
stored = null
to_chat(user, "<span class='warning'>You successfully pry the [stored] from the [src], and send its overwhelming weight tumbling onto the ground! The tapes on the [src] stop spinning...</span>")
update_icon()
return
else
to_chat(user, "<span class='warning'>It seems that the blackbox is missing...</span>")
return
/obj/machinery/blackbox_recorder/attackby(obj/item/I, mob/living/user, params)
. = ..()
if(istype(I, /obj/item/blackbox))
if(HAS_TRAIT(I, TRAIT_NODROP) || !user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return
user.visible_message("<span class='notice'>[user] clicks the [I] into the [src]!</span>", \
"<span class='notice'>You press [I] into [src], and it clicks into place. The tapes on the [src] begin spinning again...</span>")
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
stored = I
update_icon()
return ..()
return ..()
/obj/machinery/blackbox_recorder/Destroy()
if(stored)
stored.forceMove(loc)
new /obj/effect/decal/cleanable/oil(loc)
return ..()
/obj/machinery/blackbox_recorder/update_icon()
. = ..()
if(!stored)
icon_state = "blackbox_b"
else
icon_state = "blackbox"
/obj/item/blackbox
name = "the blackbox"
desc = "A strange relic, capable of recording data on extradimensional vertices. It lives inside the blackbox recorder for safe keeping."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "blackcube"
w_class = WEIGHT_CLASS_BULKY
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
// The message server itself.
@@ -140,9 +197,9 @@
..()
if(href_list["photo"])
var/mob/M = usr
M << browse_rsc(picture.picture_image, "pda_photo.png")
M << browse_rsc(picture.picture_image, "pda_photo.png")
var/dat = "<div style='overflow: hidden; margin :0; text-align: center'>"
dat += "<img src='pda_photo.png' width='192' style='-ms-interpolation-mode:nearest-neighbor' />"
dat += "</div>"
+1 -4
View File
@@ -297,10 +297,7 @@ GLOBAL_LIST_INIT(dye_registry, list(
else
return ..()
/obj/machinery/washing_machine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/washing_machine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(busy)
to_chat(user, "<span class='warning'>[src] is busy.</span>")
return
+3 -3
View File
@@ -10,7 +10,7 @@
var/charges = 1
var/insisting = 0
/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user)
/obj/machinery/wish_granter/on_attack_hand(mob/living/carbon/user)
if(charges <= 0)
to_chat(user, "The Wish Granter lies silent.")
return
@@ -31,7 +31,7 @@
user.dna.add_mutation(XRAY)
user.dna.add_mutation(SPACEMUT)
user.dna.add_mutation(TK)
user.next_move_modifier *= 0.5 //half the delay between attacks!
user.action_cooldown_mod *= 0.5
to_chat(user, "Things around you feel slower!")
charges--
insisting = FALSE
@@ -101,7 +101,7 @@
to_chat(user, "[killreward] materializes into your hands!")
else
to_chat(user, "[killreward] materializes onto the floor.")
user.next_move_modifier *= 0.8 //20% less delay between attacks!
user.action_cooldown_mod *= 0.8
to_chat(user, "Things around you feel slightly slower!")
var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc)
killwish.maxHealth = 1500
+2
View File
@@ -24,6 +24,8 @@
infra_luminosity = 15 //byond implementation is bugged.
force = 5
flags_1 = HEAR_1|BLOCK_FACE_ATOM_1
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
var/can_move = 0 //time of next allowed movement
var/mob/living/occupant = null
var/step_in = 10 //make a step in step_in/10 sec.
+2 -6
View File
@@ -54,11 +54,7 @@
. *= booster_damage_modifier
/obj/mecha/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code.
/obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1)
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>", null, null, COMBAT_MESSAGE_RANGE)
@@ -255,7 +251,7 @@
return
else if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
if(obj_integrity < max_integrity)
if(W.use_tool(src, user, 0, volume=50, amount=1))
if (internal_damage & MECHA_INT_TANK_BREACH)
+11 -1
View File
@@ -9,7 +9,7 @@
var/buckle_prevents_pull = FALSE
//Interaction
/atom/movable/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/atom/movable/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -145,3 +145,13 @@
var/mob/living/L = M.pulledby
L.set_pull_offsets(M, L.grab_state)
return M
/atom/movable/proc/precise_user_unbuckle_mob(mob/user)
if(!buckled_mobs)
return
else if(length(buckled_mobs) == 1)
return user_unbuckle_mob(buckled_mobs[1], user)
else
var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs
return user_unbuckle_mob(unbuckled, user)
+1 -4
View File
@@ -101,10 +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, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/structure/sign/poster/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(ruined)
return
visible_message("[user] rips [src] in a single, decisive motion!" )
@@ -137,10 +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, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/effect/decal/cleanable/vomit/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(isflyperson(H))
@@ -268,6 +268,8 @@
gender = PLURAL
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/obj/structure/foamedmetal/Initialize()
. = ..()
@@ -284,11 +286,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, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
/obj/structure/foamedmetal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
+1 -4
View File
@@ -60,10 +60,7 @@
/obj/effect/portal/attack_tk(mob/user)
return
/obj/effect/portal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/effect/portal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(get_turf(user) == get_turf(src))
teleport(user)
if(Adjacent(user))
+3 -6
View File
@@ -120,6 +120,8 @@
var/poison_type = "toxin"
var/poison_per_bite = 5
var/list/faction = list("spiders")
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/obj/structure/spider/spiderling/Destroy()
new/obj/item/reagent_containers/food/snacks/spiderling(get_turf(src))
@@ -153,10 +155,9 @@
else
..()
/obj/structure/spider/spiderling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/structure/spider/spiderling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(user.a_intent != INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
user.visible_message("<span class='warning'>[user] splats [src].</span>", "<span class='warning'>You splat [src].</span>", "<span class='italics'>You hear a splat...</span>")
playsound(loc, 'sound/effects/snap.ogg', 25)
@@ -253,8 +254,6 @@
/obj/structure/spider/cocoon/container_resist(mob/living/user)
var/breakout_time = 600
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You struggle against the tight bonds... (This will take about [DisplayTimeText(breakout_time)].)</span>")
visible_message("You see something struggling and writhing in \the [src]!")
if(do_after(user,(breakout_time), target = src))
@@ -262,8 +261,6 @@
return
qdel(src)
/obj/structure/spider/cocoon/Destroy()
var/turf/T = get_turf(src)
src.visible_message("<span class='warning'>\The [src] splits open.</span>")
+6 -13
View File
@@ -11,6 +11,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
attack_hand_speed = 0
attack_hand_is_action = FALSE
attack_hand_unwieldlyness = 0
///icon state name for inhand overlays
var/item_state = null
@@ -58,15 +62,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives.
var/stagger_force
/**
* Set FALSE and then checked at the end of on mob/living/attackby(), set TRUE on living/pre_attacked_by().
* Should it be FALSE by the end of the item/attack(), that means the item overrode the standard attack behaviour
* and the user still needs the delay applied. We can't be using return values since that'll stop afterattack() from being triggered.
*/
var/attack_delay_done = FALSE
///next_move click/attack delay of this item.
var/click_delay = CLICK_CD_MELEE
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
var/current_equipped_slot
pass_flags = PASSTABLE
@@ -313,10 +308,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, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/item/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!user)
return
if(anchored)
@@ -473,6 +465,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
usr.UnarmedAttack(src, TRUE)
if(usr.get_active_held_item() == src)
melee_attack_chain(usr, over)
usr.FlushCurrentAction()
return TRUE //returning TRUE as a "is this overridden?" flag
if(!Adjacent(usr) || !over.Adjacent(usr))
return // should stop you from dragging through windows
-2
View File
@@ -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))
+3 -3
View File
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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)
+1 -1
View File
@@ -188,4 +188,4 @@
else
..()
else
..()
..()
+2 -2
View File
@@ -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 ..()
+6 -4
View File
@@ -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>")
+1 -2
View File
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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)
@@ -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
+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."
@@ -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))
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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 ..()
+1 -4
View File
@@ -97,10 +97,7 @@ GLOBAL_LIST_EMPTY(power_sinks)
/obj/item/powersink/attack_ai()
return
/obj/item/powersink/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/item/powersink/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
switch(mode)
if(DISCONNECTED)
..()
@@ -31,8 +31,7 @@
SSradio.remove_object(src, frequency)
. = ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/electropack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/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)
@@ -162,7 +161,7 @@
materials = list(/datum/material/iron = 5000, /datum/material/glass =2000)
category = list("hacked", "Misc")
/obj/item/electropack/shockcollar/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/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
@@ -86,10 +86,7 @@
/obj/item/radio/intercom/attack_ai(mob/user)
interact(user)
/obj/item/radio/intercom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
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)
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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)
+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
@@ -54,8 +54,7 @@
mytape.ruin() //Fires destroy the tape
..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/taperecorder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/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))
@@ -79,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
+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 -1
View File
@@ -229,4 +229,4 @@
else
votes[selected_answer] += 1
voted[user.ckey] = selected_answer
. = TRUE
. = TRUE
+1
View File
@@ -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
+3 -3
View File
@@ -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)
+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()
+11 -1
View File
@@ -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)
+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, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/restraints/legcuffs/beartrap/energy/on_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()
@@ -121,8 +121,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 +189,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
+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
View File
@@ -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"
+7 -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()
. = ..()
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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)
@@ -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)
+2 -2
View File
@@ -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
+27 -13
View File
@@ -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 || 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!
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()
@@ -271,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
+22
View File
@@ -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
@@ -743,3 +754,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
+2 -3
View File
@@ -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)
+18 -2
View File
@@ -747,7 +747,7 @@
/obj/item/weapon/gripper
name = "engineering gripper"
desc = "A simple grasping tool for interacting with various engineering related items, such as circuits, gas tanks and conveyer belts. Alt click to drop instead of use."
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"
@@ -784,7 +784,7 @@
wrapped = null
return ..()
/obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/silicon/robot/user, proximity, params)
/obj/item/weapon/gripper/pre_attack(var/atom/target, var/mob/living/silicon/robot/user, proximity, params)
if(!proximity)
return
@@ -839,6 +839,19 @@
/obj/item/survivalcapsule
)
/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"
desc = "A basic variation of the plasma cutter, compressed into a cyborg chassis. Less effective than normal plasma cutters."
@@ -921,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"
@@ -241,9 +241,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)
. = ..()
+1 -4
View File
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/item/target/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(pinnedLoc)
pinnedLoc.removeTarget(user)
+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
-1
View File
@@ -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)
+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 -2
View File
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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
+133 -59
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,28 @@
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
@@ -233,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"
@@ -247,9 +273,11 @@
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)
@@ -292,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)
@@ -308,7 +336,7 @@
return
. = ..()
/obj/item/stack/medical/mesh/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/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
@@ -323,6 +351,52 @@
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."
@@ -355,4 +429,4 @@
M.heal_bodypart_damage(heal, heal)
return TRUE
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 \the [src]!</span>")
@@ -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( \
@@ -247,6 +247,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
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), \
+11 -3
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
@@ -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, act_intent = user.a_intent, unarmed_attack_flags)
/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
+15 -1
View File
@@ -7,10 +7,13 @@
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
@@ -54,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"
@@ -69,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
@@ -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,6 +504,7 @@
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/clothing/suit/straight_jacket(src)
new /obj/item/clothing/mask/muzzle(src)
+8 -5
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
@@ -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
+5 -6
View File
@@ -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
+4 -4
View File
@@ -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)
@@ -1423,4 +1423,4 @@ obj/item/storage/box/stingbangs
/obj/item/storage/box/strange_seeds_5pack/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/seeds/random(src)
new /obj/item/seeds/random(src)
+1 -1
View File
@@ -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)
////////////////////////////
+22 -2
View File
@@ -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
*/
+18 -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."
@@ -435,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,

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