Skip to content

Commit

Permalink
Shoe item storage refactor (#5263)
Browse files Browse the repository at this point in the history
# About the pull request

Refactors shoe item storage to fix #5245, adds a bit of documentation,
and generally just makes it a bit neater.
(The overall 'Files changed' view looks a bit messy, so I've tried to
keep each commit atomic to help with reviews.)

# Explain why it's good for the game

Code works gooder.

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

**Inserting a knife manually:**


https://github.com/cmss13-devs/cmss13/assets/57483089/adf6267c-7a30-4c00-ae32-37524048ddc6

**Inserting a knife with the (un)holster hotkey:**


https://github.com/cmss13-devs/cmss13/assets/57483089/b66824cb-5ad8-433e-a732-4854c0f68ff4

**Inserting a knife while holding the shoes:**


https://github.com/cmss13-devs/cmss13/assets/57483089/0db1ac5c-7375-478a-9464-449657c7b659

**Picking up/dropping the shoes, and inserting a knife while they're on
the ground:**


https://github.com/cmss13-devs/cmss13/assets/57483089/404a8199-dee0-4cd0-92a9-d2a46cadfac6

**Trying a few different things with two pairs of shoes:**


https://github.com/cmss13-devs/cmss13/assets/57483089/c5aab994-1002-4ffe-80e9-ddbaff4f95af


</details>


# Changelog
:cl:
fix: Fixed inserting/removing an item from shoes sometimes acting
weirdly.
refactor: Refactored shoe item storage.
/:cl:
  • Loading branch information
SabreML authored Dec 27, 2023
1 parent 8963d0a commit 92a96a8
Show file tree
Hide file tree
Showing 20 changed files with 184 additions and 171 deletions.
2 changes: 1 addition & 1 deletion code/datums/supply_packs/black_market.dm
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Non-USCM items, from CLF, UPP, colonies, etc. Mostly combat-related.
new /obj/item/clothing/head/helmet/marine/veteran/UPP(src)
new /obj/item/clothing/under/marine/veteran/UPP(src)
new /obj/item/clothing/suit/storage/marine/faction/UPP(src)
new /obj/item/clothing/shoes/marine/upp(src)
new /obj/item/clothing/shoes/marine/upp/knife(src)
new /obj/item/clothing/gloves/marine/veteran(src)
new /obj/item/storage/backpack/lightpack/five_slot(src)
if(5) //freelancer
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ cases. Override_icon_state should be a list.*/
if(WEAR_IN_SHOES)
if(human.shoes && istype(human.shoes, /obj/item/clothing/shoes))
var/obj/item/clothing/shoes/shoes = human.shoes
if(shoes.attempt_insert_item(human, src))
if(shoes.can_be_inserted(src))
return TRUE
return FALSE
if(WEAR_IN_SCABBARD)
Expand Down
90 changes: 54 additions & 36 deletions code/modules/clothing/clothing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -336,41 +336,64 @@
permeability_coefficient = 0.50
slowdown = SHOES_SLOWDOWN
blood_overlay_type = "feet"
/// The currently inserted item.
var/obj/item/stored_item
var/list/items_allowed
/// List of item types that can be inserted.
var/list/allowed_items_typecache
/// An item which should be inserted when the shoes are spawned.
var/obj/item/spawn_item_type
var/shoes_blood_amt = 0

///Checks if you can put the item inside of the shoes
/obj/item/clothing/shoes/proc/attempt_insert_item(mob/user, obj/item/attacking_item, insert_after = FALSE)
if(!items_allowed)
return
/obj/item/clothing/shoes/Initialize(mapload, ...)
. = ..()
if(allowed_items_typecache)
allowed_items_typecache = typecacheof(allowed_items_typecache)
if(spawn_item_type)
_insert_item(new spawn_item_type(src))

/// Returns a boolean indicating if `item_to_insert` can be inserted into the shoes.
/obj/item/clothing/shoes/proc/can_be_inserted(obj/item/item_to_insert)
// If the shoes can't actually hold an item.
if(allowed_items_typecache == null)
return FALSE
// If there's already an item inside.
if(stored_item)
return
var/allowed = FALSE
for(var/allowed_item in items_allowed)
if(istype(attacking_item, allowed_item))
allowed = TRUE
break
if(!allowed)
return
if(!insert_after)
return TRUE
insert_item(user, attacking_item)

///Puts the item inside of the shoe
/obj/item/clothing/shoes/proc/insert_item(mob/user, obj/item/attacking_item)
stored_item = attacking_item
user.drop_inv_item_to_loc(attacking_item, src)
to_chat(user, SPAN_NOTICE("You slide [attacking_item] into [src]."))
playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, 1)
return FALSE
// If `item_to_insert` isn't in the whitelist.
if(!is_type_in_typecache(item_to_insert, allowed_items_typecache))
return FALSE
// If all of those passed, `item_to_insert` can be inserted.
return TRUE

/**
* Try to insert `item_to_insert` into the shoes.
*
* Returns `TRUE` if it succeeded, or `FALSE` if [/obj/item/clothing/shoes/proc/can_be_inserted] failed, or `user` couldn't drop the item.
*/
/obj/item/clothing/shoes/proc/attempt_insert_item(mob/user, obj/item/item_to_insert)
if(!can_be_inserted(item_to_insert))
return FALSE
// Try to drop the item and place it inside `src`.
if(!user.drop_inv_item_to_loc(item_to_insert, src))
return FALSE
_insert_item(item_to_insert)
to_chat(user, SPAN_NOTICE("You slide [item_to_insert] into [src]."))
playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, TRUE)
return TRUE

/// Insert `item_to_insert` directly into the shoes without bothering with any checks.
/// (In the majority of cases [/obj/item/clothing/shoes/proc/attempt_insert_item()] should be used instead of this.)
/obj/item/clothing/shoes/proc/_insert_item(obj/item/item_to_insert)
PROTECTED_PROC(TRUE)
stored_item = item_to_insert
update_icon()

///Removes the item from the shoes
/// Remove `stored_item` from the shoes, and place it into the `user`'s active hand.
/obj/item/clothing/shoes/proc/remove_item(mob/user)
if(!user.put_in_active_hand(stored_item))
if(!stored_item || !user.put_in_active_hand(stored_item))
return
to_chat(user, SPAN_NOTICE("You slide [stored_item] out of [src]."))
playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, 1)
playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, TRUE)
stored_item = null
update_icon()

Expand All @@ -380,28 +403,23 @@
user.update_inv_shoes()

/obj/item/clothing/shoes/Destroy()
if(stored_item)
qdel(stored_item)
stored_item = null
. = ..()
QDEL_NULL(stored_item)
return ..()

/obj/item/clothing/shoes/get_examine_text(mob/user)
. = ..()
if(stored_item)
. += "\nIt is storing \a [stored_item]."

/obj/item/clothing/shoes/attack_hand(mob/living/user)
if(!stored_item) //Only allow someone to take out the stored_item if it's being worn or held. So you can pick them up off the floor
return ..()
if(user.is_mob_incapacitated())
return ..()
if(loc != user)
// Only allow someone to take out the `stored_item` if it's being worn or held, so that you can pick them up off the floor.
if(!stored_item || loc != user || user.is_mob_incapacitated())
return ..()
remove_item(user)

/obj/item/clothing/shoes/attackby(obj/item/attacking_item, mob/living/user)
. = ..()
user.equip_to_slot_if_possible(attacking_item, WEAR_IN_SHOES)
attempt_insert_item(user, attacking_item)

/obj/item/clothing/equipped(mob/user, slot, silent)
if(is_valid_slot(slot, TRUE)) //is it going to a matching clothing slot?
Expand Down
11 changes: 8 additions & 3 deletions code/modules/clothing/shoes/colour.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@
/obj/item/clothing/shoes/red/knife
name = "dirty red shoes"
desc = "Stylish red shoes with a small space to hold a knife."
items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/tool/screwdriver, /obj/item/weapon/straight_razor)
allowed_items_typecache = list(
/obj/item/attachable/bayonet,
/obj/item/weapon/throwing_knife,
/obj/item/weapon/gun/pistol/holdout,
/obj/item/weapon/gun/pistol/clfpistol,
/obj/item/tool/screwdriver,
/obj/item/weapon/straight_razor,
)

/obj/item/clothing/shoes/white
name = "white shoes"
Expand Down Expand Up @@ -90,5 +97,3 @@
..()
if (istype(H, /obj/item/handcuffs))
attach_cuffs(H, user)


92 changes: 42 additions & 50 deletions code/modules/clothing/shoes/marine_shoes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,46 @@
min_cold_protection_temperature = SHOE_MIN_COLD_PROT
max_heat_protection_temperature = SHOE_MAX_HEAT_PROT
siemens_coefficient = 0.7
var/armor_stage = 0
items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/tool/screwdriver, /obj/item/tool/surgery/scalpel, /obj/item/weapon/straight_razor)
var/knife_type
allowed_items_typecache = list(
/obj/item/attachable/bayonet,
/obj/item/weapon/throwing_knife,
/obj/item/weapon/gun/pistol/holdout,
/obj/item/weapon/gun/pistol/clfpistol,
/obj/item/tool/screwdriver,
/obj/item/tool/surgery/scalpel,
/obj/item/weapon/straight_razor,
)
drop_sound = "armorequip"

/obj/item/clothing/shoes/marine/Initialize(mapload, ...)
. = ..()
if(knife_type)
stored_item = new knife_type(src)
update_icon()

/obj/item/clothing/shoes/marine/update_icon()
if(stored_item && !armor_stage)
if(stored_item)
icon_state = "[initial(icon_state)]-1"
else
if(!armor_stage)
icon_state = initial(icon_state)
icon_state = initial(icon_state)

/obj/item/clothing/shoes/marine/knife
knife_type = /obj/item/attachable/bayonet
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/marine/jungle
icon_state = "marine_jungle"
desc = "Don't go walkin' slow, the devil's on the loose."

/obj/item/clothing/shoes/marine/jungle/knife
knife_type = /obj/item/attachable/bayonet
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/marine/brown
icon_state = "marine_brown"
desc = "Standard issue combat boots for combat scenarios or combat situations. All combat, all the time. These are brown."

/obj/item/clothing/shoes/marine/brown/knife
knife_type = /obj/item/attachable/bayonet
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/marine/monkey
name = "monkey combat boots"
desc = "A sturdy pair of combat boots, the reflection of the polished leather reflects your true self."
icon_state = "monkey_shoes"
item_state = "monkey_shoes"
knife_type = /obj/item/attachable/bayonet
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/marine/upp
name = "military combat boots"
Expand All @@ -67,10 +66,9 @@
armor_bullet = CLOTHING_ARMOR_HIGHPLUS
armor_bomb = CLOTHING_ARMOR_MEDIUM
armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH
knife_type = /obj/item/attachable/bayonet/upp

/obj/item/clothing/shoes/marine/upp_knife
knife_type = /obj/item/attachable/bayonet/upp
/obj/item/clothing/shoes/marine/upp/knife
spawn_item_type = /obj/item/attachable/bayonet/upp

/obj/item/clothing/shoes/marine/joe
name = "biohazard boots"
Expand All @@ -80,7 +78,7 @@
armor_bio = CLOTHING_ARMOR_MEDIUMHIGH
armor_rad = CLOTHING_ARMOR_MEDIUMHIGH
armor_internaldamage = CLOTHING_ARMOR_MEDIUMLOW
knife_type = /obj/item/attachable/bayonet
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/dress
name = "dress shoes"
Expand Down Expand Up @@ -120,18 +118,22 @@
flags_heat_protection = BODY_FLAG_FEET
flags_inventory = FPRINT|NOSLIPPING
siemens_coefficient = 0.6
items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/weapon/straight_razor)
allowed_items_typecache = list(
/obj/item/attachable/bayonet,
/obj/item/weapon/throwing_knife,
/obj/item/weapon/gun/pistol/holdout,
/obj/item/weapon/gun/pistol/clfpistol,
/obj/item/weapon/straight_razor,
)

/obj/item/clothing/shoes/veteran/pmc/update_icon()
if(stored_item)
icon_state = "[initial(icon_state)]-1"
else
icon_state = initial(icon_state)

/obj/item/clothing/shoes/veteran/pmc/knife/Initialize(mapload, ...)
. = ..()
stored_item = new /obj/item/attachable/bayonet(src)
update_icon()
/obj/item/clothing/shoes/veteran/pmc/knife
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/veteran/pmc/commando
name = "\improper PMC commando boots"
Expand All @@ -141,22 +143,13 @@
siemens_coefficient = 0.2
unacidable = TRUE

/obj/item/clothing/shoes/veteran/pmc/commando/knife/Initialize(mapload, ...)
. = ..()
stored_item = new /obj/item/attachable/bayonet(src)
update_icon()
/obj/item/clothing/shoes/veteran/pmc/commando/knife
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/veteran/pmc/van_bandolier
name = "hiking boots"
desc = "Over stone, over ice, through sun and sand, mud and snow, into raging water and hungry bog, these will never let you down."

/obj/item/clothing/shoes/veteran/pmc/van_bandolier/New()
..()
var/obj/item/attachable/bayonet/upp/knife = new(src)
knife.name = "\improper Fairbairn-Sykes fighting knife"
knife.desc = "This isn't for dressing game or performing camp chores. It's almost certainly not an original. Almost."
stored_item = knife
update_icon()
spawn_item_type = /obj/item/attachable/bayonet/van_bandolier

/obj/item/clothing/shoes/veteran/pmc/commando/cbrn
name = "\improper M3 MOPP boots"
Expand All @@ -165,22 +158,18 @@
item_state = "cbrn"
armor_rad = CLOTHING_ARMOR_GIGAHIGHPLUS
armor_bio = CLOTHING_ARMOR_GIGAHIGHPLUS

/obj/item/clothing/shoes/veteran/pmc/commando/cbrn/Initialize(mapload, ...)
. = ..()
stored_item = new /obj/item/attachable/bayonet(src)
update_icon()
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/marine/corporate
name = "rugged boots"
desc = "These synth-leather boots seem high quality when first worn, but quickly detoriate, especially in the environments the corporate security members these are issued to operate in. Still, better than nothing."
knife_type = /obj/item/attachable/bayonet
spawn_item_type = /obj/item/attachable/bayonet

/obj/item/clothing/shoes/marine/ress
name = "armored sandals"
icon_state = "sandals"
item_state = "sandals"
items_allowed = null
allowed_items_typecache = null

/obj/item/clothing/shoes/hiking
name = "hiking shoes"
Expand All @@ -201,7 +190,13 @@
flags_heat_protection = BODY_FLAG_FEET
flags_inventory = FPRINT|NOSLIPPING
siemens_coefficient = 0.6
items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/weapon/straight_razor)
allowed_items_typecache = list(
/obj/item/attachable/bayonet,
/obj/item/weapon/throwing_knife,
/obj/item/weapon/gun/pistol/holdout,
/obj/item/weapon/gun/pistol/clfpistol,
/obj/item/weapon/straight_razor,
)
var/weed_slowdown_mult = 0.5

/obj/item/clothing/shoes/hiking/equipped(mob/user, slot, silent)
Expand Down Expand Up @@ -239,7 +234,7 @@
flags_heat_protection = BODY_FLAG_FEET
flags_inventory = FPRINT|NOSLIPPING
siemens_coefficient = 0.6
items_allowed = list(
allowed_items_typecache = list(
/obj/item/attachable/bayonet,
/obj/item/weapon/throwing_knife,
/obj/item/weapon/gun/pistol/holdout,
Expand All @@ -248,7 +243,4 @@
flags_atom = NO_NAME_OVERRIDE

/obj/item/clothing/shoes/royal_marine/knife
/obj/item/clothing/shoes/royal_marine/knife/Initialize(mapload, ...)
. = ..()
stored_item = new /obj/item/attachable/bayonet/rmc(src)
update_icon()
spawn_item_type = /obj/item/attachable/bayonet/rmc
2 changes: 1 addition & 1 deletion code/modules/cm_preds/thrall_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
)
thrall = TRUE

items_allowed = list(
allowed_items_typecache = list(
/obj/item/attachable/bayonet,
/obj/item/weapon/throwing_knife,
/obj/item/weapon/gun/pistol/holdout,
Expand Down
9 changes: 4 additions & 5 deletions code/modules/cm_preds/yaut_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
siemens_coefficient = 0.2
min_cold_protection_temperature = SHOE_MIN_COLD_PROT
max_heat_protection_temperature = SHOE_MAX_HEAT_PROT
items_allowed = list(
allowed_items_typecache = list(
/obj/item/weapon/yautja/knife,
/obj/item/weapon/gun/energy/yautja/plasmapistol,
)
Expand Down Expand Up @@ -259,10 +259,9 @@
armor_rad = CLOTHING_ARMOR_MEDIUMHIGH
armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH

/obj/item/clothing/shoes/yautja/hunter/knife/New()
..()
stored_item = new /obj/item/weapon/yautja/knife(src)
update_icon()
/obj/item/clothing/shoes/yautja/hunter/knife
spawn_item_type = /obj/item/weapon/yautja/knife

/obj/item/clothing/under/chainshirt
name = "ancient alien mesh suit"
desc = "A strange alloy weave in the form of a vest. It feels cold with an alien weight."
Expand Down
Loading

0 comments on commit 92a96a8

Please sign in to comment.