Files
Bubberstation/code/modules/paperwork/pen.dm
LemonInTheDark ef714c1c34 Overlay Lighting Color/Intensity Pass (#81425)
## About The Pull Request

I was looking at screenshots of the game and realized we had a lot of
light sources that were really... flat.

Medium intensity, not colored at all, cringe.

So I went over all the uses of overlay styled lighting (since I've done
matrix lighting already) and gave them more unique features. Colors that
match the sprite they're used with, intensity to produce vibes, that
sort of thing.

It's kinda impossible to go one by one cause there's a LOT.

I may have gone a bit overboard with a few, I'm messing around with some
things like giving bots colors based off their department, etc. We'll
see how this all turns out.

Oh also I tweaked how the cone of overlay lighting is drawn. It seemed a
bit too present to me so I dropped the alpha down from like 200 to 120
at max (so it's roughly half of the mask's alpha so it's less
overwhelming

## Why It's Good For The Game

Lighting should be impactful, subtle and colorful

<details>
<summary>
Old Lights
</summary>


![dreamseeker_QJ5bFZxd63](https://github.com/tgstation/tgstation/assets/58055496/8ae74a95-32cb-473f-830a-ab4e1073a581)

![dreamseeker_DPVgI8wOoN](https://github.com/tgstation/tgstation/assets/58055496/149095af-a08a-4038-bf18-9e3401327452)

![dreamseeker_pyEmTAb37x](https://github.com/tgstation/tgstation/assets/58055496/6dbb6cf8-2ed7-4bc0-9d19-c64849088a33)

![dreamseeker_aDfvnea6YD](https://github.com/tgstation/tgstation/assets/58055496/4ed983e1-6be3-4513-ba3b-cecde08ccd38)

![dreamseeker_RnkQSwmxmc](https://github.com/tgstation/tgstation/assets/58055496/63e0210e-e1b1-42f0-be64-53d67c43f689)

![dreamseeker_G8NSC3lzAk](https://github.com/tgstation/tgstation/assets/58055496/93001925-904d-4061-8874-1d17bb225a90)

![dreamseeker_yASfxtbHDR](https://github.com/tgstation/tgstation/assets/58055496/ce0ae9ad-9067-44e0-9491-3ef331bbbb84)

![dreamseeker_4ecBbG5urI](https://github.com/tgstation/tgstation/assets/58055496/ce82f471-15c7-40ce-bc08-be4f5dc8a3b7)

![dreamseeker_udYlv8uAce](https://github.com/tgstation/tgstation/assets/58055496/c516a278-852b-44b8-ba7c-1203cea3f845)

![dreamseeker_bc2120Fnmr](https://github.com/tgstation/tgstation/assets/58055496/87a1429a-2329-4dd5-8c7b-ff44f54a08bb)

</details>

<details>
<summary>
New Lights
</summary>


![dreamseeker_0H11TyhGgx](https://github.com/tgstation/tgstation/assets/58055496/75b68a25-055e-488c-af82-b062dbe7413e)

![dreamseeker_2B9AENHsfl](https://github.com/tgstation/tgstation/assets/58055496/b52d441c-6ed3-495b-9ebd-9b0c9f924f30)

![dreamseeker_3vOVRRMTSP](https://github.com/tgstation/tgstation/assets/58055496/b265578f-34cc-4a0a-80ea-3237fb83df33)

![dreamseeker_5bTLup65rx](https://github.com/tgstation/tgstation/assets/58055496/6fcd3dc0-5927-458a-9f77-5582ad57a954)

![dreamseeker_iZzxZv4nfW](https://github.com/tgstation/tgstation/assets/58055496/67c3af13-2305-4130-936b-19ded08ccc4e)

![dreamseeker_Lhe9TSA0Av](https://github.com/tgstation/tgstation/assets/58055496/a5310e58-0ff1-45ac-bb81-b4a0212eb0ce)

![dreamseeker_ngQJUv0tV4](https://github.com/tgstation/tgstation/assets/58055496/c3d7423a-ab32-4401-9ffa-c4c3b7811334)

![dreamseeker_PL0z6sU7by](https://github.com/tgstation/tgstation/assets/58055496/2947d828-3aee-48c2-903f-2bf0db9077d2)

![dreamseeker_xineFZDzPA](https://github.com/tgstation/tgstation/assets/58055496/095ff8b0-51cf-4f7c-a2ee-752d9d7e87bd)

![dreamseeker_zpXxbZZakS](https://github.com/tgstation/tgstation/assets/58055496/c4200d35-a2fa-4c3f-8e88-1fd87f44cd46)

</details>

## Changelog
🆑
add: Tweaked the saturation, color and intensity of a bunch of lights
/🆑
2024-03-09 23:57:19 +00:00

589 lines
21 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/service/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 = SMALL_MATERIAL_AMOUNT*0.1)
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
var/dart_insert_icon = 'icons/obj/weapons/guns/toy.dmi'
var/dart_insert_casing_icon_state = "overlay_pen"
var/dart_insert_projectile_icon_state = "overlay_pen_proj"
/obj/item/pen/Initialize(mapload)
. = ..()
AddComponent(/datum/component/dart_insert, \
dart_insert_icon, \
dart_insert_casing_icon_state, \
dart_insert_icon, \
dart_insert_projectile_icon_state, \
CALLBACK(src, PROC_REF(get_dart_var_modifiers))\
)
RegisterSignal(src, COMSIG_DART_INSERT_ADDED, PROC_REF(on_inserted_into_dart))
RegisterSignal(src, COMSIG_DART_INSERT_REMOVED, PROC_REF(on_removed_from_dart))
/obj/item/pen/proc/on_inserted_into_dart(datum/source, obj/projectile/dart, mob/user, embedded = FALSE)
SIGNAL_HANDLER
/obj/item/pen/proc/get_dart_var_modifiers()
return list(
"damage" = max(5, throwforce),
"speed" = max(0, throw_speed - 3),
"embedding" = embedding,
"armour_penetration" = armour_penetration,
"wound_bonus" = wound_bonus,
"bare_wound_bonus" = bare_wound_bonus,
"demolition_mod" = demolition_mod,
)
/obj/item/pen/proc/on_removed_from_dart(datum/source, obj/projectile/dart, mob/user)
SIGNAL_HANDLER
/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--
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
dart_insert_casing_icon_state = "overlay_fountainpen"
dart_insert_projectile_icon_state = "overlay_fountainpen_proj"
/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 = SMALL_MATERIAL_AMOUNT*7.5)
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)
dart_insert_casing_icon_state = "overlay_fountainpen_gold"
dart_insert_projectile_icon_state = "overlay_fountainpen_gold_proj"
var/list/overlay_reskin = list(
"Oak" = "overlay_fountainpen_gold",
"Gold" = "overlay_fountainpen_gold",
"Rosewood" = "overlay_fountainpen_gold",
"Black and Silver" = "overlay_fountainpen",
"Command Blue" = "overlay_fountainpen_gold"
)
/obj/item/pen/fountain/captain/Initialize(mapload)
. = ..()
AddComponent(/datum/component/butchering, \
speed = 20 SECONDS, \
effectiveness = 115, \
)
//the pen is mightier than the sword
RegisterSignal(src, COMSIG_DART_INSERT_PARENT_RESKINNED, PROC_REF(reskin_dart_insert))
/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/fountain/captain/proc/reskin_dart_insert(datum/component/dart_insert/insert_comp)
if(!istype(insert_comp)) //You really shouldn't be sending this signal from anything other than a dart_insert component
return
insert_comp.casing_overlay_icon_state = overlay_reskin[current_skin]
insert_comp.projectile_overlay_icon_state = "[overlay_reskin[current_skin]]_proj"
/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]."))
ADD_TRAIT(O, TRAIT_WAS_RENAMED, PEN_LABEL_TRAIT)
O.update_appearance(UPDATE_ICON)
if(penchoice == "Description")
var/input = tgui_input_text(user, "Describe [O]", "Description", "[O.desc]", 280)
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."))
ADD_TRAIT(O, TRAIT_WAS_RENAMED, PEN_LABEL_TRAIT)
O.update_appearance(UPDATE_ICON)
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."))
REMOVE_TRAIT(O, TRAIT_WAS_RENAMED, PEN_LABEL_TRAIT)
O.update_appearance(UPDATE_ICON)
/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, transferred_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)
/obj/item/pen/sleepy/on_inserted_into_dart(datum/source, obj/item/ammo_casing/dart, mob/user)
. = ..()
var/obj/projectile/proj = dart.loaded_projectile
RegisterSignal(proj, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(on_dart_hit))
/obj/item/pen/sleepy/on_removed_from_dart(datum/source, obj/item/ammo_casing/dart, obj/projectile/proj, mob/user)
. = ..()
if(istype(proj))
UnregisterSignal(proj, COMSIG_PROJECTILE_SELF_ON_HIT)
/obj/item/pen/sleepy/proc/on_dart_hit(datum/source, atom/movable/firer, atom/target, angle, hit_limb, blocked)
SIGNAL_HANDLER
var/mob/living/carbon/carbon_target = target
if(!istype(carbon_target) || blocked == 100)
return
if(carbon_target.can_inject(target_zone = hit_limb))
reagents.trans_to(carbon_target, reagents.total_volume, transferred_by = firer, methods = INJECT)
/*
* (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 = OVERLAY_LIGHT
light_range = 1.5
light_power = 1.3
light_color = COLOR_SOFT_RED
light_on = FALSE
dart_insert_projectile_icon_state = "overlay_edagger"
/// 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"
/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/on_inserted_into_dart(datum/source, obj/item/ammo_casing/dart, mob/user)
. = ..()
var/datum/component/transforming/transform_comp = GetComponent(/datum/component/transforming)
if(HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE))
transform_comp.do_transform(src, user)
RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_FIRE, PROC_REF(on_containing_dart_fired))
RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_ON_SPAWN_DROP, PROC_REF(on_containing_dart_drop))
RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED, PROC_REF(on_containing_dart_embedded))
/obj/item/pen/edagger/on_removed_from_dart(datum/source, obj/item/ammo_casing/dart, obj/projectile/projectile, mob/user)
. = ..()
if(istype(dart))
UnregisterSignal(dart, list(COMSIG_ITEM_UNEMBEDDED, COMSIG_ITEM_FAILED_EMBED))
if(istype(projectile))
UnregisterSignal(projectile, list(COMSIG_PROJECTILE_FIRE, COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED))
/obj/item/pen/edagger/get_dart_var_modifiers()
. = ..()
var/datum/component/transforming/transform_comp = GetComponent(/datum/component/transforming)
.["damage"] = max(5, transform_comp.throwforce_on)
.["speed"] = max(0, transform_comp.throw_speed_on - 3)
var/list/embed_params = .["embedding"]
embed_params["embed_chance"] = 100
/obj/item/pen/edagger/proc/on_containing_dart_fired(obj/projectile/source)
SIGNAL_HANDLER
playsound(source, 'sound/weapons/saberon.ogg', 5, TRUE)
var/datum/component/transforming/transform_comp = GetComponent(/datum/component/transforming)
source.hitsound = transform_comp.hitsound_on
source.set_light(light_range, light_power, light_color, l_on = TRUE)
/obj/item/pen/edagger/proc/on_containing_dart_drop(datum/source, obj/item/ammo_casing/new_casing)
SIGNAL_HANDLER
playsound(new_casing, 'sound/weapons/saberoff.ogg', 5, TRUE)
/obj/item/pen/edagger/proc/on_containing_dart_embedded(datum/source, obj/item/ammo_casing/new_casing)
SIGNAL_HANDLER
RegisterSignal(new_casing, COMSIG_ITEM_UNEMBEDDED, PROC_REF(on_embedded_removed))
RegisterSignal(new_casing, COMSIG_ITEM_FAILED_EMBED, PROC_REF(on_containing_dart_failed_embed))
/obj/item/pen/edagger/proc/on_containing_dart_failed_embed(obj/item/ammo_casing/source)
SIGNAL_HANDLER
playsound(source, 'sound/weapons/saberoff.ogg', 5, TRUE)
UnregisterSignal(source, list(COMSIG_ITEM_UNEMBEDDED, COMSIG_ITEM_FAILED_EMBED))
/obj/item/pen/edagger/proc/on_embedded_removed(obj/item/ammo_casing/source, mob/living/carbon/victim)
SIGNAL_HANDLER
playsound(source, 'sound/weapons/saberoff.ogg', 5, TRUE)
UnregisterSignal(source, list(COMSIG_ITEM_UNEMBEDDED, COMSIG_ITEM_FAILED_EMBED))
victim.visible_message(
message = span_warning("The blade of the [hidden_name] retracts as the [source.name] is removed from [victim]!"),
self_message = span_warning("The blade of the [hidden_name] retracts as the [source.name] is removed from you!"),
blind_message = span_warning("You hear an energy blade retract!"),
vision_distance = 1
)
/obj/item/pen/edagger/suicide_act(mob/living/user)
if(HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE))
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
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()
if(user)
balloon_alert(user, "[hidden_name] [active ? "active" : "concealed"]")
playsound(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/service/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=SMALL_MATERIAL_AMOUNT*0.1, /datum/material/diamond=SMALL_MATERIAL_AMOUNT, /datum/material/titanium = SMALL_MATERIAL_AMOUNT*0.1)
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"
dart_insert_casing_icon_state = "overlay_survivalpen"
dart_insert_projectile_icon_state = "overlay_survivalpen_proj"
/obj/item/pen/survival/on_inserted_into_dart(datum/source, obj/item/ammo_casing/dart, mob/user)
. = ..()
RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(on_dart_hit))
/obj/item/pen/survival/on_removed_from_dart(datum/source, obj/item/ammo_casing/dart, obj/projectile/proj, mob/user)
. = ..()
if(istype(proj))
UnregisterSignal(proj, COMSIG_PROJECTILE_SELF_ON_HIT)
/obj/item/pen/survival/proc/on_dart_hit(obj/projectile/source, atom/movable/firer, atom/target)
var/turf/target_turf = get_turf(target)
if(!target_turf)
target_turf = get_turf(src)
if(ismineralturf(target_turf))
var/turf/closed/mineral/mineral_turf = target_turf
mineral_turf.gets_drilled(firer, TRUE)
/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
dart_insert_projectile_icon_state = "overlay_pendriver"
/obj/item/pen/screwdriver/get_all_tool_behaviours()
return list(TOOL_SCREWDRIVER)
/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/proc/toggle_screwdriver(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(user)
balloon_alert(user, active ? "extended" : "retracted")
playsound(src, 'sound/weapons/batonextend.ogg', 50, TRUE)
if(!active)
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)][HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE) ? "_out" : null]"
inhand_icon_state = initial(inhand_icon_state) //since transforming component switches the icon.
//The Security holopen
/obj/item/pen/red/security
name = "security pen"
desc = "This is a red ink pen exclusively provided to members of the Security Department. Its opposite end features a built-in holographic projector designed for issuing arrest prompts to individuals."
icon_state = "pen_sec"
COOLDOWN_DECLARE(holosign_cooldown)
/obj/item/pen/red/security/examine(mob/user)
. = ..()
. += span_notice("To initiate the surrender prompt, simply click on an individual within your proximity.")
//Code from the medical penlight
/obj/item/pen/red/security/afterattack(atom/target, mob/living/user, proximity)
. = ..()
if(!COOLDOWN_FINISHED(src, holosign_cooldown))
balloon_alert(user, "not ready!")
return
var/target_turf = get_turf(target)
var/mob/living/living_target = locate(/mob/living) in target_turf
if(!living_target || (living_target == user))
return
living_target.apply_status_effect(/datum/status_effect/surrender_timed)
to_chat(living_target, span_userdanger("[user] requests your immediate surrender! You are given 30 seconds to comply!"))
new /obj/effect/temp_visual/security_holosign(target_turf, user) //produce a holographic glow
COOLDOWN_START(src, holosign_cooldown, 30 SECONDS)
/obj/effect/temp_visual/security_holosign
name = "security holosign"
desc = "A small holographic glow that indicates you're under arrest."
icon_state = "sec_holo"
duration = 60
/obj/effect/temp_visual/security_holosign/Initialize(mapload, creator)
. = ..()
playsound(loc, 'sound/machines/chime.ogg', 50, FALSE) //make some noise!
if(creator)
visible_message(span_danger("[creator] created a security hologram!"))