Qol and bugfix variety pack (#21367)

changes:
  - qol: "Added detailed extended examine info on mechanics to pens."
- qol: "Added detailed extended examine info on mechanics to the
psychiatrist/chaplain Mesmetron."
- qol: "Added detailed extended examine info on mechanics to
barricades."
- qol: "Added some extended examine info to (hanging) flags, crayons,
misc."
  - code_imp: "Updated dmdocs in many locations."
- bugfix: "You can no longer force-feed people crayons. However, you can
still offer a bite of crayon for them to accept or refuse, for
tradition's sake."
- bugfix: "Reading the contents of a noticeboard now makes you actually
face the noticeboard."
This commit is contained in:
Batrachophreno
2025-09-28 12:12:48 +00:00
committed by GitHub
parent f2a59a207c
commit 28a4128ab8
16 changed files with 216 additions and 53 deletions
+1 -1
View File
@@ -28,7 +28,7 @@
/obj/machinery/stasis_bed/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You can alt-click this to toggle it on or off."
. += "ALT-click this to toggle it on or off."
/obj/machinery/stasis_bed/Initialize(mapload, d, populate_components)
. = ..()
+13 -1
View File
@@ -4,7 +4,7 @@
icon = 'icons/obj/machinery/washing_machine.dmi'
icon_state = "wm_10"
density = 1
anchored = 1.0
anchored = TRUE
clicksound = /singleton/sound_category/button_sound
clickvol = 40
@@ -32,6 +32,10 @@
. += "ALT-click a washing machine to start and stop it."
. += "Washing machines can be used as part of the leather tanning process by putting scraped bare hides in them."
/obj/machinery/washing_machine/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "It [anchored ? "is" : "could be"] anchored to the floor with some <b>bolts</b>."
/obj/machinery/washing_machine/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "If you put Ian inside this machine and run it, terrible things will happen."
@@ -109,6 +113,14 @@
state = 3
else
return ..()
else if(attacking_item.iswrench())
if(anchored)
to_chat(user, SPAN_NOTICE("You lean down and unwrench \the [src]."))
anchored = FALSE
else
to_chat(user, SPAN_NOTICE("You wrench \the [src] into place."))
anchored = TRUE
return
else
if(contents.len < 5)
if (state in list(1, 3))
+24 -2
View File
@@ -69,6 +69,10 @@
colourName = "rainbow"
reagents_to_add = list(/singleton/reagent/crayon_dust/brown = 20)
/obj/item/crayon/rainbow/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on yourself to change the current primary and shade colors."
/obj/item/pen/crayon/rainbow/attack_self(mob/living/user as mob)
colour = input(user, "Please select the main colour.", "Crayon colour") as color
shadeColour = input(user, "Please select the shade colour.", "Crayon colour") as color
@@ -80,6 +84,10 @@
shadeColour = "#886422"
desc = "A crayon that is integrated into a user's finger. It can synthesize a multitude of colors."
/obj/item/crayon/augment/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on yourself to change the current primary and shade colors."
/obj/item/pen/crayon/augment/Initialize()
. = ..()
name = "integrated crayon"
@@ -141,8 +149,22 @@
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
if(H.check_has_mouth())
target_mob.visible_message(SPAN_NOTICE("[target_mob] takes a bite of their crayon and swallows it."),
SPAN_NOTICE("You take a bite of your crayon and swallow it."))
// The end of an era: no more force-feeding people crayons.
if(user != target_mob)
var/crayon_eater_response = alert(target_mob, "[user] is trying to feed you a crayon. How hungry are you?", "Hunger", "Very hungry!", "Not that hungry.")
// The ungrateful bastard doesn't want to eat any crayon.
if(crayon_eater_response == "Not that hungry.")
target_mob.visible_message(SPAN_NOTICE("[target_mob] pushes away the crayon [user] held out for them to eat."),
SPAN_NOTICE("[target_mob] doesn't want seem to eat any crayon right now."))
return TRUE
// Yum yum! This message is handled separately to make it Very Clear to observers that someone is hand-feeding someone else a crayon.
else
target_mob.visible_message(SPAN_NOTICE("[target_mob] takes a bite of the crayon held out by [user] and swallows it."),
SPAN_NOTICE("You take a bite of crayon and swallow it."))
else
target_mob.visible_message(SPAN_NOTICE("[target_mob] takes a bite of crayon and swallows it."),
SPAN_NOTICE("You take a bite of crayon and swallow it."))
target_mob.adjustNutritionLoss(-1)
reagents.trans_to_mob(target_mob, 2, CHEM_INGEST)
@@ -52,7 +52,7 @@
/obj/item/storage/box/syndie_kit/chameleon
name = "chameleon kit"
desc = "Comes with all the clothes you need to impersonate most people. Acting lessons sold seperately."
desc = "Comes with all the clothes you need to impersonate most people. Acting lessons sold seperately."
worn_overlay = "syndiesuit"
starts_with = list(
/obj/item/clothing/under/chameleon = 1,
@@ -77,7 +77,7 @@
/obj/item/storage/box/syndie_kit/clerical
name = "clerical kit"
desc = "Comes with all you need to fake paperwork. Assumes you have passed basic writing lessons."
desc = "Comes with all you need to fake paperwork or write with invisible ink. Assumes you have passed basic writing lessons."
worn_overlay = "pen"
starts_with = list(
/obj/item/stamp/chameleon = 1,
@@ -4,19 +4,25 @@
anchored = TRUE
density = TRUE
atom_flags = ATOM_FLAG_CHECKS_BORDER
/// The type of stack the barricade dropped when disassembled if any.
var/stack_type
/// The amount of stack dropped when disassembled at full health
var/stack_amount = 5
/// to specify a non-zero amount of stack to drop when destroyed
var/destroyed_stack_amount
/// Pretty tough. Changes sprites at 300 and 150
var/health = 100
/// Basic code functions
var/maxhealth = 100
var/stack_type //The type of stack the barricade dropped when disassembled if any.
var/stack_amount = 5 //The amount of stack dropped when disassembled at full health
var/destroyed_stack_amount //to specify a non-zero amount of stack to drop when destroyed
var/health = 100 //Pretty tough. Changes sprites at 300 and 150
var/maxhealth = 100 //Basic code functions
///Used for calculating some stuff related to maxhealth as it constantly changes due to e.g. barbed wire. set to 100 to avoid possible divisions by zero
/// Used for calculating some stuff related to maxhealth as it constantly changes due to e.g. barbed wire. set to 100 to avoid possible divisions by zero
var/starting_maxhealth = 100
var/force_level_absorption = 5 //How much force an item needs to even damage it at all.
/// How much force an item needs to even damage it at all.
var/force_level_absorption = 5
var/barricade_hitsound
var/barricade_type = "barricade" //"metal", "plasteel", etc.
/// "metal", "plasteel", etc.
var/barricade_type = "barricade"
var/can_change_dmg_state = TRUE
var/damage_state = BARRICADE_DMG_NONE
var/closed = FALSE
@@ -43,12 +49,15 @@
/obj/structure/barricade/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "RIGHT-click on this to rotate it (if not anchored to the floor)."
if(!is_wired)
. += "Use a length of barbed wire on this barricade to restrict enemies from climbing it and damage them on attacking it at close range."
. += "Use a length of barbed wire on this barricade to prevent enemies from climbing it and damage them on attacking it at close range."
else
. += "Wirecutters could remove the barbed wire on this, but it will take several moments."
/obj/structure/barricade/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
. += SPAN_INFO("It is recommended to stand flush to a barricade or one tile away for maximum efficiency.")
. += SPAN_INFO("It is recommended to stand flush to a barricade or one tile away for maximum effectiveness.")
if(is_wired)
. += SPAN_INFO("There is a length of barbed wire strewn across the top of this barricade, preventing it from being climbed and making it hazardous to attack at close range.")
@@ -1,6 +1,6 @@
/obj/structure/barricade/metal
name = "metal barricade"
desc = "A sturdy and easily assembled barricade made of metal plates, often used for quick fortifications. Use a blowtorch to repair."
desc = "A sturdy and easily assembled barricade made of metal plates, often used for quick fortifications."
icon_state = "metal_0"
build_amt = 4
health = 450
@@ -12,8 +12,20 @@
barricade_hitsound = 'sound/effects/metalhit.ogg'
barricade_type = "metal"
can_wire = TRUE
var/build_state = BARRICADE_BSTATE_SECURED //Look at __game.dm for barricade defines
/// Look at __game.dm for barricade defines
var/build_state = BARRICADE_BSTATE_SECURED
// Duplicated in /obj/structure/barricade/plasteel. If you change one, also change the other.
/obj/structure/barricade/metal/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Damage (up to a point) can be repaired with a welding torch."
switch(build_state)
if(BARRICADE_BSTATE_MOVABLE)
. += "The barricade is ready to have its <b>anchor bolts</b> tightened."
if(BARRICADE_BSTATE_UNSECURED)
. += "The protection panel is ready to be <b>screwed</b> into place."
// Duplicated in /obj/structure/barricade/plasteel. If you change one, also change the other.
/obj/structure/barricade/metal/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
switch(build_state)
@@ -1,6 +1,6 @@
/obj/structure/barricade/plasteel
name = "plasteel barricade"
desc = "A very sturdy barricade made out of plasteel panels, the pinnacle of strongpoints. Use a blowtorch to repair. Can be flipped down to create a path."
desc = "A very sturdy barricade made out of plasteel panels, the pinnacle of strongpoints."
icon_state = "plasteel_closed_0"
health = 800
maxhealth = 800
@@ -15,9 +15,12 @@
closed = TRUE
can_wire = TRUE
var/build_state = BARRICADE_BSTATE_SECURED //Look at __game.dm for barricade defines
var/tool_cooldown = 0 //Delay to apply tools to prevent spamming
var/busy = 0 //Standard busy check
/// Look at __game.dm for barricade defines
var/build_state = BARRICADE_BSTATE_SECURED
/// Delay to apply tools to prevent spamming
var/tool_cooldown = 0
/// Standard busy check
var/busy = 0
var/linked = 0
var/recentlyflipped = FALSE
var/hasconnectionoverlay = TRUE
@@ -35,22 +38,37 @@
overlays += image('icons/obj/barricades.dmi', icon_state = "[src.barricade_type]_connection_[get_dir(src, cade)]")
continue
/obj/structure/barricade/plasteel/handle_barrier_chance(mob/living/M)
if(!closed) // Closed = gate down for plasteel for some reason
return ..()
else
return 0
/obj/structure/barricade/plasteel/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
/obj/structure/barricade/plasteel/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this with an empty active hand to toggle it closed or open."
. += "Multiple plasteel barricades aligned in a row can be linked together by using a crowbar on adjacent ones sequentially."
// Duplicated in /obj/structure/barricade/metal. If you change one, also change the other.
/obj/structure/barricade/plasteel/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Damage (up to a point) can be repaired with a welding torch."
switch(build_state)
if(BARRICADE_BSTATE_MOVABLE)
. += "The barricade is ready to have its <b>anchor bolts</b> tightened."
if(BARRICADE_BSTATE_UNSECURED)
. += "The protection panel is ready to be <b>screwed</b> into place."
// Duplicated in /obj/structure/barricade/metal. If you change one, also change the other.
/obj/structure/barricade/plasteel/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
switch(build_state)
if(BARRICADE_BSTATE_SECURED)
. += SPAN_INFO("The protection panel is still tighly screwed in place.")
. += "The protection panel is still tighly <b>screwed</b> in place."
if(BARRICADE_BSTATE_UNSECURED)
. += SPAN_INFO("The protection panel has been removed, you can see the anchor bolts.")
. += "The protection panel has been removed, you can see the <b>anchor bolts</b>."
if(BARRICADE_BSTATE_MOVABLE)
. += SPAN_INFO("The protection panel has been removed and the anchor bolts loosened. It's ready to be taken apart.")
. += "The protection panel has been removed and the anchor bolts loosened. It's ready to be <b>pried</b> apart."
/obj/structure/barricade/plasteel/weld_cade(obj/item/W, mob/user)
busy = TRUE
@@ -15,6 +15,10 @@
can_wire = FALSE
metallic = FALSE
/obj/structure/barricade/wooden/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "A plank of wood can be used on this to repair damage."
/obj/structure/barricade/wooden/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/stack/material/wood))
var/obj/item/stack/material/wood/D = attacking_item
@@ -27,7 +31,7 @@
if(D.use(1))
update_health(-0.5*maxhealth)
update_damage_state()
visible_message(SPAN_NOTICE("[user] clumsily repairs [src]."))
visible_message(SPAN_NOTICE("[user] haphazardly repairs [src]."))
return
. = ..()
@@ -243,7 +243,7 @@
user.put_in_hands(chosen_item)
to_chat(user, SPAN_NOTICE("You take [my_plasteel[chosen_item]] from [src]."))
my_plasteel -= chosen_item
if(/obj/item/device/lightreplacer)
if(/obj/item/device/lightreplacer, /obj/item/device/lightreplacer/advanced)
if(my_lightreplacer)
user.put_in_hands(my_lightreplacer)
to_chat(user, SPAN_NOTICE("You take [my_lightreplacer] from [src]."))
+3 -2
View File
@@ -1,12 +1,13 @@
/obj/structure/coatrack
name = "coat rack"
desc = "Rack that holds coats, or hats, if you're so inclined."
desc = "Rack that holds coats, or hats, if you're so inclined. Well, exactly one coat and one hat, at least."
icon = 'icons/obj/coatrack.dmi'
icon_state = "coatrack"
layer = ABOVE_HUMAN_LAYER
var/obj/item/clothing/coat
var/obj/item/clothing/head/hat
var/list/custom_sprites = list(/obj/item/clothing/head/beret/security, /obj/item/clothing/accessory/poncho/tajarancloak) // Custom manual sprite override.
/// Custom manual sprite override.
var/list/custom_sprites = list(/obj/item/clothing/head/beret/security, /obj/item/clothing/accessory/poncho/tajarancloak)
/obj/structure/coatrack/attack_hand(mob/user as mob)
if(use_check_and_message(user))
+14 -7
View File
@@ -10,7 +10,7 @@
icon_state = "flag_boxed"
var/flag_path
///Boolean, set to `TRUE` if a flag is large (2x1)
/// Boolean, set to `TRUE` if a flag is large (2x1)
var/flag_size = FALSE
var/obj/structure/sign/flag/flag_structure
@@ -23,17 +23,17 @@
icon = 'icons/obj/structure/flags.dmi'
icon_state = "flag"
///If a big flag, the other half of the flag is referenced here
/// If a big flag, the other half of the flag is referenced here
var/obj/structure/sign/flag/linked_flag
/// For returning your flag
var/obj/item/flag/flag_item
var/obj/item/flag/flag_item //For returning your flag
///Boolean, if we've been torn down
/// Boolean, if we've been torn down
var/ripped = FALSE
///Default offset value. Used in accurately locating the turf we're standing on.
/// Default offset value. Used in accurately locating the turf we're standing on.
var/offset_constant = 32
///Boolean, set to TRUE if someone is folding the banner.
/// Boolean, set to TRUE if someone is folding the banner.
var/currently_folding = FALSE
var/ripped_outline_state = "flag_ripped"
var/flag_path
@@ -45,6 +45,13 @@
var/unmovable = FALSE
var/stand_icon = "banner_stand"
/obj/structure/sign/flag/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "With the HELP intent, use an empty hand on this to examine it."
. += "With the DISARM intent, use an empty hand on this to fold it back up."
. += "With the GRAB intent, use an empty hand on this to salute it. How patriotic!"
. += "With the HURT intent, use an empty hand on this rip it down. You will receive a prompt to confirm the action."
/obj/structure/sign/flag/Initialize(mapload, var/newdir, var/linked_flag_path, var/deploy, var/icon_file, var/item_flag_path)
. = ..()
dir = newdir
+5 -8
View File
@@ -9,7 +9,8 @@
pass_flags_self = PASSTABLE
var/state = 0
var/health = 200
var/cover = 50 //how much cover the girder provides against projectiles.
/// How much cover the girder provides against projectiles.
var/cover = 50
build_amt = 2
var/material/reinf_material
var/reinforcing = 0
@@ -30,15 +31,13 @@
state = SPAN_NOTICE("The support struts look completely intact.")
. += state
/obj/structure/girder/mechanics_hints()
. = list()
/obj/structure/girder/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
if (state == 0 && anchored)
. += SPAN_NOTICE("It could be <b>pried</b> to subtly displace it to build a fake wall.")
return .
/obj/structure/girder/assembly_hints()
. = list()
/obj/structure/girder/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
if (health < initial(health))
. += "It could be repaired with a few choice <b>welds</b>."
@@ -55,8 +54,7 @@
. += "It [anchored ? "is" : "could be"] anchored to the floor with some <b>bolts</b>."
return .
/obj/structure/girder/disassembly_hints()
. = list()
/obj/structure/girder/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
// Reinf wall deconstruction.
if (state == 2)
@@ -66,7 +64,6 @@
if (!anchored)
. += "It is held together by a couple of <b>bolts</b>; a heavy <b>cutting</b> tool might also take it apart."
/obj/structure/girder/displaced
name = "displaced girder"
icon_state = "displaced"
@@ -47,6 +47,7 @@
// level, it should be fine to let anyone mess with the board other than ghosts.
/obj/structure/noticeboard/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended)
if(is_adjacent)
user.face_atom(src)
var/dat = "<B>Noticeboard</B><BR>"
for(var/obj/item/paper/P in src)
dat += "<A href='byond://?src=[REF(src)];read=[REF(P)]'>[P.name]</A> <A href='byond://?src=[REF(src)];write=[REF(P)]'>Write</A> <A href='byond://?src=[REF(src)];remove=[REF(P)]'>Remove</A><BR>"
+8 -1
View File
@@ -1,6 +1,6 @@
/obj/item/mesmetron
name = "mesmetron pocketwatch"
desc = "An elaborate pocketwatch, with a captivating gold etching and an enchanting face. . ."
desc = "An elaborate pocketwatch, with a captivating gold etching and an enchanting face..."
icon = 'icons/obj/item/clothing/wrists/wrist.dmi'
icon_state = "pocketwatch"
item_state = "pocketwatch"
@@ -14,6 +14,13 @@
var/time_counter = 0
var/closed = FALSE
/obj/item/mesmetron/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click this to snap it open or shut."
. += "Use this on yourself (when opened) to check the date and time."
. += "Use this on someone (when opened) to attempt to hypnotize them! They will receive a prompt; if they believe in hypnosis, they will fall into a deep slumber."
. += "While you have someone hypnotized, use this on yourself to either awaken them, or to whisper a suggestion to them!"
/obj/item/mesmetron/AltClick(mob/user)
if(!closed)
icon_state = "[initial(icon_state)]_closed"
+56 -4
View File
@@ -21,7 +21,7 @@
\[br\] : Creates a linebreak.
\[center\] - \[/center\] : Centers the text.
\[h1\] - \[/h1\] : Makes the text a first level heading.
\[h2\] - \[/h2\] : Makes the text a second level headin.
\[h2\] - \[/h2\] : Makes the text a second level heading.
\[h3\] - \[/h3\] : Makes the text a third level heading.
\[b\] - \[/b\] : Makes the text bold.
\[i\] - \[/i\] : Makes the text italic.
@@ -50,8 +50,14 @@
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
var/colour = "black" // Ink colour.
var/cursive = FALSE // Done here so other pen variants can access the cursive variable.
/// Ink colour.
var/colour = "black"
/// Done here so other pen variants can access the cursive variable.
var/cursive = FALSE
/obj/item/pen/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Pens can be used on paper to write, or on a wide variety of objects, machinery, etc. to label or rename them."
/obj/item/pen/ispen()
return TRUE
@@ -97,7 +103,7 @@
colour = "green"
/obj/item/pen/invisible
desc = "An instrument for writing or drawing with ink. This one has invisible ink."
desc = "An instrument for writing or drawing with ink. This one has invisible (white) ink."
icon_state = "pen"
colour = "white"
@@ -107,6 +113,10 @@
var/selectedColor = 1
var/colors = list("black", "blue", "red", "green", "yellow")
/obj/item/pen/multi/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on yourself to change the current pen color."
/obj/item/pen/multi/attack_self(mob/user)
if(++selectedColor > 3)
selectedColor = 1
@@ -134,6 +144,10 @@
throwforce = 1 //pointy
colour = "#1c1713" //dark ashy brownish
/obj/item/pen/fountain/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on yourself to toggle between normal and cursive script."
/obj/item/pen/fountain/attack_self(var/mob/user)
playsound(loc, 'sound/items/penclick.ogg', 50, 1)
to_chat(user, SPAN_NOTICE("You snap the nib into position to write [cursive ? "normally" : "in cursive"]."))
@@ -172,6 +186,10 @@
slot_flags = SLOT_BELT
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
/obj/item/pen/reagent/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on someone to inject them with its current reagents. They'll definitely notice."
/obj/item/pen/reagent/Initialize()
. = ..()
create_reagents(30)
@@ -203,48 +221,78 @@
/*
* Parapens
*/
/obj/item/pen/reagent/paralysis
icon_state = "pen_red"
colour = "red"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
reagents_to_add = list(/singleton/reagent/toxin/dextrotoxin = 10) // ~5 minutes worth of paralysis. Measured from falling over to getting up.
/obj/item/pen/reagent/paralysis/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You recall this pen contains approximately five minutes' worth of paralyzing agents."
/obj/item/pen/reagent/purge
icon_state = "pen_green"
colour = "green"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
reagents_to_add = list(/singleton/reagent/fluvectionem = 5)
/obj/item/pen/reagent/purge/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You recall this pen contains a paralysis counteragent for removing the effect early if desired."
/obj/item/pen/reagent/healing
icon_state = "pen_green"
colour = "green"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
reagents_to_add = list(/singleton/reagent/tricordrazine = 10, /singleton/reagent/dermaline = 5, /singleton/reagent/bicaridine = 5)
/obj/item/pen/reagent/healing/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You recall this pen contains a number of healing chemicals."
/obj/item/pen/reagent/pacifier
icon_state = "pen_blue"
colour = "blue"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
reagents_to_add = list(/singleton/reagent/wulumunusha = 2, /singleton/reagent/pacifier = 15, /singleton/reagent/drugs/cryptobiolin = 10)
/obj/item/pen/reagent/pacifier/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You recall this pen contains a mixture of chemicals to pacify its victim."
/obj/item/pen/reagent/hyperzine
icon_state = "pen_yellow"
colour = "yellow"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
reagents_to_add = list(/singleton/reagent/hyperzine = 10)
/obj/item/pen/reagent/hyperzine/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You recall this pen contains hyperzine."
/obj/item/pen/reagent/poison
icon_state = "pen_red"
colour = "red"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
reagents_to_add = list(/singleton/reagent/toxin/cyanide = 1, /singleton/reagent/lexorin = 20)
/obj/item/pen/reagent/poison/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You recall this pen contains deadly poison."
/*
* Chameleon pen
*/
/obj/item/pen/chameleon
var/signature = ""
/obj/item/pen/chameleon/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use the Change Pen Colour verb to set the colour you want to use. Note that this pen can write in invisible (white) ink!"
. += "Use this on yourself to set the current signature you want to use. Perfect for forging names on otherwise foolproof signature fields."
/obj/item/pen/chameleon/attack_self(mob/user)
signature = sanitize(input("Enter new signature. Leave blank for 'Anonymous'", "New Signature", signature))
@@ -327,6 +375,10 @@
cursive = FALSE
w_class = WEIGHT_CLASS_TINY
/obj/item/pen/augment/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on yourself to change the current pen color, or to toggle between normal and cursive script."
/obj/item/pen/augment/attack_self(mob/user)
var/choice = input(user, "Would you like to change colour or writing style?", "Pen Selector") as null|anything in list("Colour", "Style")
if(!choice)