mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 07:08:00 +01:00
Items in your hands can catch fire (#83867)
## About The Pull Request Recently we allowed items held in your hands to catch fire if you catch fire. This makes sense but the code had a few oversights, then we reverted it. This PR reintroduces the feature, but with a few refinements. The basic feature is simple: If you are on fire then items you are holding will also catch fire, in the same vein as items you are wearing on your head or hands. There are also a few caveats we forgot about the first time we added this: - If your gloves cannot catch fire, your held items will not catch fire (because your hands aren't on fire). - If you are extinguished, your held items will also be extinguished. - Stopping, Dropping, and Rolling on top of any items will also extinguish those items. As part of this change, after an argument about whether or not this is an oversight in coding-general, I've made the proc `get_equipped_items` take a bitflag instead of a series of booleans as an argument and added a new one for "include held items", so that we need no longer argue about whether holding something counts as "equipping" it (in all other parts of the game than this proc, it does). This is what gives the PR most of its code footprint, don't be scared. ## Why It's Good For The Game Items you are holding in your hands _should_ catch fire if everything else on your person is on fire, and taking an item off of your body to put it in your hands shouldn't protect it from fire, because those things don't make intuitive sense. If we want an item to be able to catch fire when worn, then it should do so. This might expose some issues where we were improperly setting the flammability flags on items, but any weapon which will burn in your hands now would also have burned if you were wearing it on your belt or back, so making those issues more visible should be a bonus (we'll also stop them from burning on your back or belt). If you see someone holding a piece of paper that you really don't want them to read you can now set them on fire to stop them from reading it, whereas previously they would deftly hold the very flammable object out of reach of their flaming body. ## Changelog 🆑 balance: Items held in your hands can catch fire. balance: Items you are holding won't catch fire if your hands cannot catch fire. balance: When you stop being on fire so will items you are holding. balance: If you roll around on your burning items they will stop being on fire. /🆑
This commit is contained in:
@@ -106,3 +106,8 @@
|
||||
/// Flags for sharpness in obj/item
|
||||
#define SHARP_EDGED (1<<0)
|
||||
#define SHARP_POINTY (1<<1)
|
||||
|
||||
/// Flags for specifically what kind of items to get in get_equipped_items
|
||||
#define INCLUDE_POCKETS (1<<0)
|
||||
#define INCLUDE_ACCESSORIES (1<<1)
|
||||
#define INCLUDE_HELD (1<<2)
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
if(HAS_TRAIT_FROM(affected_mob, TRAIT_NO_TRANSFORM, REF(src)))
|
||||
return
|
||||
ADD_TRAIT(affected_mob, TRAIT_NO_TRANSFORM, REF(src))
|
||||
for(var/obj/item/W in affected_mob.get_equipped_items(include_pockets = TRUE))
|
||||
for(var/obj/item/W in affected_mob.get_equipped_items(INCLUDE_POCKETS))
|
||||
affected_mob.dropItemToGround(W)
|
||||
for(var/obj/item/I in affected_mob.held_items)
|
||||
affected_mob.dropItemToGround(I)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
///We check if the item can be equipped, otherwise we drop it.
|
||||
/datum/element/skill_reward/proc/drop_if_unworthy(datum/source, mob/living/user)
|
||||
SIGNAL_HANDLER
|
||||
if(check_equippable(user) || !(source in user.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)))
|
||||
if(check_equippable(user) || !(source in user.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)))
|
||||
return NONE
|
||||
to_chat(user, span_warning("You feel completely and utterly unworthy to even touch \the [source]."))
|
||||
user.dropItemToGround(source, TRUE)
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
// Start with one weaker roll
|
||||
owner.spin(spintime = actual_interval, speed = actual_interval / 4)
|
||||
owner.adjust_fire_stacks(-0.25)
|
||||
|
||||
for (var/obj/item/dropped in owner.loc)
|
||||
dropped.extinguish() // Effectively extinguish your items by rolling on them
|
||||
return TRUE
|
||||
|
||||
/datum/status_effect/stop_drop_roll/on_remove()
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
owner.clear_mood_event("on_fire")
|
||||
SEND_SIGNAL(owner, COMSIG_LIVING_EXTINGUISHED, owner)
|
||||
cache_stacks()
|
||||
for(var/obj/item/equipped in owner.get_equipped_items())
|
||||
for(var/obj/item/equipped in (owner.get_equipped_items(INCLUDE_HELD)))
|
||||
equipped.extinguish()
|
||||
|
||||
/datum/status_effect/fire_handler/fire_stacks/on_remove()
|
||||
|
||||
@@ -445,7 +445,7 @@
|
||||
balloon_alert(user, "can't reach!")
|
||||
return
|
||||
|
||||
if((src in user.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) && !user.canUnEquip(src))
|
||||
if((src in user.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) && !user.canUnEquip(src))
|
||||
balloon_alert(user, "it's stuck!")
|
||||
return
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
/datum/admins/proc/equipAntagOnDummy(mob/living/carbon/human/dummy/mannequin, datum/antagonist/antag)
|
||||
for(var/I in mannequin.get_equipped_items(include_pockets = TRUE))
|
||||
for(var/I in mannequin.get_equipped_items(INCLUDE_POCKETS))
|
||||
qdel(I)
|
||||
if (ispath(antag, /datum/antagonist/ert))
|
||||
var/datum/antagonist/ert/ert = antag
|
||||
|
||||
@@ -209,7 +209,8 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(select_equipment, R_FUN, "Select Equipment", mob/ta
|
||||
delete_pocket = TRUE
|
||||
|
||||
BLACKBOX_LOG_ADMIN_VERB("Select Equipment")
|
||||
for(var/obj/item/item in human_target.get_equipped_items(include_pockets = delete_pocket))
|
||||
var/includes_flags = delete_pocket ? INCLUDE_POCKETS : NONE
|
||||
for(var/obj/item/item in human_target.get_equipped_items(includes_flags))
|
||||
qdel(item)
|
||||
|
||||
var/obj/item/organ/internal/brain/human_brain = human_target.get_organ_slot(BRAIN)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
|
||||
/datum/outfit/obsessed/post_equip(mob/living/carbon/human/H)
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
|
||||
carried_item.add_mob_blood(H)//Oh yes, there will be blood...
|
||||
H.regenerate_icons()
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
/// Removes all blacklisted items from a mob and returns them to base state
|
||||
/obj/machinery/quantum_server/proc/reset_equipment(mob/living/carbon/human/person)
|
||||
for(var/obj/item in person.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
|
||||
for(var/obj/item in person.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
|
||||
qdel(item)
|
||||
|
||||
var/datum/antagonist/bitrunning_glitch/antag_datum = locate() in person.mind?.antag_datums
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
to_chat(c, span_warning("Pick an outfit first."))
|
||||
return
|
||||
|
||||
for (var/item in dollie.get_equipped_items(include_pockets = TRUE))
|
||||
for (var/item in dollie.get_equipped_items(INCLUDE_POCKETS))
|
||||
qdel(item)
|
||||
if(dressuptime != "Naked")
|
||||
dollie.equipOutfit(dressuptime)
|
||||
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
for (var/item in dollie.get_equipped_items(include_pockets = TRUE))
|
||||
for (var/item in dollie.get_equipped_items(INCLUDE_POCKETS))
|
||||
qdel(item)
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
l_hand = /obj/item/fireaxe
|
||||
|
||||
/datum/outfit/psycho/post_equip(mob/living/carbon/human/H)
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
|
||||
carried_item.add_mob_blood(H)//Oh yes, there will be blood...
|
||||
for(var/obj/item/I in H.held_items)
|
||||
I.add_mob_blood(H)
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
suit = /obj/item/clothing/suit/apron
|
||||
|
||||
/datum/outfit/mafia/obsessed/post_equip(mob/living/carbon/human/H)
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))
|
||||
carried_item.add_mob_blood(H)//Oh yes, there will be blood...
|
||||
H.regenerate_icons()
|
||||
|
||||
|
||||
@@ -388,38 +388,37 @@
|
||||
* Used to return a list of equipped items on a mob; does not include held items (use get_all_gear)
|
||||
*
|
||||
* Argument(s):
|
||||
* * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list
|
||||
* * Optional - include_accessories (TRUE/FALSE), whether or not to include the accessories in the returned list
|
||||
* * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items)
|
||||
*/
|
||||
|
||||
/mob/living/proc/get_equipped_items(include_pockets = FALSE, include_accessories = FALSE)
|
||||
/mob/living/proc/get_equipped_items(include_flags = NONE)
|
||||
var/list/items = list()
|
||||
for(var/obj/item/item_contents in contents)
|
||||
if(item_contents.item_flags & IN_INVENTORY)
|
||||
items += item_contents
|
||||
items -= held_items
|
||||
if (!(include_flags & INCLUDE_HELD))
|
||||
items -= held_items
|
||||
return items
|
||||
|
||||
/**
|
||||
* Used to return a list of equipped items on a human mob; does not include held items (use get_all_gear)
|
||||
* Used to return a list of equipped items on a human mob; does not by default include held items, see include_flags
|
||||
*
|
||||
* Argument(s):
|
||||
* * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list
|
||||
* * Optional - include_accessories (TRUE/FALSE), whether or not to include the accessories in the returned list
|
||||
* * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items)
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/get_equipped_items(include_pockets = FALSE, include_accessories = FALSE)
|
||||
/mob/living/carbon/human/get_equipped_items(include_flags = NONE)
|
||||
var/list/items = ..()
|
||||
if(!include_pockets)
|
||||
if(!(include_flags & INCLUDE_POCKETS))
|
||||
items -= list(l_store, r_store, s_store)
|
||||
if(include_accessories && w_uniform)
|
||||
if((include_flags & INCLUDE_ACCESSORIES) && w_uniform)
|
||||
var/obj/item/clothing/under/worn_under = w_uniform
|
||||
items += worn_under.attached_accessories
|
||||
return items
|
||||
|
||||
/mob/living/proc/unequip_everything()
|
||||
var/list/items = list()
|
||||
items |= get_equipped_items(include_pockets = TRUE)
|
||||
items |= get_equipped_items(INCLUDE_POCKETS)
|
||||
for(var/I in items)
|
||||
dropItemToGround(I)
|
||||
drop_all_held_items()
|
||||
@@ -558,7 +557,7 @@
|
||||
|
||||
//GetAllContents that is reasonable and not stupid
|
||||
/mob/living/proc/get_all_gear()
|
||||
var/list/processing_list = get_equipped_items(include_pockets = TRUE, include_accessories = TRUE) + held_items
|
||||
var/list/processing_list = get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES | INCLUDE_HELD)
|
||||
list_clear_nulls(processing_list) // handles empty hands
|
||||
var/i = 0
|
||||
while(i < length(processing_list))
|
||||
|
||||
@@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
replacement.Insert(organ_holder, special=TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
|
||||
/datum/species/proc/worn_items_fit_body_check(mob/living/carbon/wearer)
|
||||
for(var/obj/item/equipped_item in wearer.get_equipped_items(include_pockets = TRUE))
|
||||
for(var/obj/item/equipped_item in wearer.get_equipped_items(INCLUDE_POCKETS))
|
||||
var/equipped_item_slot = wearer.get_slot_by_item(equipped_item)
|
||||
if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE))
|
||||
wearer.dropItemToGround(equipped_item, force = TRUE)
|
||||
|
||||
@@ -41,7 +41,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
//Instead of just deleting our equipment, we save what we can and reinsert it into SSwardrobe's store
|
||||
//Hopefully this makes preference reloading not the worst thing ever
|
||||
/mob/living/carbon/human/dummy/delete_equipment()
|
||||
var/list/items_to_check = get_equipped_items(include_pockets = TRUE) + held_items
|
||||
var/list/items_to_check = get_equipped_items(INCLUDE_POCKETS | INCLUDE_HELD)
|
||||
var/list/to_nuke = list() //List of items queued for deletion, can't qdel them before iterating their contents in case they hold something
|
||||
///Travel to the bottom of the contents chain, expanding it out
|
||||
for(var/i = 1; i <= length(items_to_check); i++) //Needs to be a c style loop since it can expand
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
return TRUE
|
||||
|
||||
var/block_chance_modifier = round(damage / -3)
|
||||
for(var/obj/item/worn_thing in get_equipped_items(include_pockets = FALSE) + held_items)
|
||||
for(var/obj/item/worn_thing in get_equipped_items(INCLUDE_HELD))
|
||||
// Things that are supposed to be worn, being held = cannot block
|
||||
if(isclothing(worn_thing))
|
||||
if(worn_thing in held_items)
|
||||
@@ -796,6 +796,10 @@
|
||||
if(leg_clothes)
|
||||
burning_items |= leg_clothes
|
||||
|
||||
if (!gloves || (!(gloves.resistance_flags & FIRE_PROOF) && (gloves.resistance_flags & FLAMMABLE)))
|
||||
for(var/obj/item/burnable_item in held_items)
|
||||
burning_items |= burnable_item
|
||||
|
||||
for(var/obj/item/burning in burning_items)
|
||||
burning.fire_act((stacks * 25 * seconds_per_tick)) //damage taken is reduced to 2% of this value by fire_act()
|
||||
|
||||
|
||||
@@ -347,7 +347,7 @@
|
||||
|
||||
//delete all equipment without dropping anything
|
||||
/mob/living/carbon/human/proc/delete_equipment()
|
||||
for(var/slot in get_equipped_items(include_pockets = TRUE))//order matters, dependant slots go first
|
||||
for(var/slot in get_equipped_items(INCLUDE_POCKETS))//order matters, dependant slots go first
|
||||
qdel(slot)
|
||||
for(var/obj/item/held_item in held_items)
|
||||
qdel(held_item)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
to_chat(src, span_warning("You can't vent crawl while buckled!"))
|
||||
return
|
||||
if(iscarbon(src) && required_nudity)
|
||||
if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items())
|
||||
if(length(get_equipped_items(INCLUDE_POCKETS)) || get_num_held_items())
|
||||
if(provide_feedback)
|
||||
to_chat(src, span_warning("You can't crawl around in the ventilation ducts with items!"))
|
||||
return
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
|
||||
SSblackbox.record_feedback("amount", "gorillas_created", 1)
|
||||
|
||||
var/Itemlist = get_equipped_items(include_pockets = TRUE)
|
||||
var/Itemlist = get_equipped_items(INCLUDE_POCKETS)
|
||||
Itemlist += held_items
|
||||
for(var/obj/item/W in Itemlist)
|
||||
dropItemToGround(W, TRUE)
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
for (var/outfit_type in outfits_to_check)
|
||||
// Only make one human and keep undressing it because it's much faster
|
||||
for (var/obj/item/I in H.get_equipped_items(include_pockets = TRUE))
|
||||
for (var/obj/item/I in H.get_equipped_items(INCLUDE_POCKETS))
|
||||
qdel(I)
|
||||
|
||||
var/datum/outfit/outfit = new outfit_type
|
||||
|
||||
Reference in New Issue
Block a user