mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-29 11:02:05 +00:00
* Refactor, improve, and rename canUseTopic to be can_perform_action * updoot * https://github.com/tgstation/tgstation/pull/72876 https://github.com/tgstation/tgstation/pull/72876 --------- Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
409 lines
13 KiB
Plaintext
409 lines
13 KiB
Plaintext
/* Pens!
|
|
* Contains:
|
|
* Pens
|
|
* Sleepy Pens
|
|
* Parapens
|
|
* Edaggers
|
|
*/
|
|
|
|
|
|
/*
|
|
* Pens
|
|
*/
|
|
/obj/item/pen
|
|
desc = "It's a normal black ink pen."
|
|
name = "pen"
|
|
icon = 'icons/obj/bureaucracy.dmi'
|
|
icon_state = "pen"
|
|
inhand_icon_state = "pen"
|
|
worn_icon_state = "pen"
|
|
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS
|
|
throwforce = 0
|
|
w_class = WEIGHT_CLASS_TINY
|
|
throw_speed = 3
|
|
throw_range = 7
|
|
custom_materials = list(/datum/material/iron=10)
|
|
pressure_resistance = 2
|
|
grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1)
|
|
var/colour = "#000000" //what colour the ink is!
|
|
var/degrees = 0
|
|
var/font = PEN_FONT
|
|
var/requires_gravity = TRUE // can you use this to write in zero-g
|
|
embedding = list(embed_chance = 50)
|
|
sharpness = SHARP_POINTY
|
|
|
|
/obj/item/pen/suicide_act(mob/living/user)
|
|
user.visible_message(span_suicide("[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku..."))
|
|
return BRUTELOSS
|
|
|
|
/obj/item/pen/blue
|
|
desc = "It's a normal blue ink pen."
|
|
icon_state = "pen_blue"
|
|
colour = "#0000FF"
|
|
|
|
/obj/item/pen/red
|
|
desc = "It's a normal red ink pen."
|
|
icon_state = "pen_red"
|
|
colour = "#FF0000"
|
|
throw_speed = 4 // red ones go faster (in this case, fast enough to embed!)
|
|
|
|
/obj/item/pen/invisible
|
|
desc = "It's an invisible pen marker."
|
|
icon_state = "pen"
|
|
colour = "#FFFFFF"
|
|
|
|
/obj/item/pen/fourcolor
|
|
desc = "It's a fancy four-color ink pen, set to black."
|
|
name = "four-color pen"
|
|
icon_state = "pen_4color"
|
|
colour = "#000000"
|
|
|
|
/obj/item/pen/fourcolor/attack_self(mob/living/carbon/user)
|
|
. = ..()
|
|
var/chosen_color = "black"
|
|
switch(colour)
|
|
if("#000000")
|
|
colour = "#FF0000"
|
|
chosen_color = "red"
|
|
throw_speed++
|
|
if("#FF0000")
|
|
colour = "#00FF00"
|
|
chosen_color = "green"
|
|
throw_speed = initial(throw_speed)
|
|
if("#00FF00")
|
|
colour = "#0000FF"
|
|
chosen_color = "blue"
|
|
else
|
|
colour = "#000000"
|
|
to_chat(user, span_notice("\The [src] will now write in [chosen_color]."))
|
|
desc = "It's a fancy four-color ink pen, set to [chosen_color]."
|
|
|
|
/obj/item/pen/fountain
|
|
name = "fountain pen"
|
|
desc = "It's a common fountain pen, with a faux wood body. Rumored to work in zero gravity situations."
|
|
icon_state = "pen-fountain"
|
|
font = FOUNTAIN_PEN_FONT
|
|
requires_gravity = FALSE // fancy spess pens
|
|
|
|
/obj/item/pen/charcoal
|
|
name = "charcoal stylus"
|
|
desc = "It's just a wooden stick with some compressed ash on the end. At least it can write."
|
|
icon_state = "pen-charcoal"
|
|
colour = "#696969"
|
|
font = CHARCOAL_FONT
|
|
custom_materials = null
|
|
grind_results = list(/datum/reagent/ash = 5, /datum/reagent/cellulose = 10)
|
|
requires_gravity = FALSE // this is technically a pencil
|
|
|
|
/datum/crafting_recipe/charcoal_stylus
|
|
name = "Charcoal Stylus"
|
|
result = /obj/item/pen/charcoal
|
|
reqs = list(/obj/item/stack/sheet/mineral/wood = 1, /datum/reagent/ash = 30)
|
|
time = 3 SECONDS
|
|
category = CAT_TOOLS
|
|
|
|
/obj/item/pen/fountain/captain
|
|
name = "captain's fountain pen"
|
|
desc = "It's an expensive Oak fountain pen. The nib is quite sharp."
|
|
icon_state = "pen-fountain-o"
|
|
force = 5
|
|
throwforce = 5
|
|
throw_speed = 4
|
|
colour = "#DC143C"
|
|
custom_materials = list(/datum/material/gold = 750)
|
|
sharpness = SHARP_EDGED
|
|
resistance_flags = FIRE_PROOF
|
|
unique_reskin = list("Oak" = "pen-fountain-o",
|
|
"Gold" = "pen-fountain-g",
|
|
"Rosewood" = "pen-fountain-r",
|
|
"Black and Silver" = "pen-fountain-b",
|
|
"Command Blue" = "pen-fountain-cb"
|
|
)
|
|
embedding = list("embed_chance" = 75)
|
|
|
|
/obj/item/pen/fountain/captain/Initialize(mapload)
|
|
. = ..()
|
|
AddComponent(/datum/component/butchering, \
|
|
speed = 20 SECONDS, \
|
|
effectiveness = 115, \
|
|
)
|
|
//the pen is mightier than the sword
|
|
|
|
/obj/item/pen/fountain/captain/reskin_obj(mob/M)
|
|
..()
|
|
if(current_skin)
|
|
desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp."
|
|
|
|
/obj/item/pen/attack_self(mob/living/carbon/user)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(loc != user)
|
|
to_chat(user, span_warning("You must be holding the pen to continue!"))
|
|
return
|
|
var/deg = tgui_input_number(user, "What angle would you like to rotate the pen head to? (0-360)", "Rotate Pen Head", max_value = 360)
|
|
if(isnull(deg) || QDELETED(user) || QDELETED(src) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH) || loc != user)
|
|
return
|
|
degrees = deg
|
|
to_chat(user, span_notice("You rotate the top of the pen to [deg] degrees."))
|
|
SEND_SIGNAL(src, COMSIG_PEN_ROTATED, deg, user)
|
|
|
|
/obj/item/pen/attack(mob/living/M, mob/user, params)
|
|
if(force) // If the pen has a force value, call the normal attack procs. Used for e-daggers and captain's pen mostly.
|
|
return ..()
|
|
if(!M.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE))
|
|
return FALSE
|
|
to_chat(user, span_warning("You stab [M] with the pen."))
|
|
to_chat(M, span_danger("You feel a tiny prick!"))
|
|
log_combat(user, M, "stabbed", src)
|
|
return TRUE
|
|
|
|
/obj/item/pen/afterattack(obj/O, mob/living/user, proximity)
|
|
. = ..()
|
|
|
|
if (!proximity)
|
|
return .
|
|
|
|
. |= AFTERATTACK_PROCESSED_ITEM
|
|
|
|
//Changing name/description of items. Only works if they have the UNIQUE_RENAME object flag set
|
|
if(isobj(O) && (O.obj_flags & UNIQUE_RENAME))
|
|
var/penchoice = tgui_input_list(user, "What would you like to edit?", "Pen Setting", list("Rename", "Description", "Reset"))
|
|
if(QDELETED(O) || !user.can_perform_action(O))
|
|
return
|
|
if(penchoice == "Rename")
|
|
var/input = tgui_input_text(user, "What do you want to name [O]?", "Object Name", "[O.name]", MAX_NAME_LEN)
|
|
var/oldname = O.name
|
|
if(QDELETED(O) || !user.can_perform_action(O))
|
|
return
|
|
if(input == oldname || !input)
|
|
to_chat(user, span_notice("You changed [O] to... well... [O]."))
|
|
else
|
|
O.AddComponent(/datum/component/rename, input, O.desc)
|
|
var/datum/component/label/label = O.GetComponent(/datum/component/label)
|
|
if(label)
|
|
label.remove_label()
|
|
label.apply_label()
|
|
to_chat(user, span_notice("You have successfully renamed \the [oldname] to [O]."))
|
|
O.renamedByPlayer = TRUE
|
|
|
|
if(penchoice == "Description")
|
|
var/input = tgui_input_text(user, "Describe [O]", "Description", "[O.desc]", 140)
|
|
var/olddesc = O.desc
|
|
if(QDELETED(O) || !user.can_perform_action(O))
|
|
return
|
|
if(input == olddesc || !input)
|
|
to_chat(user, span_notice("You decide against changing [O]'s description."))
|
|
else
|
|
O.AddComponent(/datum/component/rename, O.name, input)
|
|
to_chat(user, span_notice("You have successfully changed [O]'s description."))
|
|
O.renamedByPlayer = TRUE
|
|
|
|
if(penchoice == "Reset")
|
|
if(QDELETED(O) || !user.can_perform_action(O))
|
|
return
|
|
|
|
qdel(O.GetComponent(/datum/component/rename))
|
|
|
|
//reapply any label to name
|
|
var/datum/component/label/label = O.GetComponent(/datum/component/label)
|
|
if(label)
|
|
label.remove_label()
|
|
label.apply_label()
|
|
|
|
to_chat(user, span_notice("You have successfully reset [O]'s name and description."))
|
|
O.renamedByPlayer = FALSE
|
|
|
|
/obj/item/pen/get_writing_implement_details()
|
|
return list(
|
|
interaction_mode = MODE_WRITING,
|
|
font = font,
|
|
color = colour,
|
|
use_bold = FALSE,
|
|
)
|
|
|
|
/*
|
|
* Sleepypens
|
|
*/
|
|
|
|
/obj/item/pen/sleepy/attack(mob/living/M, mob/user, params)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
if(!reagents.total_volume)
|
|
return
|
|
if(!M.reagents)
|
|
return
|
|
reagents.trans_to(M, reagents.total_volume, transfered_by = user, methods = INJECT)
|
|
|
|
|
|
/obj/item/pen/sleepy/Initialize(mapload)
|
|
. = ..()
|
|
create_reagents(45, OPENCONTAINER)
|
|
reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 20)
|
|
reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 15)
|
|
reagents.add_reagent(/datum/reagent/toxin/staminatoxin, 10)
|
|
|
|
/*
|
|
* (Alan) Edaggers
|
|
*/
|
|
/obj/item/pen/edagger
|
|
attack_verb_continuous = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") //these won't show up if the pen is off
|
|
attack_verb_simple = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")
|
|
sharpness = SHARP_POINTY
|
|
armour_penetration = 20
|
|
bare_wound_bonus = 10
|
|
item_flags = NO_BLOOD_ON_ITEM
|
|
light_system = MOVABLE_LIGHT
|
|
light_range = 1.5
|
|
light_power = 0.75
|
|
light_color = COLOR_SOFT_RED
|
|
light_on = FALSE
|
|
/// The real name of our item when extended.
|
|
var/hidden_name = "energy dagger"
|
|
/// The real desc of our item when extended.
|
|
var/hidden_desc = "It's a normal black ink pe- Wait. That's a thing used to stab people!"
|
|
/// The real icons used when extended.
|
|
var/hidden_icon = "edagger"
|
|
/// Whether or pen is extended
|
|
var/extended = FALSE
|
|
|
|
/obj/item/pen/edagger/Initialize(mapload)
|
|
. = ..()
|
|
AddComponent(/datum/component/butchering, \
|
|
speed = 6 SECONDS, \
|
|
butcher_sound = 'sound/weapons/blade1.ogg', \
|
|
)
|
|
AddComponent(/datum/component/transforming, \
|
|
force_on = 18, \
|
|
throwforce_on = 35, \
|
|
throw_speed_on = 4, \
|
|
sharpness_on = SHARP_EDGED, \
|
|
w_class_on = WEIGHT_CLASS_NORMAL, \
|
|
inhand_icon_change = FALSE, \
|
|
)
|
|
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))
|
|
RegisterSignal(src, COMSIG_DETECTIVE_SCANNED, PROC_REF(on_scan))
|
|
|
|
/obj/item/pen/edagger/suicide_act(mob/living/user)
|
|
if(extended)
|
|
user.visible_message(span_suicide("[user] forcefully rams the pen into their mouth!"))
|
|
else
|
|
user.visible_message(span_suicide("[user] is holding a pen up to their mouth! It looks like [user.p_theyre()] trying to commit suicide!"))
|
|
attack_self(user)
|
|
return BRUTELOSS
|
|
|
|
/*
|
|
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
|
|
*
|
|
* Handles swapping their icon files to edagger related icon files -
|
|
* as they're supposed to look like a normal pen.
|
|
*/
|
|
/obj/item/pen/edagger/proc/on_transform(obj/item/source, mob/user, active)
|
|
SIGNAL_HANDLER
|
|
|
|
extended = active
|
|
if(active)
|
|
name = hidden_name
|
|
desc = hidden_desc
|
|
icon_state = hidden_icon
|
|
inhand_icon_state = hidden_icon
|
|
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
|
embedding = list(embed_chance = 100) // Rule of cool
|
|
else
|
|
name = initial(name)
|
|
desc = initial(desc)
|
|
icon_state = initial(icon_state)
|
|
inhand_icon_state = initial(inhand_icon_state)
|
|
lefthand_file = initial(lefthand_file)
|
|
righthand_file = initial(righthand_file)
|
|
embedding = list(embed_chance = EMBED_CHANCE)
|
|
|
|
updateEmbedding()
|
|
balloon_alert(user, "[hidden_name] [active ? "active":"concealed"]")
|
|
playsound(user ? user : src, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 5, TRUE)
|
|
set_light_on(active)
|
|
return COMPONENT_NO_DEFAULT_MESSAGE
|
|
|
|
/obj/item/pen/edagger/proc/on_scan(datum/source, mob/user, list/extra_data)
|
|
SIGNAL_HANDLER
|
|
LAZYADD(extra_data[DETSCAN_CATEGORY_ILLEGAL], "Hard-light generator detected.")
|
|
|
|
/obj/item/pen/survival
|
|
name = "survival pen"
|
|
desc = "The latest in portable survival technology, this pen was designed as a miniature diamond pickaxe. Watchers find them very desirable for their diamond exterior."
|
|
icon = 'icons/obj/bureaucracy.dmi'
|
|
icon_state = "digging_pen"
|
|
inhand_icon_state = "pen"
|
|
worn_icon_state = "pen"
|
|
force = 3
|
|
w_class = WEIGHT_CLASS_TINY
|
|
custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10)
|
|
pressure_resistance = 2
|
|
grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1)
|
|
tool_behaviour = TOOL_MINING //For the classic "digging out of prison with a spoon but you're in space so this analogy doesn't work" situation.
|
|
toolspeed = 10 //You will never willingly choose to use one of these over a shovel.
|
|
font = FOUNTAIN_PEN_FONT
|
|
colour = "#0000FF"
|
|
|
|
/obj/item/pen/destroyer
|
|
name = "Fine Tipped Pen"
|
|
desc = "A pen with an infinitly sharpened tip. Capable of striking the weakest point of a strucutre or robot and annihilating it instantly. Good at putting holes in people too."
|
|
force = 5
|
|
wound_bonus = 100
|
|
demolition_mod = 9000
|
|
|
|
// screwdriver pen!
|
|
|
|
/obj/item/pen/screwdriver
|
|
desc = "A pen with an extendable screwdriver tip. This one has a yellow cap."
|
|
icon_state = "pendriver"
|
|
toolspeed = 1.2 // gotta have some downside
|
|
/// whether the pen is extended
|
|
var/extended = FALSE
|
|
|
|
/obj/item/pen/screwdriver/Initialize(mapload)
|
|
. = ..()
|
|
AddComponent(/datum/component/transforming, \
|
|
throwforce_on = 5, \
|
|
w_class_on = WEIGHT_CLASS_SMALL, \
|
|
sharpness_on = TRUE, \
|
|
inhand_icon_change = FALSE, \
|
|
)
|
|
|
|
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(toggle_screwdriver))
|
|
AddElement(/datum/element/update_icon_updates_onmob)
|
|
|
|
|
|
/obj/item/pen/screwdriver/vv_edit_var(var_name, var_value)
|
|
if(var_name == NAMEOF(src, extended))
|
|
if(var_value != extended)
|
|
var/datum/component/transforming/transforming_comp = GetComponent(/datum/component/transforming)
|
|
transforming_comp.on_attack_self(src)
|
|
datum_flags |= DF_VAR_EDITED
|
|
return
|
|
return ..()
|
|
|
|
/obj/item/pen/screwdriver/proc/toggle_screwdriver(obj/item/source, mob/user, active)
|
|
SIGNAL_HANDLER
|
|
extended = active
|
|
if(user)
|
|
balloon_alert(user, "[extended ? "extended" : "retracted"]")
|
|
playsound(src, 'sound/weapons/batonextend.ogg', 50, TRUE)
|
|
|
|
if(!extended)
|
|
tool_behaviour = initial(tool_behaviour)
|
|
RemoveElement(/datum/element/eyestab)
|
|
else
|
|
tool_behaviour = TOOL_SCREWDRIVER
|
|
AddElement(/datum/element/eyestab)
|
|
|
|
update_appearance(UPDATE_ICON)
|
|
return COMPONENT_NO_DEFAULT_MESSAGE
|
|
|
|
/obj/item/pen/screwdriver/update_icon_state()
|
|
. = ..()
|
|
icon_state = "[initial(icon_state)][extended ? "_out":null]"
|
|
inhand_icon_state = initial(inhand_icon_state) //since transforming component switches the icon.
|