more work
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/obj/item/clothing/head/zao
|
||||
name = "zao police cap"
|
||||
desc = "Zao Corps standard issue police force headwear, designed with the overcoat to help with the cold weather. The headwear also features a holographic projector, allowing itself to blend in with the user to create a better face to face interaction with civilians."
|
||||
icon = 'hyperstation/icons/obj/clothing/head.dmi'
|
||||
icon_state = "zaohat"
|
||||
item_state = "helmet"
|
||||
item_color = "zaohat"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/head.dmi'
|
||||
armor = list("melee" = 40, "bullet" = 40, "laser" = 10,"energy" = 20, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 60)
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
strip_delay = 60
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
var/cloaked = 0
|
||||
|
||||
/obj/item/clothing/head/zao/dropped()
|
||||
src.icon_state = "zaohat"
|
||||
src.cloaked=0
|
||||
..()
|
||||
|
||||
/obj/item/clothing/head/zao/verb/cloakcap()
|
||||
set category = "Object"
|
||||
set name = "Cloak hat"
|
||||
|
||||
cloak(usr)
|
||||
|
||||
|
||||
/obj/item/clothing/head/zao/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
cloak(user)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/clothing/head/zao/proc/cloak(mob/user)
|
||||
if(!user.incapacitated())
|
||||
src.cloaked = !src.cloaked
|
||||
if(src.cloaked)
|
||||
icon_state = "zaohat_active"
|
||||
to_chat(user, "<span class='notice'>You toggle the hat\'s cloaking.</span>")
|
||||
else
|
||||
icon_state = "zaohat"
|
||||
to_chat(user, "<span class='notice'>You reveal the hat again.</span>")
|
||||
usr.update_inv_head() //so our mob-overlays update
|
||||
|
||||
/obj/item/clothing/head/zao/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click the hat to toggle it\'s cloaking [cloaked ? "off" : "on"].</span>"
|
||||
@@ -0,0 +1,32 @@
|
||||
/obj/item/clothing/suit/toggle/zao
|
||||
name = "zao overcoat"
|
||||
desc = "Zao Corps signature navy-blue overcoat with a golden highlight finish. Found among police forces as the suit was designed with riot control in mind, it also serves as modest winter coat insulated padding inside."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "zaocoat"
|
||||
item_state = "zaocoat"
|
||||
item_color = "zaocoat"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
togglename = "zipper"
|
||||
body_parts_covered = CHEST|ARMS|LEGS
|
||||
cold_protection = CHEST|GROIN|LEGS|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
strip_delay = 70
|
||||
equip_delay_other = 40
|
||||
max_integrity = 250
|
||||
resistance_flags = FLAMMABLE
|
||||
armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 15, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 30)
|
||||
// armor = list("melee" = 50, "bullet" = 50, "laser" = 10, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 60)
|
||||
allowed = list(/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/flashlight,
|
||||
/obj/item/storage/fancy/cigarettes,
|
||||
/obj/item/gun/ballistic,
|
||||
/obj/item/gun/energy,
|
||||
/obj/item/lighter,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/melee/classic_baton/telescopic,
|
||||
/obj/item/reagent_containers/spray/pepper,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/tank/internals/emergency_oxygen,
|
||||
/obj/item/tank/internals/plasmaman,
|
||||
/obj/item/toy) // Will be modifying/removing/adding more at a later date.
|
||||
@@ -0,0 +1,8 @@
|
||||
/obj/item/clothing/under/rank/security/zao
|
||||
name = "zao uniform"
|
||||
desc = "The standard-issue police force uniform of Zao Corp. Made with a more formal approach to a dress shirt attire while retaining the protective fibers and identity with the blue arm bands. Waistcoat encouraged."
|
||||
icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
|
||||
icon_state = "zaounder"
|
||||
item_state = "zaounder"
|
||||
item_color = "zaounder"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
|
||||
@@ -0,0 +1,45 @@
|
||||
/obj/item/clothing/glasses/hud/toggle/zao
|
||||
name = "zao security visor"
|
||||
desc = "A security visor from ZaoCorp designed to deploy and retract it's visor on a whim."
|
||||
icon = 'hyperstation/icons/obj/clothing/glasses.dmi'
|
||||
icon_state = "zaovisor"
|
||||
item_state = "trayson-meson"
|
||||
flash_protect = 1
|
||||
tint = 1
|
||||
flags_cover = GLASSESCOVERSEYES
|
||||
visor_flags_cover = GLASSESCOVERSEYES
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/eyes.dmi'
|
||||
hud_type = DATA_HUD_SECURITY_ADVANCED
|
||||
actions_types = list(/datum/action/item_action/switch_hud)
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightyellow
|
||||
|
||||
/obj/item/clothing/glasses/hud/toggle/zao/attack_self(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/wearer = user
|
||||
if (wearer.glasses != src)
|
||||
return
|
||||
|
||||
if (hud_type)
|
||||
var/datum/atom_hud/H = GLOB.huds[hud_type]
|
||||
H.remove_hud_from(user)
|
||||
|
||||
if (hud_type == DATA_HUD_SECURITY_ADVANCED)
|
||||
icon_state = "zaovisor_off"
|
||||
item_state = "zaovisor_off"
|
||||
hud_type = null
|
||||
flash_protect = 0
|
||||
tint = 0
|
||||
change_glass_color(user, /datum/client_colour/glass_colour/white)
|
||||
else
|
||||
hud_type = DATA_HUD_SECURITY_ADVANCED
|
||||
icon_state = "zaovisor"
|
||||
item_state = "zaovisor"
|
||||
flash_protect = 1
|
||||
tint = 1
|
||||
change_glass_color(user, /datum/client_colour/glass_colour/lightyellow)
|
||||
|
||||
if (hud_type)
|
||||
var/datum/atom_hud/H = GLOB.huds[hud_type]
|
||||
H.add_hud_to(user)
|
||||
user.update_inv_glasses()
|
||||
@@ -0,0 +1,17 @@
|
||||
/obj/item/ashtray
|
||||
name = "ashtray"
|
||||
icon = 'hyperstation/icons/obj/objects.dmi'
|
||||
icon_state = "ashtray"
|
||||
|
||||
/obj/item/ashtray/attackby(obj/item/I, mob/user, params)
|
||||
if (istype(I,/obj/item/clothing/mask/cigarette/))
|
||||
var/obj/item/clothing/mask/cigarette/cig = I
|
||||
if (cig.lit == 1)
|
||||
src.visible_message("[user] crushes [cig] in \the [src], putting it out.")
|
||||
else if (cig.lit == 0)
|
||||
to_chat(user, "You place [cig] in [src].")
|
||||
qdel(cig) //drop it in.
|
||||
|
||||
if (istype(I,/obj/item/cigbutt))
|
||||
to_chat(user, "You place [I] in [src].")
|
||||
qdel(I) //drop it in.
|
||||
@@ -0,0 +1,36 @@
|
||||
//Jay Sparrow
|
||||
#define ROOMY = "ROOMY"
|
||||
//Sorry jay, I killed it.
|
||||
|
||||
/obj/item/bluespace_thread
|
||||
name = "Bluespace Sewing Kit"
|
||||
desc = "Thread infused with bluespace dust to make your clothes a little more roomy. Current sewing technology already incorporates this, so thankfully, the days of needing these are long gone. Good souvenir though."
|
||||
icon = 'hyperstation/icons/obj/bluespace_thread.dmi'
|
||||
icon_state = "thread"
|
||||
item_state = "thread"
|
||||
var/uses = 5 //Give it a few charges so it can last through the shift
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/bluespace_thread/attack_obj(obj/O, mob/living/user)
|
||||
. = ..()
|
||||
if(!istype(O, /obj/item/clothing))
|
||||
user.show_message("<span class='notice'>You find yourself unable to stitch this.</span>", 1)
|
||||
return
|
||||
|
||||
/obj/item/bluespace_thread/attack_self(mob/living/user)
|
||||
user.show_message("<span class='notice'>The spool has [uses] uses remaining.</span>", 1)
|
||||
|
||||
//Let's add this to the loadout screen
|
||||
/datum/gear/bluespace_thread
|
||||
name = "Bluespace Sewing Kit"
|
||||
category =ITEM_SLOT_IN_BACKPACK
|
||||
path = /obj/item/bluespace_thread
|
||||
|
||||
//Crafting recipe
|
||||
/datum/crafting_recipe/bluespace_thread
|
||||
name = "Bluespace Sewing Kit"
|
||||
result = /obj/item/bluespace_thread
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/ore/bluespace_crystal = 1,
|
||||
/obj/item/stack/sheet/cloth = 3)
|
||||
category = CAT_MISC
|
||||
@@ -0,0 +1,128 @@
|
||||
//Made by quotefox
|
||||
//Really needs some work, mainly because condoms should be a container for semen, but I dont know how that works yet. Feel free to improve upon.
|
||||
|
||||
/obj/item/condom
|
||||
name = "condom"
|
||||
desc = "Dont be silly, cover your willy!"
|
||||
icon = 'hyperstation/icons/obj/condom.dmi'
|
||||
throwforce = 0
|
||||
icon_state = "b_condom_wrapped"
|
||||
var/unwrapped = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
price = 1
|
||||
|
||||
obj/item/condom/Initialize(mapload)
|
||||
create_reagents(300, DRAWABLE|NO_REACT)
|
||||
..()
|
||||
|
||||
obj/item/condom/update_icon()
|
||||
switch(reagents.total_volume)
|
||||
if(0 to 49)
|
||||
icon_state = "b_condom_inflated"
|
||||
if(50 to 100)
|
||||
icon_state = "b_condom_inflated_med"
|
||||
if(101 to 249)
|
||||
icon_state = "b_condom_inflated_large"
|
||||
if(250 to 300)
|
||||
icon_state = "b_condom_inflated_huge"
|
||||
..()
|
||||
|
||||
/obj/item/condom/attack_self(mob/user) //Unwrap The Condom in hands
|
||||
if(!istype(user))
|
||||
return
|
||||
if(isliving(user))
|
||||
if(unwrapped == 0)
|
||||
icon_state = "b_condom"
|
||||
unwrapped = 1
|
||||
to_chat(user, "<span class='notice'>You unwrap the condom.</span>")
|
||||
playsound(user, 'sound/items/poster_ripped.ogg', 50, 1, -1)
|
||||
return
|
||||
// if(unwrapped == 1)
|
||||
// new /obj/item/clothing/head/condom(usr.loc)
|
||||
// qdel(src)
|
||||
// to_chat(user, "<span class='notice'>You roll the condom out.</span>")
|
||||
// playsound(user, 'sound/lewd/latex.ogg', 50, 1, -1)
|
||||
// return
|
||||
|
||||
/obj/item/condom/attack(mob/living/carbon/C, mob/living/user) //apply the johnny on another person or yourself
|
||||
|
||||
if(unwrapped == 0 )
|
||||
to_chat(user, "<span class='notice'>You must remove the condom from the package first!</span>")
|
||||
return
|
||||
var/obj/item/organ/genital/penis/P = C.getorganslot("penis")
|
||||
if(P&&P.is_exposed())
|
||||
if(P.condom)
|
||||
to_chat(user, "<span class='notice'>They already have a condom on!</span>")
|
||||
return
|
||||
if(isliving(C)&&isliving(user)&&unwrapped == 1)
|
||||
C.visible_message("<span class='warning'>[user] is trying to put a condom on [C]!</span>",\
|
||||
"<span class='warning'>[user] is trying to put a condom on you!</span>")
|
||||
if(!do_mob(user, C, 4 SECONDS)) //if Failed to put the condom on
|
||||
return
|
||||
var/mob/living/carbon/human/L = C
|
||||
playsound(C, 'sound/lewd/latex.ogg', 50, 1, -1)
|
||||
P.condom = 1 //apply condom
|
||||
P.colourtint = "87ceeb"
|
||||
if(L)
|
||||
L.update_genitals() // apply the colour!
|
||||
to_chat(C, "<span class='userlove'>Your penis feels more safe!</span>")
|
||||
qdel(src)
|
||||
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You can't find anywhere to put the condom on.</span>") //Trying to put it on something without/or with a hidden
|
||||
|
||||
/obj/item/clothing/head/condom //this is ss13, it would be a sin to not include this..
|
||||
name = "condom"
|
||||
icon = 'hyperstation/icons/obj/condom.dmi'
|
||||
desc = "Looks like someone had abit of some fun!"
|
||||
alternate_worn_icon = 'hyperstation/icons/obj/clothing/head.dmi'
|
||||
icon_state = "b_condom_out"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 5, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/removecondom()
|
||||
|
||||
var/obj/item/organ/genital/penis/P = src.getorganslot("penis")
|
||||
if(P.condom)
|
||||
new /obj/item/clothing/head/condom(usr.loc)
|
||||
to_chat(src, "The condom slips off the end of your penis.")
|
||||
P.condom = 0
|
||||
P.colourtint = ""
|
||||
src.update_genitals()
|
||||
|
||||
/obj/item/condom/filled
|
||||
name = "filled condom"
|
||||
icon_state = "b_condom_inflated"
|
||||
unwrapped = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/condom/filled/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
if(!.) //if we're not being caught
|
||||
splat(hit_atom)
|
||||
|
||||
/obj/item/condom/filled/proc/splat(atom/movable/hit_atom)
|
||||
if(isliving(loc))
|
||||
return
|
||||
var/turf/T = get_turf(hit_atom)
|
||||
new/obj/effect/decal/cleanable/semen(T)
|
||||
playsound(T, "sound/misc/splort", 50, TRUE)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/carbon/human/proc/condomclimax()
|
||||
var/obj/item/organ/genital/penis/P = src.getorganslot("penis")
|
||||
if(!istype(P))
|
||||
return
|
||||
if(!P.condom)
|
||||
return
|
||||
|
||||
var/obj/item/condom/filled/C = new
|
||||
P.linked_organ.reagents.trans_to(C, P.linked_organ.reagents.total_volume)
|
||||
C.loc = loc
|
||||
P.condom = FALSE
|
||||
P.colourtint = ""
|
||||
update_genitals()
|
||||
C.update_icon()
|
||||
to_chat(src, "<span class='love'>The condom bubbles outwards and fills with your cum.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
setArousalLoss(0)
|
||||
@@ -0,0 +1,233 @@
|
||||
/obj/decal/stencil
|
||||
name = "stencil"
|
||||
desc = "A letter, one of many used to make words."
|
||||
icon = 'hyperstation/icons/decals/decal_new.dmi'
|
||||
icon_state = "a"
|
||||
anchored = TRUE
|
||||
layer = WALL_OBJ_LAYER
|
||||
|
||||
left
|
||||
pixel_x = -3 //fine-tune from this offset
|
||||
pixel_y = 8
|
||||
alpha = 200
|
||||
a
|
||||
name = "a"
|
||||
icon_state = "a"
|
||||
b
|
||||
name = "b"
|
||||
icon_state = "b"
|
||||
c
|
||||
name = "c"
|
||||
icon_state = "c"
|
||||
d
|
||||
name = "d"
|
||||
icon_state = "d"
|
||||
e
|
||||
name = "e"
|
||||
icon_state = "e"
|
||||
f
|
||||
name = "f"
|
||||
icon_state = "f"
|
||||
g
|
||||
name = "g"
|
||||
icon_state = "g"
|
||||
h
|
||||
name = "h"
|
||||
icon_state = "h"
|
||||
i
|
||||
name = "i"
|
||||
icon_state = "i"
|
||||
j
|
||||
name = "j"
|
||||
icon_state = "j"
|
||||
k
|
||||
name = "k"
|
||||
icon_state = "k"
|
||||
l
|
||||
name = "l"
|
||||
icon_state = "l"
|
||||
m
|
||||
name = "m"
|
||||
icon_state = "m"
|
||||
n
|
||||
name = "n"
|
||||
icon_state = "n"
|
||||
o
|
||||
name = "o"
|
||||
icon_state = "o"
|
||||
p
|
||||
name = "p"
|
||||
icon_state = "p"
|
||||
q
|
||||
name = "q"
|
||||
icon_state = "q"
|
||||
r
|
||||
name = "r"
|
||||
icon_state = "r"
|
||||
s
|
||||
name = "s"
|
||||
icon_state = "s"
|
||||
t
|
||||
name = "t"
|
||||
icon_state = "t"
|
||||
u
|
||||
name = "u"
|
||||
icon_state = "u"
|
||||
v
|
||||
name = "v"
|
||||
icon_state = "v"
|
||||
w
|
||||
name = "w"
|
||||
icon_state = "w"
|
||||
x
|
||||
name = "x"
|
||||
icon_state = "x"
|
||||
y
|
||||
name = "y"
|
||||
icon_state = "y"
|
||||
z
|
||||
name = "z"
|
||||
icon_state = "z"
|
||||
one
|
||||
name = "one"
|
||||
icon_state = "1"
|
||||
two
|
||||
name = "two"
|
||||
icon_state = "2"
|
||||
three
|
||||
name = "three"
|
||||
icon_state = "3"
|
||||
four
|
||||
name = "four"
|
||||
icon_state = "4"
|
||||
five
|
||||
name = "five"
|
||||
icon_state = "5"
|
||||
six
|
||||
name = "six"
|
||||
icon_state = "6"
|
||||
seven
|
||||
name = "seven"
|
||||
icon_state = "7"
|
||||
eight
|
||||
name = "eight"
|
||||
icon_state = "8"
|
||||
nine
|
||||
name = "nine"
|
||||
icon_state = "9"
|
||||
zero
|
||||
name = "zero"
|
||||
icon_state = "0"
|
||||
|
||||
right
|
||||
pixel_x = 13 // fine-tune from this offset
|
||||
pixel_y = 8
|
||||
alpha = 200
|
||||
a
|
||||
name = "a"
|
||||
icon_state = "a"
|
||||
b
|
||||
name = "b"
|
||||
icon_state = "b"
|
||||
c
|
||||
name = "c"
|
||||
icon_state = "c"
|
||||
d
|
||||
name = "d"
|
||||
icon_state = "d"
|
||||
e
|
||||
name = "e"
|
||||
icon_state = "e"
|
||||
f
|
||||
name = "f"
|
||||
icon_state = "f"
|
||||
g
|
||||
name = "g"
|
||||
icon_state = "g"
|
||||
h
|
||||
name = "h"
|
||||
icon_state = "h"
|
||||
i
|
||||
name = "i"
|
||||
icon_state = "i"
|
||||
j
|
||||
name = "j"
|
||||
icon_state = "j"
|
||||
k
|
||||
name = "k"
|
||||
icon_state = "k"
|
||||
l
|
||||
name = "l"
|
||||
icon_state = "l"
|
||||
m
|
||||
name = "m"
|
||||
icon_state = "m"
|
||||
n
|
||||
name = "n"
|
||||
icon_state = "n"
|
||||
o
|
||||
name = "o"
|
||||
icon_state = "o"
|
||||
p
|
||||
name = "p"
|
||||
icon_state = "p"
|
||||
q
|
||||
name = "q"
|
||||
icon_state = "q"
|
||||
r
|
||||
name = "r"
|
||||
icon_state = "r"
|
||||
s
|
||||
name = "s"
|
||||
icon_state = "s"
|
||||
t
|
||||
name = "t"
|
||||
icon_state = "t"
|
||||
u
|
||||
name = "u"
|
||||
icon_state = "u"
|
||||
v
|
||||
name = "v"
|
||||
icon_state = "v"
|
||||
w
|
||||
name = "w"
|
||||
icon_state = "w"
|
||||
x
|
||||
name = "x"
|
||||
icon_state = "x"
|
||||
y
|
||||
name = "y"
|
||||
icon_state = "y"
|
||||
z
|
||||
name = "z"
|
||||
icon_state = "z"
|
||||
one
|
||||
name = "one"
|
||||
icon_state = "1"
|
||||
two
|
||||
name = "two"
|
||||
icon_state = "2"
|
||||
three
|
||||
name = "three"
|
||||
icon_state = "3"
|
||||
four
|
||||
name = "four"
|
||||
icon_state = "4"
|
||||
five
|
||||
name = "five"
|
||||
icon_state = "5"
|
||||
six
|
||||
name = "six"
|
||||
icon_state = "6"
|
||||
seven
|
||||
name = "seven"
|
||||
icon_state = "7"
|
||||
eight
|
||||
name = "eight"
|
||||
icon_state = "8"
|
||||
nine
|
||||
name = "nine"
|
||||
icon_state = "9"
|
||||
zero
|
||||
name = "zero"
|
||||
icon_state = "0"
|
||||
@@ -0,0 +1,169 @@
|
||||
//Hyper station economy. Because coding it yourself is easier than port sometimes.
|
||||
|
||||
/obj/machinery/atm
|
||||
name = "automated teller machine"
|
||||
desc = "a wall mounted electronic banking outlet for accessing your bank account."
|
||||
icon = 'hyperstation/icons/obj/economy.dmi'
|
||||
icon_state = "atm"
|
||||
max_integrity = 250
|
||||
integrity_failure = 100
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30)
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
power_channel = ENVIRON
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/obj/item/card/held_card
|
||||
var/user = ""
|
||||
light_power = 0
|
||||
light_range = 7
|
||||
light_color = "#ff3232"
|
||||
var/pin = 0
|
||||
|
||||
/obj/machinery/atm/ui_interact(mob/user)
|
||||
. = ..()
|
||||
var/dat = {""}
|
||||
dat += "<p>"
|
||||
dat += "<center><span class = 'big'><p>ATM</span></span></h1>"
|
||||
dat += "<b><p>Welcome to General Station 13's Automated Teller Service.</b>"
|
||||
dat += "<p>"
|
||||
if(!held_card)
|
||||
dat += "<p>Welcome, please insert your ID to continue."
|
||||
else
|
||||
dat += "<p>Welcome user, <a href='byond://?src=[REF(src)];card=1'>[held_card ? user : "------"]</a><br><br>"
|
||||
var/obj/item/card/id/idcard = held_card
|
||||
if(idcard.registered_account)
|
||||
dat += "<p>Account ID: <b>([idcard.registered_account.account_id])</b>"
|
||||
else
|
||||
dat += "<p>Error, this account number does not exsist, please contact your local administration.</b>"
|
||||
|
||||
if(idcard.registered_account)
|
||||
if(!idcard.registered_account.account_pin || pin == idcard.registered_account.account_pin)
|
||||
dat += "<p>Balance: <b>$[idcard.registered_account.account_balance]</b>"
|
||||
//dat += "<p>Offstation Balance: <b()</b>"
|
||||
dat += "<p>"
|
||||
dat += "<a href='byond://?src=[REF(src)];withdraw=1'>Withdraw</A>"
|
||||
dat += "<a href='byond://?src=[REF(src)];changepin=1'>Change Pin</A>"
|
||||
//dat += "<a href='byond://?src=[REF(src)];settings=1'>Account Settings</A>"
|
||||
dat += "<a href='byond://?src=[REF(src)];card=1'>Eject</A>"
|
||||
else
|
||||
dat += "<p>Please enter your bank pin to continue!"
|
||||
dat += "<p>"
|
||||
dat += "<a href='byond://?src=[REF(src)];pin=1'>[pin ? pin : "----"]</a><br><br>"
|
||||
|
||||
dat += "<p></center>"
|
||||
|
||||
dat += "<p>"
|
||||
|
||||
|
||||
var/datum/browser/popup = new(user, "atm", "ATM")
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state), 500,300)
|
||||
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/atm/attackby(obj/item/I, mob/living/user)
|
||||
if(istype(I, /obj/item/card)) //input id!
|
||||
if(!held_card)
|
||||
var/obj/item/card/id/idcard = I
|
||||
if(!user.transferItemToLoc(I, src)) //check if you can put it in
|
||||
return
|
||||
held_card = idcard
|
||||
user = idcard.registered_name
|
||||
pin = ""
|
||||
playsound(src, 'sound/machines/button.ogg', 50, FALSE)
|
||||
src.ui_interact(usr)
|
||||
|
||||
if(istype(I, /obj/item/stack/credits)) //feed money back into the machine! dont need a pin to donate stuff.
|
||||
if(held_card)
|
||||
var/obj/item/stack/credits/cred = I
|
||||
var/obj/item/card/id/idcard = held_card
|
||||
idcard.registered_account.account_balance = (idcard.registered_account.account_balance+cred.amount)
|
||||
to_chat(usr, "<span class='notice'>You insert [cred] into the ATM.</span>")
|
||||
src.ui_interact(usr)
|
||||
del(cred)
|
||||
|
||||
/obj/machinery/atm/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["card"])
|
||||
if(held_card)
|
||||
if(usr.CanReach(src))
|
||||
playsound(src, 'sound/machines/button.ogg', 50, FALSE)
|
||||
if(usr.put_in_hands(held_card))
|
||||
to_chat(usr, "<span class='notice'>You take the ID out of the slot.</span>")
|
||||
held_card = null
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The machine drops the ID onto the floor!</span>")
|
||||
held_card = null
|
||||
pin = ""
|
||||
user = ""
|
||||
|
||||
if(href_list["pin"])
|
||||
playsound(src, get_sfx("terminal_type"), 25, 1)
|
||||
var/pininput = input(user, "Input pin", "Pin Number") as num|null
|
||||
if(pininput)
|
||||
if(pininput > 9999 || pininput < 1000)
|
||||
to_chat(usr, "<span class='notice'>[src.name] buzzes, you must input a 4 digit number between 1000 and 9999.</span>")
|
||||
return
|
||||
pin = max(min( round(text2num(pininput)), 9999),1000) //4 numbers or less.
|
||||
var/obj/item/card/id/idcard = held_card
|
||||
if(pin == idcard.registered_account.account_pin)
|
||||
to_chat(usr, "<span class='notice'>[src.name] beeps, accepting the pin.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>[src.name] buzzes, denying the pin.</span>")
|
||||
|
||||
if(href_list["changepin"])
|
||||
playsound(src, get_sfx("terminal_type"), 25, 1)
|
||||
var/pinchange = input(user, "Input pin", "Pin Number") as num|null
|
||||
if(pinchange > 9999 || pinchange < 1000)
|
||||
to_chat(usr, "<span class='warning'>[src.name], you must have a 4 digit number for a pin and be between 1000 and 9999.</span>")
|
||||
return
|
||||
if(pinchange)
|
||||
var/pinchange2 = input(user, "Confirm pin", "Confirm pin") as num|null //time to confirm!
|
||||
if(pinchange == pinchange2)
|
||||
var/obj/item/card/id/idcard = held_card
|
||||
idcard.registered_account.account_pin = pinchange
|
||||
to_chat(usr, "<span class='notice'>[src.name] beeps, your pin has been changed to [pinchange]!.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>[src.name] buzzes, your pins did not match!</span>")
|
||||
pin = ""
|
||||
|
||||
if(href_list["withdraw"])
|
||||
playsound(src, get_sfx("terminal_type"), 25, 1)
|
||||
if(held_card)
|
||||
var/obj/item/card/id/idcard = held_card
|
||||
if(idcard.registered_account)
|
||||
var/amount = input(user, "Choose amount", "Withdraw") as num|null
|
||||
if(amount>0)
|
||||
amount = max(min( round(text2num(amount)), idcard.registered_account.account_balance),0) //make sure they aint taking out more then what they have
|
||||
to_chat(usr, "<span class='notice'>The machine prints out [amount] credits.</span>")
|
||||
idcard.registered_account.account_balance = (idcard.registered_account.account_balance-amount) //subtract the amount they took out.
|
||||
var/obj/item/stack/credits/C = new /obj/item/stack/credits/(loc)
|
||||
C.amount = amount
|
||||
if(usr.put_in_hands(C))
|
||||
to_chat(usr, "<span class='notice'>You take [C] out of the ATM.</span>")
|
||||
|
||||
src.ui_interact(usr)
|
||||
|
||||
|
||||
//Money, Well, get back, I'm all right Jack, Keep your hands off of my stack.
|
||||
//making our own currency, just to stop exploits (for now)
|
||||
|
||||
/obj/item/stack/credits
|
||||
name = "credits"
|
||||
singular_name = "credit"
|
||||
desc = "Legal tender, a bundle of shiny metalic looking notes."
|
||||
icon = 'hyperstation/icons/obj/economy.dmi'
|
||||
icon_state = "cash"
|
||||
amount = 1
|
||||
max_amount = 99999999
|
||||
throwforce = 0
|
||||
throw_speed = 2
|
||||
throw_range = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
full_w_class = WEIGHT_CLASS_TINY
|
||||
resistance_flags = FLAMMABLE
|
||||
var/value = 1
|
||||
@@ -0,0 +1,392 @@
|
||||
//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 alot of coders
|
||||
//but if you absolutely must. please give us some credit~ <3
|
||||
//made by quotefox
|
||||
|
||||
/obj/item/fleshlight
|
||||
name = "fleshlight"
|
||||
desc = "A sex toy disguised as a flashlight, used to stimulate someones penis, complete with colour changing sleeve."
|
||||
icon = 'hyperstation/icons/obj/fleshlight.dmi'
|
||||
icon_state = "fleshlight_base"
|
||||
item_state = "fleshlight"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/sleevecolor = "#ffcbd4" //pink
|
||||
price = 8
|
||||
var/mutable_appearance/sleeve
|
||||
var/inuse = 0
|
||||
|
||||
/obj/item/fleshlight/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-Click \the [src.name] to customize it.</span>"
|
||||
|
||||
/obj/item/fleshlight/Initialize(mapload)
|
||||
. = ..()
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "vagina")
|
||||
sleeve.color = sleevecolor
|
||||
add_overlay(sleeve)
|
||||
|
||||
/obj/item/fleshlight/AltClick(mob/user)
|
||||
. = ..()
|
||||
var/style = input(usr, "Choose style", "Customize Fleshlight", "vagina") in list("vagina", "anus")
|
||||
var/new_color = input(user, "Choose color.", "Customize Fleshlight", sleevecolor) as color|null
|
||||
if(new_color)
|
||||
cut_overlays()
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', style)
|
||||
sleevecolor = new_color
|
||||
sleeve.color = new_color
|
||||
add_overlay(sleeve)
|
||||
return TRUE
|
||||
|
||||
/obj/item/fleshlight/attack(mob/living/carbon/C, mob/living/user)
|
||||
var/obj/item/organ/genital/penis/P = C.getorganslot("penis")
|
||||
if(inuse == 1) //just to stop stacking and causing people to cum instantly
|
||||
return
|
||||
if(P&&P.is_exposed())
|
||||
inuse = 1
|
||||
if(!(C == user)) //if we are targeting someone else.
|
||||
C.visible_message("<span class='userlove'>[user] is trying to use [src] on [C]'s penis.</span>", "<span class='userlove'>[user] is trying to use [src] on your penis.</span>")
|
||||
|
||||
if(!do_mob(user, C, 3 SECONDS)) //3 second delay
|
||||
inuse = 0
|
||||
return
|
||||
|
||||
//checked if not used on yourself, if not, carry on.
|
||||
playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) //slapping sound
|
||||
inuse = 0
|
||||
if(!(C == user)) //lewd flavour text
|
||||
C.visible_message("<span class='userlove'>[user] pumps [src] on [C]'s penis.</span>", "<span class='userlove'>[user] pumps [src] up and down on your penis.</span>")
|
||||
else
|
||||
user.visible_message("<span class='userlove'>[user] pumps [src] on their penis.</span>", "<span class='userlove'>You pump the fleshlight on your penis.</span>")
|
||||
|
||||
if(prob(30)) //30% chance to make them moan.
|
||||
C.emote("moan")
|
||||
|
||||
C.do_jitter_animation()
|
||||
C.adjust_arousal(20) //make the target more aroused.
|
||||
if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
|
||||
C.mob_climax(forced_climax=TRUE) //make them cum if they are over the edge.
|
||||
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You don't see anywhere to use this on.</span>")
|
||||
|
||||
inuse = 0
|
||||
..()
|
||||
|
||||
|
||||
//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 = 'hyperstation/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"
|
||||
price = 20
|
||||
var/mutable_appearance/sleeve
|
||||
var/mutable_appearance/organ
|
||||
var/inuse = 0
|
||||
var/paired = 0
|
||||
var/obj/item/portalunderwear
|
||||
var/useable = FALSE
|
||||
var/option = ""
|
||||
|
||||
/obj/item/portallight/examine(mob/user)
|
||||
. = ..()
|
||||
if(!portalunderwear)
|
||||
. += "<span class='notice'>The device is unpaired, to pair, swipe against a pair of portal panties. </span>"
|
||||
else
|
||||
. += "<span class='notice'>The device is paired, and awaiting input. </span>"
|
||||
|
||||
/obj/item/portallight/attack(mob/living/carbon/C, mob/living/user) //use portallight! nearly the same as the fleshlight apart from you have a buddy!
|
||||
var/obj/item/organ/genital/penis/P = C.getorganslot("penis")
|
||||
|
||||
if(inuse) //just to stop stacking and causing people to cum instantly
|
||||
return
|
||||
if(!useable)
|
||||
to_chat(user, "<span class='notice'>It seems the device has failed or your partner is not wearing their device.</span>")
|
||||
|
||||
if(C == user)//if your using it on yourself, more options! otherwise, just fuck.
|
||||
option = input(usr, "Choose action", "Portal Fleshlight", "Fuck") in list("Fuck", "Lick", "Touch")
|
||||
else
|
||||
option = "Fuck"
|
||||
|
||||
var/obj/item/organ/genital/G
|
||||
if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime error.
|
||||
G = portalunderwear.loc
|
||||
if(!G)
|
||||
return
|
||||
var/mob/living/carbon/human/M = G.owner
|
||||
|
||||
if(option == "Fuck"&&!P.is_exposed()) //we are trying to fuck with no penis!
|
||||
to_chat(user, "<span class='notice'>You don't see anywhere to use this on.</span>")
|
||||
return
|
||||
else //other options dont need checks
|
||||
inuse = 1
|
||||
if(!(C == user)) //if we are targeting someone else.
|
||||
C.visible_message("<span class='userlove'>[user] is trying to use [src] on [C]'s penis.</span>", "<span class='userlove'>[user] is trying to use [src] on your penis.</span>")
|
||||
|
||||
if(!do_mob(user, C, 3 SECONDS)) //3 second delay
|
||||
inuse = 0
|
||||
return
|
||||
|
||||
//checked if not used on yourself, if not, carry on.
|
||||
if(option == "Fuck")
|
||||
playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) //slapping sound for fuck.
|
||||
|
||||
inuse = 0
|
||||
if(!(C == user))
|
||||
C.visible_message("<span class='userlove'>[user] pumps [src] on [C]'s penis.</span>", "<span class='userlove'>[user] pumps [src] up and down on your penis.</span>")
|
||||
else
|
||||
if(option == "Fuck")
|
||||
user.visible_message("<span class='userlove'>[user] pumps [src] on their penis.</span>", "<span class='userlove'>You pump the fleshlight on your penis.</span>")
|
||||
if(option == "Lick")
|
||||
user.visible_message("<span class='userlove'>[user] licks into [src].</span>", "<span class='userlove'>You lick into [src].</span>")
|
||||
if(option == "Touch")
|
||||
user.visible_message("<span class='userlove'>[user] touches softly against [src].</span>", "<span class='userlove'>You touch softly on [src].</span>")
|
||||
|
||||
|
||||
if(prob(30)) //30% chance to make your partner moan.
|
||||
M.emote("moan")
|
||||
|
||||
if(option == "Fuck")// normal fuck
|
||||
to_chat(M, "<span class='love'>You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [G.name].</span>")//message your partner, and kinky!
|
||||
if(prob(30)) //30% chance to make them moan.
|
||||
C.emote("moan")
|
||||
if(prob(30)) //30% chance to make your partner moan.
|
||||
M.emote("moan")
|
||||
C.adjust_arousal(20)
|
||||
M.adjust_arousal(20)
|
||||
M.do_jitter_animation() //make your partner shake too!
|
||||
|
||||
if (M.getArousalLoss() >= 100 && ishuman(M) && prob(5))//Why not have a probability to cum when someone's getting nailed with max arousal?~
|
||||
if(G.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill
|
||||
M.mob_climax_outside(G, spillage = TRUE)
|
||||
else
|
||||
M.mob_climax_outside(G, spillage = FALSE)
|
||||
|
||||
if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
|
||||
var/mob/living/carbon/human/O = C
|
||||
|
||||
if( (P.condom == 1) || (P.sounding == 1)) //If coundomed and/or sounded, do not fire impreg chance
|
||||
O.mob_climax_partner(P, M, FALSE, FALSE, FALSE, TRUE)
|
||||
else //Else, fire impreg chance
|
||||
if(G.name == "vagina") //no more spontaneous impregnations through the butt!
|
||||
O.mob_climax_partner(P, M, FALSE, TRUE, FALSE, TRUE)
|
||||
else
|
||||
O.mob_climax_partner(P, M, FALSE, FALSE, FALSE, TRUE)
|
||||
|
||||
if(option == "Lick")
|
||||
to_chat(M, "<span class='love'>You feel a tongue lick you through the portal against your [G.name].</span>")
|
||||
M.adjust_arousal(10)
|
||||
if(option == "Touch")
|
||||
to_chat(M, "<span class='love'>You feel someone touching your [G.name] through the portal.</span>")
|
||||
M.adjust_arousal(5)
|
||||
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/portallight/proc/updatesleeve()
|
||||
//get their looks and vagina colour!
|
||||
cut_overlays()//remove current overlays
|
||||
|
||||
var/obj/item/organ/genital/G
|
||||
if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime.
|
||||
G = portalunderwear.loc
|
||||
if(!G)
|
||||
useable = FALSE
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = G.owner
|
||||
|
||||
if(H) //if the portal panties are on someone.
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_normal")
|
||||
if(H.dna.species.name == "Lizardperson") // lizard nerd
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_lizard")
|
||||
|
||||
if(H.dna.species.name == "Slimeperson") // slime nerd
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_slime")
|
||||
|
||||
if(H.dna.species.name == "Avian") // bird nerd
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_avian")
|
||||
|
||||
sleeve.color = "#" + H.dna.features["mcolor"]
|
||||
add_overlay(sleeve)
|
||||
|
||||
if(G.name == "vagina")
|
||||
organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
|
||||
organ.color = portalunderwear.loc.color
|
||||
if(G.name == "anus")
|
||||
organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus")
|
||||
organ.color = "#" + H.dna.features["mcolor"]
|
||||
|
||||
useable = TRUE
|
||||
add_overlay(organ)
|
||||
else
|
||||
useable = FALSE
|
||||
|
||||
//Hyperstation 13 portal underwear
|
||||
//can be attached to vagina or anus, just like the vibrator, still requires pairing with the portallight
|
||||
|
||||
/obj/item/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 = 'hyperstation/icons/obj/fleshlight.dmi'
|
||||
icon_state = "portalpanties"
|
||||
item_state = "fleshlight"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/obj/item/portallight
|
||||
var/attached = FALSE
|
||||
var/shapetype = "vagina"
|
||||
|
||||
/obj/item/portalpanties/examine(mob/user)
|
||||
. = ..()
|
||||
if(!portallight)
|
||||
. += "<span class='notice'>The device is unpaired, to pair, swipe the fleshlight against this pair of portal panties(TM). </span>"
|
||||
else
|
||||
. += "<span class='notice'>The device is paired, and awaiting attachment. </span>"
|
||||
|
||||
|
||||
/obj/item/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 class='notice'>[P] has been linked up successfully.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[P] has already been linked to another pair of underwear.</span>")
|
||||
else
|
||||
..() //just allows people to hit it with other objects, if they so wished.
|
||||
|
||||
/obj/item/portalpanties/attack(mob/living/carbon/C, mob/living/user)
|
||||
|
||||
if(!portallight) //we arent paired yet! noobie trap, let them know.
|
||||
to_chat(user, "<span class='warning'>[src] can only be attached once paired with a portal fleshlight.</span>")
|
||||
return
|
||||
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
var/mob/living/carbon/human/S = user
|
||||
var/mob/living/carbon/human/T = C
|
||||
picked_organ = S.target_genitals(T)
|
||||
if(picked_organ)
|
||||
C.visible_message("<span class='warning'>[user] is trying to attach [src] to [T]!</span>",\
|
||||
"<span class='warning'>[user] is trying to put [src] on you!</span>")
|
||||
if(!do_mob(user, C, 3 SECONDS))//warn them and have a delay of 5 seconds to apply.
|
||||
return
|
||||
|
||||
if((picked_organ.name == "vagina")||(picked_organ.name == "anus")) //only fits on a vagina or anus
|
||||
|
||||
src.shapetype = picked_organ.name
|
||||
if(!picked_organ.equipment)
|
||||
to_chat(user, "<span class='love'>You wrap [src] around [T]'s [picked_organ.name].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>They already have [picked_organ.equipment.name] there.</span>")
|
||||
return
|
||||
|
||||
if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
|
||||
return
|
||||
src.attached = TRUE
|
||||
picked_organ.equipment = src
|
||||
|
||||
var/obj/item/portallight/P = portallight
|
||||
//now we need to send what they look like, but saddly if the person changes colour for what ever reason, it wont update. but dont tell people shh.
|
||||
if(P) //just to make sure
|
||||
P.updatesleeve()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] can only be attached to a vagina or anus.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You don't see anywhere to attach this.</span>")
|
||||
|
||||
/obj/item/portalpanties/proc/remove() //if taken off update it.
|
||||
if(portallight)
|
||||
var/obj/item/portallight/P = portallight
|
||||
P.updatesleeve()
|
||||
|
||||
/obj/item/storage/box/portallight
|
||||
name = "Portal Fleshlight and Underwear"
|
||||
icon = 'hyperstation/icons/obj/fleshlight.dmi'
|
||||
desc = "A small silver box with Silver Love Co embossed."
|
||||
icon_state = "box"
|
||||
price = 15
|
||||
|
||||
// portal fleshlight box
|
||||
/obj/item/storage/box/portallight/PopulateContents()
|
||||
new /obj/item/portallight/(src)
|
||||
new /obj/item/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."
|
||||
|
||||
//Happy Halloween!
|
||||
//Can be crafted with a knife and a pumpkin in the crafting menu (misc category).
|
||||
//I have no regrets.
|
||||
|
||||
// /obj/item/twohanded/required/cumpkin
|
||||
|
||||
// name = "Cumpkin"
|
||||
// desc = "A carved pumpkin with a suspicious inviting hole behind it, maybe you could 'use' it for a while..."
|
||||
// icon = 'hyperstation/icons/obj/fleshlight.dmi'
|
||||
// icon_state = "cumpkin"
|
||||
// item_state = "cumpkin"
|
||||
// lefthand_file = 'hyperstation/icons/mob/item_lefthand.dmi'
|
||||
// righthand_file = 'hyperstation/icons/mob/item_righthand.dmi'
|
||||
// w_class = WEIGHT_CLASS_SMALL
|
||||
// price = 10
|
||||
// var/inuse = 0
|
||||
|
||||
// /obj/item/twohanded/required/cumpkin/attack(mob/living/carbon/C, mob/living/user)
|
||||
// var/obj/item/organ/genital/penis/P = C.getorganslot("penis")
|
||||
// if(inuse == 1) //just to stop stacking and causing people to cum instantly
|
||||
// return
|
||||
// if(P&&P.is_exposed())
|
||||
// inuse = 1
|
||||
// if(!(C == user)) //if we are targeting someone else.
|
||||
// C.visible_message("<span class='userlove'>[user] is trying to use [src] on [C]'s penis.</span>", "<span class='userlove'>[user] is trying to use [src] on your penis.</span>")
|
||||
|
||||
// if(!do_mob(user, C, 3 SECONDS)) //3 second delay
|
||||
// inuse = 0
|
||||
// return
|
||||
|
||||
// //checked if not used on yourself, if not, carry on.
|
||||
// playsound(src, 'sound/lewd/slaps.ogg', 30, 1, -1) //slapping sound
|
||||
// inuse = 0
|
||||
// if(!(C == user)) //lewd flavour text
|
||||
// C.visible_message("<span class='userlove'>[user] pumps [src] on [C]'s penis.</span>", "<span class='userlove'>[user] pumps [src] up and down on your penis.</span>")
|
||||
// else
|
||||
// user.visible_message("<span class='userlove'>[user] pumps [src] on their penis.</span>", "<span class='userlove'>You pump the cumpkin on your penis.</span>")
|
||||
|
||||
// if(prob(30)) //30% chance to make them moan.
|
||||
// C.emote("moan")
|
||||
|
||||
// C.do_jitter_animation()
|
||||
// C.adjust_arousal(20) //make the target more aroused.
|
||||
// if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
|
||||
// C.mob_climax(forced_climax=TRUE) //make them cum if they are over the edge.
|
||||
|
||||
// return
|
||||
|
||||
// else
|
||||
// to_chat(user, "<span class='notice'>You don't see anywhere to use this on.</span>")
|
||||
|
||||
// inuse = 0
|
||||
// ..()
|
||||
|
||||
// /datum/crafting_recipe/cumpkin
|
||||
// name = "Cumpkin"
|
||||
// time = 30
|
||||
// reqs = list(/obj/item/reagent_containers/food/snacks/grown/pumpkin = 1)
|
||||
// tools = list(/obj/item/kitchen/knife)
|
||||
// result = /obj/item/twohanded/required/cumpkin
|
||||
// category = CAT_MISC
|
||||
@@ -0,0 +1,17 @@
|
||||
/obj/structure/medscreen/
|
||||
name = "medical screen"
|
||||
desc = "No peaking now!"
|
||||
icon_state = "screen"
|
||||
icon = 'hyperstation/icons/obj/medical.dmi'
|
||||
anchored = TRUE
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
integrity_failure = 30
|
||||
var/buildstacktype = /obj/item/stack/sheet/metal
|
||||
var/buildstackamount = 2
|
||||
density = TRUE
|
||||
|
||||
/obj/structure/medscreen/Moved()
|
||||
. = ..()
|
||||
if(has_gravity())
|
||||
playsound(src, 'sound/effects/roll.ogg', 100, 1)
|
||||
@@ -0,0 +1,131 @@
|
||||
/obj/item/clothing/gloves/latexsleeves
|
||||
name = "latex sleeves"
|
||||
desc = "A pair of shiny latex sleeves that covers ones arms."
|
||||
icon_state = "latex"
|
||||
item_state = "latex"
|
||||
icon = 'hyperstation/icons/obj/clothing/gloves.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/gloves.dmi'
|
||||
mutantrace_variation = NONE
|
||||
price = 5
|
||||
|
||||
/obj/item/clothing/gloves/latexsleeves/security
|
||||
name = "security sleeves"
|
||||
desc = "A pair of latex sleeves, with a band of red above the elbows denoting that the wearer is part of the security team."
|
||||
icon_state = "latexsec"
|
||||
item_state = "latexsec"
|
||||
price = 5
|
||||
|
||||
/obj/item/clothing/head/dominatrixcap
|
||||
name = "dominatrix cap"
|
||||
desc = "A sign of authority, over the body."
|
||||
icon_state = "dominatrix"
|
||||
item_state = "dominatrix"
|
||||
icon = 'hyperstation/icons/obj/clothing/head.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/head.dmi'
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/shoes/highheels
|
||||
name = "high heels"
|
||||
desc = "They make the wearer appear taller, and more noisey!"
|
||||
icon_state = "highheels"
|
||||
item_state = "highheels"
|
||||
icon = 'hyperstation/icons/obj/clothing/shoes.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/feet.dmi'
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/highheels/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, list('sound/effects/footstep/highheel1.ogg' = 1,'sound/effects/footstep/highheel2.ogg' = 1), 20)
|
||||
//the classic click clack
|
||||
|
||||
obj/item/clothing/neck/stole
|
||||
name = "white boa"
|
||||
desc = "Fluffy neck wear to keep you warm, and attract others."
|
||||
icon = 'hyperstation/icons/obj/clothing/neck.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon_state = "stole"
|
||||
item_state = "" //no inhands
|
||||
price = 3
|
||||
|
||||
obj/item/clothing/neck/stole/black
|
||||
name = "black boa"
|
||||
desc = "Fluffy neck wear to keep you warm, and attract others."
|
||||
icon = 'hyperstation/icons/obj/clothing/neck.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon_state = "stole"
|
||||
item_state = "" //no inhands
|
||||
color = "#3d3d3d"
|
||||
price = 3
|
||||
|
||||
/obj/item/clothing/suit/fluffyhalfcrop
|
||||
name = "fluffy half-crop jacket"
|
||||
desc = "A fluffy synthetic fur half-cropped jacket, less about warmth, more about style!"
|
||||
icon_state = "fluffy"
|
||||
item_state = "fluffy"
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
body_parts_covered = CHEST|LEGS|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/under/latexfull
|
||||
name = "full latex jumpsuit"
|
||||
desc = "A tight fitting jumpsuit made of latex."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "latex"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/latexhalf
|
||||
name = "latex bodysuit"
|
||||
desc = "A tight fitting outfit made of latex, that covers the wearers torso."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "latexhalf"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = NONE
|
||||
do_not_cover_butt = TRUE
|
||||
|
||||
/obj/item/clothing/under/sexynursesuit
|
||||
name = "Sexy nurse outfit"
|
||||
desc = "A very revealing nurse's outfit. Not very sanitary. Does it even count as clothing?"
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "sexynursesuit"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/under/centcomdress
|
||||
name = "Centcom Dress Uniform"
|
||||
desc = "A stylish yet revealing dress uniform worn in extravagent black and gold, worthy of those who sit around and watch cameras all day in an office."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "ccdress"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
//We will never know why CC can make their skimpy outfits tough as nails
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
cold_protection = CHEST|GROIN|ARMS
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
heat_protection = CHEST|GROIN|ARMS
|
||||
armor = list("melee" = 60, "bullet" = 80, "laser" = 80, "energy" = 90, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
|
||||
/obj/item/clothing/under/centcomdressvk
|
||||
name = "Virginkiller Centcom Dress Uniform"
|
||||
desc = "This black and gold beauty does not help paperwork get done, it seems."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "ccdressvk"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
//We will never know why CC can make their skimpy outfits tough as nails
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
cold_protection = CHEST|GROIN|ARMS
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
heat_protection = CHEST|GROIN|ARMS
|
||||
armor = list("melee" = 60, "bullet" = 80, "laser" = 80, "energy" = 90, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
@@ -0,0 +1,426 @@
|
||||
//Jay Sparrow
|
||||
//TODO
|
||||
/*
|
||||
Icons, maybe?
|
||||
*/
|
||||
|
||||
#define STATUS_EFFECT_LEASH_PET /datum/status_effect/leash_pet
|
||||
#define STATUS_EFFECT_LEASH_DOM /datum/status_effect/leash_dom
|
||||
#define STATUS_EFFECT_LEASH_FREEPET /datum/status_effect/leash_freepet
|
||||
#define MOVESPEED_ID_LEASH "LEASH"
|
||||
|
||||
/////STATUS EFFECTS/////
|
||||
//These are mostly used as flags for the states each member can be in
|
||||
|
||||
/datum/status_effect/leash_dom
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
alert_type = /obj/screen/alert/status_effect/leash_dom
|
||||
|
||||
/obj/screen/alert/status_effect/leash_dom
|
||||
name = "Leash Master"
|
||||
desc = "You've got a leash, and a cute pet on the other end."
|
||||
icon_state = "leash_master" //These call icons that don't exist, so no icon comes up. Which is good.
|
||||
//As a result, the descriptions also don't proc, which is fine.
|
||||
|
||||
/datum/status_effect/leash_freepet
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
alert_type = /obj/screen/alert/status_effect/leash_freepet
|
||||
|
||||
/obj/screen/alert/status_effect/leash_freepet
|
||||
name = "Escaped Pet"
|
||||
desc = "You're on a leash, but you've no master. If anyone grabs the leash they'll gain control!"
|
||||
icon_state = "leash_freepet"
|
||||
|
||||
|
||||
/datum/status_effect/leash_pet
|
||||
id = "leashed"
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
var/mob/redirect_component
|
||||
alert_type = /obj/screen/alert/status_effect/leash_pet
|
||||
|
||||
/obj/screen/alert/status_effect/leash_pet
|
||||
name = "Leashed Pet"
|
||||
desc = "You're on the hook now! Be good for your master."
|
||||
icon_state = "leash_pet"
|
||||
|
||||
|
||||
/datum/status_effect/leash_pet/on_apply()
|
||||
//redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src,PROC_REF(owner_resist)))))
|
||||
RegisterSignal(owner, COMSIG_LIVING_RESIST,PROC_REF(owner_resist))
|
||||
redirect_component = owner
|
||||
if(!owner.stat)
|
||||
to_chat(owner, "<span class='userdanger'>You have been leashed!</span>")
|
||||
return ..()
|
||||
|
||||
//This lets the pet resist their leash
|
||||
/datum/status_effect/leash_pet/proc/owner_resist()
|
||||
to_chat(owner, "You reach for the hook on your collar...")
|
||||
//Determine how long it takes to remove the leash
|
||||
var/deleash = 15
|
||||
//if(owner.get_item_by_slot(SLOT_HANDCUFFED)) //Commented out because there is no clear way to make this proc BEFORE decuff on resist.
|
||||
//deleash = 100
|
||||
if(do_mob(owner, owner, deleash))//do_mob creates a progress bar and then enacts the code after. Owner, owner, because it's an act on themself
|
||||
if(!QDELETED(src))
|
||||
to_chat(owner, "<span class='warning'>[owner] has removed their leash!</span>")
|
||||
owner.remove_status_effect(/datum/status_effect/leash_pet)
|
||||
|
||||
///// OBJECT /////
|
||||
//The leash object itself
|
||||
//The component variables are used for hooks, used later.
|
||||
|
||||
/obj/item/leash
|
||||
name = "leash"
|
||||
desc = "A simple tether that can easily be hooked onto a collar. Perfect for your pet."
|
||||
icon = 'hyperstation/icons/obj/leash.dmi'
|
||||
icon_state = "leash"
|
||||
item_state = "leash"
|
||||
throw_range = 4
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 1
|
||||
throwforce = 1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/leash_used = 0 //A flag to see if the leash has been used yet, because for some reason picking up an unused leash is weird
|
||||
var/mob/living/leash_pet = "null" //Variable to store our pet later
|
||||
var/mob/living/leash_master = "null" //And our master too
|
||||
var/mob/mobhook_leash_pet
|
||||
var/mob/mobhook_leash_master //Needed to watch for these entities to move
|
||||
var/mob/mobhook_leash_freepet
|
||||
var/leash_location[3] //Three digit list for us to store coordinates later
|
||||
|
||||
//Called when someone is clicked with the leash
|
||||
/obj/item/leash/attack(mob/living/carbon/C, mob/living/user) //C is the target, user is the one with the leash
|
||||
if(C.has_status_effect(/datum/status_effect/leash_pet)) //If the pet is already leashed, do not leash them. For the love of god.
|
||||
to_chat(user, "<span class='notice'>[C] has already been leashed.</span>")
|
||||
return
|
||||
if(istype(C.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/petcollar) || istype(C.get_item_by_slot(SLOT_NECK), /obj/item/electropack/shockcollar))
|
||||
var/leashtime = 50
|
||||
if(C.handcuffed)
|
||||
leashtime = 5
|
||||
if(do_mob(user, C, leashtime)) //do_mob adds a progress bar, but then we also check to see if they have a collar
|
||||
log_combat(user, C, "leashed", addition="playfully")
|
||||
//TODO: Figure out how to make an easy breakout for leashed leash_pets
|
||||
C.apply_status_effect(/datum/status_effect/leash_pet)//Has now been leashed
|
||||
user.apply_status_effect(/datum/status_effect/leash_dom) //Is the leasher
|
||||
leash_pet = C //Save pet reference for later
|
||||
leash_master = user //Save dom reference for later
|
||||
//mobhook_leash_pet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src,PROC_REF(on_pet_move))))
|
||||
RegisterSignal(leash_pet, COMSIG_MOVABLE_MOVED,PROC_REF(on_pet_move))
|
||||
mobhook_leash_pet = leash_pet
|
||||
//mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src,PROC_REF(on_master_move))))
|
||||
RegisterSignal(leash_master, COMSIG_MOVABLE_MOVED,PROC_REF(on_master_move))
|
||||
mobhook_leash_master = leash_master
|
||||
leash_used = 1
|
||||
if(!leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Add slowdown if the pet didn't leash themselves
|
||||
leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH, multiplicative_slowdown = 5)
|
||||
for(var/mob/viewing in viewers(user, null))
|
||||
if(viewing == leash_master)
|
||||
to_chat(leash_master, "<span class='warning'>You have hooked a leash onto [leash_pet]!</span>")
|
||||
else
|
||||
viewing.show_message("<span class='warning'>[leash_pet] has been leashed by [leash_master]!</span>", 1)
|
||||
if(leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Pet leashed themself. They are not the dom
|
||||
leash_pet.apply_status_effect(/datum/status_effect/leash_freepet)
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_dom)
|
||||
while(1) //While true loop. The mark of a genius coder. ##MAINLOOP START
|
||||
sleep(2) //Check every other tick
|
||||
if(leash_pet == "null") //No pet, break loop
|
||||
return
|
||||
if(!(leash_pet.get_item_by_slot(SLOT_NECK))) //The pet has slipped their collar and is not the pet anymore.
|
||||
for(var/mob/viewing in viewers(user, null))
|
||||
viewing.show_message("<span class='notice'>[leash_pet] has slipped out of their collar!!</span>", 1)
|
||||
to_chat(leash_pet, "<span class='notice'>You have slipped out of your collar!</span>")
|
||||
to_chat(loc, "<span class='notice'>[leash_pet] has slipped out of their collar!</span>")
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_pet)
|
||||
|
||||
if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) //If there is no pet, there is no dom. Loop breaks.
|
||||
//QDEL_NULL(mobhook_leash_master)
|
||||
UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED)
|
||||
//QDEL_NULL(mobhook_leash_pet)
|
||||
UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED)
|
||||
//QDEL_NULL(mobhook_leash_freepet)
|
||||
UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED)
|
||||
if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet))
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_freepet)
|
||||
if(leash_pet.has_movespeed_modifier(MOVESPEED_ID_LEASH))
|
||||
leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH)
|
||||
if(!leash_master == "null")
|
||||
leash_master.remove_status_effect(/datum/status_effect/leash_dom)
|
||||
leash_used = 0 //reset the leash to neutral
|
||||
leash_pet = "null"
|
||||
return
|
||||
|
||||
else //No collar, no fun
|
||||
var/leash_message = pick("Your pet needs a collar")
|
||||
to_chat(user, "<span class='notice'>[leash_message]</span>")
|
||||
|
||||
//Called when the leash is used in hand
|
||||
//Tugs the pet closer
|
||||
/obj/item/leash/attack_self(mob/living/user)
|
||||
if(!leash_pet == "null") //No pet, no tug.
|
||||
return
|
||||
//Yank the pet. Yank em in close.
|
||||
if(leash_pet.x > leash_master.x + 1)
|
||||
step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed.
|
||||
if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master
|
||||
step(leash_pet, SOUTH, 1)
|
||||
if(leash_pet.y < leash_master.y)
|
||||
step(leash_pet, NORTH, 1)
|
||||
if(leash_pet.x < leash_master.x - 1)
|
||||
step(leash_pet, EAST, 1)
|
||||
if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master
|
||||
step(leash_pet, SOUTH, 1)
|
||||
if(leash_pet.y < leash_master.y)
|
||||
step(leash_pet, NORTH, 1)
|
||||
if(leash_pet.y > leash_master.y + 1)
|
||||
step(leash_pet, SOUTH, 1)
|
||||
if(leash_pet.x > leash_master.x)//Check the other axis, and tug them into alignment so they are behind the master
|
||||
step(leash_pet, WEST, 1)
|
||||
if(leash_pet.x < leash_master.x)
|
||||
step(leash_pet, EAST, 1)
|
||||
if(leash_pet.y < leash_master.y - 1)
|
||||
step(leash_pet, NORTH, 1)
|
||||
if(leash_pet.x > leash_master.x)//Check the other axis, and tug them into alignment so they are behind the master
|
||||
step(leash_pet, WEST, 1)
|
||||
if(leash_pet.x < leash_master.x)
|
||||
step(leash_pet, EAST, 1)
|
||||
|
||||
/obj/item/leash/proc/on_master_move()
|
||||
//Make sure the dom still has a pet
|
||||
if(leash_master == "null") //There must be a master
|
||||
return
|
||||
if(leash_pet == "null") //There must be a pet
|
||||
return
|
||||
if(leash_pet == leash_master) //Pet is the master
|
||||
return
|
||||
if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet))
|
||||
//QDEL_NULL(mobhook_leash_master) //Probably redundant, but it's nice to be safe
|
||||
UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED)
|
||||
leash_master.remove_status_effect(/datum/status_effect/leash_dom)
|
||||
return
|
||||
|
||||
//If the master moves, pull the pet in behind
|
||||
sleep(2) //A small sleep so the pet kind of bounces back after they make the step
|
||||
//Also, the sleep means that the distance check for master happens before the pet, to prevent both from proccing.
|
||||
|
||||
if(leash_master == "null") //Just to stop error messages
|
||||
return
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
if(leash_pet.x > leash_master.x + 2)
|
||||
step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed.
|
||||
if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master
|
||||
step(leash_pet, SOUTH, 1)
|
||||
if(leash_pet.y < leash_master.y)
|
||||
step(leash_pet, NORTH, 1)
|
||||
if(leash_pet.x < leash_master.x - 2)
|
||||
step(leash_pet, EAST, 1)
|
||||
if(leash_pet.y > leash_master.y)
|
||||
step(leash_pet, SOUTH, 1)
|
||||
if(leash_pet.y < leash_master.y)
|
||||
step(leash_pet, NORTH, 1)
|
||||
if(leash_pet.y > leash_master.y + 2)
|
||||
step(leash_pet, SOUTH, 1)
|
||||
if(leash_pet.x > leash_master.x)
|
||||
step(leash_pet, WEST, 1)
|
||||
if(leash_pet.x < leash_master.x)
|
||||
step(leash_pet, EAST, 1)
|
||||
if(leash_pet.y < leash_master.y - 2)
|
||||
step(leash_pet, NORTH, 1)
|
||||
if(leash_pet.x > leash_master.x)
|
||||
step(leash_pet, WEST, 1)
|
||||
if(leash_pet.x < leash_master.x)
|
||||
step(leash_pet, EAST, 1)
|
||||
|
||||
//Knock the pet over if they get further behind. Shouldn't happen too often.
|
||||
sleep(3) //This way running normally won't just yank the pet to the ground.
|
||||
if(leash_master == "null") //Just to stop error messages. Break the loop early if something removed the master
|
||||
return
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
if(leash_pet.x > leash_master.x + 3 || leash_pet.x < leash_master.x - 3 || leash_pet.y > leash_master.y + 3 || leash_pet.y < leash_master.y - 3)
|
||||
//var/leash_knockdown_message = "[leash_pet] got pulled to the ground by their leash!"
|
||||
//to_chat(leash_master, "<span class='notice'>[leash_knockdown_message]</span>")
|
||||
//to_chat(leash_pet, "<span class='notice'>[leash_knockdown_message]</span>")
|
||||
leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0)
|
||||
|
||||
//This code is to check if the pet has gotten too far away, and then break the leash.
|
||||
sleep(3) //Wait to snap the leash
|
||||
if(leash_master == "null") //Just to stop error messages
|
||||
return
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
if(leash_pet.x > leash_master.x + 5 || leash_pet.x < leash_master.x - 5 || leash_pet.y > leash_master.y + 5 || leash_pet.y < leash_master.y - 5)
|
||||
var/leash_break_message = "The leash snapped free from [leash_pet]!"
|
||||
for(var/mob/viewing in viewers(leash_pet, null))
|
||||
if(viewing == leash_master)
|
||||
to_chat(leash_master, "<span class='warning'>The leash snapped free from your pet!</span>")
|
||||
if(viewing == leash_pet)
|
||||
to_chat(leash_pet, "<span class='warning'>Your leash has popped from your collar!</span>")
|
||||
else
|
||||
viewing.show_message("<span class='warning'>[leash_break_message]</span>", 1)
|
||||
leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0)
|
||||
leash_pet.adjustOxyLoss(5)
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_pet)
|
||||
leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH)
|
||||
leash_master.remove_status_effect(/datum/status_effect/leash_dom)
|
||||
//QDEL_NULL(mobhook_leash_master)
|
||||
UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED)
|
||||
//QDEL_NULL(mobhook_leash_pet)
|
||||
UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED)
|
||||
leash_pet = "null"
|
||||
leash_master = "null"
|
||||
leash_used = 0
|
||||
|
||||
/obj/item/leash/proc/on_pet_move()
|
||||
//This should only work if there is a pet and a master.
|
||||
//This is here pretty much just to stop the console from flooding with errors
|
||||
if(leash_master == "null")
|
||||
return
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
//Make sure the pet is still a pet
|
||||
if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet))
|
||||
//QDEL_NULL(mobhook_leash_pet) //Probably redundant, but it's nice to be safe
|
||||
UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED)
|
||||
return
|
||||
|
||||
//The pet has escaped. There is no DOM. GO PET RUN.
|
||||
if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet))//If the pet is free, break
|
||||
return
|
||||
|
||||
//If the pet gets too far away, they get tugged back
|
||||
sleep(3)//A small sleep so the pet kind of bounces back after they make the step
|
||||
if(leash_master == "null")
|
||||
return
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
//West tug
|
||||
if(leash_pet.x > leash_master.x + 2)
|
||||
step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed.
|
||||
//East tug
|
||||
if(leash_pet.x < leash_master.x - 2)
|
||||
step(leash_pet, EAST, 1)
|
||||
//South tug
|
||||
if(leash_pet.y > leash_master.y + 2)
|
||||
step(leash_pet, SOUTH, 1)
|
||||
//North tug
|
||||
if(leash_pet.y < leash_master.y - 2)
|
||||
step(leash_pet, NORTH, 1)
|
||||
|
||||
/obj/item/leash/proc/on_freepet_move()
|
||||
//Pet is on the run. Let's drag the leash behind them.
|
||||
if(!leash_master == "null") //If there is a master, don't do this
|
||||
return
|
||||
if(leash_pet == "null") //If there is no pet, don't do this
|
||||
return
|
||||
if(leash_pet.is_holding_item_of_type(/obj/item/leash)) //If the pet is holding the leash, don't do this
|
||||
return
|
||||
|
||||
sleep(2)
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
//Double move to catch the leash up to the pet
|
||||
if(src.x > leash_pet.x + 2)
|
||||
. = step(src, WEST, 1)
|
||||
if(src.x < leash_pet.x - 2)
|
||||
. = step(src, EAST, 1)
|
||||
if(src.y > leash_pet.y + 2)
|
||||
. = step(src, SOUTH, 1)
|
||||
if(src.y < leash_pet.y - 2)
|
||||
. = step(src, NORTH, 1)
|
||||
//Primary dragging code
|
||||
if(src.x > leash_pet.x + 1)
|
||||
. = step(src, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed.
|
||||
if(src.y > leash_pet.y)//Check the other axis, and tug them into alignment so they are behind the pet
|
||||
. = step(src, SOUTH, 1)
|
||||
if(src.y < leash_pet.y)
|
||||
. = step(src, NORTH, 1)
|
||||
if(src.x < leash_pet.x - 1)
|
||||
. = step(src, EAST, 1)
|
||||
if(src.y > leash_pet.y)
|
||||
. = step(src, SOUTH, 1)
|
||||
if(src.y < leash_pet.y)
|
||||
. = step(src, NORTH, 1)
|
||||
if(src.y > leash_pet.y + 1)
|
||||
. = step(src, SOUTH, 1)
|
||||
if(src.x > leash_pet.x)
|
||||
. = step(src, WEST, 1)
|
||||
if(src.x < leash_pet.x)
|
||||
. = step(src, EAST, 1)
|
||||
if(src.y < leash_pet.y - 1)
|
||||
. = step(src, NORTH, 1)
|
||||
if(src.x > leash_pet.x)
|
||||
. = step(src, WEST, 1)
|
||||
if(src.x < leash_pet.x)
|
||||
. = step(src, EAST, 1)
|
||||
|
||||
sleep(1)
|
||||
//Just to prevent error messages
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
if(src.x > leash_pet.x + 5 || src.x < leash_pet.x - 5 || src.y > leash_pet.y + 5 || src.y < leash_pet.y - 5)
|
||||
var/leash_break_message = "The leash snapped free from [leash_pet]!"
|
||||
for(var/mob/viewing in viewers(leash_pet, null))
|
||||
if(viewing == leash_pet)
|
||||
to_chat(leash_pet, "<span class='warning'>Your leash has popped from your collar!</span>")
|
||||
else
|
||||
viewing.show_message("<span class='warning'>[leash_break_message]</span>", 1)
|
||||
leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0)
|
||||
leash_pet.adjustOxyLoss(5)
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_pet)
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_freepet)
|
||||
//QDEL_NULL(mobhook_leash_pet)
|
||||
UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED)
|
||||
//QDEL_NULL(mobhook_leash_freepet)
|
||||
UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED)
|
||||
leash_pet = "null"
|
||||
leash_used = 0
|
||||
|
||||
/obj/item/leash/dropped() //Drop the leash, and the leash effects stop
|
||||
. = ..()
|
||||
if(leash_pet == "null") //There is no pet. Stop this silliness
|
||||
return
|
||||
if(leash_master == "null")
|
||||
return
|
||||
//Dropping procs any time the leash changes slots. So, we will wait a tick and see if the leash was actually dropped
|
||||
sleep(1)
|
||||
if(leash_master.is_holding_item_of_type(/obj/item/leash) || istype(leash_master.get_item_by_slot(SLOT_BELT), /obj/item/leash))
|
||||
return //Dom still has the leash as it turns out. Cancel the proc.
|
||||
for(var/mob/viewing in viewers(leash_master, null))
|
||||
viewing.show_message("<span class='notice'>[leash_master] has dropped the leash.</span>", 1)
|
||||
//DOM HAS DROPPED LEASH. PET IS FREE. SCP HAS BREACHED CONTAINMENT.
|
||||
leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH)
|
||||
//mobhook_leash_freepet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src,PROC_REF(on_freepet_move))))
|
||||
RegisterSignal(leash_pet, COMSIG_MOVABLE_MOVED,PROC_REF(on_freepet_move))
|
||||
mobhook_leash_freepet = leash_pet
|
||||
leash_master.remove_status_effect(/datum/status_effect/leash_dom) //No dom with no leash. We will get a new dom if the leash is picked back up.
|
||||
leash_master = "null"
|
||||
//QDEL_NULL(mobhook_leash_master)
|
||||
UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/obj/item/leash/equipped(mob/user)
|
||||
. = ..()
|
||||
if(leash_used == 0) //Don't apply statuses with a fresh leash. Keeps things clean on the backend.
|
||||
return
|
||||
sleep(2)
|
||||
if(leash_pet == "null")
|
||||
return
|
||||
leash_master = user
|
||||
if(leash_master.has_status_effect(/datum/status_effect/leash_freepet) || leash_master.has_status_effect(/datum/status_effect/leash_pet)) //Pet picked up their own leash.
|
||||
leash_master = "null"
|
||||
return
|
||||
leash_master.apply_status_effect(/datum/status_effect/leash_dom)
|
||||
//mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src,PROC_REF(on_master_move))))
|
||||
RegisterSignal(leash_master, COMSIG_MOVABLE_MOVED,PROC_REF(on_master_move))
|
||||
mobhook_leash_master = leash_master
|
||||
leash_pet.remove_status_effect(/datum/status_effect/leash_freepet)
|
||||
//QDEL_NULL(mobhook_leash_freepet)
|
||||
UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED)
|
||||
leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH, multiplicative_slowdown = 5)
|
||||
|
||||
/datum/crafting_recipe/leash
|
||||
name = "Leash"
|
||||
result = /obj/item/leash
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/sheet/metal = 1,
|
||||
/obj/item/stack/sheet/cloth = 3)
|
||||
category = CAT_MISC
|
||||
@@ -0,0 +1,154 @@
|
||||
/obj/structure/lunaraltar
|
||||
name = "lunar altar"
|
||||
desc = "Judging by the symbols, millenia ago, it seems that the creatures of this world used to offer something precious to the icy moon that orbits this hellish planet. You... Wouldn't do that, would you?"
|
||||
icon = 'icons/obj/hand_of_god_structures.dmi' //Placeholder.
|
||||
icon_state = "convertaltar-blue" //Placeholder.
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
var/used = FALSE
|
||||
|
||||
/obj/structure/lunaraltar/Initialize(mapload)
|
||||
. = ..()
|
||||
set_light(2)
|
||||
|
||||
/obj/structure/lunaraltar/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(used)
|
||||
to_chat(user, "<span class='notice'>The altar seems shattered.</span>")
|
||||
return
|
||||
if(istype(user, /mob/living/carbon/human/))
|
||||
var/part = pick("r_arm","l_arm","r_leg","l_leg")
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/bodypart/bodypart
|
||||
var/paralysistype
|
||||
switch(part)
|
||||
if("l_leg")
|
||||
bodypart = H.get_bodypart(BODY_ZONE_L_LEG)
|
||||
paralysistype = TRAIT_PARALYSIS_L_LEG
|
||||
if("r_leg")
|
||||
bodypart = H.get_bodypart(BODY_ZONE_R_LEG)
|
||||
paralysistype = TRAIT_PARALYSIS_R_LEG
|
||||
if("l_arm")
|
||||
bodypart = H.get_bodypart(BODY_ZONE_L_ARM)
|
||||
paralysistype = TRAIT_PARALYSIS_L_ARM
|
||||
if("r_arm")
|
||||
bodypart = H.get_bodypart(BODY_ZONE_R_ARM)
|
||||
paralysistype = TRAIT_PARALYSIS_R_ARM
|
||||
if(!bodypart)
|
||||
to_chat(user, "<span class='notice'>The altar does nothing.</span>")
|
||||
return
|
||||
to_chat(user,"<span class='warning'>You begin placing your hand on the altar.</span>")
|
||||
playsound(src, 'sound/weapons/slice.ogg', 50, 1, 5)
|
||||
if(do_after(user, 100, target=src))
|
||||
if(used)
|
||||
return
|
||||
visible_message("<span class='danger'>[user]'s [bodypart] is momentarily enveloped by shadows before they are gruesomely twisted and dismembered!</span>", \
|
||||
"<span class='userdanger'>Your [bodypart] is momentarily enveloped by shadows before it's gruesomely twisted and dismembered!</span>")
|
||||
bodypart.dismember()
|
||||
bodypart.Destroy()
|
||||
ADD_TRAIT(H, paralysistype, "trauma_paralysis")
|
||||
H.update_disabled_bodyparts()
|
||||
H.bleed_rate += 5
|
||||
H.emote("scream")
|
||||
var/obj/item/lunar = pick(/obj/item/helfiretincture,
|
||||
/obj/item/instrument/guitar/biggerukulele)
|
||||
new lunar(src.loc)
|
||||
visible_message("<span class='warning'>As you blink, cracks appear on the altar and a flash of lunar light reaches its surface. A gift?</span>")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed their [bodypart] on the lunar altar at [AREACOORD(src)].")
|
||||
icon_state = "sacrificealtar-blue"
|
||||
set_light(0)
|
||||
update_icon()
|
||||
used = TRUE
|
||||
|
||||
/obj/item/helfiretincture
|
||||
name = "helfire tincture" //"Hel" not Hell. Intended.
|
||||
icon = 'hyperstation/icons/obj/lunar.dmi'
|
||||
icon_state = "helfire_tincture"
|
||||
desc = "Burn everyone nearby... Including you."
|
||||
var/cooldowntime = 45 SECONDS
|
||||
var/used = FALSE
|
||||
|
||||
/obj/item/helfiretincture/attack_self(mob/user)
|
||||
if(!used)
|
||||
used = TRUE
|
||||
visible_message("<span class='danger'>[user] draws from the power of a Hellfire Tincture!</span>", \
|
||||
"<span class='userdanger'>You draw the power of the Hellfire Tincture!</span>")
|
||||
for(var/mob/living/H in spiral_range(8, user))
|
||||
H.adjustFireLoss(10)
|
||||
H.adjust_fire_stacks(5)
|
||||
H.IgniteMob()
|
||||
playsound(src.loc, 'hyperstation/sound/misc/helfire_use.ogg', 100, 1, extrarange = 8)
|
||||
icon_state = "helfire_tincture_used"
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src,PROC_REF(restore), user), cooldowntime)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's too soon to use this again!</span>")
|
||||
|
||||
/obj/item/helfiretincture/proc/restore(mob/user)
|
||||
used = FALSE
|
||||
icon_state = "helfire_tincture"
|
||||
update_icon()
|
||||
to_chat(user, "<span class='warning'>The tincture vibrates with power once again.</span>")
|
||||
|
||||
|
||||
/obj/item/instrument/guitar/biggerukulele
|
||||
name = "bigger ukulele"
|
||||
desc = "...and his music was electric."
|
||||
icon_state = "biggerukulele"
|
||||
item_state = "guitar"
|
||||
instrumentExt = "ogg"
|
||||
attack_verb = list("played a sick solo on", "electrified", "crashed", "smashed")
|
||||
hitsound = 'sound/weapons/stringsmash.ogg'
|
||||
instrumentId = "guitar"
|
||||
siemens_coefficient = -1
|
||||
hit_reaction_chance = 100
|
||||
var/tesla_power = 25000
|
||||
var/tesla_range = 20
|
||||
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
|
||||
var/legacy = FALSE
|
||||
var/legacy_dmg = 30
|
||||
var/reactive_cooldown_duration = 20
|
||||
var/reactive_cooldown = 0
|
||||
var/firstpickup = TRUE
|
||||
|
||||
/obj/item/instrument/guitar/biggerukulele/dropped(mob/user)
|
||||
..()
|
||||
if(istype(user))
|
||||
user.flags_1 &= ~TESLA_IGNORE_1
|
||||
|
||||
/obj/item/instrument/guitar/biggerukulele/pickup(mob/user)
|
||||
..()
|
||||
if(istype(user))
|
||||
user.flags_1 |= TESLA_IGNORE_1
|
||||
if(firstpickup)
|
||||
SEND_SOUND(user, sound('hyperstation/sound/misc/biggerukulelepickup.ogg', volume = 100))
|
||||
firstpickup = FALSE
|
||||
|
||||
/obj/item/instrument/guitar/biggerukulele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(owner.flags_1 & TESLA_IGNORE_1)
|
||||
//Do literally nothing. Checking for absence of flags doesn't work for whatever reason, so if !TESLA_IGNORE_1 is not an option.
|
||||
else if (owner.flags_1)
|
||||
owner.flags_1 |= TESLA_IGNORE_1 //Sometimes picking up the item doesn't grant the user the flag. This is a way to go around that. Thank you, DM Code.
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactive_cooldown)
|
||||
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
|
||||
sparks.set_up(1, 1, src)
|
||||
sparks.start()
|
||||
owner.visible_message("<span class='danger'>The electric strings of [owner]'s bigger ukulele! The instrument merely emits some sparks.</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
|
||||
if(!legacy)
|
||||
tesla_zap(owner, tesla_range, tesla_power, tesla_flags)
|
||||
playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10)
|
||||
else
|
||||
for(var/mob/living/M in view(7, owner))
|
||||
if(M == owner)
|
||||
continue
|
||||
owner.Beam(M,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5)
|
||||
M.adjustFireLoss(legacy_dmg)
|
||||
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
reactive_cooldown = world.time + reactive_cooldown_duration
|
||||
return TRUE
|
||||
@@ -0,0 +1,83 @@
|
||||
/obj/item/milking_machine
|
||||
icon = 'hyperstation/icons/obj/milking_machine.dmi'
|
||||
name = "milking machine"
|
||||
icon_state = "Off"
|
||||
item_state = "Off"
|
||||
desc = "A pocket sized pump and tubing assembly designed to collect and store products from mammary glands."
|
||||
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKET
|
||||
|
||||
var/on = FALSE
|
||||
var/obj/item/reagent_containers/glass/inserted_item = null
|
||||
|
||||
var/transfer_rate = 0.50 // How much we transfer every 2 seconds
|
||||
var/target_organ = "breasts" // What organ we are transfering from
|
||||
|
||||
/obj/item/milking_machine/examine(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>[src] is currently [on ? "on" : "off"].</span>")
|
||||
if (inserted_item)
|
||||
to_chat(user, "<span class='notice'>[inserted_item] contains [inserted_item.reagents.total_volume]/[inserted_item.reagents.maximum_volume] units</span>")
|
||||
|
||||
/obj/item/milking_machine/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(W, /obj/item/reagent_containers/glass) && !inserted_item)
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return ..()
|
||||
inserted_item = W
|
||||
UpdateIcon()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/milking_machine/interact(mob/user)
|
||||
if(!isAI(user) && inserted_item)
|
||||
add_fingerprint(user)
|
||||
on = !on
|
||||
if (on)
|
||||
to_chat(user, "<span class='notice'>You turn [src] on.</span>")
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You turn [src] off.</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
UpdateIcon()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/milking_machine/proc/UpdateIcon()
|
||||
icon_state = "[on ? "On" : "Off"][inserted_item ? "Beaker" : ""]"
|
||||
item_state = icon_state
|
||||
|
||||
|
||||
/obj/item/milking_machine/AltClick(mob/living/user)
|
||||
add_fingerprint(user)
|
||||
user.put_in_hands(inserted_item)
|
||||
inserted_item = null
|
||||
on = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
UpdateIcon()
|
||||
|
||||
/obj/item/milking_machine/process()
|
||||
var/mob/living/carbon/W = loc
|
||||
if (W)
|
||||
var/obj/item/organ/genital/breasts/O = W.getorganslot(target_organ)
|
||||
if (O)
|
||||
if (O.reagents.total_volume >= transfer_rate * 2)
|
||||
if (inserted_item.reagents.total_volume < inserted_item.reagents.maximum_volume)
|
||||
O.reagents.trans_to(inserted_item.reagents, amount = transfer_rate)
|
||||
else
|
||||
to_chat(W, "<span class='notice'>[src] stops pumping. [inserted_item] is full.</span>")
|
||||
on = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
UpdateIcon()
|
||||
|
||||
/obj/item/milking_machine/penis
|
||||
name = "penis milking machine"
|
||||
icon_state = "PenisOff"
|
||||
item_state = "PenisOff"
|
||||
desc = "A pocket sized pump and tubing assembly designed to collect and store products from the penis."
|
||||
|
||||
target_organ = "testicles" // Since semen is stored in the balls
|
||||
|
||||
/obj/item/milking_machine/penis/UpdateIcon()
|
||||
icon_state = "Penis[on ? "On" : "Off"][inserted_item ? "Beaker" : ""]"
|
||||
item_state = icon_state
|
||||
@@ -0,0 +1,79 @@
|
||||
/*/obj/item/toy/plush/mammal/winfre
|
||||
desc = "An adorable stuffed toy of a pissed hyena. She looks unamused."
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "winfre"
|
||||
item_state = "winfre"
|
||||
attack_verb = list("cackled", "swirlie'd", "stepped on")*/
|
||||
|
||||
/*/obj/item/toy/plush/mammal/marilyn
|
||||
desc = "A cute stuffed fox toy. Now, about that sponge bath..."
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "marilyn"
|
||||
item_state = "marilyn"*/
|
||||
|
||||
/*/obj/item/toy/plush/mammal/winterbloo
|
||||
name = "Will, the biggest dog"
|
||||
desc = "A plush made to look like a thick as hell shiba, looks a little bigger than average too."
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "winterbloo"
|
||||
item_state = "winterbloo"
|
||||
attack_verb = list("hugged", "cuddled", "embraced")*/
|
||||
|
||||
/*/obj/item/toy/plush/lizardplushie/chris
|
||||
name = "Chris Plushie"
|
||||
desc = "An adorable stuffed toy of an angry ashwalker. He even comes with his own little crusher!" // CHRIS CHRIS CHRIS!
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
gender = MALE
|
||||
icon_state = "chris"
|
||||
item_state = "chris"
|
||||
squeak_override = list('sound/weapons/plasma_cutter.ogg' = 1)*/ // The sound the crusher uses is the same as the plasma cutter :P
|
||||
|
||||
|
||||
//society has progressed past the need for Tania
|
||||
|
||||
/*/obj/item/toy/plush/mammal/grug
|
||||
name = "Grug S. Cavemannington Plushie"
|
||||
desc = " Everybody's favorite space faring caveman in plushie form. You feel an overwhelming urge to break things while holding it."
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "grug"
|
||||
item_state = "grug"
|
||||
attack_verb = list("thomped", "ook'd", "stoned")
|
||||
squeak_override = list('sound/voice/gorillaplush.ogg' = 1)*/
|
||||
|
||||
/*/obj/item/toy/plush/mammal/winterdawn
|
||||
name = "hyena plushie"
|
||||
desc = "An adorable stuffed toy of a mammal that seems to resemble a crew member! She's a little yeen in a big labcoat."
|
||||
gender = FEMALE //probably a girl
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "lyricalpaws"
|
||||
item_state = "lyricalpaws"
|
||||
attack_verb = list("hugged", "cuddled", "embraced")
|
||||
squeak_override = list(
|
||||
'modular_citadel/sound/voice/bark1.ogg' = 1,
|
||||
'modular_citadel/sound/voice/bark2.ogg' = 1
|
||||
)*/
|
||||
|
||||
/*/obj/item/toy/plush/mammal/chemlight
|
||||
desc = "An adorable stuffed toy of a mammal that seems to resemble a crew member! It looks to glow and sport four arms."
|
||||
gender = MALE //he's a boy, right?
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "chemlight"
|
||||
item_state = "chemlight"
|
||||
light_color = "#CCFF33"
|
||||
light_power = 0.25
|
||||
light_range = 1.4
|
||||
attack_verb = list("bapped", "slapped", "bonked")*/
|
||||
|
||||
//Enzo_Leon patron stuff
|
||||
/*/obj/item/toy/plush/mammal/enzo_leon
|
||||
name = "rat plushie"
|
||||
desc = "An stuffed toy of a mammal that seems to resemble a crew member! Iconically it has a squeaker as you'd expect."
|
||||
gender = MALE //It's a boy!
|
||||
icon = 'hyperstation/icons/obj/plushes.dmi'
|
||||
icon_state = "enzor"
|
||||
item_state = "enzor"
|
||||
attack_verb = list("tail bapped", "whomped", "squeaked")
|
||||
squeak_override = list('sound/effects/mousesqueek.ogg'= 1)*/
|
||||
//End
|
||||
|
||||
//Removed all donator plushes for Hyperstation Admins/players in this file.
|
||||
@@ -0,0 +1,93 @@
|
||||
//hyperstation 13 stripper pole! about time?
|
||||
|
||||
/obj/structure/pole
|
||||
name = "stripper pole"
|
||||
desc = "A pole fastened to the ceiling and floor, used to show of ones goods to company."
|
||||
icon = 'hyperstation/icons/obj/pole.dmi'
|
||||
icon_state = "pole"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/icon_state_inuse
|
||||
layer = 4 //make it the same layer as players.
|
||||
pseudo_z_axis = 9 //stepping onto the pole makes you raise upwards!
|
||||
density = 0 //easy to step up on
|
||||
|
||||
/obj/structure/pole/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(obj_flags & IN_USE)
|
||||
to_chat(user, "It's already in use - wait a bit.")
|
||||
return
|
||||
else
|
||||
obj_flags |= IN_USE
|
||||
user.setDir(SOUTH)
|
||||
user.Stun(100)
|
||||
user.forceMove(src.loc)
|
||||
user.visible_message("<B>[user] dances on [src]!</B>")
|
||||
animatepole(user)
|
||||
user.layer = layer //set them to the poles layer
|
||||
obj_flags &= ~IN_USE
|
||||
user.pixel_y = 0
|
||||
user.pixel_z = pseudo_z_axis //incase we are off it when we jump on!
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/structure/pole/proc/animatepole(mob/living/user)
|
||||
return
|
||||
|
||||
/obj/structure/pole/animatepole(mob/living/user)
|
||||
|
||||
if (user.loc != src.loc)
|
||||
return
|
||||
animate(user,pixel_x = -6, pixel_y = 0, time = 10)
|
||||
sleep(20)
|
||||
user.dir = 4
|
||||
animate(user,pixel_x = -6,pixel_y = 24, time = 10)
|
||||
sleep(12)
|
||||
src.layer = 4.01 //move the pole infront for now. better to move the pole, because the character moved behind people sitting above otherwise
|
||||
animate(user,pixel_x = 6,pixel_y = 12, time = 5)
|
||||
user.dir = 8
|
||||
sleep(6)
|
||||
animate(user,pixel_x = -6,pixel_y = 4, time = 5)
|
||||
user.dir = 4
|
||||
src.layer = 4 // move it back.
|
||||
sleep(6)
|
||||
user.dir = 1
|
||||
animate(user,pixel_x = 0, pixel_y = 0, time = 3)
|
||||
sleep(6)
|
||||
user.do_jitter_animation()
|
||||
sleep(6)
|
||||
user.dir = 2
|
||||
|
||||
|
||||
/obj/item/polepack
|
||||
name = "stripper pole flatpack"
|
||||
desc = "A wrench is required to construct."
|
||||
icon = 'hyperstation/icons/obj/pole_small.dmi'
|
||||
throwforce = 0
|
||||
icon_state = "pole_base"
|
||||
var/unwrapped = 0
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
|
||||
/obj/item/polepack/attackby(obj/item/P, mob/user, params) //erecting a pole here.
|
||||
add_fingerprint(user)
|
||||
if(P.tool_behaviour == TOOL_WRENCH)
|
||||
if (!(item_flags & IN_INVENTORY))
|
||||
to_chat(user, "<span class='notice'>You start to fasten the frame to the floor and celing...</span>")
|
||||
if(P.use_tool(src, user, 8 SECONDS, volume=50))
|
||||
to_chat(user, "<span class='notice'>You construct the stripper pole!</span>")
|
||||
var/obj/structure/pole/C = new
|
||||
C.loc = loc
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/structure/pole/attackby(obj/item/P, mob/user, params) //un-erecting a pole. :(
|
||||
add_fingerprint(user)
|
||||
if(P.tool_behaviour == TOOL_WRENCH)
|
||||
to_chat(user, "<span class='notice'>You start to unfastening the frame...</span>")
|
||||
if(P.use_tool(src, user, 8 SECONDS, volume=50))
|
||||
to_chat(user, "<span class='notice'>You take down the stripper pole!</span>")
|
||||
var/obj/item/polepack/C = new
|
||||
C.loc = loc
|
||||
del(src)
|
||||
return
|
||||
@@ -0,0 +1,43 @@
|
||||
// /obj/item/pregnancytest
|
||||
// name = "pregnancy test"
|
||||
// desc = "A one time use small device, used to determine whether someone is pregnant or not."
|
||||
// icon = 'hyperstation/icons/obj/pregnancytest.dmi'
|
||||
// throwforce = 0
|
||||
// icon_state = "ptest"
|
||||
// var/status = 0
|
||||
// var/results = "null"
|
||||
// w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
|
||||
// /obj/item/pregnancytest/attack_self(mob/user)
|
||||
// if(QDELETED(src))
|
||||
// return
|
||||
// if(!isliving(user))
|
||||
// return
|
||||
// if(isAI(user))
|
||||
// return
|
||||
// if(user.stat > 0)//unconscious or dead
|
||||
// return
|
||||
// if(status == 1)
|
||||
// return //Already been used once, pregnancy tests only work once.
|
||||
// test(user)
|
||||
|
||||
// /obj/item/pregnancytest/proc/force(mob/living/user)
|
||||
// //Force it negative
|
||||
// icon_state = "negative"
|
||||
// name = "[results] pregnancy test"
|
||||
// status = 1
|
||||
// to_chat(user, "<span class='notice'>You use the pregnancy test, the display reads negative!</span>")
|
||||
|
||||
|
||||
// /obj/item/pregnancytest/proc/test(mob/living/user)
|
||||
|
||||
// var/obj/item/organ/genital/womb/W = user.getorganslot("womb")
|
||||
// if(W.pregnant == 1)
|
||||
// results = "positive"
|
||||
// icon_state = "positive"
|
||||
// name = "[results] pregnancy test"
|
||||
// status = 1
|
||||
// to_chat(user, "<span class='notice'>You use the pregnancy test, the display reads positive!</span>")
|
||||
// else
|
||||
// force(user)
|
||||
@@ -0,0 +1,200 @@
|
||||
/obj/item/pen/bluemarker
|
||||
name = "blue marker"
|
||||
desc = "A simple blueberry scented marker."
|
||||
icon_state = "marker_blue"
|
||||
colour = "blue"
|
||||
|
||||
/obj/item/pen/bluemarker/attack_self(mob/user)
|
||||
user.emote("sniff")
|
||||
to_chat(user, "<span class='notice'>Ahh~ blueberries!</span>")
|
||||
|
||||
/obj/item/clothing/suit/napoleonic
|
||||
name = "napoleonic uniform"
|
||||
desc = "An heirloom passed down from the Gruber family dynasty."
|
||||
icon_state = "napoleonic"
|
||||
item_state = "napoleonic"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
cold_protection = CHEST|GROIN|ARMS
|
||||
|
||||
/obj/item/clothing/suit/shackles
|
||||
name = "Plastitanium Shackles"
|
||||
desc = "A set of heavy plastitanium shackles, there are chains still attatched"
|
||||
icon_state = "shackles"
|
||||
item_state = "shackles"
|
||||
icon = 'hyperstation/icons/mobs/rewards.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/rewards.dmi'
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/suit/luwethtrench
|
||||
name = "Syndicate Commander's Coat"
|
||||
desc = "A sinister looking black and red jacket. The gold collar and shoulders denote that this belongs to a high ranking syndicate officer. A rather strange brooch is pinned to the coat, displaying a unique range of lustrous brass cracks through the deep blacks of it’s hammered finish."
|
||||
icon = 'hyperstation/icons/obj/clothing/rewards.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/rewards.dmi'
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
icon_state = "luwethtrench"
|
||||
item_state = "luwethtrench"
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/gloves/ring/luweth
|
||||
name = "Luweth’s Wedding Band"
|
||||
icon = 'hyperstation/icons/obj/clothing/rewards.dmi'
|
||||
icon_state = "luweth"
|
||||
desc = "A seemingly natural yet rather rough brass ring, which shows off a unique range of lustrous brass cracks through the deep blacks of it’s hammered finish. 'Till death does us part.'"
|
||||
|
||||
/obj/item/dice/d20/blue
|
||||
name = "blue d20"
|
||||
desc = "Clearly the dice hate you."
|
||||
icon_state = "d20_blue"
|
||||
sides = 20
|
||||
unique = TRUE
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/death
|
||||
name = "inconspicuous winter coat"
|
||||
icon_state = "rdeath"
|
||||
item_state = "rdeath"
|
||||
allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/screwdriver, /obj/item/crowbar, /obj/item/wrench, /obj/item/stack/cable_coil, /obj/item/weldingtool, /obj/item/multitool)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/death
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/death
|
||||
icon_state = "winterhood_death"
|
||||
|
||||
/obj/item/storage/pill_bottle/heat
|
||||
name = "heat-b-gone pill bottle"
|
||||
desc = "a bottle of pills from a sketchy pharmaceutical corporation. at the bottom of the label is a small red S."
|
||||
|
||||
/obj/item/reagent_containers/pill/heat
|
||||
name = "heat-b-gone pill"
|
||||
desc = "claims to be foolproof heat repression medication but it tastes extremely sweet."
|
||||
icon_state = "pill8"
|
||||
list_reagents = list(/datum/reagent/consumable/sugar = 10)
|
||||
roundstart = 1
|
||||
|
||||
/obj/item/storage/pill_bottle/heat/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/heat(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/betablock
|
||||
name = "anaphrodisiacs pill bottle"
|
||||
desc = "a bottle of anaphrodisiacs."
|
||||
|
||||
/obj/item/reagent_containers/pill/betablock
|
||||
name = "anaphrodisiac pill"
|
||||
desc = "Prescribed to races that have trouble keeping their urges in check."
|
||||
icon_state = "pill5"
|
||||
list_reagents = list(/datum/reagent/drug/anaphrodisiac = 10)
|
||||
roundstart = 1
|
||||
|
||||
/obj/item/storage/pill_bottle/betablock/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/betablock(src)
|
||||
|
||||
/obj/item/clothing/head/crystalline
|
||||
name = "crystalline shards"
|
||||
icon = 'hyperstation/icons/obj/rewards.dmi'
|
||||
desc = "A handful of blue crystals. They look like they came from some sort of cave."
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/rewards.dmi'
|
||||
icon_state = "crystalline"
|
||||
|
||||
/obj/item/clothing/mask/keaton
|
||||
name = "keaton mask"
|
||||
desc = "A mask made to look like the mythical Keaton."
|
||||
icon = 'hyperstation/icons/obj/rewards.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/rewards.dmi'
|
||||
icon_state = "keaton"
|
||||
flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/clothing/suit/chloe
|
||||
name = "Fleet Commander's Overcoat"
|
||||
desc = "Custom tailored to warm the cold commanding hearts of the Syndicate's feared XIV'th battle group. Its armour plating has been removed."
|
||||
icon_state = "commissar_greatcoat"
|
||||
item_state = "commissar_greatcoat"
|
||||
allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/screwdriver, /obj/item/crowbar, /obj/item/wrench, /obj/item/stack/cable_coil, /obj/item/weldingtool, /obj/item/multitool)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
mutantrace_variation = MUTANTRACE_VARIATION
|
||||
tauric = TRUE
|
||||
|
||||
/obj/item/clothing/head/chloe
|
||||
name = "Fleet Commander's Beret"
|
||||
desc = "A beret bearing a worn golden symbol that stikes fear in the hearts of many. It smells faintly of plasma and gunpowder."
|
||||
icon = 'hyperstation/icons/obj/clothing/rewards.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/rewards.dmi'
|
||||
icon_state = "commissar_beret"
|
||||
item_state = "commissar_beret"
|
||||
|
||||
/obj/item/clothing/under/touchinfuzzy
|
||||
name = "provocative jumpsuit"
|
||||
desc = "A form fitting jumpsuit with a golden trim zipper! Smells faintly of succubus milk."
|
||||
icon_state = "touchinfuzzyuni"
|
||||
item_state = "touchinfuzzyuni"
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
|
||||
/obj/item/toy/sword/chloesabre
|
||||
name = "Fleet Commander's Sabre"
|
||||
desc = "An elegant weapon, similar in design to the Captain's Sabre, but with a syndicate twist."
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
alternate_worn_icon = 'icons/mob/custom_w.dmi'
|
||||
icon_state = "darksabre"
|
||||
item_state = "darksabre"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi'
|
||||
righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi'
|
||||
obj_flags = UNIQUE_RENAME
|
||||
attack_verb = list("slashed", "cut")
|
||||
|
||||
/obj/item/toy/sword/chloesabre/get_belt_overlay()
|
||||
return mutable_appearance('icons/obj/custom.dmi', "darksheath-darksabre")
|
||||
|
||||
/obj/item/toy/sword/chloesabre/get_worn_belt_overlay(icon_file)
|
||||
return mutable_appearance(icon_file, "darksheath-darksabre")
|
||||
|
||||
/obj/item/mialasscale
|
||||
name = "Miala's Scale"
|
||||
desc = "A bright, and familiar, cyan scale from an equally familiar snake being."
|
||||
icon = 'hyperstation/icons/obj/rewards.dmi'
|
||||
icon_state = "m_scale"
|
||||
item_state = "m_scale"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/bong/kiseru
|
||||
name = "black lacquered kiseru"
|
||||
desc = "it is a black lacquered kiseru with a ornate silver head and mouthpiece, you can feel it's old age as you hold it"
|
||||
icon = 'hyperstation/icons/obj/rewards.dmi'
|
||||
icon_state = null
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
light_color = "#FFCC66"
|
||||
icon_off = "pipe"
|
||||
icon_on = "pipe_lit"
|
||||
|
||||
/obj/item/clothing/suit/hooded/occultrobes
|
||||
name = "Occult Robes"
|
||||
desc = "I didn't even know they made these in XXS..."
|
||||
icon_state = "coatwinter"
|
||||
item_state = "coatwinter"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
cold_protection = CHEST|GROIN|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
|
||||
|
||||
/obj/item/clothing/suit/hooded/occultrobes
|
||||
name = "occult robes"
|
||||
desc = "I didn't even know they made these in XXS..."
|
||||
icon_state = "occultrobes"
|
||||
hoodtype = /obj/item/clothing/head/hooded/occultrobeshood
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/head/hooded/occultrobeshood
|
||||
name = "occult hood"
|
||||
icon_state = "occultrobeshood"
|
||||
body_parts_covered = HEAD
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
|
||||
mutantrace_variation = NONE
|
||||
@@ -0,0 +1,56 @@
|
||||
//Jay
|
||||
//TODO: Better sprites
|
||||
//Rope
|
||||
/obj/item/restraints/handcuffs/rope/ //Fun
|
||||
name = "soft rope"
|
||||
desc = "A comfortable rope that would be easy to slip out of if you needed. Kinky."
|
||||
breakouttime = 10 //Easy to break out. It's not for gaming.
|
||||
icon = 'hyperstation/icons/obj/rope.dmi'
|
||||
icon_state = "rope"
|
||||
item_state = "rope" //This sprite is in restraints.dmi until I figure out how to refrence somewhere else
|
||||
cuffsound = 'sound/weapons/cablecuff.ogg'
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
price = 2
|
||||
|
||||
/mob/living/proc/rope_add(source) //Check to see if the rope is on, and then add effects
|
||||
var/mob/living/carbon/M = source
|
||||
if(M.handcuffed)
|
||||
var/rope_message = pick("The rope is tightly tied onto you!")
|
||||
to_chat(M, "<span class='userlove'>[rope_message]</span>")
|
||||
M.min_arousal = 33
|
||||
M.arousal_rate += 2
|
||||
update_stat()
|
||||
|
||||
/mob/living/proc/rope_remove(list/sources, temp_min_arousal, temp_max_arousal, temp_arousal_rate) //Check to see it the rope is gone, and reset effects
|
||||
var/mob/living/carbon/M = sources
|
||||
if (!M.handcuffed)
|
||||
var/rope_message = pick("The rope has been removed!")
|
||||
to_chat(M, "<span class='notice'>[rope_message]</span>")
|
||||
M.min_arousal = temp_min_arousal
|
||||
M.max_arousal = temp_max_arousal
|
||||
M.arousal_rate = temp_arousal_rate
|
||||
update_stat()
|
||||
|
||||
/obj/item/restraints/handcuffs/rope/attack(mob/living/carbon/C, mob/living/user)
|
||||
. = ..()
|
||||
var/temp_min_arousal = C.min_arousal //Temp variables to hold original arousal values
|
||||
var/temp_max_arousal = C.max_arousal
|
||||
var/temp_arousal_rate = C.arousal_rate
|
||||
var/datum/callback/Cback = new(user, /mob/living/proc/rope_add, C)//Put the rope on
|
||||
addtimer(Cback, 6, TIMER_UNIQUE)//We are going to call this proc six seconds after the click. The rope tying takes 5 seconds
|
||||
var/datum/callback/Cback2 = new(user, /mob/living/proc/rope_remove, C, temp_min_arousal, temp_max_arousal, temp_arousal_rate)
|
||||
while(1) //Loop until break - Because I can't figure out any better way to do it.
|
||||
var/rope_emote = pick("moan", "blush")
|
||||
sleep(50) //5 second wait
|
||||
addtimer(Cback2, 1, TIMER_UNIQUE) //Just keep calling this timer proc
|
||||
if (prob(10))
|
||||
C.emote(rope_emote)
|
||||
if (!C.handcuffed)
|
||||
return //Break when the rope is removed
|
||||
|
||||
/datum/crafting_recipe/rope
|
||||
name = "Soft Rope"
|
||||
result = /obj/item/restraints/handcuffs/rope
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/sheet/cloth = 5)
|
||||
category = CAT_MISC
|
||||
@@ -0,0 +1,14 @@
|
||||
/obj/item/reagent_containers/food/drinks/prospacillin
|
||||
name = "Prospacillin Bottle"
|
||||
desc = "An incredibly expensive bottle used by GATO command. It has golden engravings and reeks of corporate greed."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
icon_state = "prospacillin"
|
||||
list_reagents = list(/datum/reagent/growthchem = 15)
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/diminicillin
|
||||
name = "Diminicillin Bottle"
|
||||
desc = "An incredibly expensive bottle used by GATO command. It has golden engravings and reeks of corporate greed."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
icon_state = "diminicillin"
|
||||
list_reagents = list(/datum/reagent/shrinkchem = 15)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/obj/item/sounding
|
||||
name = "sounding rod"
|
||||
desc = "Dont be silly, stuff your willy!"
|
||||
icon = 'hyperstation/icons/obj/sounding.dmi'
|
||||
throwforce = 0
|
||||
icon_state = "sounding_wrapped"
|
||||
var/unwrapped = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
price = 1
|
||||
|
||||
/obj/item/sounding/attack_self(mob/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
if(isliving(user))
|
||||
if(unwrapped == 0)
|
||||
icon_state = "sounding_rod"
|
||||
unwrapped = 1
|
||||
to_chat(user, "<span class='notice'>You unwrap the rod.</span>")
|
||||
playsound(user, 'sound/items/poster_ripped.ogg', 50, 1, -1)
|
||||
return
|
||||
|
||||
/obj/item/sounding/attack(mob/living/carbon/C, mob/living/user)
|
||||
|
||||
if(unwrapped == 0 )
|
||||
to_chat(user, "<span class='notice'>You must remove the rod from the package first!</span>")
|
||||
return
|
||||
var/obj/item/organ/genital/penis/P = C.getorganslot("penis")
|
||||
if(P&&P.is_exposed())
|
||||
if(P.sounding)
|
||||
to_chat(user, "<span class='notice'>They already have a rod inside!</span>")
|
||||
return
|
||||
if(isliving(C)&&isliving(user)&&unwrapped == 1)
|
||||
C.visible_message("<span class='warning'>[user] is trying to insert a rod inside [C]!</span>",\
|
||||
"<span class='warning'>[user] is trying to insert a rod inside you!</span>")
|
||||
if(!do_mob(user, C, 4 SECONDS))
|
||||
return
|
||||
var/mob/living/carbon/human/L = C
|
||||
playsound(C, 'sound/lewd/champ_fingering.ogg', 50, 1, -1)
|
||||
P.sounding = 1
|
||||
if(L)
|
||||
L.update_genitals()
|
||||
to_chat(C, "<span class='userlove'>Your penis feels stuffed and stretched!</span>")
|
||||
qdel(src)
|
||||
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You can't find anywhere to put the rod inside.</span>")
|
||||
|
||||
/mob/living/carbon/human/proc/removesounding()
|
||||
|
||||
var/obj/item/organ/genital/penis/P = src.getorganslot("penis")
|
||||
if(P.sounding)
|
||||
new /obj/item/sounding/used_sounding(usr.loc)
|
||||
to_chat(src, "The rod falls off from your penis.")
|
||||
P.sounding = 0
|
||||
src.update_genitals()
|
||||
|
||||
/obj/item/sounding/used_sounding
|
||||
name = "sounding rod"
|
||||
icon_state = "sounding_rod"
|
||||
unwrapped = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/mob/living/carbon/human/proc/soundingclimax()
|
||||
|
||||
var/obj/item/organ/genital/penis/P = src.getorganslot("penis")
|
||||
if(P.sounding)
|
||||
new /obj/item/sounding/used_sounding(usr.loc)
|
||||
P.sounding = 0
|
||||
src.update_genitals()
|
||||
@@ -0,0 +1,9 @@
|
||||
/obj/item/clothing/under/tunic
|
||||
name = "Tunic"
|
||||
desc = "A simples tunic."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "tunic"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = NONE
|
||||
@@ -0,0 +1,157 @@
|
||||
//Hyperstation 13 vibrator
|
||||
//For all them subs/bottoms out there, that wanna give someone the power to make them cum remotely.
|
||||
|
||||
/obj/item/electropack/vibrator
|
||||
name = "remote vibrator"
|
||||
desc = "A remote device that can deliver pleasure at a fair. It has three intensities that can be set by twisting the base."
|
||||
icon = 'hyperstation/icons/obj/vibrator.dmi'
|
||||
icon_state = "vibe"
|
||||
item_state = "vibe"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_DENYPOCKET //no more pocket shockers
|
||||
var/mode = 1
|
||||
var/style = "long"
|
||||
var/inside = FALSE
|
||||
var/last = 0
|
||||
price = 3
|
||||
|
||||
/obj/item/electropack/vibrator/Initialize(mapload) //give the device its own code
|
||||
. = ..()
|
||||
code = rand(1,30)
|
||||
|
||||
/obj/item/electropack/vibrator/small //can go anywhere
|
||||
name = "small remote vibrator"
|
||||
style = "small"
|
||||
icon_state = "vibesmall"
|
||||
item_state = "vibesmall"
|
||||
|
||||
/obj/item/electropack/vibrator/AltClick(mob/living/user)
|
||||
var/dat = {"
|
||||
<TT>
|
||||
<B>Frequency/Code</B> for vibrator:<BR>
|
||||
Frequency:
|
||||
[format_frequency(src.frequency)]
|
||||
<A href='byond://?src=[REF(src)];set=freq'>Set</A><BR>
|
||||
|
||||
Code:
|
||||
[src.code]
|
||||
<A href='byond://?src=[REF(src)];set=code'>Set</A><BR>
|
||||
</TT>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
/obj/item/electropack/shockcollar/security
|
||||
name = "security shock collar"
|
||||
desc = "A reinforced security collar. It has two electrodes that press against the neck, for disobedient pets."
|
||||
icon_state = "shockseccollar"
|
||||
item_state = "shockseccollar"
|
||||
|
||||
/obj/item/electropack/vibrator/attack_self(mob/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
if(isliving(user))
|
||||
playsound(user, 'sound/effects/clock_tick.ogg', 50, 1, -1)
|
||||
switch(mode)
|
||||
if(1)
|
||||
mode = 2
|
||||
to_chat(user, "<span class='notice'>You twist the bottom of [src], setting it to the medium setting.</span>")
|
||||
return
|
||||
if(2)
|
||||
mode = 3
|
||||
to_chat(user, "<span class='warning'>You twist the bottom of [src], setting it to the high setting.</span>")
|
||||
return
|
||||
if(3)
|
||||
mode = 1
|
||||
to_chat(user, "<span class='notice'>You twist the bottom of [src], setting it to the low setting.</span>")
|
||||
return
|
||||
|
||||
/obj/item/electropack/vibrator/attack(mob/living/carbon/C, mob/living/user)
|
||||
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
var/mob/living/carbon/human/S = user
|
||||
var/mob/living/carbon/human/T = C
|
||||
picked_organ = S.target_genitals(T)
|
||||
if(picked_organ)
|
||||
C.visible_message("<span class='warning'>[user] is trying to attach [src] to [T]!</span>",\
|
||||
"<span class='warning'>[user] is trying to put [src] on you!</span>")
|
||||
if(!do_mob(user, C, 5 SECONDS))//warn them and have a delay of 5 seconds to apply.
|
||||
return
|
||||
|
||||
if(style == "long" && !(picked_organ.name == "vagina")) //long vibrators dont fit on anything but vaginas, but small ones fit everywhere
|
||||
to_chat(user, "<span class='warning'>[src] is too big to fit there, use a smaller version.</span>")
|
||||
return
|
||||
|
||||
if(!picked_organ.equipment)
|
||||
if(!(style == "long"))
|
||||
to_chat(user, "<span class='love'>You attach [src] to [T]'s [picked_organ.name].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='love'>You insert [src] into [T]'s [picked_organ.name].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>They already have a [picked_organ.equipment.name] there.</span>")
|
||||
return
|
||||
|
||||
if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
|
||||
return
|
||||
src.inside = TRUE
|
||||
picked_organ.equipment = src
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You don't see anywhere to attach this.</span>")
|
||||
|
||||
|
||||
/obj/item/electropack/vibrator/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.data["code"] != code)
|
||||
return
|
||||
|
||||
if(last > world.time)
|
||||
return
|
||||
|
||||
last = world.time + 3 SECONDS //lets stop spam.
|
||||
|
||||
if(inside)
|
||||
var/obj/item/organ/genital/G = src.loc
|
||||
var/mob/living/carbon/U = G.owner
|
||||
|
||||
if(G)
|
||||
switch(G.name) //just being fancy
|
||||
if("breasts")
|
||||
to_chat(U, "<span class='love'>[src] vibrates against your nipples!</span>")
|
||||
else
|
||||
to_chat(U, "<span class='love'>[src] vibrates against your [G.name]!</span>")
|
||||
|
||||
var/intencity = 6*mode
|
||||
U.adjust_arousal(intencity) //give pleasure
|
||||
playsound(U.loc, 'sound/lewd/vibrate.ogg', (intencity+5), 1, -1) //vibe intencity scaled up abit for sound
|
||||
|
||||
|
||||
switch(mode)
|
||||
if(1) //low, setting for RP, it wont force your character to do anything.
|
||||
to_chat(U, "<span class='love'>You feel pleasure surge through your [G.name]</span>")
|
||||
U.do_jitter_animation() //do animation without heartbeat
|
||||
if(2) //med, can make you cum
|
||||
to_chat(U, "<span class='love'>You feel intense pleasure surge through your [G.name]</span>")
|
||||
U.do_jitter_animation()
|
||||
if (U.getArousalLoss() >= 100 && ishuman(U) && U.has_dna())
|
||||
U.mob_climax(forced_climax=TRUE)
|
||||
if(3) //high, makes you stun
|
||||
to_chat(U, "<span class='userdanger'>You feel overpowering pleasure surge through your [G.name]</span>")
|
||||
U.Jitter(3)
|
||||
U.Stun(30)
|
||||
if (U.getArousalLoss() >= 100 && ishuman(U) && U.has_dna())
|
||||
U.mob_climax(forced_climax=TRUE)
|
||||
if(prob(50))
|
||||
U.emote("moan")
|
||||
|
||||
|
||||
|
||||
playsound(src, 'sound/lewd/vibrate.ogg', 40, 1, -1)
|
||||
if(style == "long") //haha vibrator go brrrrrrr
|
||||
icon_state = "vibing"
|
||||
|
||||
sleep(30)
|
||||
icon_state = "vibe"
|
||||
else
|
||||
icon_state = "vibingsmall"
|
||||
sleep(30)
|
||||
icon_state = "vibesmall"
|
||||
Reference in New Issue
Block a user