mirror of
https://github.com/Sandstorm-Station/Sandstorm-Station-13.git
synced 2026-08-20 03:38:33 +01:00
363 lines
14 KiB
Plaintext
363 lines
14 KiB
Plaintext
/**
|
|
* # Hyperstation 13 fleshlight
|
|
*
|
|
* Humbley request this doesnt get ported to other code bases, we strive to make things unique on our server and we dont have a lot of coders
|
|
* but if you absolutely must. please give us some credit~ <3
|
|
* made by quotefox and heavily modified by SandPoot
|
|
*/
|
|
/obj/item/fleshlight
|
|
name = "fleshlight"
|
|
desc = "A sex toy disguised as a flashlight, used to stimulate someones penis, complete with colour changing sleeve."
|
|
icon = 'modular_sand/icons/obj/fleshlight.dmi'
|
|
icon_state = "fleshlight_base"
|
|
item_state = "fleshlight"
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
var/style = "vagina"
|
|
var/sleevecolor = "#ffcbd4" //pink
|
|
custom_price = 8
|
|
var/mutable_appearance/sleeve
|
|
var/inuse = 0
|
|
|
|
/obj/item/fleshlight/examine(mob/user)
|
|
. = ..()
|
|
. += span_notice("Alt-Click \the [name] to customize it.")
|
|
|
|
/obj/item/fleshlight/update_appearance(updates)
|
|
. = ..()
|
|
cut_overlays()
|
|
sleeve = mutable_appearance(icon, style) // Inherits icon for if an admin wants to var edit it, thank me later.
|
|
sleeve.color = sleevecolor
|
|
add_overlay(sleeve)
|
|
|
|
/obj/item/fleshlight/AltClick(mob/user)
|
|
. = ..()
|
|
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
|
return
|
|
customize(user)
|
|
return TRUE
|
|
|
|
/obj/item/fleshlight/proc/customize(mob/living/user)
|
|
if(src && !user.incapacitated() && in_range(user,src))
|
|
var/new_style = tgui_input_list(usr, "Choose style", "Customize Fleshlight", list("vagina", "anus"))
|
|
if(new_style)
|
|
style = new_style
|
|
update_appearance()
|
|
if(src && !user.incapacitated() && in_range(user,src))
|
|
var/new_color = input(user, "Choose color.", "Customize Fleshlight", sleevecolor) as color|null
|
|
if(new_color)
|
|
sleevecolor = new_color
|
|
update_appearance()
|
|
return TRUE
|
|
|
|
/obj/item/fleshlight/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
|
var/possessive_verb = user.p_their()
|
|
var/message = ""
|
|
var/lust_amt = 0
|
|
if(ishuman(M) && (M?.client?.prefs?.toggles & VERB_CONSENT))
|
|
switch(user.zone_selected)
|
|
if(BODY_ZONE_PRECISE_GROIN)
|
|
var/has_penis = M.has_penis()
|
|
if(has_penis == TRUE || has_penis == HAS_EXPOSED_GENITAL)
|
|
message = (user == M) ? pick("pumps [src] on [possessive_verb] penis") : pick("pumps \the [src] on [M]'s penis")
|
|
lust_amt = NORMAL_LUST
|
|
if(message)
|
|
user.visible_message(span_lewd("[user] [message]."))
|
|
M.handle_post_sex(lust_amt, null, user)
|
|
playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang4.ogg',
|
|
'modular_sand/sound/interactions/bang5.ogg',
|
|
'modular_sand/sound/interactions/bang6.ogg'), 70, 1, -1)
|
|
else if(user.a_intent == INTENT_HARM)
|
|
return ..()
|
|
|
|
/**
|
|
* # Hyperstation 13 portal fleshlight
|
|
* kinky!
|
|
*/
|
|
|
|
/obj/item/portallight
|
|
name = "portal fleshlight"
|
|
desc = "A silver love(TM) fleshlight, used to stimulate someones penis, with bluespace tech that allows lovers to hump at a distance."
|
|
icon = 'modular_sand/icons/obj/fleshlight.dmi'
|
|
icon_state = "unpaired"
|
|
item_state = "fleshlight"
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
var/partnercolor = "#ffcbd4"
|
|
var/partnerbase = "normal"
|
|
var/partnerorgan = "portal_vag"
|
|
custom_price = 20
|
|
var/mutable_appearance/sleeve
|
|
var/mutable_appearance/organ
|
|
var/obj/item/clothing/underwear/briefs/panties/portalpanties/portalunderwear
|
|
var/useable = FALSE
|
|
|
|
/obj/item/portallight/examine(mob/user)
|
|
. = ..()
|
|
if(!portalunderwear)
|
|
. += span_notice("The device is unpaired, to pair, swipe against a pair of portal panties.")
|
|
else
|
|
. += span_notice("The device is paired, and awaiting input. ")
|
|
|
|
/obj/item/portallight/update_appearance(updates)
|
|
. = ..()
|
|
updatesleeve()
|
|
|
|
/obj/item/portallight/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
|
var/message = ""
|
|
var/lust_amt = 0
|
|
var/arouse_only_target = FALSE
|
|
var/obj/item/organ/genital/penis/P
|
|
var/obj/item/organ/genital/vagina/V
|
|
var/target
|
|
if(ishuman(M) && (M?.client?.prefs?.toggles & VERB_CONSENT) && useable) // I promise all those checks are worth it!
|
|
switch(user.zone_selected)
|
|
if(BODY_ZONE_PRECISE_GROIN)
|
|
var/has_penis = M.has_penis()
|
|
if(has_penis == TRUE || has_penis == HAS_EXPOSED_GENITAL)
|
|
message = (user == M) ? pick("fucks into [src]") : pick("forces [M] to fuck into [src]")
|
|
lust_amt = NORMAL_LUST
|
|
P = M.getorganslot(ORGAN_SLOT_PENIS)
|
|
target = P
|
|
if(BODY_ZONE_PRECISE_MOUTH)
|
|
if(M.has_mouth() && !M.is_mouth_covered())
|
|
message = (user == M) ? pick("licks into [src]") : pick("forces [M] to lick into [src]")
|
|
lust_amt = NORMAL_LUST
|
|
arouse_only_target = TRUE
|
|
target = "mouth"
|
|
if(BODY_ZONE_R_ARM)
|
|
if(M.has_hand())
|
|
var/can_interact = FALSE
|
|
for(var/obj/item/bodypart/r_arm/R in M.bodyparts)
|
|
can_interact = TRUE
|
|
if(can_interact)
|
|
message = (user == M) ? pick("touches softly against [src]") : pick("forces [M]'s finger on [src]")
|
|
lust_amt = NORMAL_LUST
|
|
arouse_only_target = TRUE
|
|
target = "hand"
|
|
if(BODY_ZONE_L_ARM)
|
|
if(M.has_hand())
|
|
var/can_interact = FALSE
|
|
for(var/obj/item/bodypart/l_arm/L in M.bodyparts)
|
|
can_interact = TRUE
|
|
if(can_interact)
|
|
message = (user == M) ? pick("touches softly against [src]") : pick("forces [M]'s finger on [src]")
|
|
lust_amt = NORMAL_LUST
|
|
arouse_only_target = TRUE
|
|
target = "hand"
|
|
if(!useable)
|
|
to_chat(user, span_notice("It seems the device has failed or your partner is not wearing their device."))
|
|
if(message)
|
|
var/mob/living/carbon/human/portal_target = ishuman(portalunderwear.loc) && portalunderwear.current_equipped_slot == ITEM_SLOT_UNDERWEAR ? portalunderwear.loc : null
|
|
if(portalunderwear.targetting == "vagina")
|
|
V = portal_target.getorganslot(ORGAN_SLOT_VAGINA)
|
|
if(portal_target && (portal_target?.client?.prefs.toggles & VERB_CONSENT || !portal_target.ckey))
|
|
user.visible_message(span_lewd("[user] [message]."))
|
|
if(!arouse_only_target)
|
|
if(M.handle_post_sex(lust_amt, null, null))
|
|
if(P)
|
|
to_chat(portal_target, span_userlove("You feel a [P.shape] penis of [P.length] inches go deep into your [portalunderwear.targetting] and cum!"))
|
|
switch(user.zone_selected)
|
|
if(BODY_ZONE_PRECISE_GROIN)
|
|
playlewdinteractionsound(loc, pick('modular_sand/sound/interactions/bang4.ogg',
|
|
'modular_sand/sound/interactions/bang5.ogg',
|
|
'modular_sand/sound/interactions/bang6.ogg'), 70, 1, -1)
|
|
if(BODY_ZONE_PRECISE_MOUTH)
|
|
playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
|
|
if(BODY_ZONE_R_ARM)
|
|
playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
|
|
if(BODY_ZONE_L_ARM)
|
|
playlewdinteractionsound(loc, 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
|
|
|
|
var/targeted = portalunderwear.targetting
|
|
if(M != user)
|
|
message = replacetext(message, "[M]", "someone")
|
|
message = replacetext(message, "[src]", "your [targeted]")
|
|
to_chat(portal_target, span_lewd("You feel something on your panties, it [message][P ? ", it is a [P.shape] penis of [P.length] inches" : ""]."))
|
|
if(portal_target.handle_post_sex(lust_amt, null, null))
|
|
switch(portalunderwear.targetting)
|
|
if("vagina")
|
|
to_chat(M, span_userlove("You feel \the [V] squirt over your [target]!"))
|
|
if("anus")
|
|
to_chat(M, span_userlove("You feel the anus constrict on your [target]!"))
|
|
portal_target.do_jitter_animation() //make your partner shake too!
|
|
else
|
|
user.visible_message(span_warning("\The [src] beeps and does not let [M] through."))
|
|
else if(user.a_intent == INTENT_HARM)
|
|
return ..()
|
|
|
|
/obj/item/portallight/proc/updatesleeve()
|
|
//get their looks and vagina colour!
|
|
cut_overlays()//remove current overlays
|
|
|
|
var/mob/living/carbon/human/H = null
|
|
if(ishuman(portalunderwear.loc) && portalunderwear)
|
|
H = portalunderwear.loc
|
|
else
|
|
useable = FALSE
|
|
return
|
|
var/obj/item/organ/genital/G = H.getorganslot("vagina")
|
|
if(!G && portalunderwear.targetting == "vagina")
|
|
useable = FALSE
|
|
return
|
|
if(H) //if the portal panties are on someone.
|
|
if(portalunderwear.current_equipped_slot != ITEM_SLOT_UNDERWEAR)
|
|
useable = FALSE
|
|
return
|
|
|
|
sleeve = mutable_appearance('modular_sand/icons/obj/fleshlight.dmi', "portal_sleeve_normal")
|
|
if(islizard(H)) // lizard nerd
|
|
sleeve = mutable_appearance('modular_sand/icons/obj/fleshlight.dmi', "portal_sleeve_lizard")
|
|
|
|
if(isslimeperson(H)) // slime nerd
|
|
sleeve = mutable_appearance('modular_sand/icons/obj/fleshlight.dmi', "portal_sleeve_slime")
|
|
|
|
if(H.dna.species.name == "Avian") // bird nerd (obviously bad hyper code)
|
|
sleeve = mutable_appearance('modular_sand/icons/obj/fleshlight.dmi', "portal_sleeve_avian")
|
|
|
|
sleeve.color = "#" + H.dna.features["mcolor"]
|
|
add_overlay(sleeve)
|
|
|
|
if(portalunderwear.targetting == "vagina")
|
|
organ = mutable_appearance('modular_sand/icons/obj/fleshlight.dmi', "portal_vag")
|
|
organ.color = G.color
|
|
else
|
|
organ = mutable_appearance('modular_sand/icons/obj/fleshlight.dmi', "portal_anus")
|
|
organ.color = "#" + H.dna.features["mcolor"]
|
|
|
|
useable = TRUE
|
|
add_overlay(organ)
|
|
else
|
|
useable = FALSE
|
|
|
|
/obj/item/portallight/Destroy()
|
|
if(portalunderwear)
|
|
portalunderwear.portallight = null
|
|
if(isliving(portalunderwear.loc))
|
|
portalunderwear.audible_message("[icon2html(portalunderwear, hearers(portalunderwear))] *beep* *beep* *beep*")
|
|
playsound(portalunderwear, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
|
|
to_chat(portalunderwear.loc, span_notice("The panties beep as the link to the [src] is lost."))
|
|
. = ..()
|
|
|
|
/**
|
|
* # Hyperstation 13 portal underwear
|
|
* Wear it, cannot be worn if not pointing to the bits you have.
|
|
*/
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties
|
|
name = "portal panties"
|
|
desc = "A silver love(TM) pair of portal underwear, with bluespace tech allows lovers to hump at a distance. Needs to be paired with a portal fleshlight before use."
|
|
icon = 'modular_sand/icons/obj/fleshlight.dmi'
|
|
icon_state = "portalpanties"
|
|
item_state = "fleshlight"
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
var/obj/item/portallight/portallight
|
|
var/targetting = "vagina"
|
|
equip_delay_self = 2 SECONDS
|
|
equip_delay_other = 5 SECONDS
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/attack_self(mob/user)
|
|
. = ..()
|
|
targetting = targetting == "anus" ? "vagina" : "anus"
|
|
to_chat(user, span_notice("Now when worn the portal will now be facing \an [targetting]."))
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/examine(mob/user)
|
|
. = ..()
|
|
if(!portallight)
|
|
. += span_notice("The device is unpaired, to pair, swipe the fleshlight against this pair of portal panties(TM). ")
|
|
else
|
|
. += span_notice("The device is paired, and awaiting attachment. ")
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/attackby(obj/item/I, mob/living/user) //pairing
|
|
if(istype(I, /obj/item/portallight))
|
|
var/obj/item/portallight/P = I
|
|
if(!P.portalunderwear) //make sure it aint linked to someone else
|
|
portallight = P //pair the fleshlight
|
|
P.portalunderwear = src //pair the panties on the fleshlight.
|
|
P.icon_state = "paired" //we are paired!
|
|
playsound(src, 'sound/machines/ping.ogg', 50, FALSE)
|
|
to_chat(user, span_notice("[P] has been linked up successfully."))
|
|
else
|
|
to_chat(user, span_notice("[P] has already been linked to another pair of underwear."))
|
|
else
|
|
..() //just allows people to hit it with other objects, if they so wished.
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
|
|
if(!..())
|
|
return FALSE
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/human = M
|
|
switch(targetting)
|
|
if("vagina")
|
|
var/has_vagina = !human.has_vagina()
|
|
if(has_vagina == TRUE || has_vagina == HAS_EXPOSED_GENITAL)
|
|
to_chat(human, span_warning("The vagina is covered or there is none!"))
|
|
return FALSE
|
|
if("anus")
|
|
var/has_anus = !human.has_anus()
|
|
if(has_anus == TRUE || has_anus == HAS_EXPOSED_GENITAL)
|
|
to_chat(human, span_warning("The anus is covered or there is none!"))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/equipped(mob/user, slot)
|
|
. = ..()
|
|
switch(slot)
|
|
if(ITEM_SLOT_UNDERWEAR)
|
|
if(!portallight)
|
|
audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
|
|
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
|
|
to_chat(user, span_notice("The panties are not linked to a portal fleshlight."))
|
|
else
|
|
update_portal()
|
|
RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(drop_out))
|
|
else
|
|
update_portal()
|
|
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/dropped(mob/user)
|
|
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
|
|
. = ..()
|
|
update_portal()
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/Destroy()
|
|
if(portallight)
|
|
var/obj/item/portallight/temp = portallight
|
|
moveToNullspace() // loc cannot be human so let's destroy ourselves out of anything
|
|
portallight.portalunderwear = null
|
|
temp.updatesleeve()
|
|
. = ..()
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/proc/drop_out()
|
|
var/mob/living/carbon/human/deleted
|
|
if(ishuman(loc))
|
|
deleted = loc
|
|
forceMove(get_turf(loc))
|
|
dropped(deleted) // Act like we've been dropped
|
|
plane = initial(plane)
|
|
layer = initial(layer)
|
|
update_portal()
|
|
|
|
/obj/item/clothing/underwear/briefs/panties/portalpanties/proc/update_portal()
|
|
if(portallight)
|
|
var/obj/item/portallight/P = portallight
|
|
P.updatesleeve()
|
|
|
|
/obj/item/storage/box/portallight
|
|
name = "Portal Fleshlight and Underwear"
|
|
icon = 'modular_sand/icons/obj/fleshlight.dmi'
|
|
desc = "A small silver box with Silver Love Co embossed."
|
|
icon_state = "box"
|
|
custom_price = 15
|
|
|
|
// portal fleshlight box
|
|
/obj/item/storage/box/portallight/PopulateContents()
|
|
new /obj/item/portallight/(src)
|
|
new /obj/item/clothing/underwear/briefs/panties/portalpanties/(src)
|
|
new /obj/item/paper/fluff/portallight(src)
|
|
|
|
/obj/item/paper/fluff/portallight
|
|
name = "Portal Fleshlight Instructions"
|
|
info = "Thank you for purchasing the Silver Love Portal Fleshlight!<BR>\
|
|
To use, simply register your new portal fleshlight with the provided underwear to link them together. The ask your lover to wear the underwear.<BR>\
|
|
Have fun lovers,<BR>\
|
|
<BR>\
|
|
Wilhelmina Steiner."
|