Enhances the Smoking Experience - Adds Many New Item Interactions for Cigarettes and Items Interacting With Them (#25571)

* Refactoring and other stuff.

* moar

* More smoking

* Update energy_melee_weapons.dm

* Update code/game/objects/items/robot/cyborg_gripper.dm

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Update cigs.dm

* Update cigs.dm

* Update cigs.dm

* Update code/game/objects/items/weapons/lighters.dm

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* eee

* Apply suggestions from code review

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* sigh

* Update cigs.dm

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* hell

* Update cigs.dm

* aa

* cool

* Fixing some minor typos for cyborg upgrade flavour text

Throws in some missing apostrophes, capitalisation, and the letter "s."

* Briefcase Full of Cash buff

Increases the amount of cash in the Syndicate Briefcase Full of Cash from 600 Cr to 1000 Cr

* Reverts double-feature PR

* Reverts a broken revert

* Reverting again because Ebba told me to

* And reverting yet again

* Update robot_upgrades.dm

* aa

* aaa

* suffering

* Soon

* Is it done!? Am I finally free!?

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Update

* Update

* No longer assume the cig is in a mouth

* Update tools.dm

* Update pronouns.dm

* Fixing some minor typos for cyborg upgrade flavour text

Throws in some missing apostrophes, capitalisation, and the letter "s."

* Briefcase Full of Cash buff

Increases the amount of cash in the Syndicate Briefcase Full of Cash from 600 Cr to 1000 Cr

* Reverts double-feature PR

* Reverts a broken revert

* Reverting again because Ebba told me to

* And reverting yet again

* Update robot_upgrades.dm

* Fixing some minor typos for cyborg upgrade flavour text

Throws in some missing apostrophes, capitalisation, and the letter "s."

* Briefcase Full of Cash buff

Increases the amount of cash in the Syndicate Briefcase Full of Cash from 600 Cr to 1000 Cr

* Reverts double-feature PR

* Reverts a broken revert

* Reverting again because Ebba told me to

* And reverting yet again

* Update robot_upgrades.dm

* update

* Attack animations for sword lighting!

* Update

* indentation

* Update cigs.dm

* minor refactor

* Update items.dm

* Update items.dm

* Update welder.dm

* Update energy_melee_weapons.dm

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* refactor

* Update items.dm

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Fixing some minor typos for cyborg upgrade flavour text

Throws in some missing apostrophes, capitalisation, and the letter "s."

* Briefcase Full of Cash buff

Increases the amount of cash in the Syndicate Briefcase Full of Cash from 600 Cr to 1000 Cr

* Reverts double-feature PR

* Reverts a broken revert

* Reverting again because Ebba told me to

* And reverting yet again

* Update robot_upgrades.dm

* Update flamethrower.dm

* clipping

* Update legion_loot.dm

* anti attack check

* Fixes a zippo runtime

* Fixes evil runtime and stops unnecessary violence.

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Update based on review

* Update cigs.dm

* Update energy_melee_weapons.dm

* Apply suggestions from code review

Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

* Update toys.dm

* Update energy_melee_weapons.dm

* Update legion_loot.dm

* Update code/game/objects/items/weapons/melee/energy_melee_weapons.dm

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>

---------

Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com>
Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>
Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
CRUNCH
2024-09-03 14:02:13 +01:00
committed by GitHub
parent c7340b09b5
commit 9ef47e7935
18 changed files with 929 additions and 389 deletions
+33
View File
@@ -994,3 +994,36 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
/obj/item/proc/should_stack_with(obj/item/other)
return type == other.type && name == other.name
/**
* Handles the bulk of cigarette lighting interactions. You must call `light()` to actually light the cigarette.
*
* Returns: the target's cigarette (or the cigarette itself if attacked directly) if all checks are passed.
* If the cigarette is already lit, or is a fancy smokable being lit by anything other than a zippo or match, will return `FALSE`.
* Otherwise it will return `null`.
* Arguments:
* * user - The mob trying to light the cigarette.
* * target - The mob with the cigarette.
* * direct_attackby_item - Used if the cigarette item is clicked on directly with a lighter instead of a mob wearing a cigarette.
*/
/obj/item/proc/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
if(!user || !target)
return null
var/obj/item/clothing/mask/cigarette/cig = direct_attackby_item ? direct_attackby_item : target.wear_mask
if(!istype(cig))
return null
if(user.zone_selected != "mouth" || !user.a_intent == INTENT_HELP)
return null
if(cig.lit)
to_chat(user, "<span class='warning'>[cig] is already lit!</span>")
return FALSE
// Only matches and cigars can light fancy smokables.
if(cig.fancy && !istype(src, /obj/item/match) && !istype(src, /obj/item/lighter/zippo))
to_chat(user, "<span class='danger'>[cig] straight out REFUSES to be lit by such uncivilized means!</span>")
return FALSE
return cig
@@ -324,7 +324,8 @@
/obj/item/coin,
/obj/item/paper,
/obj/item/photo,
/obj/item/toy/plushie
/obj/item/toy/plushie,
/obj/item/clothing/mask/cigarette
)
// Mining Gripper
+22 -10
View File
@@ -153,19 +153,31 @@
return
remove_fuel(0.5)
/obj/item/weldingtool/attack(mob/living/carbon/M, mob/living/carbon/user)
// For lighting other people's cigarettes.
var/obj/item/clothing/mask/cigarette/cig = M?.wear_mask
if(!istype(cig) || user.zone_selected != "mouth" || !tool_enabled)
/obj/item/weldingtool/attack(mob/living/target, mob/living/user)
if(!cigarette_lighter_act(user, target))
return ..()
if(M == user)
cig.attackby(src, user)
return
/obj/item/weldingtool/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
cig.light("<span class='notice'>[user] holds out [src] out for [M], and casually lights [cig]. What a badass.</span>")
playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE)
M.update_inv_wear_mask()
if(!tool_enabled)
to_chat(user, "<span class='warning'>You need to activate [src] before you can light anything with it!</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='notice'>[user] casually lights [cig] with [src], what a badass.</span>",
"<span class='notice'>You light [cig] with [src].</span>"
)
else
user.visible_message(
"<span class='notice'>[user] holds out [src] out for [target], and casually lights [cig]. What a badass.</span>",
"<span class='notice'>You light [cig] for [target] with [src].</span>"
)
cig.light(user, target)
return TRUE
/obj/item/weldingtool/use_tool(atom/target, user, delay, amount, volume, datum/callback/extra_checks)
target.add_overlay(GLOB.welding_sparks)
+61 -4
View File
@@ -211,7 +211,7 @@
..()
if(istype(W, /obj/item/toy/sword))
if(W == src)
to_chat(user, "<span class='notice'>You try to attach the end of the plastic sword to... itself. You're not very smart, are you?</span>")
to_chat(user, "<span class='notice'>You try to attach the end of the plastic sword to... Itself. You're not very smart, are you?</span>")
if(ishuman(user))
user.adjustBrainLoss(10)
else if((W.flags & NODROP) || (flags & NODROP))
@@ -229,10 +229,64 @@
/// Sets to TRUE once the character using it hits something and realises it's not a real energy sword
var/pranked = FALSE
/obj/item/toy/sword/attack(mob/target, mob/living/user)
if(!cigarette_lighter_act(user, target))
return ..()
/obj/item/toy/sword/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
if(!active)
to_chat(user, "<span class='warning'>You must activate [src] before you can light [cig] with it!</span>")
return TRUE
user.do_attack_animation(target)
// 1% chance to light the cig. Somehow...
if(prob(1))
if(target == user)
user.visible_message(
"<span class='warning'>[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes! \
[user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [cig] with [src] in the process. Somehow...</span>",
"<span class='notice'>You casually slash [src] at [cig], lighting it with the blade. Somehow...</span>",
"<span class='danger'>You hear an energy blade slashing something!</span>"
)
else
user.visible_message(
"<span class='danger'>[user] makes a violent slashing motion, barely missing the nose of [target] as light flashes! \
[user.p_they(TRUE)] light[user.p_s()] [cig] in the mouth of [target] with [src] in the process. Somehow...</span>",
"<span class='notice'>You casually slash [src] at [cig] in the mouth of [target], lighting it with the blade. Somehow...</span>",
"<span class='danger'>You hear an energy blade slashing something!</span>"
)
playsound(user.loc, 'sound/weapons/blade1.ogg', 50, TRUE)
cig.light(user, target)
return TRUE
// Else, bat it out of the target's mouth.
if(target == user)
user.visible_message(
"<span class='warning'>[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes! \
[user.p_they(TRUE)] instead hit [cig], knocking it out of [user.p_their()] mouth and dropping it to the floor.</span>",
"<span class='warning'>You casually slash [src] at [cig], swatting it out of your mouth.</span>",
"<span class='notice'>You hear a gentle tapping.</span>"
)
else
user.visible_message(
"<span class='warning'>[user] makes a violent slashing motion, barely missing the nose of [target] as light flashes! \
[user] does hit [cig], knocking it out of the mouth of [target] and dropping it to the floor. Wow, rude!</span>",
"<span class='warning'>You casually slash [src] at [cig] in the mouth of [target], swatting it to the floor!</span>",
"<span class='notice'>You hear a gentle tapping.</span>"
)
playsound(loc, 'sound/weapons/tap.ogg', vary = TRUE)
target.unEquip(cig, TRUE)
return TRUE
/obj/item/toy/sword/chaosprank/afterattack(mob/living/target, mob/living/user, proximity)
..()
if(!pranked)
to_chat(user, "<span class='chaosverybad'>Oh... it's a fake.</span>")
to_chat(user, "<span class='chaosverybad'>Oh... It's a fake.</span>")
name = "toy sword"
pranked = TRUE
@@ -241,7 +295,7 @@
*/
/obj/item/dualsaber/toy
name = "double-bladed toy sword"
desc = "A cheap, plastic replica of TWO energy swords. Double the fun!"
desc = "A cheap, plastic replica of TWO energy swords. Double the fun!"
force = 0
throwforce = 0
throw_speed = 3
@@ -280,7 +334,10 @@
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/toy/katana/suicide_act(mob/user)
var/dmsg = pick("[user] tries to stab \the [src] into [user.p_their()] abdomen, but it shatters! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.","[user] tries to stab \the [src] into [user.p_their()] abdomen, but \the [src] bends and breaks in half! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.","[user] tries to slice [user.p_their()] own throat, but the plastic blade has no sharpness, causing [user.p_them()] to lose [user.p_their()] balance, slip over, and break [user.p_their()] neck with a loud snap!")
var/dmsg = pick(
"[user] tries to stab [src] into [user.p_their()] abdomen, but it shatters! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.",
"[user] tries to stab [src] into [user.p_their()] abdomen, but [src] bends and breaks in half! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.",
"[user] tries to slice [user.p_their()] own throat, but the plastic blade has no sharpness, causing [user.p_them()] to lose [user.p_their()] balance, slip over, and break [user.p_their()] neck with a loud snap!")
user.visible_message("<span class='suicide'>[dmsg] It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
+248 -245
View File
@@ -1,11 +1,12 @@
#define REAGENT_TIME_RATIO 2.5
/*
CONTAINS:
CIGARETTES
CIGARS
SMOKING PIPES
HOLO-CIGAR
CONTENTS:
1. CIGARETTES
2. CIGARS
3. HOLO-CIGAR
4. PIPES
5. ROLLING
CIGARETTE PACKETS ARE IN FANCY.DM
LIGHTERS ARE IN LIGHTERS.DM
@@ -19,22 +20,31 @@ LIGHTERS ARE IN LIGHTERS.DM
name = "cigarette"
desc = "A roll of tobacco and nicotine."
icon_state = "cigoff"
throw_speed = 0.5
item_state = "cigoff"
throw_speed = 0.5
slot_flags = SLOT_FLAG_MASK
w_class = WEIGHT_CLASS_TINY
body_parts_covered = null
attack_verb = null
container_type = INJECTABLE
/// Is the cigarette lit?
var/lit = FALSE
/// Lit cigarette sprite.
var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi
/// Unlit cigarette sprite.
var/icon_off = "cigoff"
/// Are we an extra-classy smokable?
var/fancy = FALSE
/// What trash item the cigarette makes when it burns out.
var/type_butt = /obj/item/cigbutt
var/lastHolder = null
var/smoketime = 150
/// How long does the cigarette last before going out? Decrements by 1 every cycle.
var/smoketime = 150 // 300 seconds.
/// The cigarette's total reagent capacity.
var/chem_volume = 60
/// A list of the types and amounts of reagents in the cigarette.
var/list/list_reagents = list("nicotine" = 40)
var/first_puff = TRUE // the first puff is a bit more reagents ingested
/// Has anyone taken any reagents from the cigarette? The first tick gives a bigger dose.
var/first_puff = TRUE
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
"Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
@@ -42,14 +52,6 @@ LIGHTERS ARE IN LIGHTERS.DM
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi',
"Grey" = 'icons/mob/clothing/species/grey/mask.dmi')
var/static/things_that_light = typecacheof(list(
/obj/item/lighter,
/obj/item/match,
/obj/item/melee/energy/sword/saber,
/obj/item/assembly/igniter,
/obj/item/gun/magic/wand/fireball))
/obj/item/clothing/mask/cigarette/Initialize(mapload)
. = ..()
create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 30
@@ -57,19 +59,12 @@ LIGHTERS ARE IN LIGHTERS.DM
if(list_reagents)
reagents.add_reagent_list(list_reagents)
smoketime = reagents.total_volume * 2.5
RegisterSignal(src, COMSIG_ITEM_BEING_ATTACKED, PROC_REF(try_light))
/obj/item/clothing/mask/cigarette/Destroy()
QDEL_NULL(reagents)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clothing/mask/cigarette/proc/try_light(obj/item/cigarette, obj/item/lighting_item)
SIGNAL_HANDLER
if(lighting_item.get_heat())
light()
return COMPONENT_CANCEL_ATTACK_CHAIN
/obj/item/clothing/mask/cigarette/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(isdrone(user))
C.stored_comms["wood"] += 1
@@ -81,17 +76,74 @@ LIGHTERS ARE IN LIGHTERS.DM
if(istype(M) && M.on_fire)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(M)
light("<span class='notice'>[user] coldly lights [src] with the burning body of [M]. Clearly, [user.p_they()] offer[user.p_s()] the warmest of regards...</span>")
if(M != user)
user.visible_message(
"<span class='notice'>[user] coldly lights [src] with the burning body of [M]. Clearly, [user.p_they()] offer[user.p_s()] the warmest of regards...</span>",
"<span class='notice'>You coldly light [src] with the burning body of [M].</span>"
)
else
// The fire will light it in your hands by itself, but if you whip out the cig and click yourself fast enough, this will happen. TRULY you have your priorities stright.
user.visible_message(
"<span class='notice'>[user] quickly whips out [src] and nonchalantly lights it with [user.p_their()] own burning body. Clearly, [user.p_they()] [user.p_have()] [user.p_their()] priorities straight.</span>",
"<span class='notice'>You quickly whip out [src] and nonchalantly light it with your own burning body. Clearly, you have your priorities straight.</span>"
)
light(user, user)
return TRUE
else
return ..()
/obj/item/clothing/mask/cigarette/afterattack(atom/target, mob/living/user, proximity)
if(!proximity)
return
if(ismob(target))
// If the target has no cig, try to give them the cig.
var/mob/living/carbon/M = target
if(istype(M) && user.zone_selected == "mouth" && !M.wear_mask && user.a_intent == INTENT_HELP)
user.unEquip(src, TRUE)
M.equip_to_slot_if_possible(src, SLOT_HUD_WEAR_MASK)
if(target != user)
user.visible_message(
"<span class='notice'>[user] slips \a [name] into the mouth of [M].</span>",
"<span class='notice'>You slip [src] into the mouth of [M].</span>"
)
else
to_chat(user, "<span class='notice'>You put [src] into your mouth.</span>")
return TRUE
// If they DO have a cig, try to light it with your own cig.
if(!cigarette_lighter_act(user, M))
return ..()
// You can dip cigarettes into beakers.
if(istype(target, /obj/item/reagent_containers/glass))
var/obj/item/reagent_containers/glass/glass = target
var/transfered = glass.reagents.trans_to(src, chem_volume)
if(transfered)
to_chat(user, "<span class='notice'>You dip [src] into [glass].</span>")
return
// Either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
to_chat(user, "<span class='notice'>[glass] is empty.</span>")
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
return ..()
/obj/item/clothing/mask/cigarette/attack_self(mob/user)
if(lit)
user.visible_message(
"<span class='notice'>[user] calmly drops and treads on [src], putting it out instantly.</span>",
"<span class='notice'>You calmly drop and tread on [src], putting it out instantly.</span>",
"<span class='notice'>You hear a foot being brought down on something, and the tiny fizzling of an ember going out.</span>"
)
die()
return ..()
/obj/item/clothing/mask/cigarette/can_enter_storage(obj/item/storage/S, mob/user)
if(lit)
to_chat(user, "<span class='warning'>[S] can't hold [initial(name)] while it's lit!</span>") // initial(name) so it doesn't say "lit" twice in a row
to_chat(user, "<span class='warning'>[S] can't hold \the [initial(name)] while it's lit!</span>") // initial(name) so it doesn't say "lit" twice in a row
return FALSE
else
return TRUE
return TRUE
/obj/item/clothing/mask/cigarette/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
..()
@@ -101,116 +153,95 @@ LIGHTERS ARE IN LIGHTERS.DM
if(!lit)
light("<span class='warning'>[src] is lit by the flames!</span>")
/obj/item/clothing/mask/cigarette/welder_act(mob/user, obj/item/I)
. = TRUE
if(I.tool_use_check(user, 0)) //Don't need to flash eyes because you are a badass
light("<span class='notice'>[user] casually lights [src] with [I], what a badass.</span>")
/obj/item/clothing/mask/cigarette/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
/obj/item/clothing/mask/cigarette/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/lighter/zippo))
var/obj/item/lighter/zippo/Z = I
if(Z.lit)
light("<span class='rose'>With a single flick of [user.p_their()] wrist, [user] smoothly lights [user.p_their()] [name] with [user.p_their()] [Z]. Damn [user.p_theyre()] cool.</span>")
else if(istype(I, /obj/item/lighter))
var/obj/item/lighter/L = I
if(L.lit)
light("<span class='notice'>After some fiddling, [user] manages to light [user.p_their()] [name] with [L].</span>")
else if(istype(I, /obj/item/match/unathi))
var/obj/item/match/unathi/U = I
if(U.lit)
playsound(user.loc, 'sound/effects/unathiignite.ogg', 40, FALSE)
light("<span class='rose'>[user] spits fire at [user.p_their()] [name], igniting it.</span>")
U.matchburnout()
else if(istype(I, /obj/item/match))
var/obj/item/match/M = I
if(M.lit)
light("<span class='notice'>[user] lights [user.p_their()] [name] with [user.p_their()] [M].</span>")
else if(istype(I, /obj/item/melee/energy/sword/saber))
var/obj/item/melee/energy/sword/saber/S = I
if(HAS_TRAIT(S, TRAIT_ITEM_ACTIVE))
light("<span class='warning'>[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes. [user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [name] with [S] in the process.</span>")
else if(istype(I, /obj/item/assembly/igniter))
light("<span class='notice'>[user] fiddles with [I], and manages to light [user.p_their()] [name].</span>")
else if(istype(I, /obj/item/gun/magic/wand/fireball))
var/obj/item/gun/magic/wand/fireball/F = I
if(F.charges)
if(prob(50) || user.mind.assigned_role == "Wizard")
light("<span class='notice'>Holy shit, did [user] just manage to light [user.p_their()] [name] with [F], with only moderate eyebrow singing?</span>")
else
to_chat(user, "<span class='warning'>Unsure which end of the wand is which, [user] fails to light [name] with [F].</span>")
explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2)
F.charges--
//can't think of any other way to update the overlays :<
user.update_inv_wear_mask()
user.update_inv_l_hand()
user.update_inv_r_hand()
/obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/glass/glass, mob/user, proximity)
..()
if(!proximity)
return
if(istype(glass)) //you can dip cigarettes into beakers
var/transfered = glass.reagents.trans_to(src, chem_volume)
if(transfered) //if reagents were transfered, show the message
smoketime = reagents.total_volume * 2.5
to_chat(user, "<span class='notice'>You dip \the [src] into \the [glass].</span>")
else //if not, either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
to_chat(user, "<span class='notice'>[glass] is empty.</span>")
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
/obj/item/clothing/mask/cigarette/proc/light(flavor_text = null)
if(!lit)
lit = TRUE
name = "lit [name]"
attack_verb = list("burnt", "singed")
hitsound = 'sound/items/welder.ogg'
damtype = "fire"
force = 4
if(reagents.get_reagent_amount("plasma")) // the plasma explodes when exposed to fire
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0)
e.start()
if(ismob(loc))
var/mob/M = loc
M.unEquip(src, 1)
qdel(src)
return
if(reagents.get_reagent_amount("fuel")) // the fuel explodes, too, but much less violently
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0)
e.start()
if(ismob(loc))
var/mob/M = loc
M.unEquip(src, 1)
qdel(src)
return
reagents.set_reacting(TRUE)
reagents.handle_reactions()
icon_state = icon_on
item_state = icon_on
if(flavor_text)
var/turf/T = get_turf(src)
T.visible_message(flavor_text)
if(iscarbon(loc))
var/mob/living/carbon/C = loc
if(C.wear_mask == src) // Don't update if it's just in their hand
C.wear_mask_update(src)
set_light(2, 0.25, "#E38F46")
START_PROCESSING(SSobj, src)
playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE)
to_chat(user, "<span class='warning'>You cannot light [cig] with [src] because you need a lighter to light [src] before you can use [src] as a lighter to light [cig]... This seems a little convoluted.</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='notice'>[user] presses [src] against [cig] until it lights. Seems oddly recursive...</span>",
"<span class='notice'>You press [src] against [cig] until it lights. Seems oddly recursive...</span>"
)
else
user.visible_message(
"<span class='notice'>[user] presses [src] until it lights. Sharing is caring!</span>",
"<span class='notice'>You press [src] against [cig] until it lights. Sharing is caring!</span>"
)
cig.light(user, target)
return TRUE
/obj/item/clothing/mask/cigarette/attackby(obj/item/I, mob/living/user, params)
if(I.cigarette_lighter_act(user, user, src))
return
// Catch any item that has no cigarette_lighter_act but logically should be able to work as a lighter due to being hot.
if(I.get_heat())
//Give a generic light message.
user.visible_message(
"<span class='notice'>[user] lights [src] with [I]</span>",
"<span class='notice'>You light [src] with [I].</span>"
)
light(user)
/obj/item/clothing/mask/cigarette/proc/light(mob/living/user, mob/living/target)
if(lit)
return
lit = TRUE
name = "lit [name]"
attack_verb = list("burnt", "singed")
hitsound = 'sound/items/welder.ogg'
damtype = BURN
force = 4
var/mob/M = loc
// Plasma explodes when exposed to fire.
if(reagents.get_reagent_amount("plasma"))
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0)
e.start()
if(ismob(M))
M.unEquip(src, TRUE)
qdel(src)
return
// Fuel explodes, too, but much less violently.
if(reagents.get_reagent_amount("fuel"))
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0)
e.start()
if(ismob(M))
M.unEquip(src, TRUE)
qdel(src)
return
// If there is no target, the user is probably lighting their own cig.
if(isnull(target))
target = user
// If there is also no user, the cig is being lit by atmos or something.
if(target)
target.update_inv_wear_mask()
target.update_inv_l_hand()
target.update_inv_r_hand()
reagents.set_reacting(TRUE)
reagents.handle_reactions()
icon_state = icon_on
item_state = icon_on
if(iscarbon(loc))
var/mob/living/carbon/C = loc
if(C.wear_mask == src) // Don't update if it's just in their hand
C.wear_mask_update(src)
set_light(2, 0.25, "#E38F46")
START_PROCESSING(SSobj, src)
playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE)
return TRUE
/obj/item/clothing/mask/cigarette/process()
var/mob/living/M = loc
@@ -222,18 +253,11 @@ LIGHTERS ARE IN LIGHTERS.DM
return
smoke()
/obj/item/clothing/mask/cigarette/extinguish_light(force)
if(!force)
return
die()
/obj/item/clothing/mask/cigarette/attack_self(mob/user)
if(lit)
user.visible_message("<span class='notice'>[user] calmly drops and treads on [src], putting it out instantly.</span>")
die()
return ..()
/obj/item/clothing/mask/cigarette/proc/smoke()
var/turf/location = get_turf(src)
var/is_being_smoked = FALSE
@@ -264,16 +288,16 @@ LIGHTERS ARE IN LIGHTERS.DM
if(ismob(loc))
var/mob/living/M = loc
to_chat(M, "<span class='notice'>Your [name] goes out.</span>")
M.unEquip(src, 1) //Force the un-equip so the overlays update
M.unEquip(src, TRUE) //Force the un-equip so the overlays update
STOP_PROCESSING(SSobj, src)
qdel(src)
/obj/item/clothing/mask/cigarette/get_heat()
return lit * 1000
/obj/item/clothing/mask/cigarette/proc/can_light_fancy(obj/item/lighting_item)
return (istype(lighting_item, /obj/item/match) || istype(lighting_item, /obj/item/lighter/zippo))
//////////////////////////////
// MARK: CIGARETTES
//////////////////////////////
/obj/item/clothing/mask/cigarette/menthol
list_reagents = list("nicotine" = 40, "menthol" = 20)
@@ -314,6 +338,26 @@ LIGHTERS ARE IN LIGHTERS.DM
/obj/item/clothing/mask/cigarette/rollie/custom
list_reagents = list()
/obj/item/cigbutt
name = "cigarette butt"
desc = "A manky old cigarette butt."
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "cigbutt"
w_class = WEIGHT_CLASS_TINY
throwforce = 1
/obj/item/cigbutt/Initialize(mapload)
. = ..()
pixel_x = rand(-10, 10)
pixel_y = rand(-10, 10)
transform = turn(transform, rand(0, 360))
/obj/item/cigbutt/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(isdrone(user))
C.stored_comms["wood"] += 1
qdel(src)
return TRUE
return ..()
/obj/item/cigbutt/roach
name = "roach"
@@ -325,27 +369,59 @@ LIGHTERS ARE IN LIGHTERS.DM
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
////////////
// CIGARS //
////////////
//////////////////////////////
// MARK: ROLLING
//////////////////////////////
/obj/item/rollingpaper
name = "rolling paper"
desc = "A thin piece of paper used to make fine smokeables."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cig_paper"
w_class = WEIGHT_CLASS_TINY
/obj/item/rollingpaper/afterattack(atom/target, mob/user, proximity)
if(!proximity)
return
if(!istype(target, /obj/item/food/grown))
return ..()
var/obj/item/food/grown/plant = target
if(!plant.dry)
to_chat(user, "<span class='warning'>You need to dry this first!</span>")
return
user.unEquip(plant, TRUE)
user.unEquip(src, TRUE)
var/obj/item/clothing/mask/cigarette/rollie/custom/custom_rollie = new (get_turf(user))
custom_rollie.reagents.maximum_volume = plant.reagents.total_volume
plant.reagents.trans_to(custom_rollie, plant.reagents.total_volume)
custom_rollie.smoketime = custom_rollie.reagents.total_volume * 2.5
user.put_in_active_hand(custom_rollie)
to_chat(user, "<span class='notice'>You roll the [plant.name] into a rolling paper.</span>")
custom_rollie.desc = "Dried [plant.name] rolled up in a thin piece of paper."
qdel(plant)
qdel(src)
//////////////////////////////
// MARK: CIGARS
//////////////////////////////
/obj/item/clothing/mask/cigarette/cigar
name = "\improper Premium Cigar"
desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!"
icon_state = "cigaroff"
item_state = "cigaroff"
icon_on = "cigaron"
icon_off = "cigaroff"
type_butt = /obj/item/cigbutt/cigarbutt
throw_speed = 0.5
item_state = "cigaroff"
fancy = TRUE
type_butt = /obj/item/cigbutt/cigarbutt
smoketime = 300
chem_volume = 120
list_reagents = list("nicotine" = 120)
/obj/item/clothing/mask/cigarette/cigar/try_light(obj/item/cigar, obj/item/lighting_item)
if(can_light_fancy(lighting_item))
return ..()
/obj/item/clothing/mask/cigarette/cigar/cohiba
name = "\improper Cohiba Robusto Cigar"
desc = "There's little more you could want from a cigar."
@@ -363,45 +439,19 @@ LIGHTERS ARE IN LIGHTERS.DM
chem_volume = 180
list_reagents = list("nicotine" = 180)
/obj/item/cigbutt
name = "cigarette butt"
desc = "A manky old cigarette butt."
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "cigbutt"
w_class = WEIGHT_CLASS_TINY
throwforce = 1
/obj/item/cigbutt/Initialize(mapload)
. = ..()
pixel_x = rand(-10,10)
pixel_y = rand(-10,10)
transform = turn(transform,rand(0,360))
/obj/item/cigbutt/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(isdrone(user))
C.stored_comms["wood"] += 1
qdel(src)
return TRUE
return ..()
/obj/item/cigbutt/cigarbutt
name = "cigar butt"
desc = "A manky old cigar butt."
icon_state = "cigarbutt"
/obj/item/clothing/mask/cigarette/cigar/attackby(obj/item/I, mob/user, params)
if(!is_type_in_typecache(I, things_that_light))
return
if(can_light_fancy(I))
..()
else
to_chat(user, "<span class='notice'>[src] straight out REFUSES to be lit by such uncivilized means.</span>")
//////////////////////////////
// MARK: HOLO-CIGAR
//////////////////////////////
/obj/item/clothing/mask/holo_cigar
name = "Holo-Cigar"
desc = "A sleek electronic cigar imported straight from Sol. You feel badass merely glimpsing it..."
icon_state = "holocigaroff"
/// Is the holo-cigar lit?
var/enabled = FALSE
/// Tracks if this is the first cycle smoking the cigar.
var/has_smoked = FALSE
@@ -462,10 +512,9 @@ LIGHTERS ARE IN LIGHTERS.DM
update_appearance(UPDATE_ICON_STATE)
/////////////////
//SMOKING PIPES//
/////////////////
//////////////////////////////
// MARK: PIPES
//////////////////////////////
/obj/item/clothing/mask/cigarette/pipe
name = "smoking pipe"
desc = "A pipe, for smoking. Probably made of meershaum or something."
@@ -473,6 +522,7 @@ LIGHTERS ARE IN LIGHTERS.DM
item_state = "pipeoff"
icon_on = "pipeon" //Note - these are in masks.dmi
icon_off = "pipeoff"
fancy = TRUE
smoketime = 500
chem_volume = 200
list_reagents = list("nicotine" = 200)
@@ -480,15 +530,12 @@ LIGHTERS ARE IN LIGHTERS.DM
/obj/item/clothing/mask/cigarette/pipe/die()
return
/obj/item/clothing/mask/cigarette/pipe/light(flavor_text = null)
/obj/item/clothing/mask/cigarette/pipe/light()
if(!lit)
lit = TRUE
damtype = "fire"
icon_state = icon_on
item_state = icon_on
if(flavor_text)
var/turf/T = get_turf(src)
T.visible_message(flavor_text)
START_PROCESSING(SSobj, src)
/obj/item/clothing/mask/cigarette/pipe/process()
@@ -509,18 +556,18 @@ LIGHTERS ARE IN LIGHTERS.DM
/obj/item/clothing/mask/cigarette/pipe/attack_self(mob/user) // Extinguishes the pipe.
if(lit)
user.visible_message("<span class='notice'>[user] puts out [src].</span>")
user.visible_message(
"<span class='notice'>[user] puts out [src].</span>",
"<span class='notice'>You put out [src].</span>"
)
lit = FALSE
first_puff = TRUE
icon_state = icon_off
item_state = icon_off
STOP_PROCESSING(SSobj, src)
return
/obj/item/clothing/mask/cigarette/pipe/try_light(obj/item/cigar, obj/item/lighting_item)
if(can_light_fancy(lighting_item))
return ..()
// Refill or light the pipe
// Refill the pipe
/obj/item/clothing/mask/cigarette/pipe/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/food/grown))
var/obj/item/food/grown/O = I
@@ -534,14 +581,6 @@ LIGHTERS ARE IN LIGHTERS.DM
qdel(O)
else
to_chat(user, "<span class='warning'>You need to dry this first!</span>")
return
if(!is_type_in_typecache(I, things_that_light))
return
if(can_light_fancy(I))
..()
else
to_chat(user, "<span class='notice'>[src] straight out REFUSES to be lit by such means.</span>")
/obj/item/clothing/mask/cigarette/pipe/cobpipe
name = "corn cob pipe"
@@ -554,40 +593,4 @@ LIGHTERS ARE IN LIGHTERS.DM
chem_volume = 160
list_reagents = list()
///////////
//ROLLING//
///////////
/obj/item/rollingpaper
name = "rolling paper"
desc = "A thin piece of paper used to make fine smokeables."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cig_paper"
w_class = WEIGHT_CLASS_TINY
/obj/item/rollingpaper/afterattack(atom/target, mob/user, proximity)
if(!proximity)
return
if(!istype(target, /obj/item/food/grown))
return ..()
var/obj/item/food/grown/plant = target
if(!plant.dry)
to_chat(user, "<span class='warning'>You need to dry this first!</span>")
return
user.unEquip(plant, TRUE)
user.unEquip(src, TRUE)
var/obj/item/clothing/mask/cigarette/rollie/custom/custom_rollie = new (get_turf(user))
custom_rollie.reagents.maximum_volume = plant.reagents.total_volume
plant.reagents.trans_to(custom_rollie, plant.reagents.total_volume)
custom_rollie.smoketime = custom_rollie.reagents.total_volume * 2.5
user.put_in_active_hand(custom_rollie)
to_chat(user, "<span class='notice'>You roll the [plant.name] into a rolling paper.</span>")
custom_rollie.desc = "Dried [plant.name] rolled up in a thin piece of paper."
qdel(plant)
qdel(src)
#undef REAGENT_TIME_RATIO
@@ -74,6 +74,53 @@
else
return TRUE
/obj/item/flamethrower/attack(mob/living/target, mob/living/user)
if(!cigarette_lighter_act(user, target))
return ..()
/obj/item/flamethrower/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
if(!lit)
to_chat(user, "<span class='warning'>You need to ignite [src] before you can use it as a lighter!</span>")
return TRUE
// Pulling this off 'safely' requires years of experience, a true badass, or blind luck!
if(HAS_TRAIT(user, TRAIT_BADASS) || (user.mind.assigned_role in list("Station Engineer", "Chief Engineer", "Life Support Specialist")) || prob(50))
if(user == target)
user.visible_message(
"<span class='warning'>[user] confidently lifts up [src] and releases a big puff of flame at [user.p_their()] [cig] to light it, like some kind of psychopath!</span>",
"<span class='notice'>You lift up [src] and lightly pull the trigger, lighting [cig].</span>",
"<span class='warning'>You hear a brief burst of flame!</span>"
)
else
user.visible_message(
"<span class='warning'>[user] confidently lifts up [src] and releases a big puff of flame at [target], lighting [target.p_their()] [cig.name], like some kind of psychopath!</span>",
"<span class='notice'>You lift up [src] and point it at [target], lightly pullling the trigger to light [target.p_their()] [cig.name] with a big puff of flame.</span>",
"<span class='warning'>You hear a brief burst of flame!</span>"
)
else
// You set them on fire, but at least the cigarette got lit...
if(target == user)
user.visible_message(
"<span class='danger'>[user] carelessly lifts up [src] and releases a large burst of flame at [user.p_their()] [cig] to light it, accidentally setting [user.p_themselves()] ablaze in the process!</span>",
"<span class='userdanger'>You lift up [src] and squeeze the trigger to light [cig]. Unfortunately, you squeeze a little too hard and release a large burst of flame that sets you ablaze!</span>",
"<span class='danger'>You hear a plume of fire and something igniting!</span>"
)
else
user.visible_message(
"<span class='danger'>[user] carelessly lifts up [src] and releases a large burst of flame at [target] to light [target.p_their()] [cig.name], accidentally setting [target.p_them()] ablaze!</span>",
"<span class='danger'>You lift up [src] up and point it at [target], squeezing the trigger to light [target.p_their()] [cig.name]. \
Unfortunately, your squeeze a little too hard and release large burst of flame that sets [target.p_them()] ablaze!</span>",
"<span class='danger'>You hear a plume of fire and something igniting!</span>"
)
target.adjust_fire_stacks(2)
target.IgniteMob()
cig.light(user, target)
return TRUE
/obj/item/flamethrower/afterattack(atom/target, mob/user, flag)
. = ..()
if(flag)
+150 -63
View File
@@ -1,7 +1,7 @@
// Basic lighters
// MARK: LIGHTERS
/obj/item/lighter
name = "cheap lighter"
desc = "A cheap-as-free lighter."
desc = "A cheap cigarette lighter. It gets the job done, barely."
icon = 'icons/obj/lighter.dmi'
lefthand_file = 'icons/mob/inhands/lighter_lefthand.dmi'
righthand_file = 'icons/mob/inhands/lighter_righthand.dmi'
@@ -20,6 +20,7 @@
var/next_off_message
/// Our lighter color suffix. => [base_icon_state]-[lightercolor] => lighter-r
var/lighter_color
var/is_a_zippo = FALSE
/obj/item/lighter/random
base_icon_state = "lighter"
@@ -95,26 +96,41 @@
playsound(src, 'sound/items/lighter/plastic_close.ogg', 25, TRUE)
next_off_message = world.time + 5 SECONDS
/obj/item/lighter/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!isliving(M))
return
M.IgniteMob()
if(!ismob(M))
/obj/item/lighter/attack(mob/living/target, mob/living/user)
if(cigarette_lighter_act(user, target))
return
if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_selected == "mouth" && lit)
var/obj/item/clothing/mask/cigarette/cig = M.wear_mask
if(M == user)
cig.attackby(src, user)
else
if(istype(src, /obj/item/lighter/zippo))
cig.light("<span class='rose'>[user] whips [src] out and holds it for [M]. [user.p_their(TRUE)] arm is as steady as the unflickering flame [user.p_they()] light[user.p_s()] \the [cig] with.</span>")
else
cig.light("<span class='notice'>[user] holds [src] out for [M], and lights [cig].</span>")
playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE)
M.update_inv_wear_mask()
if(lit && target.IgniteMob())
message_admins("[key_name_admin(user)] set [key_name_admin(target)] on fire")
log_game("[key_name(user)] set [key_name(target)] on fire")
return ..()
/obj/item/lighter/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
// Otherwise the later parts of this proc can be passed to the zippo and cause a runtime.
if(is_a_zippo)
return cig
if(!cig)
return !isnull(cig)
if(!lit)
to_chat(user, "<span class='warning'>You need to light [src] before it can be used to light anything!</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='notice'>After some fiddling, [user] manages to light [user.p_their()] [cig] with [src].</span>",
"<span class='notice'>After some fiddling, you manage to light [cig] with [src].</span>,"
)
else
..()
user.visible_message(
"<span class='notice'>After some fiddling, [user] manages to light [cig] for [target] with [src].</span>",
"<span class='notice'>After some fiddling, you manage to light [cig] for [target] with [src].</span>"
)
cig.light(user, target)
return TRUE
/obj/item/lighter/process()
var/turf/location = get_turf(src)
@@ -131,18 +147,24 @@
/obj/item/lighter/get_heat()
return lit * 1500
// Zippo lighters
// ZIPPO LIGHTERS
/obj/item/lighter/zippo
name = "zippo lighter"
desc = "The zippo."
desc = "A premium cigarette lighter, for cool and distinguished individuals."
icon_state = "zippo"
item_state = "zippo"
is_a_zippo = TRUE
/obj/item/lighter/zippo/turn_on_lighter(mob/living/user)
. = ..()
if(world.time > next_on_message)
user.visible_message("<span class='rose'>Without even breaking stride, [user] flips open and lights [src] in one smooth movement.</span>")
playsound(src.loc, 'sound/items/zippolight.ogg', 25, 1)
user.visible_message(
"<span class='rose'>Without even breaking stride, [user] flips open and lights [src] in one smooth movement.</span>",
"<span class='rose'>Without breaking your stride, you flip open and light [src] in one smooth movement.</span>",
"<span class='rose'>You hear a zippo being lit.</span>"
)
playsound(src.loc, 'sound/items/zippolight.ogg', 25, TRUE)
next_on_message = world.time + 5 SECONDS
else
to_chat(user, "<span class='notice'>You light [src].</span>")
@@ -153,11 +175,37 @@
return
if(world.time > next_off_message)
user.visible_message("<span class='rose'>You hear a quiet click, as [user] shuts off [src] without even looking at what [user.p_theyre()] doing. Wow.")
playsound(src.loc, 'sound/items/zippoclose.ogg', 25, 1)
user.visible_message(
"<span class='rose'>You hear a quiet click as [user] shuts off [src] without even looking at what [user.p_theyre()] doing. Wow.</span>",
"<span class='rose'>You shut off [src] without even looking at what you're doing.</span>",
"<span class='rose'>You hear a quiet click as a zippo lighter is shut off. Wow.</span>"
)
playsound(loc, 'sound/items/zippoclose.ogg', 25, TRUE)
next_off_message = world.time + 5 SECONDS
else
to_chat(user, "<span class='notice'>You shut off [src].")
to_chat(user, "<span class='notice'>You shut off [src].</span>")
/obj/item/lighter/zippo/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
if(!lit)
to_chat(user, "<span class='warning'>You need to light [src] before it can be used to light anything!</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='rose'>With a single flick of [user.p_their()] wrist, [user] smoothly lights [user.p_their()] [cig.name] with [src]. Damn [user.p_theyre()] cool.</span>",
"<span class='rose'>With a single flick of your wrist, you smoothly light [cig] with [src].</span>"
)
else
user.visible_message(
"<span class='rose'>[user] whips [src] out and holds it for [target]. [user.p_their(TRUE)] arm is as steady as the unflickering flame [user.p_they()] light [cig] with. Damn [user.p_theyre()] cool.</span>",
"<span class='rose'>You whip [src] out and hold it for [target]. Your arm is as steady as the unflickering flame you light [cig] with.</span>"
)
cig.light(user, target)
return TRUE
/obj/item/lighter/zippo/show_off_message(mob/living/user)
return
@@ -165,10 +213,9 @@
/obj/item/lighter/zippo/attempt_light(mob/living/user)
return
//EXTRA LIGHTERS
/obj/item/lighter/zippo/nt_rep
name = "gold engraved zippo"
desc = "An engraved golden Zippo lighter with the letters NT on it."
desc = "An engraved golden Zippo lighter with the letters \"NT\" engraved on the sides."
icon_state = "zippo-nt"
item_state = "zippo-gold"
@@ -195,9 +242,8 @@
icon_state = "zippo-gonzo"
item_state = "zippo-red"
///////////
//MATCHES//
///////////
// MARK: MATCHES
/obj/item/match
name = "match"
desc = "A simple match stick, used for lighting fine smokables."
@@ -209,6 +255,7 @@
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=1"
attack_verb = null
var/is_unathi_fire = FALSE
/obj/item/match/process()
var/turf/location = get_turf(src)
@@ -268,35 +315,43 @@
else
return TRUE
/obj/item/match/attack(mob/living/carbon/M, mob/living/carbon/user)
if(!isliving(M))
return ..()
if(lit && M.IgniteMob())
message_admins("[key_name_admin(user)] set [key_name_admin(M)] on fire")
log_game("[key_name(user)] set [key_name(M)] on fire")
var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M)
if(lit && cig && user.a_intent == INTENT_HELP)
if(cig.lit)
to_chat(user, "<span class='notice'>[cig] is already lit.</span>")
if(M == user)
cig.attackby(src, user)
else
if(istype(src, /obj/item/match/unathi))
if(prob(50))
cig.light("<span class='rose'>[user] spits fire at [M], lighting [cig] and nearly burning [user.p_their()] face!</span>")
matchburnout()
else
cig.light("<span class='rose'>[user] spits fire at [M], burning [user.p_their()] face and lighting [cig] in the process.</span>")
var/obj/item/organ/external/head/affecting = M.get_organ("head")
affecting.receive_damage(0, 5)
M.UpdateDamageIcon()
playsound(user.loc, 'sound/effects/unathiignite.ogg', 40, FALSE)
/obj/item/match/attack(mob/living/target, mob/living/user)
if(cigarette_lighter_act(user, target))
return
else
cig.light("<span class='notice'>[user] holds [src] out for [M], and lights [cig].</span>")
playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE)
if(lit && target.IgniteMob())
message_admins("[key_name_admin(user)] set [key_name_admin(target)] on fire")
log_game("[key_name(user)] set [key_name(target)] on fire")
return ..()
/obj/item/match/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
// Otherwise the later parts of this proc can be passed to the unathi's blaze and cause a runtime.
if(is_unathi_fire)
return cig
if(!cig)
return !isnull(cig)
if(!lit)
to_chat(user, "<span class='warning'>You need to light [src] before it can be used to light anything!</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='notice'>[user] lights [user.p_their()] [cig] with [src].</span>",
"<span class='notice'>You light [cig] with [src].</span>"
)
else
..()
user.visible_message(
"<span class='notice'>[user] holds [src] out for [target], and lights [cig].</span>",
"<span class='notice'>You hold [src] out for [target], and light [user.p_their()] [cig].</span>"
)
cig.light(user, target)
matchburnout()
return TRUE
/obj/item/match/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(isdrone(user) && burnt)
@@ -305,11 +360,6 @@
return TRUE
return ..()
/obj/item/proc/help_light_cig(mob/living/M)
var/mask_item = M.get_item_by_slot(SLOT_HUD_WEAR_MASK)
if(istype(mask_item, /obj/item/clothing/mask/cigarette))
return mask_item
/obj/item/match/get_heat()
return lit * 1000
@@ -332,6 +382,43 @@
origin_tech = null
lit = TRUE
w_class = WEIGHT_CLASS_BULKY //to prevent it going to pockets
is_unathi_fire = TRUE
/obj/item/match/unathi/cigarette_lighter_act(mob/living/target, mob/living/user, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
if(!lit)
to_chat(user, "<span class='userdanger'>If you can see this message, please make an issue report to GitHub, something bad has happened.</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='rose'>[user] spits fire at [user.p_their()] [cig.name], igniting it.</span>",
"<span class='rose'>You spit fire at [cig], igniting it.</span>",
"<span class='warning'>You hear a brief burst of flame!</span>"
)
else
if(prob(50))
user.visible_message(
"<span class='rose'>[user] spits fire at [target], lighting [cig] in [target.p_their()] mouth and nearly burning [target.p_their()] face!</span>",
"<span class='rose'>You spit fire at [target], lighting [cig] in [target.p_their()] mouth and nearly burning [target.p_their()] face!</span>",
"<span class='warning'>You hear a brief burst of flame!</span>"
)
else
user.visible_message(
"<span class='rose'>[user] spits fire at [target], burning [target.p_their()] face and lighting [cig] in the process!</span>",
"<span class='rose'>You spit fire at [target], burning [target.p_their()] face and lighting [cig] in the process!</span>",
"<span class='warning'>You hear a brief burst of flame!</span>"
)
var/obj/item/organ/external/head/affecting = target.get_organ("head")
affecting.receive_damage(0, 5)
target.UpdateDamageIcon()
cig.light(user, target)
playsound(user.loc, 'sound/effects/unathiignite.ogg', 40, FALSE)
matchburnout()
return TRUE
/obj/item/match/unathi/Initialize(mapload)
. = ..()
@@ -44,6 +44,8 @@
light_power = 2
var/brightness_on = 2
var/colormap = list(red=LIGHT_COLOR_RED, blue=LIGHT_COLOR_LIGHTBLUE, green=LIGHT_COLOR_GREEN, purple=LIGHT_COLOR_PURPLE, rainbow=LIGHT_COLOR_WHITE)
/// Used to mark the item as a cleaving saw so that cigarette_lighter_act() will perform an early return.
var/is_a_cleaving_saw = FALSE
/obj/item/melee/energy/Initialize(mapload)
. = ..()
@@ -55,7 +57,10 @@
UnregisterSignal(src, COMSIG_ITEM_SHARPEN_ACT)
return ..()
/obj/item/melee/energy/attack(mob/living/target, mob/living/carbon/human/user)
/obj/item/melee/energy/attack(mob/living/target, mob/living/user)
if(cigarette_lighter_act(user, target))
return
var/nemesis_faction = FALSE
if(LAZYLEN(nemesis_factions))
for(var/F in target.faction)
@@ -68,6 +73,37 @@
if(nemesis_faction)
force -= faction_bonus_force
/obj/item/melee/energy/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
if(is_a_cleaving_saw)
return FALSE
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE))
to_chat(user, "<span class='warning'>You must activate [src] before you can light [cig] with it!</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='warning'>[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes! \
[user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [cig] with [src] in the process.</span>",
"<span class='notice'>You casually slash [src] at [cig], lighting it with the blade.</span>",
"<span class='danger'>You hear an energy blade slashing something!</span>"
)
else
user.visible_message(
"<span class='danger'>[user] makes a violent slashing motion, barely missing the nose of [target] as light flashes! \
[user.p_they(TRUE)] light[user.p_s()] [cig] in the mouth of [target] with [src] in the process.</span>",
"<span class='notice'>You casually slash [src] at [cig] in the mouth of [target], lighting it with the blade.</span>",
"<span class='danger'>You hear an energy blade slashing something!</span>"
)
user.do_attack_animation(target)
playsound(user.loc, hitsound, 50, TRUE)
cig.light(user, target)
return TRUE
/obj/item/melee/energy/suicide_act(mob/user)
user.visible_message(pick("<span class='suicide'>[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!</span>", \
"<span class='suicide'>[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>"))
@@ -365,6 +401,7 @@
icon_state = "cleaving_saw"
icon_state_on = "cleaving_saw_open"
slot_flags = SLOT_FLAG_BELT
is_a_cleaving_saw = TRUE
var/attack_verb_off = list("attacked", "sawed", "sliced", "torn", "ripped", "diced", "cut")
attack_verb_on = list("cleaved", "swiped", "slashed", "chopped")
hitsound = 'sound/weapons/bladeslice.ogg'
@@ -235,39 +235,45 @@
/obj/item/storage/fancy/cigarettes/update_icon_state()
icon_state = "[initial(icon_state)][length(contents)]"
/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M, mob/living/user)
if(!ismob(M))
return
if(istype(M) && M == user && user.zone_selected == "mouth" && length(contents) > 0 && !user.wear_mask)
var/got_cig = 0
for(var/num=1, num <= length(contents), num++)
if(istype(M) && user.zone_selected == "mouth" && length(contents) > 0 && !M.wear_mask)
var/got_cig = FALSE
for(var/num in 1 to length(contents))
var/obj/item/I = contents[num]
if(istype(I, /obj/item/clothing/mask/cigarette))
var/obj/item/clothing/mask/cigarette/C = I
user.equip_to_slot_if_possible(C, SLOT_HUD_WEAR_MASK)
to_chat(user, "<span class='notice'>You take \a [C.name] out of the pack.</span>")
M.equip_to_slot_if_possible(C, SLOT_HUD_WEAR_MASK)
if(M != user)
user.visible_message(
"<span class='notice'>[user] takes \a [C.name] out of [src] and gives it to [M].</span>",
"<span class='notice'>You take \a [C.name] out of [src] and give it to [M].</span>"
)
else
to_chat(user, "<span class='notice'>You take \a [C.name] out of the pack.</span>")
update_icon()
got_cig = 1
got_cig = TRUE
break
if(!got_cig)
to_chat(user, "<span class='warning'>There are no smokables in the pack!</span>")
else
..()
/obj/item/storage/fancy/cigarettes/can_be_inserted(obj/item/W as obj, stop_messages = 0)
/obj/item/storage/fancy/cigarettes/can_be_inserted(obj/item/W, stop_messages = FALSE)
if(istype(W, /obj/item/match))
var/obj/item/match/M = W
if(M.lit)
if(!stop_messages)
to_chat(usr, "<span class='notice'>Putting a lit [W] in [src] probably isn't a good idea.</span>")
return 0
return FALSE
if(istype(W, /obj/item/lighter))
var/obj/item/lighter/L = W
if(L.lit)
if(!stop_messages)
to_chat(usr, "<span class='notice'>Putting [W] in [src] while lit probably isn't a good idea.</span>")
return 0
return FALSE
//if we get this far, handle the insertion checks as normal
. = ..()
@@ -140,6 +140,9 @@
set_light(0)
/obj/item/dualsaber/attack(mob/target, mob/living/user)
if(cigarette_lighter_act(user, target))
return
if(HAS_TRAIT(user, TRAIT_HULK))
to_chat(user, "<span class='warning'>You grip the blade too hard and accidentally drop it!</span>")
if(HAS_TRAIT(src, TRAIT_WIELDED))
@@ -153,6 +156,33 @@
if((HAS_TRAIT(src, TRAIT_WIELDED)) && prob(50))
INVOKE_ASYNC(src, PROC_REF(jedi_spin), user)
/obj/item/dualsaber/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item)
var/obj/item/clothing/mask/cigarette/cig = ..()
if(!cig)
return !isnull(cig)
if(!HAS_TRAIT(src, TRAIT_WIELDED))
to_chat(user, "<span class='warning'>You need to activate [src] before you can light anything with it!</span>")
return TRUE
if(target == user)
user.visible_message(
"<span class='danger'>[user] flips through the air and spins [src] wildly! It brushes against [user.p_their()] [cig] and sets it alight!</span>",
"<span class='notice'>You flip through the air and twist [src] so it brushes against [cig], lighting it with the blade.</span>",
"<span class='danger'>You hear an energy blade slashing something!</span>"
)
else
user.visible_message(
"<span class='danger'>[user] flips through the air and slashes at [user] with [src]! The blade barely misses, brushing against [user.p_their()] [cig] and setting it alight!</span>",
"<span class='notice'>You flip through the air and slash [src] at [cig], lighting it for [target].</span>",
"<span class='danger'>You hear an energy blade slashing something!</span>"
)
user.do_attack_animation(target)
playsound(user.loc, hitsound, 50, TRUE)
cig.light(user, target)
INVOKE_ASYNC(src, PROC_REF(jedi_spin), user)
return TRUE
/obj/item/dualsaber/proc/jedi_spin(mob/living/user)
for(var/i in list(NORTH, SOUTH, EAST, WEST, EAST, SOUTH, NORTH, SOUTH, EAST, WEST, EAST, SOUTH))
user.setDir(i)