[MODULAR] Fixes an assortment of bugs related to the interaction menu and toys (#22272)

* Fixes an assortment of bugs related to the interaction menu and toys

* Fixes some bugs, raises the sprite up a bit

And adds one for the toggled version of the DD.

This item is such a mess.

* More fixes/tweaks

* removes this

* Revert "removes this"

This reverts commit b2e50e55cf4597b7eae411732a9c5be2f7ca3f8a.

* Fixes issue with removing one end from someone else causing a bad state

Keeping it simple as possible for now so it is not prone to breaking

* Update dildo.dm

* Sorry CI suite..

* very sorry

* ugh

* This is what happens when you rush

* This is not needed to do twice

* We can also do away with this proc

* I said I wasn't going to refactor further but this bit bothered me

Trimming the fat. I am certain that belt stuff is needed anymore. Also neatens up a bit.

Well tested, no bugs found

* Update modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm
This commit is contained in:
Bloop
2023-07-12 09:57:40 -07:00
committed by GitHub
parent 51450dda19
commit 8a49675874
12 changed files with 156 additions and 83 deletions
@@ -156,14 +156,14 @@
var/item_index = params["item_slot"]
var/mob/living/carbon/human/source = locate(params["userref"])
var/mob/living/carbon/human/target = locate(params["selfref"])
var/obj/item/new_item = source.get_active_held_item()
var/obj/item/existing_item = target.vars[item_index]
var/obj/item/clothing/sextoy/new_item = source.get_active_held_item()
var/obj/item/clothing/sextoy/existing_item = target.vars[item_index]
if(!existing_item && !new_item)
source.show_message(span_warning("No item to insert or remove!"))
return
if(!existing_item && !istype(new_item, /obj/item/clothing/sextoy))
if(!existing_item && !istype(new_item))
source.show_message(span_warning("The item you're holding is not a toy!"))
return
@@ -182,7 +182,7 @@
source,
5 SECONDS,
target,
interaction_key = "interation_[item_index]"
interaction_key = "interaction_[item_index]"
) && can_lewd_strip(source, target, item_index))
if(existing_item)
@@ -193,7 +193,8 @@
source.visible_message(span_purple("[source.name] [internal ? "inserts" : "attaches"] the [new_item.name] [into_or_onto] [target.name]'s [item_index]."), span_purple("You [insert_or_attach] the [new_item.name] [into_or_onto] [target.name]'s [item_index]."), span_purple("You hear someone [insert_or_attach] something [into_or_onto] someone nearby."), vision_distance = 1)
target.vars[item_index] = new_item
new_item.forceMove(target)
target.update_inv_lewd()
new_item.lewd_equipped(target, item_index)
target.update_inv_lewd()
else
source.show_message(span_warning("Failed to adjust [target.name]'s toys!"))
@@ -9,6 +9,28 @@
/// The currently accepted defines are all prefixes with LEWD_SLOT_, and there is one for each lewd organ.
/// See code/__DEFINES/~skyrat_defines/inventory.dm for the full list.
var/lewd_slot_flags = NONE
/// This is to keep track of where we are stored, because sometimes we might want to know that
var/current_equipped_slot
/**
* Called after an item is placed in a lewd slot via the interaction menu. This gets called after equipped() does.
*
* Use this instead of equipped() when dealing with lewd slots. We really should hook this better into the upstream
* equip chain but for now this will have to do.
*
* Arguments:
* * user is mob that equipped it
* * slot(s) that item is equipped to
* * initial is used to indicate whether or not this is the initial equipment (job datums etc) or just a player doing it
*/
/obj/item/clothing/sextoy/proc/lewd_equipped(mob/living/carbon/human/user, slot, initial)
SHOULD_CALL_PARENT(TRUE)
current_equipped_slot = slot
// Give out actions our item has to people who equip it.
for(var/datum/action/action as anything in actions)
give_item_action(action, user)
/obj/item/clothing/sextoy/dropped(mob/user)
..()
@@ -21,6 +43,19 @@
holder.update_inv_lewd()
holder.fan_hud_set_fandom()
// Try to force evacuate it.
/obj/item/clothing/sextoy/moveToNullspace()
if(!ishuman(loc) || !current_equipped_slot)
return ..()
var/mob/living/carbon/human/current_holder = loc
current_holder.dropItemToGround(src, force = TRUE) // Force is true, cause nodrop shouldn't affect lewd items.
current_holder.vars[current_equipped_slot] = null
current_holder.update_inv_lewd()
return ..()
/// A check to confirm if you can open the toy's color/design radial menu
/obj/item/clothing/sextoy/proc/check_menu(mob/living/user)
if(!istype(user))
@@ -36,8 +36,8 @@
/// Creates the designs for the color choice radial menu
/obj/item/clothing/sextoy/eggvib/proc/populate_vib_designs()
vib_designs = list(
"pink" = image(icon = src.icon, icon_state = "[initial(icon_state)]_pink_low[(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? "_on" : ""]"),
"teal" = image(icon = src.icon, icon_state = "[initial(icon_state)]_teal_low[(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? "_on" : ""]"))
"pink" = image(icon = src.icon, icon_state = "[initial(base_icon_state)]_pink_low[(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? "_on" : ""]"),
"teal" = image(icon = src.icon, icon_state = "[initial(base_icon_state)]_teal_low[(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? "_on" : ""]"))
/obj/item/clothing/sextoy/eggvib/AltClick(mob/user)
if(!color_changed)
@@ -110,7 +110,7 @@
toy_on = FALSE
playsound(loc, 'sound/weapons/magout.ogg', 20, TRUE, ignore_walls = FALSE)
/obj/item/clothing/sextoy/eggvib/equipped(mob/living/carbon/human/user, slot, initial)
/obj/item/clothing/sextoy/eggvib/lewd_equipped(mob/living/carbon/human/user, slot, initial)
. = ..()
if(!istype(user))
return
@@ -83,7 +83,7 @@
icon_state = "[base_icon_state]_[current_color]_[current_size]"
worn_icon_state = "[base_icon_state]_[current_color]"
/obj/item/clothing/sextoy/buttplug/equipped(mob/living/carbon/human/user, slot)
/obj/item/clothing/sextoy/buttplug/lewd_equipped(mob/living/carbon/human/user, slot)
. = ..()
if(!istype(user))
return
@@ -36,7 +36,7 @@
. = ..()
worn_icon_state = "[initial(icon_state)]_[breast_type]_[breast_size]"
/obj/item/clothing/sextoy/nipple_clamps/equipped(mob/living/carbon/human/user, slot, initial)
/obj/item/clothing/sextoy/nipple_clamps/lewd_equipped(mob/living/carbon/human/user, slot, initial)
. = ..()
if(!istype(user))
return
@@ -87,7 +87,7 @@
update_icon()
//When condom equipped we doing stuff
/obj/item/clothing/sextoy/condom/equipped(mob/user, slot, initial)
/obj/item/clothing/sextoy/condom/lewd_equipped(mob/user, slot, initial)
. = ..()
if((slot == LEWD_SLOT_PENIS) && condom_state == "unused")
condom_state = "used"
@@ -66,11 +66,11 @@
icon_state = "[base_icon_state][change_sprite ? "_[current_type]" : ""]"
inhand_icon_state = "[base_icon_state][change_sprite ? "_[current_type]" : ""]"
/obj/item/clothing/sextoy/dildo/equipped(mob/living/carbon/human/user, slot)
/obj/item/clothing/sextoy/dildo/lewd_equipped(mob/living/carbon/human/user, slot)
. = ..()
if(!istype(user))
return
if(src == user.anus || src == user.vagina)
if(is_inside_lewd_slot(user))
START_PROCESSING(SSobj, src)
/obj/item/clothing/sextoy/dildo/dropped(mob/user, slot)
@@ -272,16 +272,17 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
w_class = WEIGHT_CLASS_TINY
lewd_slot_flags = LEWD_SLOT_ANUS | LEWD_SLOT_VAGINA
actions_types = list(/datum/action/item_action/take_dildo)
/// If one end of the toy is in your hand
var/in_hands = FALSE
/// Reference to the end of the toy that you can hold when the other end is inserted in you
var/obj/item/clothing/sextoy/dildo_side/the_toy
change_sprite = FALSE
/// If one end of the toy is in your hand
var/end_in_hand = FALSE
/// Reference to the end of the toy that you can hold when the other end is inserted in you
var/obj/item/clothing/sextoy/dildo/double_dildo_end/other_end
/// Whether or not the current location is front or behind
var/in_back = FALSE
/obj/item/clothing/sextoy/dildo/double_dildo/Initialize(mapload)
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
update_mob_action_buttonss()
/obj/item/clothing/sextoy/dildo/double_dildo/populate_dildo_designs()
return
@@ -289,13 +290,15 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
/obj/item/clothing/sextoy/dildo/double_dildo/AltClick(mob/user)
return
/// Proc to update the actionbutton icon
/obj/item/clothing/sextoy/dildo/double_dildo/proc/update_mob_action_buttonss()
var/datum/action/item_action/action_button
if(istype(action_button, /datum/action/item_action/take_dildo))
action_button.button_icon_state = "dildo_side"
action_button.button_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_icons.dmi'
update_icon()
/obj/item/clothing/sextoy/dildo/double_dildo/lewd_equipped(mob/living/carbon/human/user, slot, initial)
. = ..()
in_back = (src == user.anus)
update_icon_state()
/obj/item/clothing/sextoy/dildo/double_dildo/update_icon_state()
. = ..()
icon_state = "[initial(icon_state)]"
worn_icon_state = "[initial(worn_icon_state)][(in_back ? "_back" : "")]"
//button stuff
/datum/action/item_action/take_dildo
@@ -305,10 +308,10 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
/datum/action/item_action/take_dildo/Trigger(trigger_flags)
var/obj/item/clothing/sextoy/dildo/double_dildo/dildo = target
if(istype(dildo))
dildo.check()
dildo.can_take_in_hand()
/// A check to make sure the user can actually take one end in their hand
/obj/item/clothing/sextoy/dildo/double_dildo/proc/check()
/obj/item/clothing/sextoy/dildo/double_dildo/proc/can_take_in_hand()
var/mob/living/carbon/human/user = usr
if(src == user.vagina)
toggle(user)
@@ -317,42 +320,8 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
else
to_chat(user, span_warning("You need to equip [src] before you can use it!"))
/// Code for taking out/putting away the other end of the toy when one end is in you
/obj/item/clothing/sextoy/dildo/double_dildo/proc/toggle(mob/living/carbon/human/user)
playsound(user, 'modular_skyrat/modules/modular_items/lewd_items/sounds/latex.ogg', 40, TRUE, ignore_walls = FALSE)
var/obj/item/held = user.get_active_held_item()
var/obj/item/secondary_held = user.get_inactive_held_item()
if(!in_hands)
new_dildo(user)
return FALSE
if((istype(held, /obj/item/clothing/sextoy/dildo/dildo_side) || istype(secondary_held, /obj/item/clothing/sextoy/dildo/dildo_side)) && held?.item_flags == ABSTRACT | HAND_ITEM)
var/qdel_hand = ((istype(held, /obj/item/clothing/sextoy/dildo/dildo_side)) ? held : secondary_held)
QDEL_NULL(qdel_hand)
user.visible_message(span_notice("[user] puts one end of [src] back.")) // I tried to work out what this message is trying to say, but I can't quite get it.
in_hands = FALSE
return
else if(!held)
if(istype(secondary_held, /obj/item/clothing/sextoy/dildo/dildo_side) && secondary_held.item_flags == ABSTRACT | HAND_ITEM)
if(src == user.belt)
QDEL_NULL(secondary_held)
new_dildo(user)
else
user.visible_message(span_notice("[user] tries to hold one end of [src] in [user.p_their()] hand, but [user.p_their()] hand isn't empty!"))
/// Code for creating the other end of the toy when one end's in you
/obj/item/clothing/sextoy/dildo/double_dildo/proc/new_dildo(mob/living/carbon/human/user)
the_toy = new()
user.put_in_hands(the_toy)
the_toy.update_icon_state()
the_toy.update_icon()
user.visible_message(span_notice("[user] holds one end of [src] in [user.p_their()] hand."))
in_hands = TRUE
//dumb way to fix organs overlapping with toys, but WHY NOT. Find a better way if you're not lazy as me.
/obj/item/clothing/sextoy/dildo/double_dildo/equipped(mob/living/carbon/human/user, slot)
/obj/item/clothing/sextoy/dildo/double_dildo/lewd_equipped(mob/living/carbon/human/user, slot)
. = ..()
if(!istype(user))
return
@@ -360,7 +329,7 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
var/obj/item/organ/external/genital/womb/womb = user.get_organ_slot(ORGAN_SLOT_WOMB)
var/obj/item/organ/external/genital/penis/penis = user.get_organ_slot(ORGAN_SLOT_PENIS)
var/obj/item/organ/external/genital/testicles/testicles = user.get_organ_slot(ORGAN_SLOT_TESTICLES)
var/obj/item/organ/external/genital/anus/anus = user.get_organ_slot(ORGAN_SLOT_ANUS)
if(src == user.vagina)
vagina?.visibility_preference = GENITAL_NEVER_SHOW
@@ -370,15 +339,8 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
user.update_body()
else if(src == user.anus)
user.cut_overlay(user.overlays_standing[ANUS_LAYER])
/obj/item/clothing/sextoy/dildo/double_dildo/dropped(mob/living/carbon/human/user)
. = ..()
if(!istype(user))
return
if(the_toy && !ismob(loc) && in_hands && src != user.belt)
QDEL_NULL(the_toy)
in_hands = FALSE
anus?.visibility_preference = GENITAL_NEVER_SHOW
user.update_body()
/obj/item/clothing/sextoy/dildo/double_dildo/process(seconds_per_tick)
var/mob/living/carbon/human/user = loc
@@ -393,31 +355,105 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
if(!istype(user))
return FALSE
if(other_end)
QDEL_NULL(other_end)
var/obj/item/organ/external/genital/vagina/vagina = user.get_organ_slot(ORGAN_SLOT_VAGINA)
var/obj/item/organ/external/genital/womb/womb = user.get_organ_slot(ORGAN_SLOT_WOMB)
var/obj/item/organ/external/genital/penis/penis = user.get_organ_slot(ORGAN_SLOT_PENIS)
var/obj/item/organ/external/genital/testicles/testicles = user.get_organ_slot(ORGAN_SLOT_TESTICLES)
var/obj/item/organ/external/genital/anus/anus = user.get_organ_slot(ORGAN_SLOT_ANUS)
if(!(src == user.vagina))
return FALSE
anus?.visibility_preference = GENITAL_HIDDEN_BY_CLOTHES
user.update_body()
return
vagina?.visibility_preference = GENITAL_HIDDEN_BY_CLOTHES
womb?.visibility_preference = GENITAL_HIDDEN_BY_CLOTHES
penis?.visibility_preference = GENITAL_HIDDEN_BY_CLOTHES
testicles?.visibility_preference = GENITAL_HIDDEN_BY_CLOTHES
user.update_body()
/obj/item/clothing/sextoy/dildo/dildo_side
/obj/item/clothing/sextoy/dildo/double_dildo/Destroy()
moveToNullspace() // This will ensure it gets removed from the world, and from any slots in mobs
if(!QDELETED(other_end))
QDEL_NULL(other_end)
return ..()
/// Code for taking out/putting away the other end of the toy when one end is in you
/obj/item/clothing/sextoy/dildo/double_dildo/proc/toggle(mob/living/carbon/human/user)
playsound(user, 'modular_skyrat/modules/modular_items/lewd_items/sounds/latex.ogg', 40, TRUE, ignore_walls = FALSE)
if(!end_in_hand)
take_in_hand(user)
return
var/obj/item/clothing/sextoy/dildo/double_dildo_end/end_piece = user.is_holding_item_of_type(/obj/item/clothing/sextoy/dildo/double_dildo_end)
if(end_piece)
end_piece.moveToNullspace()
QDEL_NULL(other_end)
user.visible_message(span_notice("[user] releases their grip on one end of the [src]."))
end_in_hand = FALSE
return
/// For holding the other end while the thing is inserted, returns FALSE if unsuccessful
/obj/item/clothing/sextoy/dildo/double_dildo/proc/take_in_hand(mob/living/carbon/human/user)
other_end = new /obj/item/clothing/sextoy/dildo/double_dildo_end
if(!user.put_in_hands(other_end))
user.visible_message(span_notice("[user] tries to hold one end of [src] in [user.p_their()] hand, but [user.p_their()] hand isn't empty!"))
return FALSE
other_end.parent_end = WEAKREF(src)
user.visible_message(span_notice("[user] holds one end of [src] in [user.p_their()] hand."))
end_in_hand = TRUE
return TRUE
/obj/item/clothing/sextoy/dildo/double_dildo_end
name = "dildo side"
desc = "You looking so hot!"
icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_icons.dmi'
icon_state = "dildo_side"
inhand_icon_state = "nothing"
inhand_icon_state = null
worn_icon_state = ""
item_flags = ABSTRACT | HAND_ITEM
side_double = TRUE
/// ref to the parent end
var/datum/weakref/parent_end
/obj/item/clothing/sextoy/dildo_side/dildo/Initialize(mapload)
/obj/item/clothing/sextoy/dildo/double_dildo_end/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, STRAPON_TRAIT)
/obj/item/clothing/sextoy/dildo/double_dildo_end/update_icon_state()
. = ..()
icon_state = "[initial(icon_state)]"
inhand_icon_state = null
worn_icon_state = null
/obj/item/clothing/sextoy/dildo/double_dildo_end/dropped()
. = ..()
if(ismob(loc)) // if it's in a mob we don't want to be qdeleting it just yet
return
if(!QDELETED(src))
QDEL_NULL(src)
/obj/item/clothing/sextoy/dildo/double_dildo_end/Destroy()
var/obj/item/clothing/sextoy/dildo/double_dildo/our_parent = parent_end?.resolve()
if(!our_parent)
parent_end = null
moveToNullspace()
return ..()
moveToNullspace()
our_parent.end_in_hand = FALSE
our_parent.other_end = null
parent_end = null
return ..()
#undef AROUSAL_REGULAR_THRESHOLD
@@ -54,7 +54,7 @@
. = ..()
icon_state = "[base_icon_state]_[vibration_mode]"
/obj/item/clothing/sextoy/magic_wand/equipped(mob/living/carbon/human/user, slot)
/obj/item/clothing/sextoy/magic_wand/lewd_equipped(mob/living/carbon/human/user, slot)
. = ..()
if(vibration_mode == "off" || !istype(user))
return
@@ -79,10 +79,11 @@
icon_state = "[base_icon_state]_[current_color]_[vibration_mode]"
inhand_icon_state = "[base_icon_state]_[current_color]"
/obj/item/clothing/sextoy/vibrator/equipped(mob/user, slot)
/obj/item/clothing/sextoy/vibrator/lewd_equipped(mob/living/carbon/human/user, slot)
. = ..()
var/mob/living/carbon/human/target = user
if(src == target.anus || src == target.vagina)
if(!istype(user))
return
if(is_inside_lewd_slot(user))
START_PROCESSING(SSobj, src)
/obj/item/clothing/sextoy/vibrator/dropped(mob/user, slot)
@@ -67,11 +67,11 @@
icon_state = "[base_icon_state]_[current_color]_[toy_on? "on" : "off"]"
inhand_icon_state = "[base_icon_state]_[current_color]"
/obj/item/clothing/sextoy/vibroring/equipped(mob/living/carbon/human/user, slot, initial)
/obj/item/clothing/sextoy/vibroring/lewd_equipped(mob/living/carbon/human/user, slot, initial)
. = ..()
if(istype(user))
if(!istype(user))
return
if(src == user.penis)
if(is_inside_lewd_slot(user))
START_PROCESSING(SSobj, src)
/obj/item/clothing/sextoy/vibroring/dropped(mob/user, silent)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 57 KiB