more work

This commit is contained in:
Metis
2024-09-13 01:50:58 -04:00
parent 8fd779ef02
commit 7b0780804f
320 changed files with 12185 additions and 161 deletions
+50
View File
@@ -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>"
+32
View File
@@ -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.
+8
View File
@@ -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'
+45
View File
@@ -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()
+17
View File
@@ -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
+128
View File
@@ -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)
+233
View File
@@ -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"
+169
View File
@@ -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
+392
View File
@@ -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
+17
View File
@@ -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)
+131
View File
@@ -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)
+426
View File
@@ -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
+154
View File
@@ -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
+83
View File
@@ -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
+79
View File
@@ -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.
+93
View 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
+43
View File
@@ -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)
+200
View File
@@ -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 its 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 = "Luweths 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 its 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
+56
View File
@@ -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
+14
View File
@@ -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)
+69
View File
@@ -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
+157
View File
@@ -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"