more work
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/client/proc/spawn_floor_cluwne()
|
||||
set category = "Fun"
|
||||
set name = "Unleash Targeted Floor Cluwne"
|
||||
set desc = "Pick a specific target. Be warned: spawning more than one may cause issues!"
|
||||
var/target
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
target = input("Any specific target in mind? Please note only live, non cluwned, human targets are valid.", "Target", target) as null|anything in GLOB.player_list
|
||||
if(target && ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(H.loc)
|
||||
FC.forced = TRUE
|
||||
FC.Acquire_Victim(H)
|
||||
FC.target = H
|
||||
FC.current_victim = H
|
||||
log_admin("[key_name(usr)] spawned floor cluwne.")
|
||||
message_admins("[key_name(usr)] spawned floor cluwne.")
|
||||
deadchat_broadcast("<span class='deadsay'><b>Floor Cluwne</b> has just been spawned!</span>")
|
||||
|
||||
/client/proc/spawn_random_floor_cluwne()
|
||||
set category = "Fun"
|
||||
set name = "Unleash Random Floor Cluwne"
|
||||
set desc = "Goes after a random player in your Z level. Be warned: spawning more than one may cause issues!"
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(usr)
|
||||
new /mob/living/simple_animal/hostile/floor_cluwne(T)
|
||||
log_admin("[key_name(usr)] spawned a random target floor cluwne.")
|
||||
message_admins("[key_name(usr)] spawned a random target floor cluwne.")
|
||||
|
||||
/client/proc/spawn_twitch_plays_clowncar()
|
||||
set category = "Fun"
|
||||
set name = "Spawn Twich Plays: Clown Car Edition"
|
||||
set desc = "A clown car that weights the direction it goes based on the keys ghosts are pushing. Terrible idea? Maybe."
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(usr)
|
||||
var/obj/vehicle/sealed/car/clowncar/twitch_plays/G = new /obj/vehicle/sealed/car/clowncar/twitch_plays(T)
|
||||
var/area/A = get_area(G)
|
||||
log_admin("[key_name(usr)] spawned a twitch plays clown car.")
|
||||
message_admins("[key_name(usr)] spawned a twitch plays clown car. Some soundtrack is likely recommended for the fuckshit that's about to unfold.")
|
||||
notify_ghosts("A Ghost Controlled Clown Car has been spawned at \the [A.name]! Double click it to orbit and wrestle its direction with other ghosts!", 'yogstation/sound/misc/bikehorn_creepy.ogg', source = G, action = NOTIFY_JUMP, flashwindow = FALSE)
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
Holds things like antag datums, game modes, abilities, and everything
|
||||
related to the antag that could be a datum
|
||||
*/
|
||||
|
||||
//ANTAGONIST
|
||||
/datum/antagonist/wendigo
|
||||
name = "wendigo"
|
||||
antagpanel_category = "Wendigo"
|
||||
|
||||
/datum/antagonist/wendigo/on_gain()
|
||||
if(istype(owner.current, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/wendigo/new_owner = new/mob/living/carbon/wendigo(get_turf(owner.current))
|
||||
var/mob/current_body = owner.current
|
||||
current_body.transfer_ckey(new_owner)
|
||||
current_body.Destroy()
|
||||
owner = new_owner.mind
|
||||
owner.current = new_owner
|
||||
..()
|
||||
|
||||
|
||||
//HUD
|
||||
//Contents: Intentions, Hands, Dropping/Throwing/Pulling, Inventory Equip
|
||||
// Health + Souls on the bottom of screen
|
||||
//TODO: Health doll, Soul counter (not devil)
|
||||
|
||||
/datum/hud/wendigo/New(mob/living/carbon/wendigo/owner)
|
||||
..()
|
||||
var/obj/screen/using
|
||||
var/obj/screen/inventory/inv_box
|
||||
|
||||
var/widescreenlayout = FALSE //adds support for different hud layouts depending on widescreen pref
|
||||
if(owner.client && owner.client.prefs && owner.client?.prefs?.widescreenpref)
|
||||
widescreenlayout = FALSE
|
||||
|
||||
//CRAFTING
|
||||
using = new /obj/screen/craft
|
||||
using.icon = ui_style
|
||||
if(!widescreenlayout)
|
||||
using.screen_loc = ui_boxcraft
|
||||
static_inventory += using
|
||||
|
||||
//LANG MENU
|
||||
using = new/obj/screen/language_menu
|
||||
using.icon = ui_style
|
||||
if(!widescreenlayout)
|
||||
using.screen_loc = ui_boxlang
|
||||
static_inventory += using
|
||||
|
||||
//AREA EDITOR
|
||||
using = new /obj/screen/area_creator
|
||||
using.icon = ui_style
|
||||
if(!widescreenlayout)
|
||||
using.screen_loc = ui_boxarea
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/voretoggle()
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.screen_loc = ui_voremode
|
||||
if(!widescreenlayout)
|
||||
using.screen_loc = ui_boxvore
|
||||
static_inventory += using
|
||||
|
||||
//INTENTS & ACTIONS
|
||||
action_intent = new /obj/screen/act_intent/segmented
|
||||
action_intent.icon_state = mymob.a_intent
|
||||
static_inventory += action_intent
|
||||
|
||||
using = new /obj/screen/human/equip()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_equip_position(mymob)
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/mov_intent
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking")
|
||||
using.screen_loc = ui_movi
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/resist()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_overridden_resist
|
||||
hotkeybuttons += using
|
||||
|
||||
using = new /obj/screen/restbutton()
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.screen_loc = ui_pull_resist
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/combattoggle()
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.screen_loc = ui_combat_toggle
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/drop()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_drop_throw
|
||||
static_inventory += using
|
||||
|
||||
pull_icon = new /obj/screen/pull()
|
||||
pull_icon.icon = ui_style
|
||||
pull_icon.update_icon(mymob)
|
||||
pull_icon.screen_loc = ui_pull_resist
|
||||
static_inventory += pull_icon
|
||||
|
||||
throw_icon = new /obj/screen/throw_catch()
|
||||
throw_icon.icon = ui_style
|
||||
throw_icon.screen_loc = ui_drop_throw
|
||||
hotkeybuttons += throw_icon
|
||||
|
||||
//////
|
||||
//INVENTORY
|
||||
//////
|
||||
build_hand_slots()
|
||||
|
||||
using = new /obj/screen/human/toggle()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_inventory
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/swap_hand()
|
||||
using.icon = ui_style
|
||||
using.icon_state = "swap_1"
|
||||
using.screen_loc = ui_swaphand_position(owner,1)
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/swap_hand()
|
||||
using.icon = ui_style
|
||||
using.icon_state = "swap_2"
|
||||
using.screen_loc = ui_swaphand_position(owner,2)
|
||||
static_inventory += using
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "neck"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "neck"
|
||||
inv_box.screen_loc = ui_neck
|
||||
inv_box.slot_id =ITEM_SLOT_NECK
|
||||
toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "back"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "back"
|
||||
inv_box.screen_loc = ui_back
|
||||
inv_box.slot_id =ITEM_SLOT_BACK
|
||||
static_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "gloves"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "gloves"
|
||||
inv_box.screen_loc = ui_gloves
|
||||
inv_box.slot_id =ITEM_SLOT_GLOVES
|
||||
toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "eyes"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "glasses"
|
||||
inv_box.screen_loc = ui_glasses
|
||||
inv_box.slot_id =ITEM_SLOT_GLASSES
|
||||
toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "ears"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "ears"
|
||||
inv_box.screen_loc = ui_ears
|
||||
inv_box.slot_id =ITEM_SLOT_EARS
|
||||
toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "head"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "head"
|
||||
inv_box.screen_loc = ui_head
|
||||
inv_box.slot_id =ITEM_SLOT_HEAD
|
||||
toggleable_inventory += inv_box
|
||||
|
||||
inv_box = new /obj/screen/inventory()
|
||||
inv_box.name = "belt"
|
||||
inv_box.icon = ui_style
|
||||
inv_box.icon_state = "belt"
|
||||
inv_box.screen_loc = ui_belt
|
||||
inv_box.slot_id =ITEM_SLOT_BELT
|
||||
static_inventory += inv_box
|
||||
|
||||
//INFO DISPLAY
|
||||
|
||||
internals = new /obj/screen/internals()
|
||||
infodisplay += internals
|
||||
|
||||
healths = new /obj/screen/healths()
|
||||
infodisplay += healths
|
||||
|
||||
healthdoll = new /obj/screen/healthdoll()
|
||||
infodisplay += healthdoll
|
||||
|
||||
zone_select = new /obj/screen/zone_sel()
|
||||
zone_select.icon = ui_style
|
||||
zone_select.update_icon(mymob)
|
||||
static_inventory += zone_select
|
||||
|
||||
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
|
||||
if(inv.slot_id)
|
||||
inv.hud = src
|
||||
inv_slots[inv.slot_id] = inv
|
||||
inv.update_icon()
|
||||
|
||||
/datum/hud/wendigo/hidden_inventory_update(mob/viewer)
|
||||
if(!mymob)
|
||||
return
|
||||
var/mob/living/carbon/wendigo/W = mymob
|
||||
|
||||
var/mob/screenmob = viewer || W
|
||||
|
||||
if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown)
|
||||
if(W.gloves)
|
||||
W.gloves.screen_loc = ui_gloves
|
||||
screenmob.client.screen += W.gloves
|
||||
if(W.ears)
|
||||
W.ears.screen_loc = ui_ears
|
||||
screenmob.client.screen += W.ears
|
||||
if(W.glasses)
|
||||
W.glasses.screen_loc = ui_glasses
|
||||
screenmob.client.screen += W.glasses
|
||||
if(W.wear_neck)
|
||||
W.wear_neck.screen_loc = ui_neck
|
||||
screenmob.client.screen += W.wear_neck
|
||||
if(W.head)
|
||||
W.head.screen_loc = ui_head
|
||||
screenmob.client.screen += W.head
|
||||
else
|
||||
if(W.gloves) screenmob.client.screen -= W.gloves
|
||||
if(W.ears) screenmob.client.screen -= W.ears
|
||||
if(W.glasses) screenmob.client.screen -= W.glasses
|
||||
if(W.wear_neck) screenmob.client.screen -= W.wear_neck
|
||||
if(W.head) screenmob.client.screen -= W.head
|
||||
|
||||
/datum/hud/wendigo/persistent_inventory_update(mob/viewer)
|
||||
if(!mymob)
|
||||
return
|
||||
..()
|
||||
var/mob/living/carbon/wendigo/W = mymob
|
||||
|
||||
var/mob/screenmob = viewer || W
|
||||
|
||||
if(screenmob.hud_used)
|
||||
if(screenmob.hud_used.hud_shown)
|
||||
if(W.belt)
|
||||
W.belt.screen_loc = ui_belt
|
||||
screenmob.client.screen += W.belt
|
||||
if(W.back)
|
||||
W.back.screen_loc = ui_back
|
||||
screenmob.client.screen += W.back
|
||||
else
|
||||
if(W.belt)
|
||||
screenmob.client.screen -= W.belt
|
||||
if(W.back)
|
||||
screenmob.client.screen -= W.back
|
||||
|
||||
if(hud_version != HUD_STYLE_NOHUD)
|
||||
for(var/obj/item/I in W.held_items)
|
||||
I.screen_loc = ui_hand_position(W.get_held_index_of_item(I))
|
||||
screenmob.client.screen += I
|
||||
else
|
||||
for(var/obj/item/I in W.held_items)
|
||||
I.screen_loc = null
|
||||
screenmob.client.screen -= I
|
||||
|
||||
/datum/hud/wendigo/show_hud(version = 0,mob/viewmob)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/mob/screenmob = viewmob || mymob
|
||||
hidden_inventory_update(screenmob)
|
||||
@@ -0,0 +1,14 @@
|
||||
/obj/structure/soul_storage
|
||||
name = "soul storage"
|
||||
desc = "Stores souls!"
|
||||
var/list/souls = list()
|
||||
|
||||
//This is a big WIP. I don't even want it having the name "soul storage" but it'll do for now
|
||||
|
||||
/obj/structure/soul_storage/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.wendigo_soul_storages += src
|
||||
|
||||
/obj/structure/soul_storage/Destroy()
|
||||
GLOB.wendigo_soul_storages -= src
|
||||
return ..()
|
||||
@@ -0,0 +1,11 @@
|
||||
/mob/living/carbon/wendigo/UnarmedAttack(atom/A, proximity)
|
||||
A.attack_hand(src)
|
||||
|
||||
/mob/living/carbon/wendigo/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
if(incapacitated() || lying)
|
||||
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
|
||||
return FALSE
|
||||
if(be_close && !in_range(M, src))
|
||||
to_chat(src, "<span class='warning'>You are too far away!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
@@ -0,0 +1,115 @@
|
||||
#define DEFAULT_MOVESPEED 1.5
|
||||
//The mob itself
|
||||
/mob/living/carbon/wendigo
|
||||
name = "wendigo"
|
||||
gender = FEMALE
|
||||
unique_name = FALSE
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD)
|
||||
hud_type = /datum/hud/wendigo
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
appearance_flags = TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
|
||||
status_flags = CANSTUN //cant be knocked down, unconscious, or be pushed
|
||||
maxHealth = 200
|
||||
icon = 'hyperstation/icons/mobs/wendigo.dmi'
|
||||
icon_state = "reference"
|
||||
|
||||
bodyparts = list(/obj/item/bodypart/chest/wendigo, /obj/item/bodypart/head/wendigo,
|
||||
/obj/item/bodypart/l_arm/wendigo, /obj/item/bodypart/r_arm/wendigo,
|
||||
/obj/item/bodypart/l_leg/wendigo, /obj/item/bodypart/r_leg/wendigo)
|
||||
var/obj/item/belt = null
|
||||
var/datum/physiology/physiology
|
||||
var/obj/structure/soul_storage/connected_link
|
||||
var/fake_breast_size = 5 //She doesn't actually have the organ, but we cache her breast size for rp reasons
|
||||
var/fake_penis_size = 8
|
||||
|
||||
/mob/living/carbon/wendigo/Initialize(mapload)
|
||||
. = ..()
|
||||
/* //TODO: Uncomment when objectives + forest get finished
|
||||
if(!connected_link)
|
||||
if(!GLOB.wendigo_soul_storages.len)
|
||||
connected_link = new /obj/structure/soul_storage(get_turf(src))
|
||||
else
|
||||
connected_link = pick(GLOB.wendigo_soul_storages)
|
||||
gender = pick(FEMALE, MALE)
|
||||
*/
|
||||
if(gender == MALE)
|
||||
fake_breast_size = 0
|
||||
else
|
||||
fake_penis_size = 0
|
||||
real_name = name
|
||||
//DAMAGE RESISTANCE
|
||||
physiology = new()
|
||||
physiology.brute_mod = 0.7
|
||||
physiology.burn_mod = 1.25
|
||||
physiology.tox_mod = -1
|
||||
physiology.oxy_mod = 1
|
||||
physiology.clone_mod = 0
|
||||
physiology.stamina_mod = 0 //Running and attacking, prods
|
||||
physiology.heat_mod = 2 //IM MELTIIINNNGGGG-!
|
||||
physiology.cold_mod = 0
|
||||
physiology.siemens_coeff = 0.2
|
||||
physiology.stun_mod = 0 //prods n aggressive grab
|
||||
//physiology.bleed_mod = 2
|
||||
physiology.speed_mod = 0.9 //Should be faster than a normal person's walking speed
|
||||
physiology.hunger_mod = 2 //We're gonna have a FEAST TONIGHT!
|
||||
physiology.do_after_speed = 1
|
||||
|
||||
//Traits & Bodyparts
|
||||
create_bodyparts()
|
||||
create_internal_organs()
|
||||
ADD_TRAIT(src, TRAIT_NOCLONE, "initialize")
|
||||
add_verb(src, /mob/living/proc/mob_sleep)
|
||||
add_verb(src, /mob/living/proc/lay_down)
|
||||
add_movespeed_modifier("MOVESPEED_DEFAULT", multiplicative_slowdown=DEFAULT_MOVESPEED)
|
||||
update_body_parts()
|
||||
|
||||
/mob/living/carbon/wendigo/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/wendigo/update_body_parts()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.update_limb()
|
||||
|
||||
/mob/living/carbon/wendigo/update_move_intent_slowdown()
|
||||
var/mod = 0
|
||||
if(m_intent == MOVE_INTENT_WALK)
|
||||
mod = (CONFIG_GET(number/movedelay/walk_delay) / 2) //complete copy besides this part
|
||||
else
|
||||
mod = 1.30
|
||||
if(!isnum(mod))
|
||||
mod = 1
|
||||
add_movespeed_modifier(MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
|
||||
|
||||
/mob/living/carbon/wendigo/update_movespeed(resort=TRUE)
|
||||
return (..() * physiology.speed_mod)
|
||||
|
||||
/mob/living/carbon/wendigo/can_hold_items()
|
||||
return TRUE
|
||||
/mob/living/carbon/wendigo/IsAdvancedToolUser()
|
||||
return TRUE
|
||||
/mob/living/carbon/wendigo/can_be_pulled()
|
||||
return FALSE
|
||||
/mob/living/carbon/wendigo/is_literate()
|
||||
return TRUE
|
||||
/mob/living/carbon/wendigo/canBeHandcuffed()
|
||||
return TRUE
|
||||
/mob/living/carbon/wendigo/update_inv_handcuffed()
|
||||
return
|
||||
/mob/living/carbon/wendigo/update_inv_legcuffed()
|
||||
return
|
||||
|
||||
//
|
||||
//ORGANS
|
||||
//
|
||||
/mob/living/carbon/wendigo/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/eyes/wendigo
|
||||
internal_organs += new /obj/item/organ/liver/wendigo
|
||||
|
||||
internal_organs += new /obj/item/organ/tongue
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
internal_organs += new /obj/item/organ/stomach
|
||||
internal_organs += new /obj/item/organ/ears
|
||||
..()
|
||||
@@ -0,0 +1,86 @@
|
||||
/mob/living/carbon/wendigo/examine(mob/user)
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_His = p_their(TRUE)
|
||||
var/t_his = p_their()
|
||||
var/t_him = p_them()
|
||||
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
|
||||
if(handcuffed)
|
||||
. += "<span class='warning'>[t_He] is [icon2html(handcuffed, user)] handcuffed!</span>"
|
||||
if(legcuffed)
|
||||
. += "<span class='warning'>[t_He] has [icon2html(legcuffed, user)] leg cuffs!</span>"
|
||||
if(head)
|
||||
. += "[t_He] is wearing [head.get_examine_string(user)] on [t_his] head."
|
||||
if(wear_neck)
|
||||
. += "[t_He] is wearing [wear_neck.get_examine_string(user)] around [t_his] neck."
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.item_flags & ABSTRACT))
|
||||
. += "[t_He] is holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))]."
|
||||
|
||||
if(back)
|
||||
. += "[t_He] has [back.get_examine_string(user)] on [t_his] back."
|
||||
|
||||
if(stat == DEAD)
|
||||
. += "<span class='deadsay'>[t_He] is limp and unresponsive, with no signs of life.</span>"
|
||||
|
||||
var/list/msg = ("<span class='warning'>")
|
||||
var/temp_hp = getBruteLoss()
|
||||
if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY))
|
||||
if(temp_hp)
|
||||
if(temp_hp <= 25) msg += "[t_He] has minor bruising.\n"
|
||||
else if(temp_hp <= 75) msg += "[t_He] has <B>moderate</B> bruising!\n"
|
||||
else msg += "<B>[t_He] has severe bruising!</B>\n"
|
||||
temp_hp = getFireLoss()
|
||||
if(temp_hp)
|
||||
if(temp_hp <= 25) msg += "[t_He] has minor burns.\n"
|
||||
else if(temp_hp <= 50) msg += "[t_He] has <B>moderate</B> burns!\n"
|
||||
else msg += "<B>[t_He] has severe burns!</B>\n"
|
||||
if(fire_stacks > 0)
|
||||
msg += "[t_He] is covered in something flammable.\n"
|
||||
if(fire_stacks < 0)
|
||||
msg += "[t_He] looks a little soaked.\n"
|
||||
if(pulledby)
|
||||
if(pulledby.grab_state)
|
||||
msg += "[t_He] is restrained by [pulledby]'s grip.\n"
|
||||
|
||||
msg += "</span>"
|
||||
. += msg
|
||||
|
||||
if(stat == UNCONSCIOUS)
|
||||
. += "[t_He] isn't responding to anything around [t_him] and seems to be asleep."
|
||||
else if(InCritical())
|
||||
. += "[t_His] breathing is shallow and labored."
|
||||
|
||||
|
||||
if(fake_breast_size < 16)
|
||||
. += "You see a pair of breasts. You estimate them to be [ascii2text(round(fake_breast_size)+63)]-cups."
|
||||
else if(!fake_breast_size && gender == FEMALE)
|
||||
. += "You see a pair of breasts. They're small and flatchested, however."
|
||||
else
|
||||
. += "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [round(fake_breast_size)]cm in diameter."
|
||||
|
||||
if(fake_penis_size)
|
||||
. += "You see a flaccid human penis. You estimate it's about [round(fake_penis_size, 0.25)] inch[round(fake_penis_size, 0.25) != 1 ? "es" : ""] long." //would put girth here but lazy
|
||||
|
||||
if(connected_link)
|
||||
if(connected_link.souls.len > 5)
|
||||
. += "<span class='warning'><B>[t_His] eyes are glowing a deadly red.</B></span>"
|
||||
else
|
||||
var/A = "<span class='deadsay'>"
|
||||
switch(connected_link.souls.len)
|
||||
if(0)
|
||||
A += "[t_He] looks malnourished and weak."
|
||||
if(1)
|
||||
A += "[t_He] looks hungry."
|
||||
if(2 to 4)
|
||||
A += "[t_He] is salivating."
|
||||
if(5)
|
||||
A += "[t_His] eyes are glowing red."
|
||||
. += "[A]</span>"
|
||||
else
|
||||
. += "<span class='deadsay'>[t_He] looks lost.</span>"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, .)
|
||||
. += "*---------*</span>"
|
||||
@@ -0,0 +1,55 @@
|
||||
//Snowflake metabolization with naughty organ manipulation
|
||||
/mob/living/carbon/wendigo/proc/metabolize_hunger()
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
return
|
||||
|
||||
if(connected_link)
|
||||
if(connected_link.souls.len > 3)
|
||||
nutrition = min(800, nutrition + (HUNGER_FACTOR*connected_link.souls.len))
|
||||
nutrition = max(0, nutrition - (HUNGER_FACTOR / (physiology.hunger_mod / (connected_link.souls.len + 1))))
|
||||
else
|
||||
nutrition = max(0, nutrition - (HUNGER_FACTOR / physiology.hunger_mod))
|
||||
|
||||
switch(nutrition)
|
||||
if(NUTRITION_LEVEL_WELL_FED to INFINITY)
|
||||
throw_alert("nutrition", /obj/screen/alert/full)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
throw_alert("nutrition", /obj/screen/alert/sated)
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
throw_alert("nutrition", /obj/screen/alert/hungry)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
throw_alert("nutrition", /obj/screen/alert/starving)
|
||||
|
||||
/mob/living/carbon/wendigo/reagent_check(datum/reagent/R)
|
||||
if(istype(R, /datum/reagent/fermi))
|
||||
var/had_changed = FALSE
|
||||
if(R.type == /datum/reagent/fermi/penis_enlarger)
|
||||
fake_penis_size += 0.25
|
||||
had_changed = "penis_enlarger"
|
||||
if(R.type == /datum/reagent/fermi/PEsmaller)
|
||||
fake_penis_size = max(0, fake_penis_size - 0.25)
|
||||
had_changed = "PEsmaller"
|
||||
if(R.type == /datum/reagent/fermi/breast_enlarger)
|
||||
fake_breast_size += 0.25
|
||||
had_changed = "breast_enlarger"
|
||||
if(R.type == /datum/reagent/fermi/BEsmaller)
|
||||
fake_breast_size = max(0, fake_breast_size - 0.25)
|
||||
had_changed = "BEsmaller"
|
||||
|
||||
if(had_changed)
|
||||
R.volume -= R.metabolization_rate
|
||||
if(round(fake_penis_size, 1) == fake_penis_size && fake_penis_size)
|
||||
switch(had_changed)
|
||||
if("penis_enlarger")
|
||||
to_chat(src, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [fake_penis_size] inch penis.</b></span>")
|
||||
if("PEsmaller")
|
||||
if(fake_penis_size > 0)
|
||||
to_chat(src, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [fake_penis_size] inch penis.</b></span>")
|
||||
else if(round(fake_breast_size, 1) == fake_breast_size && fake_breast_size)
|
||||
switch(had_changed)
|
||||
if("breast_enlarger")
|
||||
to_chat(src, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [ascii2text(round(fake_breast_size)+63)]-cup.</b></span>")
|
||||
if("BEsmaller)")
|
||||
if(fake_breast_size > 0)
|
||||
to_chat(src, "<span class='warning'>Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [ascii2text(round(fake_breast_size)+63)]-cup.</b></span>")
|
||||
return TRUE
|
||||
@@ -0,0 +1,125 @@
|
||||
/mob/living/carbon/wendigo/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
|
||||
var/loc_temp = get_temperature(environment)
|
||||
|
||||
if(stat != DEAD)
|
||||
adjust_bodytemperature(natural_bodytemperature_stabilization())
|
||||
|
||||
if(!on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
|
||||
if(loc_temp < bodytemperature)
|
||||
adjust_bodytemperature(max((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
|
||||
else
|
||||
adjust_bodytemperature(min((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
|
||||
|
||||
|
||||
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTHEAT))
|
||||
switch(bodytemperature)
|
||||
if(280 to 300)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 1)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1*physiology.heat_mod, BURN)
|
||||
if(300 to 350)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 2)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2*physiology.heat_mod, BURN)
|
||||
if(350 to INFINITY)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
if(on_fire)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3*physiology.heat_mod, BURN)
|
||||
else
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2*physiology.heat_mod, BURN)
|
||||
|
||||
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTCOLD))
|
||||
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1*physiology.cold_mod, BURN)
|
||||
if(0 to 120)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2*physiology.cold_mod, BURN)
|
||||
if(-INFINITY to 0)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3*physiology.cold_mod, BURN)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
//Account for massive pressure differences
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
|
||||
switch(adjusted_pressure)
|
||||
if(HAZARD_HIGH_PRESSURE to INFINITY)
|
||||
adjustBruteLoss(min((((adjusted_pressure / HAZARD_HIGH_PRESSURE)-1)*PRESSURE_DAMAGE_COEFFICIENT)*physiology.pressure_mod, MAX_HIGH_PRESSURE_DAMAGE))
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
|
||||
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 1)
|
||||
if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
|
||||
clear_alert("pressure")
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
|
||||
else
|
||||
adjustBruteLoss( LOW_PRESSURE_DAMAGE*physiology.pressure_mod )
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/carbon/wendigo/handle_breath_temperature(datum/gas_mixture/breath)
|
||||
if(abs(BODYTEMP_NORMAL - breath.temperature) > 50)
|
||||
switch(breath.temperature)
|
||||
if(-INFINITY to 0)
|
||||
adjustFireLoss(3)
|
||||
if(0 to 120) //We flourish in a cold environment
|
||||
adjustFireLoss(1.5)
|
||||
if(298 to 350) //But hoo boy do we not like the heat
|
||||
adjustFireLoss(2)
|
||||
if(350 to 800)
|
||||
adjustFireLoss(3)
|
||||
if(800 to INFINITY)
|
||||
adjustFireLoss(8)
|
||||
|
||||
/mob/living/carbon/wendigo/handle_fire()
|
||||
if(..())
|
||||
return
|
||||
adjust_bodytemperature(BODYTEMP_HEATING_MAX*physiology.heat_mod)
|
||||
return
|
||||
|
||||
/mob/living/carbon/wendigo/adjustBruteLoss(amount, updating_health, forced)
|
||||
return ..(amount*physiology.brute_mod, updating_health, forced)
|
||||
|
||||
/mob/living/carbon/wendigo/adjustFireLoss(amount, updating_health, forced)
|
||||
return ..(amount*physiology.burn_mod, updating_health, forced)
|
||||
|
||||
/mob/living/carbon/wendigo/adjustToxLoss(amount, updating_health, forced)
|
||||
return ..(amount*physiology.tox_mod, updating_health, forced)
|
||||
|
||||
/mob/living/carbon/wendigo/adjustOxyLoss(amount, updating_health, forced)
|
||||
return ..(amount*physiology.oxy_mod, updating_health, forced)
|
||||
|
||||
/mob/living/carbon/wendigo/adjustCloneLoss(amount, updating_health, forced)
|
||||
return ..(amount*physiology.clone_mod, updating_health, forced)
|
||||
|
||||
/mob/living/carbon/wendigo/adjustStaminaLoss(amount, updating_health, forced)
|
||||
return ..(amount*physiology.stamina_mod, updating_health, forced)
|
||||
|
||||
/mob/living/carbon/wendigo/do_after_coefficent()
|
||||
. = ..()
|
||||
. *= physiology.do_after_speed
|
||||
|
||||
/mob/living/carbon/wendigo/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
return ..(shock_damage, source, physiology.siemens_coeff, safety, override, tesla_shock, illusion, stun)
|
||||
|
||||
/mob/living/carbon/wendigo/Stun(amount, updating, ignore_canstun)
|
||||
return ..(amount*physiology.stun_mod, updating, ignore_canstun)
|
||||
|
||||
/mob/living/carbon/wendigo/Knockdown(amount, updating, ignore_canknockdown, override_hardstun, override_stamdmg)
|
||||
return ..(amount*physiology.stun_mod, updating, ignore_canknockdown, override_hardstun, override_stamdmg)
|
||||
|
||||
/mob/living/carbon/wendigo/Unconscious(amount, updating, ignore_canunconscious)
|
||||
return ..(amount*physiology.stun_mod, updating, ignore_canunconscious)
|
||||
|
||||
/mob/living/carbon/wendigo/bleed(amt)
|
||||
return ..(amt*physiology.bleed_mod)
|
||||
@@ -0,0 +1,100 @@
|
||||
/mob/living/carbon/wendigo/can_equip(obj/item/I, slot, disable_warning)
|
||||
switch(slot)
|
||||
if(SLOT_HANDS)
|
||||
if(get_empty_held_indexes())
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(SLOT_GLASSES)
|
||||
if(glasses)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_EYES))
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(SLOT_NECK)
|
||||
if(wear_neck)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_NECK))
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(SLOT_EARS)
|
||||
if(ears)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_EARS))
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(SLOT_GLOVES)
|
||||
if(gloves)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_GLOVES))
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(SLOT_BACK)
|
||||
if(back)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_BACK))
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(SLOT_IN_BACKPACK)
|
||||
if(back)
|
||||
if(SEND_SIGNAL(back, COMSIG_TRY_STORAGE_CAN_INSERT, I, src, TRUE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(SLOT_HEAD)
|
||||
if(head)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_HEAD))
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(SLOT_BELT)
|
||||
if(belt)
|
||||
return FALSE
|
||||
if(!(I.slot_flags & ITEM_SLOT_BELT))
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/wendigo/equip_to_slot(obj/item/I, slot)
|
||||
if(!..())
|
||||
return
|
||||
switch(slot)
|
||||
if(SLOT_GLASSES)
|
||||
glasses = I
|
||||
update_inv_glasses()
|
||||
if(SLOT_EARS)
|
||||
ears = I
|
||||
update_inv_ears()
|
||||
if(SLOT_GLOVES)
|
||||
gloves = I
|
||||
update_inv_gloves()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/wendigo/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE)
|
||||
. = ..()
|
||||
if(!. || !I)
|
||||
return
|
||||
|
||||
else if(I == gloves)
|
||||
gloves = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_gloves()
|
||||
else if(I == glasses)
|
||||
glasses = null
|
||||
var/obj/item/clothing/glasses/G = I
|
||||
if(G.tint)
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
if(HAS_TRAIT(src, TRAIT_NEARSIGHT))
|
||||
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
|
||||
adjust_eye_damage(0)
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
|
||||
update_sight()
|
||||
if(!QDELETED(src))
|
||||
update_inv_glasses()
|
||||
else if(I == ears)
|
||||
ears = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_ears()
|
||||
else if(I == belt)
|
||||
belt = null
|
||||
if(!QDELETED(src))
|
||||
update_inv_belt()
|
||||
@@ -0,0 +1,58 @@
|
||||
/obj/item/organ/liver/wendigo
|
||||
name = "rotten liver"
|
||||
desc = "A liver from a wendigo. It looks like a spoiled tomato."
|
||||
decay_factor = 0
|
||||
|
||||
/obj/item/organ/liver/wendigo/on_life()
|
||||
var/mob/living/carbon/C = owner
|
||||
if(istype(C))
|
||||
damage = initial(maxHealth)
|
||||
|
||||
if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER))
|
||||
//handle liver toxin filtration
|
||||
for(var/datum/reagent/toxin/T in C.reagents.reagent_list)
|
||||
var/thisamount = C.reagents.get_reagent_amount(T.type)
|
||||
if (thisamount && thisamount <= toxTolerance)
|
||||
C.reagents.remove_reagent(T.type, 1)
|
||||
|
||||
C.reagents.metabolize(C, can_overdose=FALSE)
|
||||
if(istype(C, /mob/living/carbon/wendigo))
|
||||
var/mob/living/carbon/wendigo/A = C
|
||||
A.metabolize_hunger()
|
||||
|
||||
/obj/item/organ/eyes/wendigo
|
||||
sight_flags = SEE_MOBS
|
||||
|
||||
/obj/item/bodypart/head/wendigo
|
||||
dismemberable = FALSE
|
||||
max_damage = INFINITY
|
||||
animal_origin = WENDIGO_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/wendigo
|
||||
dismemberable = FALSE
|
||||
max_damage = INFINITY
|
||||
animal_origin = WENDIGO_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm/wendigo
|
||||
dismemberable = FALSE
|
||||
max_damage = INFINITY
|
||||
attack_verb = list("slashed", "clawed", "mauled")
|
||||
animal_origin = WENDIGO_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm/wendigo
|
||||
dismemberable = FALSE
|
||||
max_damage = INFINITY
|
||||
attack_verb = list("slashed", "clawed", "mauled")
|
||||
animal_origin = WENDIGO_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg/wendigo
|
||||
dismemberable = FALSE
|
||||
max_damage = INFINITY
|
||||
attack_verb = list("pounded", "stomped", "stamped", "kicked")
|
||||
animal_origin = WENDIGO_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg/wendigo
|
||||
dismemberable = FALSE
|
||||
max_damage = INFINITY
|
||||
attack_verb = list("pounded", "stomped", "stamped", "kicked")
|
||||
animal_origin = WENDIGO_BODYPART
|
||||
@@ -0,0 +1,370 @@
|
||||
#define HEAD_X_OFFSET_NORTH 2
|
||||
#define HEAD_Y_OFFSET_NORTH 8
|
||||
#define HEAD_X_OFFSET_EAST 2
|
||||
#define HEAD_Y_OFFSET_EAST 8
|
||||
#define HEAD_X_OFFSET_SOUTH 8
|
||||
#define HEAD_Y_OFFSET_SOUTH 2
|
||||
#define HEAD_X_OFFSET_WEST 8
|
||||
#define HEAD_Y_OFFSET_WEST -2
|
||||
|
||||
#define LHAND_X_OFFSET_NORTH -5
|
||||
#define LHAND_Y_OFFSET_NORTH 3
|
||||
#define LHAND_X_OFFSET_EAST -2
|
||||
#define LHAND_Y_OFFSET_EAST 3
|
||||
#define LHAND_X_OFFSET_SOUTH 8
|
||||
#define LHAND_Y_OFFSET_SOUTH 3
|
||||
#define LHAND_X_OFFSET_WEST -2
|
||||
#define LHAND_Y_OFFSET_WEST 3
|
||||
|
||||
#define RHAND_X_OFFSET_NORTH 8
|
||||
#define RHAND_Y_OFFSET_NORTH 3
|
||||
#define RHAND_X_OFFSET_EAST 2
|
||||
#define RHAND_Y_OFFSET_EAST 3
|
||||
#define RHAND_X_OFFSET_SOUTH -5
|
||||
#define RHAND_Y_OFFSET_SOUTH 3
|
||||
#define RHAND_X_OFFSET_WEST 2
|
||||
#define RHAND_Y_OFFSET_WEST 3
|
||||
|
||||
#define EARS_X_OFFSET_NORTH 0
|
||||
#define EARS_Y_OFFSET_NORTH 0
|
||||
#define EARS_X_OFFSET_EAST 0
|
||||
#define EARS_Y_OFFSET_EAST 0
|
||||
#define EARS_X_OFFSET_SOUTH 0
|
||||
#define EARS_Y_OFFSET_SOUTH 0
|
||||
#define EARS_X_OFFSET_WEST 0
|
||||
#define EARS_Y_OFFSET_WEST 0
|
||||
|
||||
#define GLASSES_X_OFFSET_NORTH 5
|
||||
#define GLASSES_Y_OFFSET_NORTH 10
|
||||
#define GLASSES_X_OFFSET_EAST 1
|
||||
#define GLASSES_Y_OFFSET_EAST 10
|
||||
#define GLASSES_X_OFFSET_SOUTH -2
|
||||
#define GLASSES_Y_OFFSET_SOUTH 10
|
||||
#define GLASSES_X_OFFSET_WEST -1
|
||||
#define GLASSES_Y_OFFSET_WEST 10
|
||||
|
||||
#define BELT_X_OFFSET_NORTH 0
|
||||
#define BELT_Y_OFFSET_NORTH 10
|
||||
#define BELT_X_OFFSET_EAST 0
|
||||
#define BELT_Y_OFFSET_EAST 0
|
||||
#define BELT_X_OFFSET_SOUTH 0
|
||||
#define BELT_Y_OFFSET_SOUTH 0
|
||||
#define BELT_X_OFFSET_WEST 0
|
||||
#define BELT_Y_OFFSET_WEST 0
|
||||
|
||||
#define BACK_X_OFFSET_NORTH 1
|
||||
#define BACK_Y_OFFSET_NORTH 8
|
||||
#define BACK_X_OFFSET_EAST 0
|
||||
#define BACK_Y_OFFSET_EAST 8
|
||||
#define BACK_X_OFFSET_SOUTH 1
|
||||
#define BACK_Y_OFFSET_SOUTH 8
|
||||
#define BACK_X_OFFSET_WEST 0
|
||||
#define BACK_Y_OFFSET_WEST 8
|
||||
|
||||
#define NECK_X_OFFSET_NORTH 2
|
||||
#define NECK_Y_OFFSET_NORTH 10
|
||||
#define NECK_X_OFFSET_EAST 0
|
||||
#define NECK_Y_OFFSET_EAST 10
|
||||
#define NECK_X_OFFSET_SOUTH 2
|
||||
#define NECK_Y_OFFSET_SOUTH 10
|
||||
#define NECK_X_OFFSET_WEST 0
|
||||
#define NECK_Y_OFFSET_WEST 10
|
||||
|
||||
/mob/living/carbon/wendigo/setDir(newdir, ismousemovement)
|
||||
if(dir == newdir)
|
||||
return //Don't spend time regenerating icons when we don't move
|
||||
. = ..()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/carbon/wendigo/regenerate_icons()
|
||||
if(!..())
|
||||
update_inv_head()
|
||||
update_inv_gloves()
|
||||
update_inv_ears()
|
||||
update_inv_glasses()
|
||||
update_inv_belt()
|
||||
update_inv_back()
|
||||
update_inv_neck()
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/wendigo/update_inv_gloves()
|
||||
if(gloves)
|
||||
gloves.screen_loc = ui_gloves
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += gloves
|
||||
|
||||
//GLASSES
|
||||
/mob/living/carbon/wendigo/update_inv_glasses()
|
||||
if(glasses)
|
||||
glasses.screen_loc = ui_glasses
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += glasses
|
||||
|
||||
//EARS
|
||||
/mob/living/carbon/wendigo/update_inv_ears()
|
||||
remove_overlay(EARS_LAYER)
|
||||
if(ears)
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS]
|
||||
inv.update_icon()
|
||||
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += ears
|
||||
|
||||
overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = ((ears.alternate_worn_icon) ? ears.alternate_worn_icon : 'icons/mob/ears.dmi'))
|
||||
var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER]
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
ears_overlay.pixel_x += EARS_X_OFFSET_NORTH
|
||||
ears_overlay.pixel_y += EARS_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
ears_overlay.pixel_x += EARS_X_OFFSET_EAST
|
||||
ears_overlay.pixel_y += EARS_Y_OFFSET_EAST
|
||||
if(SOUTH)
|
||||
ears_overlay.pixel_x += EARS_X_OFFSET_SOUTH
|
||||
ears_overlay.pixel_y += EARS_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
ears_overlay.pixel_x += EARS_X_OFFSET_WEST
|
||||
ears_overlay.pixel_y += EARS_Y_OFFSET_WEST
|
||||
overlays_standing[EARS_LAYER] = ears_overlay
|
||||
apply_overlay(EARS_LAYER)
|
||||
|
||||
//BELT
|
||||
/mob/living/carbon/wendigo/update_inv_belt()
|
||||
remove_overlay(BELT_LAYER)
|
||||
|
||||
if(belt)
|
||||
belt.screen_loc = ui_belt
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += belt
|
||||
|
||||
var/t_state = belt.item_state
|
||||
if(!t_state)
|
||||
t_state = belt.icon_state
|
||||
|
||||
overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = ((belt.alternate_worn_icon) ? belt.alternate_worn_icon : 'icons/mob/belt.dmi'))
|
||||
var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER]
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
belt_overlay.pixel_x += BELT_X_OFFSET_NORTH
|
||||
belt_overlay.pixel_y += BELT_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
belt_overlay.pixel_x += BELT_X_OFFSET_EAST
|
||||
belt_overlay.pixel_y += BELT_Y_OFFSET_EAST
|
||||
if(SOUTH)
|
||||
belt_overlay.pixel_x += BELT_X_OFFSET_SOUTH
|
||||
belt_overlay.pixel_y += BELT_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
belt_overlay.pixel_x += BELT_X_OFFSET_WEST
|
||||
belt_overlay.pixel_y += BELT_Y_OFFSET_WEST
|
||||
overlays_standing[BELT_LAYER] = belt_overlay
|
||||
apply_overlay(BELT_LAYER)
|
||||
|
||||
//BACK
|
||||
/mob/living/carbon/wendigo/update_inv_back()
|
||||
..()
|
||||
if(back)
|
||||
back.screen_loc = ui_back
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += back
|
||||
var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER]
|
||||
if(back_overlay)
|
||||
remove_overlay(BACK_LAYER)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
back_overlay.pixel_x += BACK_X_OFFSET_NORTH
|
||||
back_overlay.pixel_y += BACK_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
back_overlay.pixel_x += BACK_X_OFFSET_EAST
|
||||
back_overlay.pixel_y += BACK_Y_OFFSET_EAST
|
||||
if(SOUTH)
|
||||
back_overlay.pixel_x += BACK_X_OFFSET_SOUTH
|
||||
back_overlay.pixel_y += BACK_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
back_overlay.pixel_x += BACK_X_OFFSET_WEST
|
||||
back_overlay.pixel_y += BACK_Y_OFFSET_WEST
|
||||
overlays_standing[BACK_LAYER] = back_overlay
|
||||
apply_overlay(BACK_LAYER)
|
||||
|
||||
//NECK
|
||||
/mob/living/carbon/wendigo/update_inv_neck()
|
||||
..()
|
||||
if(wear_neck)
|
||||
wear_neck.screen_loc = ui_neck
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += wear_neck
|
||||
var/mutable_appearance/neck_overlay = overlays_standing[NECK_LAYER]
|
||||
if(neck_overlay)
|
||||
remove_overlay(NECK_LAYER)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
neck_overlay.pixel_x += NECK_X_OFFSET_NORTH
|
||||
neck_overlay.pixel_y += NECK_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
neck_overlay.pixel_x += NECK_X_OFFSET_EAST
|
||||
neck_overlay.pixel_y += NECK_Y_OFFSET_EAST
|
||||
if(SOUTH)
|
||||
neck_overlay.pixel_x += NECK_X_OFFSET_SOUTH
|
||||
neck_overlay.pixel_y += NECK_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
neck_overlay.pixel_x += NECK_X_OFFSET_WEST
|
||||
neck_overlay.pixel_y += NECK_Y_OFFSET_WEST
|
||||
overlays_standing[NECK_LAYER] = neck_overlay
|
||||
apply_overlay(NECK_LAYER)
|
||||
|
||||
//HANDS
|
||||
/mob/living/carbon/wendigo/update_inv_hands()
|
||||
remove_overlay(HANDS_LAYER)
|
||||
if (handcuffed)
|
||||
drop_all_held_items()
|
||||
return
|
||||
|
||||
var/list/hands = list()
|
||||
for(var/obj/item/I in held_items)
|
||||
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
|
||||
I.screen_loc = ui_hand_position(get_held_index_of_item(I))
|
||||
client.screen += I
|
||||
if(observers && observers.len)
|
||||
for(var/M in observers)
|
||||
var/mob/dead/observe = M
|
||||
if(observe.client && observe.client.eye == src)
|
||||
observe.client.screen += I
|
||||
else
|
||||
observers -= observe
|
||||
if(!observers.len)
|
||||
observers = null
|
||||
break
|
||||
|
||||
var/t_state = I.item_state
|
||||
if(!t_state)
|
||||
t_state = I.icon_state
|
||||
|
||||
var/icon_file = I.lefthand_file
|
||||
var/righthand = 0
|
||||
if(get_held_index_of_item(I) % 2 == 0)
|
||||
icon_file = I.righthand_file
|
||||
righthand = 1
|
||||
|
||||
var/mutable_appearance/thing = I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE)
|
||||
if(righthand)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
thing.pixel_x += RHAND_X_OFFSET_NORTH
|
||||
thing.pixel_y += RHAND_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
thing = null //ghetto
|
||||
if(SOUTH)
|
||||
thing.pixel_x += RHAND_X_OFFSET_SOUTH
|
||||
thing.pixel_y += RHAND_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
thing.pixel_x += RHAND_X_OFFSET_WEST
|
||||
thing.pixel_y += RHAND_Y_OFFSET_WEST
|
||||
else
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
thing.pixel_x += LHAND_X_OFFSET_NORTH
|
||||
thing.pixel_y += LHAND_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
thing.pixel_x += LHAND_X_OFFSET_EAST
|
||||
thing.pixel_y += LHAND_Y_OFFSET_EAST
|
||||
if(SOUTH)
|
||||
thing.pixel_x += LHAND_X_OFFSET_SOUTH
|
||||
thing.pixel_y += LHAND_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
thing = null //ghetto
|
||||
|
||||
hands += thing
|
||||
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
apply_overlay(HANDS_LAYER)
|
||||
|
||||
//HEAD
|
||||
/mob/living/carbon/wendigo/update_inv_head()
|
||||
remove_overlay(HEAD_LAYER)
|
||||
|
||||
if(head)
|
||||
head.screen_loc = ui_head
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += head
|
||||
var/mutable_appearance/head_icon = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi')
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
head_icon.pixel_x += HEAD_X_OFFSET_NORTH
|
||||
head_icon.pixel_y += HEAD_Y_OFFSET_NORTH
|
||||
if(EAST)
|
||||
head_icon.pixel_x += HEAD_X_OFFSET_EAST
|
||||
head_icon.pixel_y += HEAD_Y_OFFSET_EAST
|
||||
if(SOUTH)
|
||||
head_icon.pixel_x += HEAD_X_OFFSET_SOUTH
|
||||
head_icon.pixel_y += HEAD_Y_OFFSET_SOUTH
|
||||
if(WEST)
|
||||
head_icon.pixel_x += HEAD_X_OFFSET_WEST
|
||||
head_icon.pixel_y += HEAD_Y_OFFSET_WEST
|
||||
overlays_standing[SLOT_HEAD] = head_icon
|
||||
update_hud_head(head)
|
||||
|
||||
apply_overlay(HEAD_LAYER)
|
||||
|
||||
#undef LHAND_X_OFFSET_NORTH
|
||||
#undef LHAND_Y_OFFSET_NORTH
|
||||
#undef LHAND_X_OFFSET_EAST
|
||||
#undef LHAND_Y_OFFSET_EAST
|
||||
#undef LHAND_X_OFFSET_SOUTH
|
||||
#undef LHAND_Y_OFFSET_SOUTH
|
||||
#undef LHAND_X_OFFSET_WEST
|
||||
#undef LHAND_Y_OFFSET_WEST
|
||||
#undef RHAND_X_OFFSET_NORTH
|
||||
#undef RHAND_Y_OFFSET_NORTH
|
||||
#undef RHAND_X_OFFSET_EAST
|
||||
#undef RHAND_Y_OFFSET_EAST
|
||||
#undef RHAND_X_OFFSET_SOUTH
|
||||
#undef RHAND_Y_OFFSET_SOUTH
|
||||
#undef RHAND_X_OFFSET_WEST
|
||||
#undef RHAND_Y_OFFSET_WEST
|
||||
#undef EARS_X_OFFSET_NORTH
|
||||
#undef EARS_Y_OFFSET_NORTH
|
||||
#undef EARS_X_OFFSET_EAST
|
||||
#undef EARS_Y_OFFSET_EAST
|
||||
#undef EARS_X_OFFSET_SOUTH
|
||||
#undef EARS_Y_OFFSET_SOUTH
|
||||
#undef EARS_X_OFFSET_WEST
|
||||
#undef EARS_Y_OFFSET_WEST
|
||||
#undef GLASSES_X_OFFSET_NORTH
|
||||
#undef GLASSES_Y_OFFSET_NORTH
|
||||
#undef GLASSES_X_OFFSET_EAST
|
||||
#undef GLASSES_Y_OFFSET_EAST
|
||||
#undef GLASSES_X_OFFSET_SOUTH
|
||||
#undef GLASSES_Y_OFFSET_SOUTH
|
||||
#undef GLASSES_X_OFFSET_WEST
|
||||
#undef GLASSES_Y_OFFSET_WEST
|
||||
#undef BELT_X_OFFSET_NORTH
|
||||
#undef BELT_Y_OFFSET_NORTH
|
||||
#undef BELT_X_OFFSET_EAST
|
||||
#undef BELT_Y_OFFSET_EAST
|
||||
#undef BELT_X_OFFSET_SOUTH
|
||||
#undef BELT_Y_OFFSET_SOUTH
|
||||
#undef BELT_X_OFFSET_WEST
|
||||
#undef BELT_Y_OFFSET_WEST
|
||||
#undef BACK_X_OFFSET_NORTH
|
||||
#undef BACK_Y_OFFSET_NORTH
|
||||
#undef BACK_X_OFFSET_EAST
|
||||
#undef BACK_Y_OFFSET_EAST
|
||||
#undef BACK_X_OFFSET_SOUTH
|
||||
#undef BACK_Y_OFFSET_SOUTH
|
||||
#undef BACK_X_OFFSET_WEST
|
||||
#undef BACK_Y_OFFSET_WEST
|
||||
#undef NECK_X_OFFSET_NORTH
|
||||
#undef NECK_Y_OFFSET_NORTH
|
||||
#undef NECK_X_OFFSET_EAST
|
||||
#undef NECK_Y_OFFSET_EAST
|
||||
#undef NECK_X_OFFSET_SOUTH
|
||||
#undef NECK_Y_OFFSET_SOUTH
|
||||
#undef NECK_X_OFFSET_WEST
|
||||
#undef NECK_Y_OFFSET_WEST
|
||||
@@ -0,0 +1,704 @@
|
||||
//Hyperstation Arousal hud
|
||||
//This needs alot of attention, im a bad coder. a shitty attempt at making a more user friendly/modern hud
|
||||
//if you wanna use this on your own server go ahead, but alittle credit would always be nice! -quotefox
|
||||
//This still uses alot of cits arousal system!
|
||||
|
||||
/obj/screen/arousal/ui_interact(mob/user)
|
||||
. = ..()
|
||||
var/dat = {"<B>Genitals</B><BR><HR>"}
|
||||
|
||||
var/mob/living/carbon/U = user
|
||||
for(var/obj/item/organ/genital/G in U.internal_organs)
|
||||
if(!G.nochange)
|
||||
if(!G.dontlist)
|
||||
// GS13: Fix spelling
|
||||
dat += "<a href='byond://?src=[REF(src)];hide[G.name]=1'>[G.mode == "hidden" ? "[G.name] <font color='red'>(Hidden)</font>" : (G.mode == "clothes" ? "[G.name] <font color='yellow'>(Hidden by Clothes)</font>" : (G.mode == "visible" ? "[G.name] <font color='green'>(Visible)</font>" : "[G.name] <font color='green'>(Visible)</font>"))]</a><BR>"
|
||||
|
||||
dat += {"<BR><B>Contexual Options</B><BR><HR>"}
|
||||
var/obj/item/organ/genital/penis/P = user.getorganslot("penis")
|
||||
//Options
|
||||
dat += "<a href='byond://?src=[REF(src)];masturbate=1'>Masturbate</A>"
|
||||
dat += "(Stimulate a sexual organ with your hands.)<BR>"
|
||||
|
||||
dat += "<a href='byond://?src=[REF(src)];climax=1'>Climax</A>"
|
||||
dat += "(Orgasm from a sexual organ.)<BR>"
|
||||
|
||||
dat += "<a href='byond://?src=[REF(src)];container=1'>Fill container</A>"
|
||||
dat += "(Use a container in your hand to collect your seminal fluid.)<BR>"
|
||||
|
||||
var/mob/living/carbon/human/C = usr
|
||||
if(C && C.w_uniform || C.wear_suit) //if they are wearing cloths
|
||||
dat += "<a href='byond://?src=[REF(src)];clothesplosion=1'>Explode out of clothes</A>"
|
||||
dat += "(Flex your body to cause your clothes to burst apart.)<BR>"
|
||||
|
||||
if(user.pulling)
|
||||
dat += "<a href='byond://?src=[REF(src)];kiss=1'>Kiss [user.pulling]</A>"
|
||||
dat += "(Kiss a partner, or object.)<BR>"
|
||||
dat += "<a href='byond://?src=[REF(src)];feed=1'>Feed [user.pulling]</A>"
|
||||
dat += "(Feed a partner.)<BR>"
|
||||
dat += "<a href='byond://?src=[REF(src)];feedfrom=1'>Feed from [user.pulling]</A>"
|
||||
dat += "(Feed a partner.)<BR>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Kiss</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
dat += "<span class='linkOff'>Feed others</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
dat += "<span class='linkOff'>Feed from others</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
dat += "<a href='byond://?src=[REF(src)];feedyourself=1'>Feed yourself</A>"
|
||||
dat += "(Feed yourself with your own genitals)<BR>"
|
||||
|
||||
var/obj/item/organ/genital/belly/Belly = user.getorganslot("belly")
|
||||
if(Belly)
|
||||
if(Belly.inflatable)
|
||||
// GS13: Fix description
|
||||
dat += "<a href='byond://?src=[REF(src)];shrink_belly=1'>Decrease belly size</A>"
|
||||
dat += "(Shrink your belly down a size)<BR>"
|
||||
dat += "<a href='byond://?src=[REF(src)];inflate_belly=1'>Increase belly size</A>"
|
||||
dat += "(Bloat your belly up a size)<BR>"
|
||||
|
||||
if(user.pulling)
|
||||
dat += "<a href='byond://?src=[REF(src)];climaxover=1'>Climax over [user.pulling]</A>" //you can cum on objects if you really want...
|
||||
dat += "(Orgasm over a person or object.)<BR>"
|
||||
if(isliving(user.pulling))
|
||||
if(iscarbon(user.pulling))
|
||||
dat += "<a href='byond://?src=[REF(src)];climaxwith=1'>Climax with [user.pulling]</A>"
|
||||
dat += {"(Orgasm with another person.)<BR>"}
|
||||
|
||||
var/mob/living/carbon/human/H = user.pulling
|
||||
if(H.breedable && P && H)
|
||||
dat += "<a href='byond://?src=[REF(src)];impreg=1'>Impregnate [U.pulling] ([clamp(U.impregchance,0,100)]%)</A>"
|
||||
dat += "(Climax inside another person, and attempt to knock them up.)<BR>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Climax over</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
dat += "<span class='linkOff'>Climax with</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
|
||||
//old code needs to be cleaned
|
||||
if(P)
|
||||
if(P.condom == 1)
|
||||
dat += "<a href='byond://?src=[REF(src)];removecondom=1'>Remove condom (penis)</A><BR>"
|
||||
if(P.sounding == 1)
|
||||
dat += "<a href='byond://?src=[REF(src)];removesound=1'>Remove sounding rod (penis)</A><BR>"
|
||||
for(var/obj/item/organ/genital/G in U.internal_organs)
|
||||
if(G.equipment) //they have equipment
|
||||
dat += "<a href='byond://?src=[REF(src)];removeequipment[G.name]=1;'>Remove [G.equipment.name] ([G.name])</A><BR>"
|
||||
|
||||
dat += {"<HR>"}//Newline for the objects
|
||||
//bottom options
|
||||
dat += "<a href='byond://?src=[REF(src)];refresh=1'>Refresh</A>"
|
||||
dat += "<a href='byond://?src=[REF(src)];omenu=1'>Old Menu</A>"
|
||||
dat += "<a href='byond://?src=[REF(src)];underwear=1'>Toggle Undergarments </A>"
|
||||
dat += "<BR>"
|
||||
|
||||
var/datum/browser/popup = new(user, "arousal", "Arousal Panel")
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state), 500,600)
|
||||
|
||||
popup.open()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/screen/arousal/Topic(href, href_list)
|
||||
. = ..() //Sanity checks.
|
||||
if(..())
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if (!H)
|
||||
return
|
||||
if(usr.stat==1) //No sleep-masturbation, you're unconscious.
|
||||
to_chat(usr, "<span class='warning'>You must be conscious to do that!</span>")
|
||||
usr << browse(null, "window=arousal") //closes the window
|
||||
return
|
||||
if(usr.stat==3)
|
||||
to_chat(usr, "<span class='warning'>You must be alive to do that!</span>")
|
||||
usr << browse(null, "window=arousal") //closes the window
|
||||
return
|
||||
|
||||
if(href_list["hidepenis"])
|
||||
var/obj/item/organ/genital/penis/P = usr.getorganslot("penis")
|
||||
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
P.toggle_visibility(picked_visibility)
|
||||
|
||||
if(href_list["hidevagina"])
|
||||
var/obj/item/organ/genital/vagina/V = usr.getorganslot("vagina")
|
||||
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
V.toggle_visibility(picked_visibility)
|
||||
|
||||
if(href_list["hidebreasts"])
|
||||
var/obj/item/organ/genital/breasts/B = usr.getorganslot("breasts")
|
||||
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
B.toggle_visibility(picked_visibility)
|
||||
|
||||
if(href_list["hidebelly"])
|
||||
var/obj/item/organ/genital/belly/E = usr.getorganslot("belly")
|
||||
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
E.toggle_visibility(picked_visibility)
|
||||
|
||||
if(href_list["hideanus"])
|
||||
var/obj/item/organ/genital/anus/A = usr.getorganslot("anus")
|
||||
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
A.toggle_visibility(picked_visibility)
|
||||
|
||||
if(href_list["hidetesticles"])
|
||||
var/obj/item/organ/genital/testicles/T = usr.getorganslot("testicles")
|
||||
var/picked_visibility = input(usr, "Choose visibility", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
|
||||
T.toggle_visibility(picked_visibility)
|
||||
|
||||
if(href_list["masturbate"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
|
||||
H.solomasturbate()
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["container"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
|
||||
H.cumcontainer()
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["clothesplosion"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //Requires 33% arousal.
|
||||
H.clothesplosion()
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["climax"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
|
||||
H.climaxalone(FALSE)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["climaxover"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
|
||||
H.climaxover(usr.pulling)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["climaxwith"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
|
||||
H.climaxwith(usr.pulling)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["impreg"])
|
||||
if (H.arousalloss >= (H.max_arousal / 100) * 33) //requires 33% arousal.
|
||||
H.impregwith(usr.pulling)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You aren't aroused enough for that! </span>")
|
||||
return
|
||||
|
||||
if(href_list["kiss"])
|
||||
if(usr.pulling)
|
||||
kiss()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You cannot do this alone!</span>")
|
||||
return
|
||||
|
||||
if(href_list["feed"])
|
||||
if(usr.pulling)
|
||||
feed()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You cannot do this alone!</span>")
|
||||
return
|
||||
|
||||
if(href_list["feedfrom"])
|
||||
if(usr.pulling)
|
||||
feedfrom()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You cannot do this alone!</span>")
|
||||
return
|
||||
|
||||
if(href_list["feedyourself"])
|
||||
feedyourself()
|
||||
return
|
||||
|
||||
if(href_list["shrink_belly"])
|
||||
var/obj/item/organ/genital/belly/E = usr.getorganslot("belly")
|
||||
if(E.size > 0)
|
||||
to_chat(usr, "<span class='userlove'>You feel your belly diminish.</span>")
|
||||
E.size -= 1
|
||||
H.update_genitals()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Your belly is already at the minimum size! </span>")
|
||||
|
||||
if(href_list["inflate_belly"])
|
||||
var/obj/item/organ/genital/belly/E = usr.getorganslot("belly")
|
||||
if(E.size < 11)
|
||||
to_chat(usr, "<span class='userlove'>You feel your belly bloat out..</span>")
|
||||
E.size += 1
|
||||
H.update_genitals()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Your belly is already at the maximum size! </span>")
|
||||
|
||||
|
||||
if(href_list["removecondom"])
|
||||
H.menuremovecondom()
|
||||
|
||||
if(href_list["removesound"])
|
||||
H.menuremovesounding()
|
||||
|
||||
if(href_list["removeequipmentpenis"])
|
||||
var/obj/item/organ/genital/penis/O = usr.getorganslot("penis")
|
||||
var/obj/item/I = O.equipment
|
||||
usr.put_in_hands(I)
|
||||
O.equipment = null
|
||||
|
||||
if(href_list["removeequipmentbreasts"])
|
||||
var/obj/item/organ/genital/breasts/O = usr.getorganslot("breasts")
|
||||
var/obj/item/I = O.equipment
|
||||
usr.put_in_hands(I)
|
||||
O.equipment = null
|
||||
|
||||
|
||||
if(href_list["removeequipmentvagina"])
|
||||
var/obj/item/organ/genital/vagina/O = usr.getorganslot("vagina")
|
||||
var/obj/item/I = O.equipment
|
||||
usr.put_in_hands(I)
|
||||
if(istype(I, /obj/item/portalpanties))
|
||||
var/obj/item/portalpanties/P = I
|
||||
P.remove()
|
||||
O.equipment = null
|
||||
|
||||
if(href_list["removeequipmentbelly"])
|
||||
var/obj/item/organ/genital/belly/O = usr.getorganslot("belly")
|
||||
var/obj/item/I = O.equipment
|
||||
usr.put_in_hands(I)
|
||||
O.equipment = null
|
||||
|
||||
if(href_list["removeequipmentanus"])
|
||||
var/obj/item/organ/genital/anus/O = usr.getorganslot("anus")
|
||||
var/obj/item/I = O.equipment
|
||||
usr.put_in_hands(I)
|
||||
O.equipment = null
|
||||
|
||||
|
||||
if(href_list["omenu"])
|
||||
usr << browse(null, "window=arousal") //closes the window
|
||||
H.mob_climax()
|
||||
return
|
||||
|
||||
if(href_list["underwear"])
|
||||
H.underwear_toggle()
|
||||
return
|
||||
|
||||
src.ui_interact(usr)
|
||||
|
||||
|
||||
obj/screen/arousal/proc/kiss()
|
||||
if(usr.restrained(TRUE))
|
||||
to_chat(usr, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if (H)
|
||||
H.kisstarget(H.pulling)
|
||||
|
||||
obj/screen/arousal/proc/feed()
|
||||
if(usr.restrained(TRUE))
|
||||
to_chat(usr, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if (H)
|
||||
H.genitalfeed(H.pulling)
|
||||
|
||||
obj/screen/arousal/proc/feedfrom()
|
||||
if(usr.restrained(TRUE))
|
||||
to_chat(usr, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if (H)
|
||||
H.genitalfeedfrom(H.pulling)
|
||||
|
||||
obj/screen/arousal/proc/feedyourself()
|
||||
if(usr.restrained(TRUE))
|
||||
to_chat(usr, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if (H)
|
||||
H.genitalfeedyourself()
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/menuremovecondom()
|
||||
|
||||
if(restrained(TRUE))
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
var/obj/item/organ/genital/penis/P = getorganslot("penis")
|
||||
if(!P.condom)
|
||||
to_chat(src, "<span class='warning'>You don't have a condom on!</span>")
|
||||
return
|
||||
if(P.condom)
|
||||
to_chat(src, "<span class='warning'>You tug the condom off the end of your penis!</span>")
|
||||
removecondom()
|
||||
src.ui_interact(usr) //reopen dialog
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/menuremovesounding()
|
||||
|
||||
if(restrained(TRUE))
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
var/obj/item/organ/genital/penis/P = getorganslot("penis")
|
||||
if(!P.sounding)
|
||||
to_chat(src, "<span class='warning'>You don't have a rod inside!</span>")
|
||||
return
|
||||
if(P.sounding)
|
||||
to_chat(src, "<span class='warning'>You pull the rod off from the tip of your penis!</span>")
|
||||
removesounding()
|
||||
src.ui_interact(usr) //reopen dialog
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/solomasturbate()
|
||||
if(restrained(TRUE))
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_masturbate_genitals()
|
||||
if(picked_organ)
|
||||
src << browse(null, "window=arousal") //closes the window
|
||||
mob_masturbate(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
|
||||
//Kissing target proc
|
||||
/mob/living/carbon/human/proc/kisstarget(mob/living/L)
|
||||
|
||||
src << browse(null, "window=arousal") //closes the arousal window, if its open, mainly to stop spam
|
||||
if(isliving(L)) //is your target living? Living people can resist your advances if they want to via moving.
|
||||
if(iscarbon(L))
|
||||
src.visible_message("<span class='notice'>[src] is about to kiss [L]!</span>", \
|
||||
"<span class='notice'>You're attempting to kiss [L]!</span>", \
|
||||
"<span class='notice'>You're attempting to kiss with something!</span>")
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "kissed", /datum/mood_event/kiss) //how cute, affection is nice.
|
||||
//Well done you kissed it/them!
|
||||
src.visible_message("<span class='notice'>[src] kisses [L]!</span>", \
|
||||
"<span class='notice'>You kiss [L]!</span>", \
|
||||
"<span class='notice'>You kiss something!</span>")
|
||||
|
||||
/mob/living/carbon/human/proc/climaxalone()
|
||||
//we dont need hands to climax alone, its hands free!
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
src << browse(null, "window=arousal") //closes the window
|
||||
mob_climax_outside(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/climaxwith(mob/living/T)
|
||||
|
||||
var/mob/living/carbon/human/L = pick_partner()
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
var/mob/living/partner = L
|
||||
if(partner)
|
||||
src << browse(null, "window=arousal") //alls fine, we can close the window now.
|
||||
var/obj/item/organ/genital/penis/P = picked_organ
|
||||
var/spillage = "No" //default to no, just incase player has items on to prevent climax
|
||||
if(!P.condom == 1&&!P.sounding == 1) //you cant climax with a condom on or sounding in.
|
||||
spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
|
||||
if(spillage == "Yes")
|
||||
mob_climax_partner(picked_organ, partner, TRUE, FALSE, FALSE)
|
||||
else
|
||||
mob_climax_partner(picked_organ, partner, FALSE, FALSE, FALSE)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/climaxover(mob/living/T)
|
||||
|
||||
var/mob/living/carbon/human/L = T
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
src << browse(null, "window=arousal") //alls fine, we can close the window now.
|
||||
var/mob/living/partner = L
|
||||
if(partner)
|
||||
var/obj/item/organ/genital/penis/P = picked_organ
|
||||
if(P.condom == 1)
|
||||
to_chat(src, "<span class='warning'>You cannot do this action with a condom on.</span>")
|
||||
return
|
||||
if(P.sounding == 1)
|
||||
to_chat(src, "<span class='warning'>You cannot do this action with a sounding in.</span>")
|
||||
return
|
||||
mob_climax_partner(picked_organ, partner, FALSE, FALSE, TRUE)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/clothesplosion()
|
||||
if(usr.restrained(TRUE))
|
||||
to_chat(usr, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/items = H.get_contents()
|
||||
for(var/obj/item/W in items)
|
||||
if(W == H.w_uniform || W == H.wear_suit)
|
||||
H.dropItemToGround(W, TRUE)
|
||||
playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
|
||||
H.visible_message("<span class='boldnotice'>[H] explodes out of their clothes!'</span>")
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/impregwith(mob/living/T)
|
||||
|
||||
var/mob/living/carbon/human/L = pick_partner()
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = src.getorganslot("penis") //Impregnation must be done with a penis.
|
||||
if(picked_organ)
|
||||
var/mob/living/partner = L
|
||||
if(partner)
|
||||
if(!partner.breedable)//check if impregable.
|
||||
to_chat(src, "<span class='warning'>Your partner cannot be impregnated.</span>")//some fuckary happening, you shouldnt even get to this point tbh.
|
||||
return
|
||||
var/obj/item/organ/genital/penis/P = picked_organ
|
||||
//you cant impreg with a condom on or sounding in.
|
||||
if(P.condom == 1)
|
||||
to_chat(src, "<span class='warning'>You cannot do this action with a condom on.</span>")
|
||||
return
|
||||
if(P.sounding == 1)
|
||||
to_chat(src, "<span class='warning'>You cannot do this action with a sounding in.</span>")
|
||||
return
|
||||
src << browse(null, "window=arousal") //alls fine, we can close the window now.
|
||||
//Keeping this for messy fun
|
||||
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
|
||||
if(spillage == "Yes")
|
||||
mob_climax_partner(picked_organ, partner, TRUE, TRUE, FALSE)
|
||||
else
|
||||
mob_climax_partner(picked_organ, partner, FALSE, TRUE, FALSE)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
|
||||
return
|
||||
else //no penis :(
|
||||
to_chat(src, "<span class='warning'>You cannot impregnate without a penis.</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/cumcontainer(mob/living/T)
|
||||
//We'll need hands and no restraints.
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
src << browse(null, "window=arousal")
|
||||
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
|
||||
if(picked_organ)
|
||||
//Good, got an organ, time to pick a container
|
||||
var/obj/item/reagent_containers/fluid_container = pick_climax_container()
|
||||
if(fluid_container)
|
||||
mob_fill_container(picked_organ, fluid_container)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this without anything to fill.</span>")
|
||||
return
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
/atom/proc/add_cum_overlay() //This can go in a better spot, for now its here.
|
||||
cum_splatter_icon = icon(initial(icon), initial(icon_state), , 1)
|
||||
cum_splatter_icon.Blend("#fff", ICON_ADD)
|
||||
cum_splatter_icon.Blend(icon('hyperstation/icons/effects/cumoverlay.dmi', "cum_obj"), ICON_MULTIPLY)
|
||||
add_overlay(cum_splatter_icon)
|
||||
|
||||
/atom/proc/wash_cum()
|
||||
cut_overlay(mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi', "cum_normal"))
|
||||
cut_overlay(mutable_appearance('hyperstation/icons/effects/cumoverlay.dmi', "cum_large"))
|
||||
if(cum_splatter_icon)
|
||||
cut_overlay(cum_splatter_icon)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/proc/genitalfeed(mob/living/L, mb_time = 30)
|
||||
if(isliving(L)) //is your target living? Living people can resist your advances if they want to via moving.
|
||||
if(iscarbon(L))
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
src << browse(null, "window=arousal")
|
||||
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
|
||||
if(picked_organ)
|
||||
//Good, got an organ, time to pick a container
|
||||
if(picked_organ.name == "penis")//if the select organ is a penis
|
||||
var/obj/item/organ/genital/penis/P = src.getorganslot("penis")
|
||||
if(P.condom) //if the penis is condomed
|
||||
to_chat(src, "<span class='warning'>You cannot feed someone when there is a condom over your [picked_organ.name].</span>")
|
||||
return
|
||||
if(P.sounding) //if the penis is sounded
|
||||
to_chat(src, "<span class='warning'>You cannot feed someone when there is a rod inside your [picked_organ.name].</span>")
|
||||
return
|
||||
if(picked_organ.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = picked_organ.reagents
|
||||
else
|
||||
if(!picked_organ.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [picked_organ.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = picked_organ.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
src.visible_message("<span class='love'>[src] starts to feed [L.name] with their [picked_organ.name].</span>", \
|
||||
"<span class='userlove'>You feed [L.name] with your [picked_organ.name].</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids)
|
||||
src.visible_message("<span class='love'>[src] uses [p_their()] [picked_organ.name] to feed [L.name]!</span>", \
|
||||
"<span class='userlove'>You used your [picked_organ.name] to feed [L.name] a total of [total_fluids]u's.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(picked_organ.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing exposed genitals.</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/genitalfeedfrom(mob/living/target, mb_time = 30)
|
||||
var/mob/living/carbon/human/L = target
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
src << browse(null, "window=arousal")
|
||||
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = L.get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in L.internal_organs)
|
||||
if(G.can_climax) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
if(!G.dontlist)
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
picked_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
|
||||
else
|
||||
return
|
||||
|
||||
if(picked_organ)
|
||||
//Good, got an organ, time to pick a container
|
||||
if(picked_organ.name == "penis")//if the select organ is a penis
|
||||
var/obj/item/organ/genital/penis/P = L.getorganslot("penis")
|
||||
if(P.condom) //if the penis is condomed
|
||||
to_chat(src, "<span class='warning'>You cannot feed from [picked_organ.name] when there is a condom over it.</span>")
|
||||
return
|
||||
if(P.sounding) //if the penis is sounded
|
||||
to_chat(src, "<span class='warning'>You cannot feed from [picked_organ.name] when there is a rod inside it.</span>")
|
||||
return
|
||||
if(picked_organ.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = picked_organ.reagents
|
||||
else
|
||||
if(!picked_organ.linked_organ)
|
||||
to_chat(src, "<span class='warning'>The [picked_organ.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = picked_organ.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
src.visible_message("<span class='love'>[src] starts to feed from [L.name]'s [picked_organ.name].</span>", \
|
||||
"<span class='userlove'>You feed from [L.name]'s '[picked_organ.name].</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(src, total_fluids)
|
||||
src.visible_message("<span class='love'>[src] feeds from [L.name]'s [picked_organ.name]!</span>", \
|
||||
"<span class='userlove'>You used [L.name]'s [picked_organ.name] to feed with a total of [total_fluids]u's.</span>")
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(picked_organ.can_climax)
|
||||
L.setArousalLoss(min_arousal)
|
||||
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing exposed genitals.</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/genitalfeedyourself(mb_time = 30)
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
src << browse(null, "window=arousal")
|
||||
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
|
||||
if(picked_organ)
|
||||
//Good, got an organ, time to pick a container
|
||||
if(picked_organ.name == "penis")//if the select organ is a penis
|
||||
var/obj/item/organ/genital/penis/P = src.getorganslot("penis")
|
||||
if(P.condom) //if the penis is condomed
|
||||
to_chat(src, "<span class='warning'>You cannot feed yourself when there is a condom over your [picked_organ.name].</span>")
|
||||
return
|
||||
if(P.sounding) //if the penis is sounded
|
||||
to_chat(src, "<span class='warning'>You cannot feed yourself when there is a rod inside your [picked_organ.name].</span>")
|
||||
return
|
||||
if(picked_organ.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = picked_organ.reagents
|
||||
else
|
||||
if(!picked_organ.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [picked_organ.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = picked_organ.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
src.visible_message("<span class='love'>[src] starts to feed themselves with their [picked_organ.name].</span>", \
|
||||
"<span class='userlove'>You feed yourself with your [picked_organ.name].</span>")
|
||||
if(do_after(src, mb_time))
|
||||
fluid_source.trans_to(src, total_fluids)
|
||||
src.visible_message("<span class='love'>[src] uses [p_their()] [picked_organ.name] to feed themselves!</span>", \
|
||||
"<span class='userlove'>You used your [picked_organ.name] to feed yourself a total of [total_fluids]u's.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
if(picked_organ.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing exposed genitals.</span>")
|
||||
return
|
||||
@@ -0,0 +1,15 @@
|
||||
/mob/living/carbon/human/handle_creampie()
|
||||
if(NOBLOOD in dna.species.species_traits)
|
||||
cumdrip_rate = 0
|
||||
return
|
||||
|
||||
if(cumdrip_rate < 0)
|
||||
cumdrip_rate = 0
|
||||
|
||||
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE)))
|
||||
cumdrip_rate = cumdrip_rate - 1
|
||||
cumdrip()
|
||||
|
||||
/mob/living/carbon/human/proc/cumdrip()
|
||||
if(isturf(loc))
|
||||
new/obj/effect/decal/cleanable/semendrip(get_turf(src))
|
||||
@@ -0,0 +1,4 @@
|
||||
/datum/export/plutonium_rod
|
||||
cost = 20000
|
||||
unit_name = "Plutonium Rod"
|
||||
export_types = list(/obj/item/twohanded/required/fuel_rod/plutonium)
|
||||
@@ -0,0 +1,24 @@
|
||||
/datum/export/sweatshop/stool
|
||||
cost = 850
|
||||
unit_name = "custom stool"
|
||||
export_types = list(/obj/item/processed/wood/stool)
|
||||
|
||||
/datum/export/sweatshop/cushion
|
||||
cost = 300
|
||||
unit_name = "cloth cushion"
|
||||
export_types = list(/obj/item/cushion)
|
||||
|
||||
/datum/export/sweatshop/cushionsilk
|
||||
cost = 500
|
||||
unit_name = "silk cushion"
|
||||
export_types = list(/obj/item/cushion)
|
||||
|
||||
/datum/export/sweatshop/stool/cushioncloth
|
||||
cost = 1800
|
||||
unit_name = "cushioned stool (cloth)"
|
||||
export_types = list(/obj/item/processed/wood/stoolcloth)
|
||||
|
||||
/datum/export/sweatshop/stool/cushionsilk
|
||||
cost = 2400
|
||||
unit_name = "cushioned stool (cloth)"
|
||||
export_types = list(/obj/item/processed/wood/stoolsilk)
|
||||
@@ -0,0 +1,7 @@
|
||||
/datum/supply_pack/service/stripperpole
|
||||
name = "Stripper Pole Crate"
|
||||
desc = "No private bar is complete without a stripper pole, show off the goods! Comes with a ready-to-assemble stripper pole, and a complementary wrench to get things set up!"
|
||||
cost = 3550
|
||||
contains = list(/obj/item/polepack/,
|
||||
/obj/item/wrench/)
|
||||
crate_name = "stripper pole crate"
|
||||
@@ -0,0 +1,6 @@
|
||||
/obj/item/processed/metal
|
||||
name = "Heated Metal"
|
||||
desc = "A malleable metal, able to be cut into nails."
|
||||
icon = 'hyperstation/icons/obj/cargo/sweatshop/metal.dmi'
|
||||
icon_state = "metal"
|
||||
sharpness = TRUE
|
||||
@@ -0,0 +1,256 @@
|
||||
//THE TOOLS
|
||||
/obj/item/carpentry
|
||||
name = "carpentry"
|
||||
desc = "You shouldn't be seeing this!"
|
||||
icon = 'hyperstation/icons/obj/cargo/sweatshop/sweatshop.dmi'
|
||||
usesound = list('sound/effects/picaxe1.ogg', 'sound/effects/picaxe2.ogg', 'sound/effects/picaxe3.ogg')
|
||||
|
||||
/obj/item/carpentry/handsaw
|
||||
name = "handsaw"
|
||||
desc = "A shoddy tool used to process wood into smaller segments."
|
||||
icon_state = "handsaw"
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
force = 8
|
||||
sharpness = TRUE
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
materials = list(MAT_METAL=50)
|
||||
attack_verb = list("slashed", "sawed")
|
||||
|
||||
/obj/item/carpentry/hammer
|
||||
name = "hammer"
|
||||
desc = "A tool used to manually bash nails into place."
|
||||
icon_state = "hammer"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 7
|
||||
sharpness = FALSE
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
materials = list(MAT_METAL=100)
|
||||
attack_verb = list("bonked", "nailed")
|
||||
|
||||
/obj/item/carpentry/glue
|
||||
name = "glue"
|
||||
desc = "Used to haphazardly stick things together; secured by the toughest Monkey Glue(TM)."
|
||||
icon_state = "glue"
|
||||
force = 0
|
||||
sharpness = FALSE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_PLASTIC=25)
|
||||
attack_verb = list("glued", "coughed")
|
||||
|
||||
/obj/item/carpentry/borer
|
||||
name = "manual borer"
|
||||
desc = "An incredibly awful tool used to manually drill holes into something... Surely there's a better option."
|
||||
icon_state = "borer"
|
||||
force = 3
|
||||
sharpness = TRUE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=25)
|
||||
attack_verb = list("bored", "drilled")
|
||||
|
||||
/obj/item/carpentry/sandpaper
|
||||
name = "sandpaper strip"
|
||||
desc = "A strip of sandpaper, commonly used for sanding down rough surfaces into a more smooth shape."
|
||||
icon_state = "sandpaper"
|
||||
force = 1
|
||||
sharpness = FALSE
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
materials = list(MAT_GLASS=1) //lmao
|
||||
attack_verb = list("sanded", "licked")
|
||||
|
||||
/obj/item/nails
|
||||
name = "metal nails"
|
||||
desc = "A bunch of nails, used for hammering into things."
|
||||
icon = 'hyperstation/icons/obj/cargo/sweatshop/sweatshop.dmi'
|
||||
icon_state = "nails"
|
||||
force = 0
|
||||
sharpness = TRUE
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
materials = list(MAT_METAL=10)
|
||||
attack_verb = list("nailed", "screwed")
|
||||
|
||||
/obj/item/cushion
|
||||
name = "basic cushion"
|
||||
desc = "Beats sitting on the floor."
|
||||
icon = 'hyperstation/icons/obj/cargo/sweatshop/cloth.dmi'
|
||||
icon_state = "clothcushion"
|
||||
force = 0
|
||||
sharpness = FALSE
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("thomped", "thwacked")
|
||||
|
||||
/obj/item/cushion/silk
|
||||
name = "silk cushion"
|
||||
desc = "How'd it turn red?!"
|
||||
icon_state = "silkcushion"
|
||||
|
||||
//BASIC RECIPES - To do, add sound. As well as refactor everything in a more smart way so we can add the possibility of multiple wood types in the future.
|
||||
//saw a plank into two platforms
|
||||
/obj/item/processed/wood/plank/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/handsaw))
|
||||
to_chat(user,"<span class='notice'> You begin to saw [src] in half...</span>")
|
||||
if(do_after(user, 40) && isturf(loc))
|
||||
new src.sawobj(loc)
|
||||
new src.sawobj(loc) //send help i dont know how to make two in the same line lmfao
|
||||
to_chat(user, "<span class='notice'> You saw [src] in half.</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to saw [src]!</span>")
|
||||
else
|
||||
..()
|
||||
//saw a platform into four blocks
|
||||
/obj/item/processed/wood/platform/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/handsaw))
|
||||
to_chat(user,"<span class='notice'> You begin cut [src] into smaller pieces...</span>")
|
||||
if(do_after(user, 20) && isturf(loc))
|
||||
new src.sawobj(loc)
|
||||
new src.sawobj(loc)
|
||||
new src.sawobj(loc)
|
||||
new src.sawobj(loc)
|
||||
to_chat(user, "<span class='notice'> You cut [src] into four pieces.</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to saw [src]!</span>")
|
||||
else
|
||||
..()
|
||||
//sand a block into a peg
|
||||
/obj/item/processed/wood/block/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/sandpaper))
|
||||
to_chat(user,"<span class='notice'> You carefully begin to sand down [src]...</span>")
|
||||
if(do_after(user, 50) && isturf(loc))
|
||||
new src.sandobj(loc)
|
||||
to_chat(user, "<span class='notice'> You smooth [src] into a peg.</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to sand [src]!</span>")
|
||||
else
|
||||
..()
|
||||
//cut heated metal into nails
|
||||
/obj/item/processed/metal/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_WIRECUTTER)
|
||||
to_chat(user,"<span class='notice'> You tediously begin to cut [src] into several nails...</span>")
|
||||
if(do_after(user, 80) && isturf(loc))
|
||||
new /obj/item/nails(loc)
|
||||
new /obj/item/nails(loc)
|
||||
to_chat(user, "<span class='notice'> You make some crude metal nails.</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to process [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
//Covered in glue
|
||||
//cover a wooden block in glue
|
||||
/obj/item/processed/wood/block/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/glue))
|
||||
to_chat(user,"<span class='notice'> You begin to glue down one end of [src]...</span>")
|
||||
if(do_after(user, 10) && isturf(loc))
|
||||
new src.glueobj(loc)
|
||||
to_chat(user, "<span class='notice'> You slap some glue onto [src].</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to glue [src]!</span>")
|
||||
else
|
||||
..()
|
||||
//cover a wooden peg in glue
|
||||
/obj/item/processed/wood/peg/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/glue))
|
||||
to_chat(user,"<span class='notice'> You begin to glue down one end of the [src]...</span>")
|
||||
if(do_after(user, 10) && isturf(loc))
|
||||
new src.glueobj(loc)
|
||||
to_chat(user, "<span class='notice'> You slap some glue onto [src].</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to glue [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
//Seats
|
||||
//bore a platform into a seat
|
||||
/obj/item/processed/wood/platform/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/borer))
|
||||
to_chat(user,"<span class='notice'> You begin to cut four holes into [src]...</span>")
|
||||
if(do_after(user, 40) && isturf(loc))
|
||||
new src.boreobj(loc)
|
||||
to_chat(user, "<span class='notice'> You drill four holes into [src].</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to refine [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
//Stools - Further crafting
|
||||
/obj/item/processed/wood/stool1/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/nails))
|
||||
to_chat(user,"<span class='notice'> You place nails into [src]...</span>")
|
||||
if(do_after(user, 20) && isturf(loc))
|
||||
new /obj/item/processed/wood/stool2(loc)
|
||||
to_chat(user, "<span class='notice'> The nails are ready to be hammered.</span>")
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to refine [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/processed/wood/stool2/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/hammer))
|
||||
to_chat(user,"<span class='notice'> You begin to hammer the [src]...</span>")
|
||||
if(do_after(user, 30) && isturf(loc))
|
||||
new /obj/item/processed/wood/stool3(loc)
|
||||
to_chat(user, "<span class='notice'> The nails are hammered into place.</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to refine [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/processed/wood/stool3/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/carpentry/sandpaper))
|
||||
to_chat(user,"<span class='notice'> You begin to sand the [src]...</span>")
|
||||
if(do_after(user, 30) && isturf(loc))
|
||||
new /obj/item/processed/wood/stool4(loc)
|
||||
to_chat(user, "<span class='notice'> You sand down the [src].</span>")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to refine [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/processed/wood/stool4/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/processed/wood/glueblock))
|
||||
to_chat(user,"<span class='notice'> You add some finishing touches to the [src]...</span>")
|
||||
if(do_after(user, 30) && isturf(loc))
|
||||
new /obj/item/processed/wood/stool(loc)
|
||||
to_chat(user, "<span class='notice'> You complete the [src].</span>")
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to refine [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/processed/wood/stool/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/cushion))
|
||||
to_chat(user,"<span class='notice'> You secure a cloth cushion to [src]...</span>")
|
||||
if(do_after(user, 30) && isturf(loc))
|
||||
new /obj/item/processed/wood/stoolcloth(loc)
|
||||
to_chat(user, "<span class='notice'> You add a cushion to [src].</span>")
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to detail [src]!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/processed/wood/stool/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/cushion/silk))
|
||||
to_chat(user,"<span class='notice'> You secure a silk cushion to [src]...</span>")
|
||||
if(do_after(user, 30) && isturf(loc))
|
||||
new /obj/item/processed/wood/stoolsilk(loc)
|
||||
to_chat(user, "<span class='notice'> You add a cushion to [src].</span>")
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold still to detail [src]!</span>")
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,128 @@
|
||||
//WOODEN COMPONENTS. honestly i need to move some shit around to allow for easier material swapping, but that's for a later date.
|
||||
|
||||
/obj/item/processed/wood
|
||||
name = "Wooden Processed Item"
|
||||
desc = "You shouldn't see this!"
|
||||
icon = 'hyperstation/icons/obj/cargo/sweatshop/wooden.dmi'
|
||||
sharpness = FALSE
|
||||
attack_verb = list("slapped", "thunked")
|
||||
var/sawobj = /obj/item/condom
|
||||
var/glueobj = /obj/item/dildo
|
||||
var/sandobj = /obj/item/carpentry/sandpaper
|
||||
var/boreobj = /obj/item/carpentry/borer
|
||||
|
||||
/obj/item/processed/wood/plank
|
||||
name = "processable wooden plank"
|
||||
desc = "A somewhat sturdy refined plank. This can be used in various applications."
|
||||
icon_state = "plank"
|
||||
force = 3
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
sawobj = /obj/item/processed/wood/platform
|
||||
|
||||
/obj/item/processed/wood/platform
|
||||
name = "wood platform"
|
||||
desc = "A somewhat sturdy cropping of a plank. This one is an alright foundation for chairs and stools."
|
||||
icon_state = "platform"
|
||||
force = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
sawobj = /obj/item/processed/wood/block
|
||||
boreobj = /obj/item/processed/wood/seat
|
||||
|
||||
/obj/item/processed/wood/block
|
||||
name = "wood block"
|
||||
desc = "A chopped platform into a wooden block. This one can be used for sanded into pegs, or used as a base on it's own."
|
||||
icon_state = "block"
|
||||
force = 2
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
sandobj = /obj/item/processed/wood/peg
|
||||
glueobj = /obj/item/processed/wood/glueblock
|
||||
|
||||
/obj/item/processed/wood/peg
|
||||
name = "wood peg"
|
||||
desc = "A wooden peg. Useful for fitting into holes."
|
||||
icon_state = "peg"
|
||||
force = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
attack_verb = list("donked", "thunked")
|
||||
glueobj = /obj/item/processed/wood/gluepeg
|
||||
|
||||
//glue
|
||||
|
||||
/obj/item/processed/wood/gluepeg
|
||||
name = "glued wood peg"
|
||||
desc = "A wooden peg. With a bunch of glue used for securing."
|
||||
icon_state = "gluepeg"
|
||||
force = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
attack_verb = list("pegged", "thunked")
|
||||
|
||||
/obj/item/processed/wood/glueblock
|
||||
name = "glued wood block"
|
||||
desc = "A wooden block. With a bunch of glue used for securing."
|
||||
icon_state = "glueblock"
|
||||
force = 2
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("blocked", "thunked")
|
||||
|
||||
//seat
|
||||
/obj/item/processed/wood/seat
|
||||
name = "wood seat"
|
||||
desc = "A baseline for crafting seats. Not exactly that comfortable to sit on..."
|
||||
icon_state = "seat"
|
||||
force = 2
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("slapped", "thunked")
|
||||
|
||||
|
||||
//Stool steps. There's probably an easier way to do this, but I cannot be assed rn, I'll refine after PR
|
||||
/obj/item/processed/wood/stool1
|
||||
name = "stool base"
|
||||
desc = "A haphazardly made base for a stool. It's not even secured with any nails."
|
||||
icon_state = "stool1"
|
||||
force = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/processed/wood/stool2
|
||||
name = "nailed stool base"
|
||||
desc = "Nails are in position"
|
||||
icon_state = "stool2"
|
||||
force = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/processed/wood/stool3
|
||||
name = "hammered stool base"
|
||||
desc = "A vaguely stool-shaped... Thing. Could use some sandpaper."
|
||||
icon_state = "stool3"
|
||||
force = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/processed/wood/stool4
|
||||
name = "bland stool"
|
||||
desc = "A rather bland stool."
|
||||
icon_state = "stool4"
|
||||
force = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
//The finished product
|
||||
/obj/item/processed/wood/stool
|
||||
name = "custom stool"
|
||||
desc = "An intricite, custom stool."
|
||||
icon_state = "stool"
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
//Let's make it soft and more expensive
|
||||
|
||||
/obj/item/processed/wood/stoolcloth
|
||||
name = "cloth-cushioned stool"
|
||||
desc = "A custom stool with a cloth cushion."
|
||||
icon_state = "stoolcloth"
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/processed/wood/stoolsilk
|
||||
name = "cloth-cushioned stool"
|
||||
desc = "A custom stool with a silk cushion."
|
||||
icon_state = "stoolsilk"
|
||||
force = 11 //lol
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/gear/glasses/garb
|
||||
name = "polychromic gar glasses"
|
||||
category =ITEM_SLOT_GLASSES
|
||||
path = /obj/item/clothing/glasses/polychromic/garpoly
|
||||
cost = 2
|
||||
|
||||
/datum/gear/glasses/gigagarb
|
||||
name = "polychromic giga gar glasses"
|
||||
category =ITEM_SLOT_GLASSES
|
||||
path = /obj/item/clothing/glasses/polychromic/supergarpoly
|
||||
cost = 2
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/gear/syntech/ring
|
||||
name = "Normalizer Ring"
|
||||
category =ITEM_SLOT_GLOVES
|
||||
path = /obj/item/clothing/gloves/ring/syntech
|
||||
cost = 6
|
||||
|
||||
/datum/gear/syntech/band
|
||||
name = "Normalizer Band"
|
||||
category =ITEM_SLOT_GLOVES
|
||||
path = /obj/item/clothing/gloves/ring/syntech/band
|
||||
cost = 6
|
||||
@@ -0,0 +1,17 @@
|
||||
/datum/gear/syntech/pendant
|
||||
name = "Normalizer Pendant"
|
||||
category =ITEM_SLOT_NECK
|
||||
path = /obj/item/clothing/neck/syntech
|
||||
cost = 6
|
||||
|
||||
/datum/gear/syntech/choker
|
||||
name = "Normalizer Choker"
|
||||
category =ITEM_SLOT_NECK
|
||||
path = /obj/item/clothing/neck/syntech/choker
|
||||
cost = 6
|
||||
|
||||
/datum/gear/syntech/collar
|
||||
name = "Normalizer Collar"
|
||||
category =ITEM_SLOT_NECK
|
||||
path = /obj/item/clothing/neck/syntech/collar
|
||||
cost = 6
|
||||
@@ -0,0 +1,5 @@
|
||||
/datum/gear/backpack/tablet
|
||||
name = "Tablet Computer"
|
||||
category =ITEM_SLOT_IN_BACKPACK
|
||||
path = /obj/item/modular_computer/tablet/preset/cheap/
|
||||
cost = 3
|
||||
@@ -0,0 +1,39 @@
|
||||
/obj/item/clothing/glasses/polychromic
|
||||
name = "polychromic glasses template"
|
||||
desc = "You shouldn't be seeing this. Report it if you do."
|
||||
icon = 'hyperstation/icons/obj/clothing/glasses.dmi'
|
||||
icon_state = "polygar"
|
||||
item_color = "polygar"
|
||||
item_state = "polygar"
|
||||
alternate_worn_icon = 'hyperstation/icons/mob/eyes.dmi' //Because, as it appears, the item itself is normally not directly aware of its worn overlays, so this is about the easiest way, without adding a new var.
|
||||
hasprimary = TRUE
|
||||
primary_color = "#0c0c0c"
|
||||
vision_correction = 1
|
||||
|
||||
/obj/item/clothing/glasses/polychromic/worn_overlays(isinhands, icon_file) //this is where the main magic happens. Also mandates that ALL polychromic stuff MUST USE alternate_worn_icon
|
||||
. = ..()
|
||||
if(hasprimary | hassecondary | hastertiary)
|
||||
if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
|
||||
if(hasprimary) //checks if overlays are enabled
|
||||
var/mutable_appearance/primary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-primary") //automagical sprite selection
|
||||
primary_worn.color = primary_color //colors the overlay
|
||||
. += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
|
||||
if(hassecondary)
|
||||
var/mutable_appearance/secondary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-secondary")
|
||||
secondary_worn.color = secondary_color
|
||||
. += secondary_worn
|
||||
if(hastertiary)
|
||||
var/mutable_appearance/tertiary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-tertiary")
|
||||
tertiary_worn.color = tertiary_color
|
||||
. += tertiary_worn
|
||||
|
||||
/obj/item/clothing/glasses/polychromic/garpoly
|
||||
name = "polychromic gar glasses"
|
||||
desc = "Go beyond impossible and kick reason to the curb! Doesn't seem to have flash protection and doesn't seem sharp either. It is made out of bluespace prescription glass though."
|
||||
|
||||
/obj/item/clothing/glasses/polychromic/supergarpoly
|
||||
name = "polychromic giga gar glasses"
|
||||
desc = "Believe in the you who believes in yourself. Also doesn't seem to have flash protection and doesn't seem sharp either. It is made out of bluespace prescription glass though."
|
||||
icon_state = "polysupergar"
|
||||
item_color = "polysupergar"
|
||||
item_state = "polysupergar"
|
||||
@@ -0,0 +1,13 @@
|
||||
/obj/item/clothing/gloves/guncaster
|
||||
name = "fingerless leather gloves"
|
||||
desc = "Sturdy leather gloves with no fingertips, buckled at the wrist."
|
||||
icon_state = "guncaster"
|
||||
item_state = "guncaster"
|
||||
icon = 'hyperstation/icons/obj/clothing/gloves.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/gloves.dmi'
|
||||
item_color = null //So they don't wash.
|
||||
transfer_prints = TRUE
|
||||
strip_delay = 40
|
||||
equip_delay_other = 20
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
@@ -0,0 +1,8 @@
|
||||
/obj/item/clothing/head/maidband
|
||||
name = "maid head-band"
|
||||
desc = "To complete the maid look."
|
||||
icon_state = "maid_head"
|
||||
item_state = "maid_head"
|
||||
icon = 'hyperstation/icons/obj/clothing/head.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/head.dmi'
|
||||
mutantrace_variation = NONE
|
||||
@@ -0,0 +1,116 @@
|
||||
//Clothing vars and procs
|
||||
/obj/item/clothing
|
||||
var/normalize_size = RESIZE_NORMAL //This number is used as the "normal" height people will be given when wearing one of these accessories
|
||||
var/natural_size = null //The value of the wearer's body_size var in prefs. Unused for now.
|
||||
var/recorded_size = null //the user's height prior to equipping
|
||||
|
||||
//For applying a normalization
|
||||
/obj/item/clothing/proc/normalize_mob_size(mob/living/carbon/human/H)
|
||||
if(H.normalized) //First we make a check to see if they're already normalized, from wearing another article of SynTech jewelry
|
||||
to_chat(H, "<span class='warning'>This accessory buzzes, being overwritten by another.</span>")
|
||||
playsound(H, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
return
|
||||
recorded_size = H.get_effective_size() //If not, grab their current size
|
||||
playsound(H, 'sound/effects/magic.ogg', 50, 1)
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_PURPLE)
|
||||
H.visible_message("<span class='warning'>A flash of purple light engulfs [H], before they change to normal!</span>","<span class='notice'>You feel warm for a moment, before everything scales to your size...</span>")
|
||||
H.resize(normalize_size) //Then apply the size
|
||||
H.normalized = TRUE //And set normalization
|
||||
|
||||
//For removing a normalization, and reverting back to normal
|
||||
/obj/item/clothing/proc/denormalize_mob_size(mob/living/carbon/human/H)
|
||||
if(H.normalized) //sanity check
|
||||
playsound(H,'sound/weapons/emitter2.ogg', 50, 1)
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_YELLOW)
|
||||
H.visible_message("<span class='warning'>Golden light engulfs [H], and they shoot back to their default height!</span>","<span class='notice'>Energy rushes through your body, and you return to normal.</span>")
|
||||
H.resize(recorded_size)
|
||||
H.normalized = FALSE
|
||||
|
||||
|
||||
//For storing normalization on mobs
|
||||
/mob/living
|
||||
var/normalized = FALSE
|
||||
//normalized is a check for instances where more than one accessory of jewelry is worn. For all intensive purposes, only the first worn accessory stores the user's size.
|
||||
//Anything else is just extra.
|
||||
|
||||
//Clothing below. Code could be compressed more, but until I make jewelry slots, this will do. -Dahl
|
||||
|
||||
//GLOVE SLOT ITEMS...
|
||||
//SynTech ring
|
||||
/obj/item/clothing/gloves/ring/syntech
|
||||
name = "normalizer ring"
|
||||
desc = "An expensive, shimmering SynTech ring gilded with golden GATO markings. It will 'normalize' the size of the user to a specified height approved for work-conditions, as long as it is equipped. The artificial violet gem inside twinkles ominously."
|
||||
icon = 'hyperstation/icons/obj/clothing/sizeaccessories.dmi'
|
||||
icon_state = "ring"
|
||||
item_state = "sring" //No use in a unique sprite since it's just one pixel
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
body_parts_covered = 0
|
||||
transfer_prints = TRUE
|
||||
strip_delay = 40
|
||||
//These are already defined under the parent ring, but I wanna leave em here for reference purposes
|
||||
|
||||
//For glove slots
|
||||
/obj/item/clothing/gloves/ring/syntech/equipped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
if(slot ==ITEM_SLOT_GLOVES)
|
||||
|
||||
if(human_target.custom_body_size)
|
||||
normalize_mob_size(human_target)
|
||||
|
||||
/obj/item/clothing/gloves/ring/syntech/dropped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
|
||||
if(human_target.normalized)
|
||||
denormalize_mob_size(human_target)
|
||||
|
||||
|
||||
|
||||
//SynTech Wristband
|
||||
/obj/item/clothing/gloves/ring/syntech/band
|
||||
name = "normalizer wristband"
|
||||
desc = "An expensive technological wristband cast in SynTech purples with shimmering GATO hues. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. There is a small screen buzzing with information."
|
||||
icon_state = "wristband"
|
||||
item_state = "syntechband"
|
||||
|
||||
|
||||
//NECK SLOT ITEMS...
|
||||
//Syntech Pendant
|
||||
/obj/item/clothing/neck/syntech
|
||||
name = "normalizer pendant"
|
||||
desc = "A vibrant violet jewel cast in silvery-gold metals, sporting the elegance of GATO with SynTech prowess. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. The artificial violet gem inside twinkles ominously."
|
||||
icon = 'hyperstation/icons/obj/clothing/sizeaccessories.dmi'
|
||||
icon_state = "pendant"
|
||||
item_state = "pendant"
|
||||
w_class = WEIGHT_CLASS_SMALL //Gainstation Edit: Small, not normal sized.
|
||||
|
||||
//For neck items
|
||||
/obj/item/clothing/neck/syntech/equipped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
if(slot ==ITEM_SLOT_NECK)
|
||||
|
||||
if(human_target.custom_body_size)
|
||||
normalize_mob_size(human_target)
|
||||
|
||||
/obj/item/clothing/neck/syntech/dropped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
|
||||
if(human_target.normalized)
|
||||
denormalize_mob_size(human_target)
|
||||
|
||||
//Syntech Choker
|
||||
/obj/item/clothing/neck/syntech/choker
|
||||
name = "normalizer choker"
|
||||
desc = "A sleek, tight-fitting choker embezzled with silver to gold, adorned with vibrant purple studs; combined technology of GATO and SynTech. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. There is a small screen buzzing with information."
|
||||
icon_state = "choker"
|
||||
item_state = "collar"
|
||||
|
||||
//Syntech Collar
|
||||
/obj/item/clothing/neck/syntech/collar
|
||||
name = "normalizer collar"
|
||||
desc = "A cute pet collar, technologically designed with vibrant purples and smooth silvers. There is a small gem bordered by gold at the front, reading 'SYNTECH' engraved within the metal. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. The artificial violet gem inside twinkles ominously."
|
||||
icon_state = "collar"
|
||||
item_state = "collar"
|
||||
@@ -0,0 +1,178 @@
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/rd/hev
|
||||
name = "HEV Suit helmet"
|
||||
desc = "A Hazardous Environment Helmet. It fits snug over the suit and has a heads-up display for researchers. The flashlight seems broken, fitting considering this was made before the start of the milennium."
|
||||
icon_state = "hev"
|
||||
item_state = "hev"
|
||||
item_color = "rd"
|
||||
resistance_flags = ACID_PROOF | FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
armor = list("melee" = 30, "bullet" = 10, "laser" = 10, "energy" = 5, "bomb" = 80, "bio" = 100, "rad" = 100, "fire" = 60, "acid" = 60)
|
||||
actions_types = list(/datum/action/item_action/toggle_research_scanner)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/rd/hev/no_scanner
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/rd/hev
|
||||
name = "HEV Suit"
|
||||
desc = "The hazard suit. It was designed to protect scientists from the blunt trauma, radiation, energy discharge that hazardous materials might produce or entail. Fits you like a glove. The automatic medical system seems broken... They're waiting for you, Gordon. In the test chamberrrrrr."
|
||||
icon_state = "hev"
|
||||
item_state = "hev"
|
||||
resistance_flags = ACID_PROOF | FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT //Same as an emergency firesuit. Not ideal for extended exposure.
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/gun/energy/wormhole_projector,
|
||||
/obj/item/hand_tele, /obj/item/aicard)
|
||||
armor = list("melee" = 30, "bullet" = 10, "laser" = 10, "energy" = 5, "bomb" = 80, "bio" = 100, "rad" = 100, "fire" = 60, "acid" = 60)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd/hev
|
||||
tauric = FALSE //Citadel Add for tauric hardsuits
|
||||
taurmode = NOT_TAURIC
|
||||
var/firstpickup = TRUE
|
||||
var/pickupsound = TRUE
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/rd/hev/no_sound
|
||||
pickupsound = FALSE
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/rd/hev/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!pickupsound)
|
||||
return
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot ==ITEM_SLOT_WEAR_SUIT)
|
||||
if(!firstpickup)
|
||||
SEND_SOUND(user, sound('hyperstation/sound/halflife/hevsuit_pickup.ogg', volume = 50))
|
||||
else
|
||||
firstpickup = FALSE
|
||||
SEND_SOUND(user, sound('hyperstation/sound/halflife/hevsuit_firstpickup.ogg', volume = 50))
|
||||
SEND_SOUND(user, sound('hyperstation/sound/halflife/anomalous_materials.ogg', volume = 50))
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/goldenpa
|
||||
name = "GATO Power Armor"
|
||||
desc = "An advanced armor with built in energy shielding, developed by GATO via unknown means. It belongs by only few exclusive members of the corporation."
|
||||
icon_state = "golden_pa"
|
||||
item_state = "golden_pa"
|
||||
max_charges = 4
|
||||
current_charges = 4
|
||||
recharge_delay = 15
|
||||
armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/goldenpa
|
||||
slowdown = 0
|
||||
tauric = TRUE //Citadel Add for tauric hardsuits
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/goldenpa/Initialize(mapload)
|
||||
jetpack = new /obj/item/tank/jetpack/suit(src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/shielded/goldenpa
|
||||
name = "GATO Power Helmet"
|
||||
desc = "An advanced armor helmet with built in energy shielding, developed by GATO via unknown means. It belongs by only few exclusive members of the corporation."
|
||||
icon_state = "hardsuit0-goldenpa"
|
||||
item_state = "hardsuit0-goldenpa"
|
||||
item_color = "goldenpa"
|
||||
armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/teslapa
|
||||
name = "Tesla Power Armor"
|
||||
desc = "An advanced power armor, with built-in tesla technology. You're sure this will fry whoever dares attack in close quarters."
|
||||
icon_state = "tesla_pa"
|
||||
item_state = "tesla_pa"
|
||||
item_color = "tesla_pa"
|
||||
armor = list("melee" = 70, "bullet" = 70, "laser" = 90, "energy" = 90, "bomb" = 70, "bio" = 100, "rad" = 40, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 300
|
||||
equip_delay_self = 300
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/teslapahelmet
|
||||
slowdown = 1
|
||||
siemens_coefficient = -1
|
||||
blood_overlay_type = "armor"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
hit_reaction_chance = 50
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
var/teslapa_cooldown = 20
|
||||
var/teslapa_cooldown_duration = 10
|
||||
var/tesla_power = 20000
|
||||
var/tesla_range = 4
|
||||
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
|
||||
var/legacy = FALSE
|
||||
var/legacy_dmg = 35
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/teslapa/Initialize(mapload)
|
||||
jetpack = new /obj/item/tank/jetpack/suit(src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/teslapa/dropped(mob/user)
|
||||
..()
|
||||
if(istype(user))
|
||||
user.flags_1 &= ~TESLA_IGNORE_1
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/teslapa/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
|
||||
user.flags_1 |= TESLA_IGNORE_1
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/teslapa/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(prob(hit_reaction_chance))
|
||||
if(world.time < teslapa_cooldown_duration)
|
||||
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 tesla capacitors on [owner]'s Tesla Power Armor are still recharging! The armor 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)
|
||||
else
|
||||
for(var/mob/living/M in view(2, 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)
|
||||
teslapa_cooldown = world.time + teslapa_cooldown_duration
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/teslapahelmet
|
||||
name = "Tesla Power Armor Helmet"
|
||||
desc = "An advanced power armor, with built-in tesla technology. You're sure this will fry whoever dares attack in close quarters."
|
||||
icon_state = "teslaup"
|
||||
item_state = "teslaup"
|
||||
armor = list("melee" = 70, "bullet" = 70, "laser" = 90, "energy" = 90, "bomb" = 70, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 130
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/advancedpa
|
||||
name = "Advanced Power Armor"
|
||||
desc = "An advanced power armor. You're sure this is near to impossible to penetrate in close quarters."
|
||||
icon_state = "advanced_pa"
|
||||
item_state = "advanced_pa"
|
||||
item_color = "advanced_pa"
|
||||
armor = list("melee" = 95, "bullet" = 95, "laser" = 70, "energy" = 80, "bomb" = 70, "bio" = 100, "rad" = 40, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 300 //chonky armor means chonky strip
|
||||
equip_delay_self = 300
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/advancedpahelmet
|
||||
slowdown = 0
|
||||
blood_overlay_type = "armor"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/advancedpa/Initialize(mapload)
|
||||
jetpack = new /obj/item/tank/jetpack/suit(src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/advancedpahelmet
|
||||
name = "Advanced Power Armor Helmet"
|
||||
desc = "An advanced power armor. You're sure this is almost impenetrable in close quarters."
|
||||
icon_state = "adv_pa"
|
||||
item_state = "adv_pa"
|
||||
armor = list("melee" = 95, "bullet" = 90, "laser" = 70, "energy" = 80, "bomb" = 70, "bio" = 100, "rad" = 40, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 300
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
@@ -0,0 +1,24 @@
|
||||
/obj/item/clothing/suit/kaminacape
|
||||
name = "Kamina's Cape"
|
||||
desc = "Don't believe in yourself, dumbass. Believe in me. Believe in the Kamina who believes in you."
|
||||
icon_state = "kaminacape"
|
||||
item_state = "kaminacape"
|
||||
body_parts_covered = 0
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/suit/gcvest
|
||||
name = "\improper Guncaster's Vest"
|
||||
desc = "An open leather vest with battlescarred metal shoulderpads, perfect for hunting interdimensional wazards. Smells of gunpowder and plasma."
|
||||
icon_state = "guncaster"
|
||||
item_state = "guncaster"
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/suit/gcvest/alt
|
||||
name = "\improper Hellraider's Vest"
|
||||
desc = "An open leather vest with battlescarred metal shoulderpads, discovered in a dimensional anomaly. Smells of gunpowder and plasma."
|
||||
icon_state = "guncaster_alt"
|
||||
item_state = "guncaster_alt"
|
||||
@@ -0,0 +1,9 @@
|
||||
/obj/item/clothing/under/lumberjack
|
||||
name = "lumberjack outfit"
|
||||
desc = "I am a lumberjack and I am ok, I sleep all night and I work all day."
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
icon_state = "lumberjack"
|
||||
item_state = "lumberjack"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = NONE
|
||||
@@ -0,0 +1,29 @@
|
||||
#define DUMPTIME 3000
|
||||
|
||||
/datum/bank_account
|
||||
var/account_holder = "Some pleb"
|
||||
var/account_balance = 0
|
||||
var/account_offstation_balance = 0
|
||||
var/account_pin = 0
|
||||
var/account_dna = ""
|
||||
var/datum/job/account_job
|
||||
var/list/bank_cards = list()
|
||||
var/add_to_accounts = TRUE
|
||||
var/transferable = TRUE
|
||||
var/account_id
|
||||
var/withdrawDelay = 0
|
||||
|
||||
/datum/bank_account/New(newname, job)
|
||||
if(add_to_accounts)
|
||||
if(!SSeconomy)
|
||||
log_world("Wack")
|
||||
SSeconomy.bank_accounts += src
|
||||
account_holder = newname
|
||||
account_job = job
|
||||
account_id = rand(111111,999999)
|
||||
|
||||
/datum/bank_account/Destroy()
|
||||
if(add_to_accounts)
|
||||
SSeconomy.bank_accounts -= src
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
/datum/round_event_control/crystalline_reentry
|
||||
name = "Crystalline Asteroid"
|
||||
typepath = /datum/round_event/crystalline_reentry
|
||||
min_players = 15
|
||||
max_occurrences = 5
|
||||
var/atom/special_target
|
||||
|
||||
/datum/round_event_control/crystalline_reentry/admin_setup()
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
var/aimed = alert("Aimed at current location?","Snipe", "Yes", "No")
|
||||
if(aimed == "Yes")
|
||||
special_target = get_turf(usr)
|
||||
|
||||
/datum/round_event/crystalline_reentry
|
||||
announceWhen = 0
|
||||
startWhen = 10
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/crystalline_reentry/announce(fake)
|
||||
priority_announce("A crystalline asteroid has suffered a violent atmospheric entry. Brace for possible impact.", "General Alert")
|
||||
|
||||
/datum/round_event/crystalline_reentry/start()
|
||||
var/datum/round_event_control/crystalline_reentry/C = control
|
||||
var/startside = pick(GLOB.cardinals)
|
||||
var/z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, z)
|
||||
new /obj/effect/crystalline_reentry(startT, endT, C.special_target)
|
||||
|
||||
/datum/round_event_control/crystalline_wave
|
||||
name = "Catastrophic Crystalline Asteroid Wave"
|
||||
typepath = /datum/round_event/crystalline_wave
|
||||
min_players = 35
|
||||
max_occurrences = 0 //This is only an admin spawn. Ergo, wrath of the gods.
|
||||
var/atom/special_target
|
||||
|
||||
/datum/round_event_control/crystalline_wave/admin_setup()
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
/* No special target for you
|
||||
var/aimed = alert("Aimed at current location?","Snipe", "Yes", "No")
|
||||
if(aimed == "Yes")
|
||||
special_target = get_turf(usr)
|
||||
*/
|
||||
var/randselect = pick("https://youtu.be/S0HTqqwZq-o","https://youtu.be/Liv4CvpMdRA","https://youtu.be/9XZyQ12qt7w")
|
||||
message_admins("A crystalline asteroid wave has been triggered. Maybe you should add some music for the players? Consider this random selection: [randselect]")
|
||||
|
||||
/datum/round_event/crystalline_wave
|
||||
announceWhen = 0
|
||||
startWhen = 15
|
||||
endWhen = 60 //45 seconds of pain
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/crystalline_wave/announce(fake)
|
||||
priority_announce("Several crystalline asteroids have been detected en route with the station. All hands, brace for impact. Organic signals have been detected contained within some of the asteroids.", title = "Priority Alert", sound = 'sound/misc/voyalert.ogg')
|
||||
|
||||
/datum/round_event/crystalline_wave/tick()
|
||||
if(ISMULTIPLE(activeFor, 3))
|
||||
spawn_asteroids(rand(4,5)) // A looooot of asteroids...
|
||||
|
||||
/datum/round_event/crystalline_wave/proc/spawn_asteroids(number = 5)
|
||||
var/datum/round_event_control/crystalline_reentry/C = control
|
||||
for(var/i = 0; i < number; i++)
|
||||
var/startside = pick(GLOB.cardinals)
|
||||
var/z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, z)
|
||||
new /obj/effect/crystalline_reentry/notendrilalert(startT, endT, C.special_target)
|
||||
|
||||
/obj/effect/crystalline_reentry
|
||||
name = "dense ice asteroid"
|
||||
desc = "Oh shit."
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "ice"
|
||||
throwforce = 100
|
||||
move_force = INFINITY
|
||||
move_resist = INFINITY
|
||||
pull_force = INFINITY
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
var/asteroidhealth = 150
|
||||
var/z_original = 0
|
||||
var/destination
|
||||
var/notify = TRUE
|
||||
var/tendrilnotify = TRUE
|
||||
var/atom/special_target
|
||||
var/dropamt = 5
|
||||
var/droptype = list(/obj/item/stack/ore/bluespace_crystal)
|
||||
var/meteorsound = 'sound/effects/meteorimpact.ogg'
|
||||
|
||||
/obj/effect/crystalline_reentry/New(atom/start, atom/end, aimed_at)
|
||||
..()
|
||||
SSaugury.register_doom(src, 2000)
|
||||
z_original = z
|
||||
destination = end
|
||||
special_target = aimed_at
|
||||
asteroidhealth = rand(150,300)
|
||||
if(notify)
|
||||
notify_ghosts("\A [src] is inbound!",
|
||||
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>",
|
||||
source=src, action=NOTIFY_ORBIT)
|
||||
GLOB.poi_list += src
|
||||
|
||||
var/special_target_valid = FALSE
|
||||
if(special_target)
|
||||
var/turf/T = get_turf(special_target)
|
||||
if(T.z == z_original)
|
||||
special_target_valid = TRUE
|
||||
if(special_target_valid)
|
||||
walk_towards(src, special_target, 1)
|
||||
else if(end && end.z==z_original)
|
||||
walk_towards(src, destination, 1)
|
||||
|
||||
/obj/effect/crystalline_reentry/Topic(href, href_list)
|
||||
if(href_list["orbit"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
ghost.ManualFollow(src)
|
||||
|
||||
/obj/effect/crystalline_reentry/Destroy()
|
||||
GLOB.poi_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/effect/crystalline_reentry/Moved()
|
||||
if((z != z_original) || (loc == destination))
|
||||
qdel(src)
|
||||
if(special_target && loc == get_turf(special_target))
|
||||
complete_trajectory()
|
||||
return ..()
|
||||
|
||||
/obj/effect/crystalline_reentry/proc/complete_trajectory()
|
||||
//We hit what we wanted to hit, time to go boom!
|
||||
collision_effect()
|
||||
|
||||
/obj/effect/crystalline_reentry/ex_act(severity, target)
|
||||
return FALSE
|
||||
|
||||
/obj/effect/crystalline_reentry/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/crystalline_reentry/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/crystalline_reentry/Bump(atom/clong)
|
||||
if(!special_target)//If it has a special target, THERE ARE NO BRAKES ON THE ADMINBUS, BABY
|
||||
asteroidhealth = asteroidhealth - rand(7,14)
|
||||
|
||||
if(prob(10))
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
audible_message("<span class='danger'>You hear a BONK!</span>")
|
||||
|
||||
if(clong && prob(25))
|
||||
x = clong.x
|
||||
y = clong.y
|
||||
|
||||
if(special_target && clong == special_target)
|
||||
complete_trajectory()
|
||||
|
||||
if(isturf(clong) || isobj(clong))
|
||||
if(clong.density)
|
||||
clong.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
else if(isliving(clong))
|
||||
penetrate(clong)
|
||||
else if(istype(clong, type))
|
||||
var/obj/effect/crystalline_reentry/other = clong
|
||||
visible_message("<span class='danger'>[src] collides with [other]!\
|
||||
</span>")
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(2, get_turf(src))
|
||||
smoke.start()
|
||||
qdel(src)
|
||||
qdel(other)
|
||||
if(asteroidhealth <= 0)
|
||||
collision_effect()
|
||||
else
|
||||
atmos_spawn_air("water_vapor=75;TEMP=0") //brr
|
||||
|
||||
/obj/effect/crystalline_reentry/proc/penetrate(mob/living/L)
|
||||
L.visible_message("<span class='danger'>[L] is smashed by a crystalline asteroid!</span>" , "<span class='userdanger'>The crystalline asteroid smashes you!</span>" , "<span class ='danger'>You hear a BONK!</span>")
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
H.adjustBruteLoss(160)
|
||||
if(special_target && loc == get_turf(special_target)) // just in case. Otherwise the asteroid can stop if it penetrates someone that is standing exactly on that spot and that is bad
|
||||
complete_trajectory()
|
||||
|
||||
/obj/effect/crystalline_reentry/proc/make_debris()
|
||||
for(var/throws = dropamt, throws > 0, throws--)
|
||||
var/thing_to_spawn = pick(droptype)
|
||||
new thing_to_spawn(get_turf(src))
|
||||
|
||||
/obj/effect/crystalline_reentry/proc/collision_effect()
|
||||
make_debris()
|
||||
explosion(src.loc, 0, 0, 5, 3, 1, 0, 0, 0, 0)
|
||||
var/sound/meteor_sound = sound(meteorsound)
|
||||
var/random_frequency = get_rand_frequency()
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if((M.orbiting) && (SSaugury.watchers[M]))
|
||||
continue
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T || T.z != src.z)
|
||||
continue
|
||||
var/dist = get_dist(M.loc, src.loc)
|
||||
shake_camera(M, dist > 20 ? 2 : 4, dist > 20 ? 1 : 3)
|
||||
M.playsound_local(src.loc, null, 50, 1, random_frequency, 10, S = meteor_sound)
|
||||
atmos_spawn_air("water_vapor=1250;TEMP=0") //brr
|
||||
switch(rand(1,100))
|
||||
if(1 to 30)
|
||||
var/obj/structure/spawner/crystalline/M = new(src.loc)
|
||||
visible_message("<span class='danger'>A [M] emerges from the asteroid's rubble!</span>")
|
||||
if(prob(50) && tendrilnotify)
|
||||
priority_announce("Unknown organic entities have been detected in the vincinity of [station_name()]. General caution is advised.", "General Alert")
|
||||
if(31 to 99)
|
||||
visible_message("The asteroid collapses into nothing...")
|
||||
if(100)
|
||||
var/mob/living/simple_animal/bot/hugbot/M = new(src.loc)
|
||||
visible_message("<span class='danger'>A [M] emerges from the asteroid's rubble! Wait... What?</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/crystalline_reentry/notendrilalert
|
||||
tendrilnotify = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/tendril
|
||||
fromtendril = TRUE
|
||||
|
||||
//Crystalline Tendrils, which spawn crystalline monsters
|
||||
/obj/structure/spawner/crystalline
|
||||
name = "crystalline tendril"
|
||||
desc = "A vile tendril of corruption, originating from gods know where. Terrible monsters are pouring out of it."
|
||||
icon = 'icons/mob/nest.dmi'
|
||||
icon_state = "tendril"
|
||||
faction = list("mining")
|
||||
max_mobs = 3
|
||||
max_integrity = 9000 // Don't worry, the value is normalized within Initialize
|
||||
obj_integrity = 9000 // Same as above
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/tendril)
|
||||
move_resist = INFINITY // just killing it tears a massive hole in the ground, let's not move it
|
||||
anchored = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | LAVA_PROOF
|
||||
var/gps = null
|
||||
var/obj/effect/light_emitter/tendril/emitted_light
|
||||
|
||||
/obj/structure/spawner/crystalline/Initialize(mapload)
|
||||
. = ..()
|
||||
emitted_light = new(loc)
|
||||
for(var/F in RANGE_TURFS(1, src))
|
||||
if(iswallturf(F))
|
||||
var/turf/closed/M = F
|
||||
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
|
||||
if(iscloudturf(F))
|
||||
var/turf/open/chasm/cloud/M = F
|
||||
M.TerraformTurf(/turf/open/floor/plating/asteroid/layenia, /turf/open/floor/plating/asteroid/layenia)
|
||||
gps = new /obj/item/gps/internal(src)
|
||||
addtimer(CALLBACK(src,PROC_REF(delayedInitialize)), 4 SECONDS)
|
||||
|
||||
/obj/structure/spawner/crystalline/deconstruct(disassembled)
|
||||
new /obj/effect/cloud_collapse(loc)
|
||||
new /obj/structure/closet/crate/necropolis/tendril(loc)
|
||||
return ..()
|
||||
|
||||
/obj/structure/spawner/crystalline/Destroy()
|
||||
QDEL_NULL(emitted_light)
|
||||
QDEL_NULL(gps)
|
||||
return ..()
|
||||
|
||||
/obj/structure/spawner/crystalline/proc/delayedInitialize()
|
||||
//Why is this needed? Simple, because apparently explosion is so slow that it triggers after the spawner spawns and kills it on the spot. This just makes it killable.
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
max_integrity = 225
|
||||
obj_integrity = 225
|
||||
|
||||
/obj/effect/light_emitter/crystalline
|
||||
set_luminosity = 4
|
||||
set_cap = 2.5
|
||||
light_color = LIGHT_COLOR_LIGHT_CYAN
|
||||
|
||||
/obj/effect/cloud_collapse
|
||||
name = "collapsing crystalline tendril"
|
||||
desc = "Get clear!"
|
||||
layer = TABLE_LAYER
|
||||
icon = 'icons/mob/nest.dmi'
|
||||
icon_state = "tendril"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/obj/effect/light_emitter/crystalline/emitted_light
|
||||
|
||||
/obj/effect/cloud_collapse/Initialize(mapload)
|
||||
. = ..()
|
||||
emitted_light = new(loc)
|
||||
visible_message("<span class='boldannounce'>The tendril writhes in fury as the earth around it begins to crack and break apart! Get back!</span>")
|
||||
visible_message("<span class='warning'>Something falls free of the tendril!</span>")
|
||||
playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, 0, 50, 1, 1)
|
||||
addtimer(CALLBACK(src,PROC_REF(collapse)), 50)
|
||||
|
||||
/obj/effect/cloud_collapse/Destroy()
|
||||
QDEL_NULL(emitted_light)
|
||||
return ..()
|
||||
|
||||
/obj/effect/cloud_collapse/proc/collapse()
|
||||
for(var/mob/M in range(7,src))
|
||||
shake_camera(M, 15, 1)
|
||||
playsound(get_turf(src),'sound/effects/explosionfar.ogg', 200, 1)
|
||||
visible_message("<span class='boldannounce'>The tendril falls into the clouds below!</span>")
|
||||
for(var/turf/T in range(1,src))
|
||||
if(!T.density)
|
||||
T.TerraformTurf(/turf/open/chasm/cloud, /turf/open/chasm/cloud)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,5 @@
|
||||
/datum/chemical_reaction/pilk
|
||||
name = "Pilk"
|
||||
id = /datum/reagent/consumable/pilk
|
||||
results = list(/datum/reagent/consumable/pilk = 2)
|
||||
required_reagents = list(/datum/reagent/consumable/milk = 1, /datum/reagent/consumable/space_cola = 1)
|
||||
@@ -0,0 +1,80 @@
|
||||
/* Doesnt fucking work, dont know why, everything I add in this game has some kinda of issue.
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/gmeasurement
|
||||
name = "body measurement"
|
||||
desc = "Used to get a measurement of a refs genitals size and body size."
|
||||
icon_state = "medscan"
|
||||
complexity = 5
|
||||
extended_desc = "Upon activation, the circuit will attempt to measure all body parts on the refs body within one tile away."
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"penis length" = IC_PINTYPE_NUMBER,
|
||||
"breast size" = IC_PINTYPE_NUMBER,
|
||||
"testicle size" = IC_PINTYPE_NUMBER,
|
||||
"body size" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 40
|
||||
cooldown_per_use = 20
|
||||
ext_cooldown = 25
|
||||
|
||||
/obj/item/integrated_circuit/input/gmeasurement/do_work()
|
||||
|
||||
var/mob/living/L = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
|
||||
if(!istype(L) || !L.Adjacent(get_turf(src)) ) //Invalid input
|
||||
return
|
||||
|
||||
var/obj/item/organ/genital/penis/P = L.getorganslot("penis")
|
||||
var/obj/item/organ/genital/breasts/B = L.getorganslot("breasts")
|
||||
var/obj/item/organ/genital/testicles/T = L.getorganslot("testicles")
|
||||
|
||||
//reset data, just incase they dont have that genitle
|
||||
set_pin_data(IC_OUTPUT, 1, 0)
|
||||
set_pin_data(IC_OUTPUT, 2, 0)
|
||||
set_pin_data(IC_OUTPUT, 3, 0)
|
||||
set_pin_data(IC_OUTPUT, 4, 0)
|
||||
|
||||
//get sizes
|
||||
set_pin_data(IC_OUTPUT, 1, P.length)
|
||||
set_pin_data(IC_OUTPUT, 2, B.cached_size)
|
||||
set_pin_data(IC_OUTPUT, 3, T.cached_size )
|
||||
set_pin_data(IC_OUTPUT, 4, L.size_multiplier*100)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/pregtest
|
||||
name = "pregnancy tester"
|
||||
desc = "A circuit used to determine whether someone is pregnant or not and if they possess the ability to be impregnated."
|
||||
icon_state = "medscan"
|
||||
complexity = 5
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"is pregnant" = IC_PINTYPE_BOOLEAN,
|
||||
"breedable" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 40
|
||||
cooldown_per_use = 20
|
||||
ext_cooldown = 25
|
||||
|
||||
/obj/item/integrated_circuit/input/pregtest/do_work()
|
||||
|
||||
var/mob/living/L = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
|
||||
if(!istype(L) || !L.Adjacent(get_turf(src)) ) //Invalid input
|
||||
return
|
||||
|
||||
var/obj/item/organ/genital/womb/W = L.getorganslot("womb")
|
||||
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 1, W.pregnant)
|
||||
set_pin_data(IC_OUTPUT, 2, L.breedable)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
*/
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Roleplay Jobs, Currently borked.
|
||||
|
||||
/datum/job/rpcentral
|
||||
title = "Central Command Inspector"
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
minimal_player_age = 1
|
||||
supervisors = "central command"
|
||||
selection_color = "#ffeef0"
|
||||
custom_spawn_text = "You are from central command doing a routine inspection of the station, please fill out the provided information and submit it to central command by the end of the shift."
|
||||
*/
|
||||
@@ -0,0 +1,8 @@
|
||||
// yes, I COULD make it a seperate object from the surv capsule but the code needed is indeticle soo...
|
||||
|
||||
/obj/item/survivalcapsule/reactor // the not-so-survival capsule
|
||||
name = "RMBK Reactor Beacon"
|
||||
desc = "A special bluespace beacon designed to implement a reactor into the hull of the ship or station that it is activated on."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "beacon"
|
||||
template_id = "reactor"
|
||||
@@ -0,0 +1,7 @@
|
||||
// yes, I COULD make it a seperate object from the surv capsule but the code needed is indeticle soo...
|
||||
|
||||
/datum/map_template/shelter/reactor
|
||||
name = "RBMK Reactor"
|
||||
shelter_id = "reactor"
|
||||
description = "A reactor core, coolant and moderator loop not included."
|
||||
mappath = "_maps/templates/reactor_1.dmm"
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
COSMETIC PARTS
|
||||
|
||||
this system allows you to change the _base_ appearance of a limb independent
|
||||
of species or markings. this, for example, allows us to create "hybrids" like a
|
||||
mammal with avian legs.
|
||||
|
||||
keep in mind that this does not change the species of a leg! in the above example,
|
||||
the mammal's bird-legs are still mammal legs. this matters in some places, like
|
||||
body part transplants; mis-matched species will cause extra damage if the surgery
|
||||
fails and the part is rejected. so you can't attach mammal-bird legs to avians
|
||||
safely.
|
||||
*/
|
||||
|
||||
/datum/cosmetic_part
|
||||
/** A unique string that is used to identify this part for save files. Allows name changes without breaking saves */
|
||||
var/id
|
||||
/** The name of the cosmetic part. This shows up in the preferences dropdown. */
|
||||
var/name
|
||||
var/icon = 'hyperstation/icons/mob/char_parts.dmi'
|
||||
var/icon_state
|
||||
/** How colors are determined for this part. MUTCOLORS for base color, MATRIXED to allow multiple channels. */
|
||||
var/color_src = MUTCOLORS
|
||||
/** Whether or not this cosmetic part has an alternate form for digitigrade legs. */
|
||||
var/support_digitigrade = TRUE
|
||||
/**
|
||||
WE
|
||||
HATE
|
||||
GENDER!!!!!!!!!!
|
||||
*/
|
||||
var/support_gender = null
|
||||
/** Species IDs that support this cosmetic part. Bypassed with "show mismatched markings" option. */
|
||||
var/list/supported_species
|
||||
|
||||
/datum/cosmetic_part/head
|
||||
/datum/cosmetic_part/chest
|
||||
/datum/cosmetic_part/arms
|
||||
/datum/cosmetic_part/legs
|
||||
|
||||
// HEADS
|
||||
// =========================================
|
||||
|
||||
/datum/cosmetic_part/head/default
|
||||
id = "default"
|
||||
name = "default"
|
||||
icon = null
|
||||
|
||||
/datum/cosmetic_part/head/ipc_round
|
||||
id = "ipc_round"
|
||||
name = "round ipc head"
|
||||
icon_state = "ipc_round"
|
||||
supported_species = list("ipc")
|
||||
support_gender = FALSE
|
||||
|
||||
|
||||
// CHESTS
|
||||
// =========================================
|
||||
|
||||
/datum/cosmetic_part/chest/default
|
||||
id = "default"
|
||||
name = "default"
|
||||
icon = null
|
||||
|
||||
/datum/cosmetic_part/chest/ipc_sleek
|
||||
id = "ipc_sleek"
|
||||
name = "sleek ipc chest"
|
||||
icon_state = "ipc_sleek"
|
||||
supported_species = list("ipc")
|
||||
color_src = MATRIXED
|
||||
support_gender = FALSE
|
||||
|
||||
/datum/cosmetic_part/chest/ipc_jointed
|
||||
id = "ipc_jointed"
|
||||
name = "jointed ipc chest"
|
||||
icon_state = "ipc_jointed"
|
||||
supported_species = list("ipc")
|
||||
color_src = MATRIXED
|
||||
support_gender = FALSE
|
||||
|
||||
|
||||
// ARMS
|
||||
// =========================================
|
||||
|
||||
/datum/cosmetic_part/arms/default
|
||||
id = "default"
|
||||
name = "default"
|
||||
icon = null
|
||||
|
||||
/datum/cosmetic_part/arms/avian_alt
|
||||
id = "avian_alt"
|
||||
name = "avian claws"
|
||||
icon_state = "avian_alt"
|
||||
supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
|
||||
|
||||
/datum/cosmetic_part/arms/insect
|
||||
id = "insect"
|
||||
name = "insect arms"
|
||||
icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
|
||||
icon_state = "insect"
|
||||
supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
|
||||
|
||||
/datum/cosmetic_part/arms/ipc_sleek
|
||||
id = "ipc_sleek"
|
||||
name = "sleek ipc arms"
|
||||
icon_state = "ipc_sleek"
|
||||
supported_species = list("ipc")
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/cosmetic_part/arms/ipc_jointed
|
||||
id = "ipc_jointed"
|
||||
name = "jointed ipc arms"
|
||||
icon_state = "ipc_jointed"
|
||||
supported_species = list("ipc")
|
||||
color_src = MATRIXED
|
||||
|
||||
|
||||
// LEGS
|
||||
// =========================================
|
||||
|
||||
/datum/cosmetic_part/legs/default
|
||||
id = "default"
|
||||
name = "default"
|
||||
icon = null
|
||||
|
||||
/datum/cosmetic_part/legs/avian
|
||||
id = "avian"
|
||||
name = "avian legs"
|
||||
icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
|
||||
icon_state = "avian"
|
||||
supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
|
||||
support_digitigrade = FALSE
|
||||
|
||||
/datum/cosmetic_part/legs/mammal
|
||||
id = "mammal"
|
||||
name = "mammal legs"
|
||||
icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
|
||||
icon_state = "mammal"
|
||||
supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
|
||||
support_digitigrade = TRUE
|
||||
|
||||
/datum/cosmetic_part/legs/insect
|
||||
id = "insect"
|
||||
name = "insect legs"
|
||||
icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
|
||||
icon_state = "insect"
|
||||
supported_species = list("mammal", "avian", "aquatic", "insect", "xeno", "synthliz")
|
||||
support_digitigrade = TRUE
|
||||
|
||||
/datum/cosmetic_part/legs/ipc_sleek
|
||||
id = "ipc_sleek"
|
||||
name = "sleek ipc legs"
|
||||
icon_state = "ipc_sleek"
|
||||
supported_species = list("ipc")
|
||||
color_src = MATRIXED
|
||||
support_digitigrade = FALSE
|
||||
|
||||
/datum/cosmetic_part/legs/ipc_jointed
|
||||
id = "ipc_jointed"
|
||||
name = "jointed ipc legs"
|
||||
icon_state = "ipc_jointed"
|
||||
supported_species = list("ipc")
|
||||
color_src = MATRIXED
|
||||
support_digitigrade = FALSE
|
||||
@@ -0,0 +1,575 @@
|
||||
/*
|
||||
from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
|
||||
/datum/sprite_accessory
|
||||
var/extra = FALSE
|
||||
var/extra_color_src = MUTCOLORS2 //The color source for the extra overlay.
|
||||
var/extra2 = FALSE
|
||||
var/extra_icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
var/extra2_icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
var/extra2_color_src = MUTCOLORS3
|
||||
var/list/ckeys_allowed
|
||||
|
||||
we use the "citadel" versions of mutant/species parts, which usually (but not always)
|
||||
begins with "mam_" somewhere. stuff that's built for only humans/lizards in other parts
|
||||
of the code are from TG, don't use those.
|
||||
|
||||
keep everything in alphabetical order, please!
|
||||
*/
|
||||
|
||||
// TODO: code it so that we don't have to type in "icon = 'hyperstation/icons/mob/etc'"
|
||||
// manually for hyperstation parts
|
||||
|
||||
|
||||
/*
|
||||
SNOUTS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/bigmandible // sarcoph @ hyperstation, march 2022
|
||||
name = "Big Mandibles (Hyper)"
|
||||
icon_state = "bigmandible"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/proboscis // sarcoph @ hyperstation, march 2022
|
||||
name = "Proboscis (Hyper)"
|
||||
icon_state = "proboscis"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/rhinobeetle // sarcoph @ hyperstation, march 2022
|
||||
name = "Rhino Beetle (Hyper)"
|
||||
icon_state = "rhinobeetle"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/scarab // sarcoph @ hyperstation, march 2022
|
||||
name = "Scarab Beetle (Hyper)"
|
||||
icon_state = "scarab"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/smallmandible // sarcoph @ hyperstation, march 2022
|
||||
name = "Small Mandibles (Hyper)"
|
||||
icon_state = "smallmandible"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/spider // sarcoph @ hyperstation, march 2022
|
||||
name = "Spider (Hyper)"
|
||||
icon_state = "spider"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/tarantula // sarcoph @ hyperstation, march 2022
|
||||
name = "Tarantula (Hyper)"
|
||||
icon_state = "tarantula"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easterndw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/feasterndragon
|
||||
name = "Eastern Dragon (Top) (Hyper)"
|
||||
icon_state = "feasterndw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/easterndragonnowhiskers
|
||||
name = "Eastern Dragon - No Whiskers (Hyper)"
|
||||
icon_state = "easterndnw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/feasterndragonnowhiskers
|
||||
name = "Eastern Dragon - No Whiskers (Top) (Hyper)"
|
||||
icon_state = "feasterndnw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
|
||||
name = "Kinaris - Shuttle (Hyper)"
|
||||
icon_state = "knshuttle"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/fchemlight
|
||||
name = "RadDog (Top) (Hyper)"
|
||||
icon_state = "fchemlight"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/pinata
|
||||
name = "pinata (Hyper)"
|
||||
icon_state = "pinata"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/pinatasmile
|
||||
name = "pinata Smile (Hyper)"
|
||||
icon_state = "pinatasmile"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/*
|
||||
EARS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/mam_ears/faceant // sarcoph @ hyperstation, march 2022
|
||||
name = "Face Antennae (Hyper)"
|
||||
icon_state = "faceant"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/faceant2 // sarcoph @ hyperstation, march 2022
|
||||
name = "Face Antennae 2 (Hyper)"
|
||||
icon_state = "faceant2"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/moth
|
||||
name = "Moth Antennae (Hyper)"
|
||||
icon_state = "moth"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/plumeant // sarcoph @ hyperstation, march 2022
|
||||
name = "Plume Antennae (Hyper)"
|
||||
icon_state = "plumeant"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/roundant // sarcoph @ hyperstation, march 2022
|
||||
name = "Round Antennae (Hyper)"
|
||||
icon_state = "roundant"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/thinant // sarcoph @ hyperstation, march 2022
|
||||
name = "Thin Antennae (Hyper)"
|
||||
icon_state = "thinant"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_ears/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
|
||||
name = "Kinaris - Shuttle (Hyper)"
|
||||
icon_state = "knshuttle"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_ears/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
|
||||
/*
|
||||
WINGS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/deco_wings/beetle // sarcoph @ hyperstation, march 2022
|
||||
name = "Beetle (Hyper)"
|
||||
icon_state = "beetle"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/moth_wings/beetle
|
||||
name = "Beetle (Hyper)"
|
||||
icon_state = "beetle"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/beetle2 // sarcoph @ hyperstation, march 2022
|
||||
name = "Beetle - 2-toned (Hyper)"
|
||||
icon_state = "beetle2"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/moth_wings/beetle2
|
||||
name = "Beetle - 2-toned (Hyper)"
|
||||
icon_state = "beetle2"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/deco_wings/insect // sarcoph @ hyperstation, march 2022
|
||||
name = "Insect (Hyper)"
|
||||
icon_state = "insect"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/moth_wings/insect
|
||||
name = "Insect (Hyper)"
|
||||
icon_state = "insect"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
|
||||
name = "Kinaris - Shuttle (Hyper)"
|
||||
icon_state = "knshuttle"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
//recommended_species = list("synthliz") need to give synths a deco wing slot
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/deco_wings/minibat // sarcoph @ hyperstation, march 2022
|
||||
name = "Mini Bat (Hyper)"
|
||||
icon_state = "minibat"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/minifeather // sarcoph @ hyperstation, march 2022
|
||||
name = "Mini Feather (Hyper)"
|
||||
icon_state = "minifeather"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/tinybat // sarcoph @ hyperstation, march 2022
|
||||
name = "Tiny Bat (Hyper)"
|
||||
icon_state = "tinybat"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/tinyfeather // sarcoph @ hyperstation, march 2022
|
||||
name = "Tiny Feather (Hyper)"
|
||||
icon_state = "tinyfeather"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/sylveon // Aphast @ hyperstation, november 2022
|
||||
name = "Sylveon Ribbons"
|
||||
icon_state = "sylveon_bow"
|
||||
icon = 'hyperstation/icons/mob/char_wings.dmi'
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/horns/sylveon // Aphast @ hyperstation, november 2022, best place to put this due to being a pair and no horn slots here
|
||||
name = "Sylveon Bow"
|
||||
icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
|
||||
icon_state = "sylveon_bow"
|
||||
color_src = MATRIXED
|
||||
|
||||
/*
|
||||
TAILS + ANIMATED TAILS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/mam_tails/bee // sarcoph @ hyperstation, march 2022
|
||||
name = "Bee (Hyper)"
|
||||
icon_state = "bee"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/bee
|
||||
name = "Bee (Hyper)"
|
||||
icon_state = "bee"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails/bee2 // sarcoph @ hyperstation, march 2022
|
||||
name = "Bee w/ Stinger (Hyper)"
|
||||
icon_state = "bee2"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/bee2
|
||||
name = "Bee w/ Stinger (Hyper)"
|
||||
icon_state = "bee2"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
// "fan" bird tail, short
|
||||
/datum/sprite_accessory/mam_tails/shorthawk // sarcoph @ hyperstation, jan 2022
|
||||
name = "Hawk - Short (Hyper)"
|
||||
icon_state = "shorthawk"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/shorthawk
|
||||
name = "Hawk - Short (Hyper)"
|
||||
icon_state = "shorthawk"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/insect // sarcoph @ hyperstation, march 2022
|
||||
name = "Insect (Hyper)"
|
||||
icon_state = "insect"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/insect
|
||||
name = "Insect (Hyper)"
|
||||
icon_state = "insect"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails/bug2tone // sarcoph @ hyperstation, march 2022
|
||||
name = "Insect - 2-tone (Hyper)"
|
||||
icon_state = "bug2tone"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/bug2tone
|
||||
name = "Insect - 2-tone (Hyper)"
|
||||
icon_state = "bug2tone"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
// "narrow" bird tail, long
|
||||
/datum/sprite_accessory/mam_tails/longpigeon // sarcoph @ hyperstation, jan 2022
|
||||
name = "Pigeon - Long (Hyper)"
|
||||
icon_state = "longpigeon"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/longpigeon
|
||||
name = "Pigeon - Long (Hyper)"
|
||||
icon_state = "longpigeon"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
// "narrow" bird tail, short
|
||||
/datum/sprite_accessory/mam_tails/shortpigeon // sarcoph @ hyperstation, jan 2022
|
||||
name = "Pigeon - Short (Hyper)"
|
||||
icon_state = "shortpigeon"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/shortpigeon
|
||||
name = "Pigeon - Short (Hyper)"
|
||||
icon_state = "shortpigeon"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
// "forked" bird tail, long
|
||||
/datum/sprite_accessory/mam_tails/swallow // sarcoph @ hyperstation, jan 2022
|
||||
name = "Swallow (Hyper)"
|
||||
icon_state = "swallow"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/swallow
|
||||
name = "Swallow (Hyper)"
|
||||
icon_state = "swallow"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
// forked bird tail, long; special stripe markings
|
||||
/datum/sprite_accessory/mam_tails/swallowstriped // sarcoph @ hyperstation, jan 2022
|
||||
name = "Swallow - Striped (Hyper)"
|
||||
icon_state = "swallowstriped"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/swallowstriped
|
||||
name = "Swallow - Striped (Hyper)"
|
||||
icon_state = "swallowstriped"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/easterndragon //Pulled base from Virgo, seriously love the server and love you guys, stay lovely.
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
|
||||
name = "Kinaris - Shuttle (Hyper)"
|
||||
icon_state = "knshuttle"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/knshuttle
|
||||
name = "Kinaris - Shuttle (Hyper)"
|
||||
icon_state = "knshuttle"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
|
||||
/*
|
||||
BODY MARKINGS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
|
||||
/datum/sprite_accessory/mam_body_markings
|
||||
extra = FALSE
|
||||
extra2 = FALSE
|
||||
color_src = MATRIXED
|
||||
gender_specific = 0
|
||||
icon = 'modular_citadel/icons/mob/mam_markings.dmi'
|
||||
recommended_species = list("mammal", "xeno", "slimeperson", "podweak", "avian", "aquatic")
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/bee // sarcoph @ hyperstation, march 2022
|
||||
name = "Bee (Hyper)"
|
||||
icon_state = "bee"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/bee_fluff // sarcoph @ hyperstation, march 2022
|
||||
name = "Bee - Fluffy (Hyper)"
|
||||
icon_state = "bee_fluff"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/bug3tone // sarcoph @ hyperstation, march 2022
|
||||
name = "Beetle - 3-tone (Hyper)"
|
||||
icon_state = "bug3tone"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/moth // sarcoph @ hyperstation, jan 2022
|
||||
name = "Moth (Hyper)"
|
||||
icon_state = "moth"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/empty
|
||||
name = "None (Hyper)"
|
||||
icon_state = "empty"
|
||||
recommended_species = list("podweak", /*"mammal",*/ "avian", "aquatic", "insect", "xeno", "synthliz", "slimeperson")
|
||||
// mammals are cursed to no empty markings until they get their heads fixed.
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/pigeon // sarcoph @ hyperstation, jan 2022
|
||||
name = "Pigeon (Hyper)"
|
||||
icon_state = "pigeon"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("avian")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/shrike // sarcoph @ hyperstation, jan 2022
|
||||
name = "Shrike (Hyper)"
|
||||
icon_state = "shrike"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("avian")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/knshuttle // Dahlular and Arcstaisia @ hyperstation, april 2022. Feel free to remove comment. Just remember this is snowflakey Kinaris stuff.
|
||||
name = "Kinaris - Shuttle (Hyper)"
|
||||
icon_state = "knshuttle"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
//doged was here
|
||||
/datum/sprite_accessory/mam_body_markings/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
//racc do a code maybe it won't explode
|
||||
/datum/sprite_accessory/mam_body_markings/raccalt
|
||||
name = "RaccAlt (Hyper)"
|
||||
icon_state = "raccalt"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/pinata
|
||||
name = "pinata (Hyper)"
|
||||
icon_state = "pinata"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
/*
|
||||
TAUR BODIES
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
|
||||
/datum/sprite_accessory/taur
|
||||
icon = 'modular_citadel/icons/mob/mam_taur.dmi'
|
||||
extra_icon = 'modular_citadel/icons/mob/mam_taur.dmi'
|
||||
extra = TRUE
|
||||
extra2_icon = 'modular_citadel/icons/mob/mam_taur.dmi'
|
||||
extra2 = TRUE
|
||||
center = TRUE
|
||||
dimension_x = 64
|
||||
var/taur_mode = NOT_TAURIC
|
||||
color_src = MATRIXED
|
||||
recommended_species = list("human", "lizard", "insect", "mammal", "xeno", "jelly", "slimeperson", "podweak", "avian", "aquatic")
|
||||
*/
|
||||
/datum/sprite_accessory/taur/chemnaga //Chemlight experimental sprites for future spriting
|
||||
name = "RadDog Naga (Hyper)"
|
||||
icon_state = "chemnaga"
|
||||
taur_mode = SNEK_TAURIC
|
||||
ckeys_allowed = list("chemlight")
|
||||
|
||||
/datum/sprite_accessory/taur/chemlight
|
||||
name = "RadDog Taur (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
taur_mode = PAW_TAURIC
|
||||
ckeys_allowed = list("chemlight")
|
||||
|
||||
|
||||
/*
|
||||
IPCS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
|
||||
|
||||
/datum/sprite_accessory/antenna
|
||||
icon = 'modular_citadel/icons/mob/ipc_antennas.dmi'
|
||||
color_src = MUTCOLORS3
|
||||
recommended_species = list("ipc")
|
||||
|
||||
/datum/sprite_accessory/screen
|
||||
icon = 'modular_citadel/icons/mob/ipc_screens.dmi'
|
||||
color_src = null
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/antenna/idog_down
|
||||
name = "Dog, down (Hyper)"
|
||||
icon_state = "idog_down"
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/antenna/idog_up
|
||||
name = "Dog, up (Hyper)"
|
||||
icon_state = "idog_up"
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/antenna/headset
|
||||
name = "Headphones (Hyper)"
|
||||
icon_state = "headset"
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/antenna/aquatic
|
||||
name = "Fins (Hyper)"
|
||||
icon_state = "aquatic"
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/screen/ghost
|
||||
name = "Ghost (Hyper)"
|
||||
icon_state = "ghost"
|
||||
|
||||
/datum/sprite_accessory/screen/heartbeat
|
||||
name = "Heartbeat (Hyper)"
|
||||
icon_state = "heartbeat"
|
||||
|
||||
/datum/sprite_accessory/screen/ocean
|
||||
name = "Ocean (Hyper)"
|
||||
icon_state = "ocean"
|
||||
|
||||
/datum/sprite_accessory/antenna/catears
|
||||
name = "Pointy Ears (Hyper)"
|
||||
icon_state = "catears"
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/screen/valley
|
||||
name = "Valley (Hyper)"
|
||||
icon_state = "valley"
|
||||
|
||||
/*
|
||||
BEARDS
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
/datum/sprite_accessory/facial_hair
|
||||
icon = 'icons/mob/human_face.dmi'
|
||||
gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P)
|
||||
*/
|
||||
|
||||
/datum/sprite_accessory/facial_hair/mane
|
||||
name = "Neckfluff (Hyper)"
|
||||
icon_state = "facial_neckfluff"
|
||||
@@ -0,0 +1,3 @@
|
||||
//This file is empty right now, but leaves room for people to put shit here in the future for those who are lazy
|
||||
/mob/living/silicon/robot
|
||||
var/datum/action/cyborg_small_sprite/small_sprite_action //This gets replaced every time the cyborg changes modules --Cyanosis
|
||||
@@ -0,0 +1,18 @@
|
||||
//This file is empty right now, but leaves room for people to put shit here in the future for those who are lazy
|
||||
|
||||
//This proc gets called whenever a new robot module is being applied --Cyanosis
|
||||
/obj/item/robot_module/proc/handle_sprite_action(mob/living/silicon/robot/R, is_huge = FALSE)
|
||||
ASSERT(istype(R))
|
||||
if(R.small_sprite_action)
|
||||
QDEL_NULL(R.small_sprite_action)
|
||||
if(!is_huge) //only from the expander upgrade. The borg won't have an action if they don't have the expander upgrade
|
||||
return
|
||||
for(var/P in typesof(/datum/action/cyborg_small_sprite))
|
||||
var/datum/action/cyborg_small_sprite/action = P
|
||||
if(initial(action.designated_module) == name)
|
||||
R.small_sprite_action = new action()
|
||||
R.small_sprite_action.Grant(R)
|
||||
break
|
||||
if(!R.small_sprite_action)
|
||||
R.small_sprite_action = new()
|
||||
R.small_sprite_action.Grant(R)
|
||||
@@ -0,0 +1,51 @@
|
||||
//Ported from virgo, with some touch ups to make it work with our code.
|
||||
|
||||
/mob/living
|
||||
var/list/status_indicators = null // Will become a list as needed.
|
||||
|
||||
/mob/living/proc/add_status_indicator(mutable_appearance/thing)
|
||||
if(get_status_indicator(thing))
|
||||
return
|
||||
|
||||
if(!istype(thing, /mutable_appearance))
|
||||
thing = mutable_appearance('hyperstation/icons/mob/status_indicators.dmi', icon_state = thing)
|
||||
|
||||
LAZYADD(status_indicators, thing)
|
||||
handle_status_indicators()
|
||||
|
||||
/mob/living/proc/remove_status_indicator(mutable_appearance/thing)
|
||||
thing = get_status_indicator(thing)
|
||||
|
||||
cut_overlay(thing)
|
||||
LAZYREMOVE(status_indicators, thing)
|
||||
handle_status_indicators()
|
||||
|
||||
/mob/living/proc/get_status_indicator(mutable_appearance/thing)
|
||||
if(!istype(thing, /mutable_appearance))
|
||||
for(var/mutable_appearance/I in status_indicators)
|
||||
if(I.icon_state == thing)
|
||||
return I
|
||||
return LAZYACCESS(status_indicators, LAZYFIND(status_indicators, thing))
|
||||
|
||||
/mob/living/proc/handle_status_indicators()
|
||||
// First, get rid of all the overlays.
|
||||
for(var/thing in status_indicators)
|
||||
cut_overlay(thing)
|
||||
|
||||
if(!LAZYLEN(status_indicators))
|
||||
return
|
||||
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
// Now the indicator row can actually be built.
|
||||
for(var/thing in status_indicators)
|
||||
var/mutable_appearance/I = thing
|
||||
|
||||
I.appearance_flags = PIXEL_SCALE|KEEP_APART
|
||||
I.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
I.plane = HUD_PLANE
|
||||
I.layer = ABOVE_FLY_LAYER
|
||||
I.pixel_y = 18
|
||||
I.pixel_x = 18
|
||||
add_overlay(I)
|
||||
@@ -0,0 +1,29 @@
|
||||
mob/proc/checkloadappearance()
|
||||
var/mob/living/carbon/human/H = src
|
||||
//This will be where the person gets to select their appearance instead of the random character
|
||||
if (world.time <= (H.time_initialized + 900) && H.mirrorcanloadappearance == TRUE)
|
||||
SEND_SOUND(H, 'sound/misc/server-ready.ogg')
|
||||
to_chat(H, "<span class='boldannounce'>This ghost role allows you to select your loaded character's appearance. Make sure you have your ID in your ID slot, if you have one.</span>")
|
||||
if(alert(H, "Would you like to load your currently loaded character's appearance?", "This can only be done up until 90s after you spawn.", "Yes", "No") == "Yes" && world.time <= (H.time_initialized + 900))
|
||||
if(alert(H, "You should only load a character that has not currently died in the round. Do you accept this?", "Warning", "Yes", "No") == "Yes" && world.time <= (H.time_initialized + 900))
|
||||
H.client?.prefs?.copy_to(H)
|
||||
if (H.custom_body_size) //Do they have a custom size set?
|
||||
H.resize(H.custom_body_size * 0.01)
|
||||
H.real_name = H.client?.prefs?.real_name
|
||||
H.mind.name = H.real_name //Makes sure to change their mind name to their real name.
|
||||
SSquirks.AssignQuirks(H, H.client, TRUE, FALSE, H.job, FALSE)//This Assigns the selected character's quirks
|
||||
H.dna.update_dna_identity() //This makes sure their DNA is updated.
|
||||
var/obj/item/card/id/idCard = H.get_idcard() //Time to change their ID card as well if they have one.
|
||||
if (idCard != null)
|
||||
idCard.update_label(H.real_name, idCard.assignment)
|
||||
idCard.registered_name = H.real_name
|
||||
H.mirrorcanloadappearance = FALSE //Prevents them from using the mirror again.
|
||||
ADD_TRAIT(H,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT) //Makes sure they are exempt from health events.
|
||||
SEND_SOUND(H, 'sound/magic/charge.ogg') //Fluff
|
||||
to_chat(H, "<span class='boldannounce'>Your head aches for a second. You feel like this is how things should have been.</span>")
|
||||
log_game("[key_name(H)] has loaded their default appearance for a ghost role.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(H)] has loaded their default appearance for a ghost role.")
|
||||
return
|
||||
else
|
||||
to_chat(H, "<span class='boldannounce'>You either took too long or chose not to change. Alrighty. Remember, you have 90 seconds from spawn to get to a mirror and still do it if you wish.</span>")
|
||||
return
|
||||
@@ -0,0 +1,15 @@
|
||||
#define PATREONFILE "[global.config.directory]/patreons.txt"
|
||||
|
||||
GLOBAL_LIST_EMPTY(patreons)
|
||||
|
||||
/proc/load_patreons()
|
||||
GLOB.patreons = list()
|
||||
for(var/line in world.file2list(PATREONFILE))
|
||||
if(!line)
|
||||
continue
|
||||
GLOB.patreons += ckey(line)
|
||||
|
||||
/proc/check_patreons(var/ckey)
|
||||
if(!GLOB.patreons)
|
||||
return FALSE
|
||||
. = (ckey in GLOB.patreons)
|
||||
@@ -0,0 +1,45 @@
|
||||
/obj/item/pen/attack(mob/living/M, mob/user,stealth)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(!force)
|
||||
if(M.can_inject(user, 1))
|
||||
if(user.a_intent == "harm") //old poke requires harm intent.
|
||||
to_chat(user, "<span class='warning'>You stab [M] with the pen.</span>")
|
||||
if(!stealth)
|
||||
to_chat(M, "<span class='danger'>You feel a tiny prick!</span>")
|
||||
. = 1
|
||||
|
||||
else //writing time
|
||||
var/mob/living/carbon/human/T = M
|
||||
if(!T) //not human.
|
||||
return
|
||||
if(!T.is_chest_exposed())
|
||||
to_chat(user, "<span class='warning'>You cannot write on someone with their clothes on.</span>")
|
||||
return
|
||||
|
||||
var/writting = input(user, "Add writing, doesn't replace current text", "Writing on [T]") as text|null
|
||||
if(!writting)
|
||||
return
|
||||
|
||||
var/obj/item/bodypart/BP = T.get_bodypart(user.zone_selected)
|
||||
|
||||
if(!(user==T))
|
||||
src.visible_message("<span class='notice'>[user] begins to write on [T]'s [BP.name].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin to write on your [BP.name].</span>")
|
||||
|
||||
if(do_mob(user, T, 4 SECONDS))
|
||||
if((length(BP.writtentext))+(length(writting)) < 100) //100 character limmit to stop spamming.
|
||||
BP.writtentext += html_encode(writting) //you can add to text, not remove it.
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There isnt enough space to write that on [T]'s [BP.name].</span>")
|
||||
return
|
||||
|
||||
if(!(user==T))
|
||||
to_chat(user, "<span class='notice'>You write on [T]'s [BP.name].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You write on your [BP.name].</span>")
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
/obj/item/twohanded/required/fuel_rod
|
||||
var/rad_strength = 500
|
||||
var/half_life = 2000 // how many depletion ticks are needed to half the fuel_power (1 tick = 1 second)
|
||||
var/time_created = 0
|
||||
var/og_fuel_power = 0.20 //the original fuel power value
|
||||
var/process = FALSE
|
||||
// The depletion where depletion_final() will be called (and does something)
|
||||
var/depletion_threshold = 100
|
||||
// How fast this rod will deplete
|
||||
var/depletion_speed_modifier = 1
|
||||
var/depleted_final = FALSE // depletion_final should run only once
|
||||
var/depletion_conversion_type = "plutonium"
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/Initialize(mapload)
|
||||
. = ..()
|
||||
time_created = world.time
|
||||
AddComponent(/datum/component/radioactive, rad_strength, src) // This should be temporary for it won't make rads go lower than 350
|
||||
if(process)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/Destroy()
|
||||
if(process)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc
|
||||
if(istype(N))
|
||||
N.fuel_rods -= src
|
||||
. = ..()
|
||||
|
||||
// This proc will try to convert your fuel rod if you don't override this proc
|
||||
// So, ideally, you should write an override of this for every fuel rod you want to create
|
||||
/obj/item/twohanded/required/fuel_rod/proc/depletion_final(result_rod = "")
|
||||
if(result_rod)
|
||||
var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc
|
||||
// Rod conversion is moot when you can't find the reactor
|
||||
if(istype(N))
|
||||
var/obj/item/twohanded/required/fuel_rod/R
|
||||
|
||||
// You can add your own depletion scheme and not override this proc if you are going to convert a fuel rod into another type
|
||||
switch(result_rod)
|
||||
if("plutonium")
|
||||
R = new /obj/item/twohanded/required/fuel_rod/plutonium(loc)
|
||||
R.depletion = depletion
|
||||
if("depleted")
|
||||
if(fuel_power < 10)
|
||||
fuel_power = 0
|
||||
playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE)
|
||||
R = new /obj/item/twohanded/required/fuel_rod/depleted(loc)
|
||||
R.depletion = depletion
|
||||
|
||||
// Finalization of conversion
|
||||
if(istype(R))
|
||||
N.fuel_rods += R
|
||||
qdel(src)
|
||||
else
|
||||
depleted_final = FALSE // Maybe try again later?
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/deplete(amount=0.035) // override for the one in rmbk.dm
|
||||
depletion += amount * depletion_speed_modifier
|
||||
if(depletion >= depletion_threshold && !depleted_final)
|
||||
depleted_final = TRUE
|
||||
depletion_final(depletion_conversion_type)
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/plutonium
|
||||
fuel_power = 0.20
|
||||
name = "Plutonium-239 Fuel Rod"
|
||||
desc = "A highly energetic titanium sheathed rod containing a sizeable measure of weapons grade plutonium, it's highly efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised."
|
||||
icon_state = "inferior"
|
||||
rad_strength = 1500
|
||||
process = TRUE // for half life code
|
||||
depletion_threshold = 300
|
||||
depletion_conversion_type = "depleted"
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/plutonium/process()
|
||||
fuel_power = og_fuel_power * 0.5**((world.time - time_created) / half_life SECONDS) // halves the fuel power every half life (33 minutes)
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/depleted
|
||||
name = "Depleted Fuel Rod"
|
||||
desc = "A highly radioactive fuel rod which has expended most of it's useful energy."
|
||||
icon_state = "normal"
|
||||
rad_strength = 6000 // smelly
|
||||
depletion_conversion_type = "" // It means that it won't turn into anything
|
||||
|
||||
// Master type for material optional (or requiring, wyci) and/or producing rods
|
||||
/obj/item/twohanded/required/fuel_rod/material
|
||||
// Whether the rod has been harvested. Should be set in expend().
|
||||
var/expended = FALSE
|
||||
// The material that will be inserted and then multiplied (or not). Should be some sort of /obj/item/stack
|
||||
var/material_type
|
||||
// The name of material that'll be used for texts
|
||||
var/material_name
|
||||
var/material_name_singular
|
||||
var/initial_amount = 0
|
||||
// The maximum amount of material the rod can hold
|
||||
var/max_initial_amount = 10
|
||||
var/grown_amount = 0
|
||||
// The multiplier for growth. 1 for the same 2 for double etc etc
|
||||
var/multiplier = 2
|
||||
// After this depletion, you won't be able to add new materials
|
||||
var/material_input_deadline = 25
|
||||
// Material fuel rods generally don't get converted into another fuel object
|
||||
depletion_conversion_type = ""
|
||||
|
||||
// Called when the rod is fully harvested
|
||||
/obj/item/twohanded/required/fuel_rod/material/proc/expend()
|
||||
expended = TRUE
|
||||
|
||||
// Basic checks for material rods
|
||||
/obj/item/twohanded/required/fuel_rod/material/proc/check_material_input(mob/user)
|
||||
if(depletion >= material_input_deadline)
|
||||
to_chat(user, "<span class='warning'>The sample slots have sealed themselves shut, it's too late to add [material_name] now!</span>") // no cheesing in crystals at 100%
|
||||
return FALSE
|
||||
if(expended)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s material slots have already been used.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// The actual growth
|
||||
/obj/item/twohanded/required/fuel_rod/material/depletion_final(result_rod)
|
||||
if(result_rod)
|
||||
..() // So if you put anything into depletion_conversion_type then your fuel rod will be converted (or not) and *won't grow*
|
||||
else
|
||||
grown_amount = initial_amount * multiplier
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/attackby(obj/item/W, mob/user, params)
|
||||
var/obj/item/stack/M = W
|
||||
if(istype(M, material_type))
|
||||
if(!check_material_input(user))
|
||||
return
|
||||
if(initial_amount < max_initial_amount)
|
||||
var/adding = min((max_initial_amount - initial_amount), M.amount)
|
||||
M.amount -= adding
|
||||
initial_amount += adding
|
||||
if (adding == 1)
|
||||
to_chat(user, "<span class='notice'>You insert [adding] [material_name_singular] into \the [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You insert [adding] [material_name] into \the [src].</span>")
|
||||
M.zero_amount()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src]'s material slots are full!</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/attack_self(mob/user)
|
||||
if(expended)
|
||||
to_chat(user, "<span class='notice'>You have already removed [material_name] from \the [src].</span>")
|
||||
return
|
||||
|
||||
if(depleted_final)
|
||||
new material_type(user.loc, grown_amount)
|
||||
if (grown_amount == 1)
|
||||
to_chat(user, "<span class='notice'>You harvest [grown_amount] [material_name_singular] from \the [src].</span>") // Unlikely
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You harvest [grown_amount] [material_name] from \the [src].</span>")
|
||||
grown_amount = 0
|
||||
expend()
|
||||
else if(depletion)
|
||||
to_chat(user, "<span class='warning'>\The [src] has not fissiled enough to fully grow the sample. The progress bar shows it is [min(depletion/depletion_threshold*100,100)]% complete.</span>")
|
||||
else if(initial_amount)
|
||||
new material_type(user.loc, initial_amount)
|
||||
if (initial_amount == 1)
|
||||
to_chat(user, "<span class='notice'>You remove [initial_amount] [material_name_singular] from \the [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You remove [initial_amount] [material_name] from \the [src].</span>")
|
||||
initial_amount = 0
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/examine(mob/user)
|
||||
. = ..()
|
||||
if(expended)
|
||||
. += "<span class='warning'>The material slots have been slagged by the extreme heat, you can't grow [material_name] in this rod again...</span>"
|
||||
return
|
||||
else if(depleted_final)
|
||||
if(grown_amount == 1)
|
||||
. += "<span class='warning'>This fuel rod's [material_name] are now fully grown, and it currently bears [grown_amount] harvestable [material_name_singular].</span>"
|
||||
else
|
||||
. += "<span class='warning'>This fuel rod's [material_name] are now fully grown, and it currently bears [grown_amount] harvestable [material_name].</span>"
|
||||
return
|
||||
if(depletion)
|
||||
. += "<span class='danger'>The sample is [min(depletion/depletion_threshold*100,100)]% fissiled.</span>"
|
||||
. += "<span class='disarm'>[initial_amount]/[max_initial_amount] of the slots for [material_name] are full.</span>"
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/telecrystal
|
||||
name = "Telecrystal Fuel Rod"
|
||||
desc = "A disguised titanium sheathed rod containing several small slots infused with uranium dioxide. Permits the insertion of telecrystals to grow more. Fissiles much faster than its standard counterpart"
|
||||
icon_state = "telecrystal"
|
||||
fuel_power = 0.30 // twice as powerful as a normal rod, you're going to need some engineering autism if you plan to mass produce TC
|
||||
depletion_speed_modifier = 3 // headstart, otherwise it takes two hours
|
||||
rad_strength = 1500
|
||||
max_initial_amount = 8
|
||||
multiplier = 3
|
||||
material_type = /obj/item/stack/telecrystal
|
||||
material_name = "telecrystals"
|
||||
material_name_singular = "telecrystal"
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/telecrystal/depletion_final(result_rod)
|
||||
..()
|
||||
if(!result_rod)
|
||||
fuel_power = 0.60 // thrice as powerful as plutonium, you'll want to get this one out quick!
|
||||
name = "Exhausted Telecrystal Fuel Rod"
|
||||
desc = "A highly energetic, disguised titanium sheathed rod containing a number of slots filled with greatly expanded telecrystals which can be removed by hand. It's extremely efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised."
|
||||
icon_state = "telecrystal_used"
|
||||
AddComponent(/datum/component/radioactive, 3000, src)
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/bananium
|
||||
name = "Bananium Fuel Rod"
|
||||
desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than its cowardly counterparts. However, its cutting-edge cosmic clown technology allows rooms for extraordinarily exhilarating extraterrestrial element called bananium to menacingly multiply."
|
||||
icon_state = "bananium"
|
||||
fuel_power = 0.15
|
||||
depletion_speed_modifier = 3
|
||||
rad_strength = 350
|
||||
max_initial_amount = 10
|
||||
multiplier = 3
|
||||
material_type = /obj/item/stack/sheet/mineral/bananium
|
||||
material_name = "sheets of bananium"
|
||||
material_name_singular = "sheet of bananium"
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/bananium/deplete(amount=0.035)
|
||||
..()
|
||||
if(initial_amount == max_initial_amount && prob(10))
|
||||
playsound(src, pick('sound/items/bikehorn.ogg', 'yogstation/sound/misc/bikehorn_creepy.ogg'), 50) // HONK
|
||||
|
||||
/obj/item/twohanded/required/fuel_rod/material/bananium/depletion_final(result_rod)
|
||||
..()
|
||||
if(!result_rod)
|
||||
fuel_power = 0.3 // Be warned
|
||||
name = "Fully Grown Bananium Fuel Rod"
|
||||
desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than it cowardly counterparts. Its greatly grimacing grwoth stage is now over, and bananium outgrowth hums as if it's blatantly honking bike horns."
|
||||
icon_state = "bananium_used"
|
||||
AddComponent(/datum/component/radioactive, 1250, src)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
// modular shitcode but it works:tm:
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if(istype(I))
|
||||
to_chat(user, "<span class='notice'>You add \the [src]'s ID into the multitool's buffer.</span>")
|
||||
I.buffer = src.id
|
||||
return TRUE
|
||||
/obj/machinery/computer/reactor/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if(istype(I))
|
||||
to_chat(user, "<span class='notice'>You add the reactor's ID to \the [src]>")
|
||||
src.id = I.buffer
|
||||
link_to_reactor()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo // easier on the brain
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo/New()
|
||||
. = ..()
|
||||
id = rand(1, 9999999) // cmon, what are the chances? The chances are... Very low friend... But maybe we can make this a bit better.
|
||||
|
||||
// Cargo variants can be wrenched down and don't start linked to the default RMBK reactor
|
||||
|
||||
/obj/machinery/computer/reactor/control_rods/cargo
|
||||
anchored = FALSE
|
||||
id = null
|
||||
|
||||
/obj/machinery/computer/reactor/stats/cargo
|
||||
anchored = FALSE
|
||||
id = null
|
||||
|
||||
/obj/machinery/computer/reactor/fuel_rods/cargo
|
||||
anchored = FALSE
|
||||
id = null
|
||||
|
||||
/obj/item/paper/fluff/rbmkcargo
|
||||
name = "Nuclear Reactor Instructions"
|
||||
info = "Make sure a 5x5 area is completely clear of pipes, cables and machinery when using the beacon. Those will be provided automatically with the beacon's bluespace decompression. Use a multitool on the reactor then on the computers provided to link them together. Also make sure the reactor has a proper pipeline filled with cooling gas before inserting fuel rods. Good luck!"
|
||||
@@ -0,0 +1,23 @@
|
||||
/datum/reagent/consumable/pilk
|
||||
name = "Pilk"
|
||||
description = "A forbidden mixture that dates back to the early days of space civilization, its creation is known to have caused at least one or two massacres."
|
||||
color = "#cf9f6f"
|
||||
taste_description = "heresy"
|
||||
glass_icon_state = "whiskeycolaglass"
|
||||
glass_name = "glass of Pilk"
|
||||
glass_desc = "Why would you do this to yourself?"
|
||||
hydration = 3
|
||||
|
||||
/datum/reagent/consumable/pilk/on_mob_life(mob/living/carbon/M)
|
||||
M.drowsyness = max(0,M.drowsyness-3)
|
||||
M.adjust_bodytemperature(-3 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
|
||||
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
|
||||
M.heal_bodypart_damage(0.75,0, 0)
|
||||
. = 1
|
||||
else
|
||||
if(M.getBruteLoss() && prob(20))
|
||||
M.heal_bodypart_damage(0.5,0, 0)
|
||||
. = 1
|
||||
if(holder.has_reagent(/datum/reagent/consumable/capsaicin))
|
||||
holder.remove_reagent(/datum/reagent/consumable/capsaicin, 1)
|
||||
..()
|
||||
@@ -0,0 +1,8 @@
|
||||
/datum/reagent/consumable/alienhoney //for players who want bee character bewbs that produce honey.
|
||||
name = "alien honey"
|
||||
description = "Sweet honey that came from a alien source. This honey doesn't possess the same healing or nutrition properties as earth-bound bee honey."
|
||||
color = "#d3a308"
|
||||
value = 3 //plentiful, so wouldnt be worth as much.
|
||||
nutriment_factor = 5 * REAGENTS_METABOLISM
|
||||
metabolization_rate = 1 * REAGENTS_METABOLISM
|
||||
taste_description = "sweetness"
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* If you ever decide to add more reactions, please remember to keep these
|
||||
* in alphabetical order, according to reagent names and not their datums.
|
||||
* It could be hard to find reactions when code diving.
|
||||
* Due note, unlike before this change, that subtypes will apply to the tray the same as their parents
|
||||
* -DT
|
||||
*/
|
||||
|
||||
#define DEFAULT_ACT_MUTAGEN switch(rand(100)){\
|
||||
if(91 to 100){\
|
||||
T.adjustHealth(-10);\
|
||||
to_chat(user, "<span class='warning'>The plant shrivels and burns.</span>");}\
|
||||
if(81 to 90)\
|
||||
T.mutatespecie();\
|
||||
if(66 to 80)\
|
||||
T.hardmutate();\
|
||||
if(41 to 65)\
|
||||
T.mutate();\
|
||||
if(21 to 41)\
|
||||
to_chat(user, "<span class='notice'>The plants don't seem to react...</span>");\
|
||||
if(11 to 20)\
|
||||
T.mutateweed();\
|
||||
if(1 to 10)\
|
||||
T.mutatepest(user);\
|
||||
else\
|
||||
to_chat(user, "<span class='notice'>Nothing happens...</span>");}
|
||||
|
||||
//Ammonia
|
||||
/datum/reagent/ammonia/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustHealth(round(volume * 0.5))
|
||||
T.adjustNutri(round(volume * 1))
|
||||
if(..())
|
||||
T.myseed.adjust_yield(round(volume * 0.01))
|
||||
return TRUE
|
||||
|
||||
//Ash
|
||||
/datum/reagent/ash/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
// Ash is used IRL in gardening, as a fertilizer enhancer and weed killer
|
||||
T.adjustHealth(round(volume * 0.25))
|
||||
T.adjustNutri(round(volume * 0.5))
|
||||
T.adjustWeeds(-round(volume / 10))
|
||||
return TRUE
|
||||
|
||||
//Beer
|
||||
/datum/reagent/consumable/ethanol/beer/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
// Beer is a chemical composition of alcohol and various other things. It's a shitty nutrient but hey, it's still one. Also alcohol is bad, mmmkay?
|
||||
T.adjustHealth(-round(volume * 0.05))
|
||||
T.adjustNutri(round(volume * 0.25))
|
||||
T.adjustWater(round(volume * 0.7))
|
||||
return TRUE
|
||||
|
||||
//Blood
|
||||
/datum/reagent/blood/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustNutri(round(volume * 0.6))
|
||||
T.adjustHealth(-round(volume))
|
||||
T.adjustPests(rand(2,4)) //they HUNGER
|
||||
return TRUE
|
||||
|
||||
//Charcoal
|
||||
/datum/reagent/medicine/charcoal/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustToxic(-round(volume * 2)) //Antitoxin binds shit pretty well. So the tox goes significantly down
|
||||
return TRUE
|
||||
|
||||
//Chlorine
|
||||
/datum/reagent/chlorine/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustHealth(-round(volume * 1))
|
||||
T.adjustToxic(round(volume * 1.5))
|
||||
T.adjustWater(-round(volume * 0.5))
|
||||
T.adjustWeeds(-rand(1,volume * 0.125))
|
||||
return TRUE
|
||||
|
||||
//Diethylamine
|
||||
/datum/reagent/diethylamine/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
//Corrosive to pests, but not to plants
|
||||
if(..())
|
||||
T.myseed.adjust_yield(round(volume * 0.02))
|
||||
T.adjustHealth(round(volume))
|
||||
T.adjustNutri(round(volume * 2))
|
||||
T.adjustPests(-rand(1,round(volume / 30)))
|
||||
return TRUE
|
||||
|
||||
//Earthsblood
|
||||
/datum/reagent/medicine/earthsblood/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.self_sufficiency_progress += volume
|
||||
if(T.self_sufficiency_progress >= T.self_sufficiency_req)
|
||||
T.become_self_sufficient()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[T] warms as it might on a spring day under a genuine Sun.</span>")
|
||||
return TRUE
|
||||
|
||||
//Enduro-Grow
|
||||
/datum/reagent/plantnutriment/endurogrow/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
if(!..())
|
||||
return -1
|
||||
T.myseed.adjust_potency(-round(volume / 10))
|
||||
T.myseed.adjust_yield(-round(volume / 30))
|
||||
T.myseed.adjust_endurance(round(volume / 30))
|
||||
return TRUE
|
||||
|
||||
//E-Z Nutrient
|
||||
/datum/reagent/plantnutriment/eznutriment/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.yieldmod = 1
|
||||
T.mutmod = 1
|
||||
return ..()
|
||||
|
||||
//Flourine
|
||||
/datum/reagent/fluorine/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
// Fluorine one of the most corrosive and deadly gasses
|
||||
T.adjustHealth(-round(volume * 2))
|
||||
T.adjustToxic(round(volume * 2.5))
|
||||
T.adjustWater(-round(volume * 0.5))
|
||||
T.adjustWeeds(-rand(1, volume * 0.25))
|
||||
return TRUE
|
||||
|
||||
//Fluorosulfuric acid
|
||||
/datum/reagent/toxin/acid/fluacid/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustHealth(-round(volume * 2))
|
||||
T.adjustToxic(round(volume * 3))
|
||||
T.adjustWeeds(-rand(1,volume * 0.5))
|
||||
return TRUE
|
||||
|
||||
//Holy Water
|
||||
/datum/reagent/water/holywater/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
//Mostly the same as water, it also heals the plant a little with the power of the spirits~
|
||||
T.adjustWater(round(volume))
|
||||
T.adjustHealth(round(volume * 0.1))
|
||||
return TRUE
|
||||
|
||||
//Left-4-Zed
|
||||
/datum/reagent/plantnutriment/left4zednutriment/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.yieldmod = 0
|
||||
T.mutmod = 2
|
||||
return ..()
|
||||
|
||||
//Liquid Earthquake
|
||||
/datum/reagent/plantnutriment/liquidearthquake/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
if(!..())
|
||||
return -1
|
||||
T.myseed.adjust_weed_chance(round(volume / 10))
|
||||
T.myseed.adjust_weed_rate(round(volume / 30))
|
||||
T.myseed.adjust_production(-round(volume / 30))
|
||||
return TRUE
|
||||
|
||||
//Milk
|
||||
/datum/reagent/consumable/milk/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustNutri(round(volume * 0.2))
|
||||
T.adjustWater(round(volume * 0.5))
|
||||
if(..()) // Milk is good for humans, but bad for plants. The sugars canot be used by plants, and the milk fat fucks up growth.
|
||||
if(!T.myseed.get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) //Not shrooms though
|
||||
T.adjustHealth(-round(volume / 2))
|
||||
return TRUE
|
||||
|
||||
//Napalm
|
||||
/datum/reagent/napalm/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
if(..())
|
||||
if(T.myseed.resistance_flags & FIRE_PROOF)
|
||||
return TRUE
|
||||
T.adjustHealth(-round(volume * 6))
|
||||
T.adjustToxic(round(volume * 7))
|
||||
T.adjustWeeds(-rand(5,9))
|
||||
return TRUE
|
||||
|
||||
//Nutriment
|
||||
/datum/reagent/consumable/nutriment/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
//Compost, effectively
|
||||
T.adjustHealth(round(volume * 0.5))
|
||||
T.adjustNutri(round(volume))
|
||||
return TRUE
|
||||
|
||||
//Pest Killer
|
||||
/datum/reagent/toxin/pestkiller/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustToxic(round(volume * 0.5))
|
||||
T.adjustPests(-rand(1,volume / 5))
|
||||
return TRUE
|
||||
|
||||
//Phosphorus
|
||||
/datum/reagent/phosphorus/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
// White Phosphorous + water -> phosphoric acid. That's not a good thing really.
|
||||
// Phosphoric salts are beneficial though. And even if the plant suffers, in the long run the tray gets some nutrients. The benefit isn't worth that much.
|
||||
T.adjustHealth(-round(volume * 0.75))
|
||||
T.adjustNutri(round(volume * 0.1))
|
||||
T.adjustWater(-round(volume * 0.5))
|
||||
T.adjustWeeds(-rand(1, volume * 0.1))
|
||||
return TRUE
|
||||
|
||||
//Plant-B-Gone
|
||||
/datum/reagent/toxin/plantbgone/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustHealth(-round(volume * 5))
|
||||
T.adjustToxic(round(volume * 6))
|
||||
T.adjustWeeds(-rand(4,8))
|
||||
return TRUE
|
||||
|
||||
//Plant Base
|
||||
//For subtypes of /datum/reagent/plantnutriment/
|
||||
/datum/reagent/plantnutriment/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustNutri(round(volume))
|
||||
return ..()
|
||||
|
||||
//Radium
|
||||
/datum/reagent/radium/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
if(volume >= 10)
|
||||
DEFAULT_ACT_MUTAGEN
|
||||
else if(volume >= 5)
|
||||
T.hardmutate()
|
||||
else if(volume >= 2)
|
||||
T.mutate()
|
||||
|
||||
T.adjustHealth(-round(volume))
|
||||
T.adjustToxic(round(volume * 3)) // Radium is harsher (OOC: also easier to produce)
|
||||
return TRUE
|
||||
|
||||
//Robust Harvest
|
||||
/datum/reagent/plantnutriment/robustharvestnutriment/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.yieldmod = 1.3
|
||||
T.mutmod = 0
|
||||
return ..()
|
||||
|
||||
//Saltpetre
|
||||
/datum/reagent/saltpetre/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
// Saltpetre is used for gardening IRL. To simplify highly, it speeds up growth and strengthens plants
|
||||
T.adjustHealth(round(volume * 0.25))
|
||||
if (..())
|
||||
T.myseed.adjust_production(-round(volume/100)-prob(volume%100))
|
||||
T.myseed.adjust_potency(round(volume*0.5))
|
||||
return TRUE
|
||||
|
||||
//Soda Water
|
||||
/datum/reagent/consumable/sodawater/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
// A variety of nutrients are dissolved in club soda, without sugar.
|
||||
// These nutrients include carbon, oxygen, hydrogen, phosphorous, potassium, sulfur and sodium, all of which are needed for healthy plant growth.
|
||||
T.adjustWater(round(volume) * 0.9)
|
||||
T.adjustHealth(round(volume * 0.1))
|
||||
T.adjustNutri(round(volume * 0.1))
|
||||
return TRUE
|
||||
|
||||
//Sugar
|
||||
/datum/reagent/consumable/sugar/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustWeeds(round(rand(1, volume / 5)))
|
||||
T.adjustPests(round(rand(1, volume / 5)))
|
||||
return TRUE
|
||||
|
||||
//Sulphuric Acid
|
||||
/datum/reagent/toxin/acid/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustHealth(-round(volume * 1))
|
||||
T.adjustToxic(round(volume * 1.5))
|
||||
T.adjustWeeds(-rand(1,volume * 0.25))
|
||||
return TRUE
|
||||
|
||||
//Toxin
|
||||
/datum/reagent/toxin/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustToxic(round(volume * 2))
|
||||
return TRUE
|
||||
|
||||
//Unstable Mutagen
|
||||
/datum/reagent/toxin/mutagen/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
if(volume >= 5)
|
||||
DEFAULT_ACT_MUTAGEN
|
||||
else if(volume >= 2)
|
||||
T.hardmutate()
|
||||
else if(volume >= 1)
|
||||
T.mutate()
|
||||
return TRUE
|
||||
|
||||
//Uranium
|
||||
/datum/reagent/uranium/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
if(volume >= 10)
|
||||
DEFAULT_ACT_MUTAGEN
|
||||
else if(volume >= 5)
|
||||
T.hardmutate()
|
||||
else if(volume >= 2)
|
||||
T.mutate()
|
||||
|
||||
T.adjustHealth(-round(volume))
|
||||
T.adjustToxic(round(volume * 2))
|
||||
return TRUE
|
||||
|
||||
//Virus Food
|
||||
/datum/reagent/toxin/mutagen/mutagenvirusfood/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustNutri(round(volume * 0.5))
|
||||
T.adjustHealth(-round(volume * 0.5))
|
||||
return TRUE
|
||||
|
||||
//Water
|
||||
/datum/reagent/water/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustWater(round(volume))
|
||||
return TRUE
|
||||
|
||||
//Weed Killer
|
||||
/datum/reagent/toxin/plantbgone/weedkiller/on_tray(obj/machinery/hydroponics/T, volume, mob/user)
|
||||
T.adjustToxic(round(volume / 2))
|
||||
T.adjustWeeds(-rand(1,volume / 5))
|
||||
return TRUE
|
||||
|
||||
#undef DEFAULT_ACT_MUTAGEN
|
||||
@@ -0,0 +1,29 @@
|
||||
/datum/reagent/medicine/copium
|
||||
name = "copium"
|
||||
description = "A heavy scented substance meant to help one deal with loss."
|
||||
reagent_state = LIQUID
|
||||
color = "#a8707e"
|
||||
overdose_threshold = 21
|
||||
metabolization_rate = 0.75 * REAGENTS_METABOLISM
|
||||
pH = 4
|
||||
|
||||
/datum/reagent/medicine/copium/on_mob_life(mob/living/carbon/M)
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if(mood.sanity <= SANITY_NEUTRAL && current_cycle >= 5)
|
||||
mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL))
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "copium", /datum/mood_event/copium)
|
||||
..()
|
||||
|
||||
/datum/reagent/medicine/copium/overdose_process(mob/living/carbon/M) //copious amounts of copium
|
||||
M.blur_eyes(10)
|
||||
if(prob(50))
|
||||
M.adjustToxLoss(1, 0)
|
||||
if(prob(5))
|
||||
M.say(pick("That's okay. Things are going to be okay.", "This is fine.", "I'm okay with the events that are unfolding currently.", "World of Spacecraft is still a good game...", "I'm winning.", "Diesels are far more powerful."))
|
||||
if(prob(5))
|
||||
M.emote("me", 1, "seems to be crying.")
|
||||
if(prob(4))
|
||||
M.emote("me", 1, "falls over, crying.")
|
||||
M.Knockdown(40)
|
||||
|
||||
//To-do: /datum/reagent/medicine/seethium
|
||||
@@ -0,0 +1,6 @@
|
||||
/datum/chemical_reaction/copium
|
||||
name = "copium"
|
||||
id = /datum/reagent/medicine/copium
|
||||
results = list(/datum/reagent/medicine/copium = 5)
|
||||
required_reagents = list(/datum/reagent/medicine/mannitol = 2, /datum/reagent/water = 1, /datum/reagent/medicine/epinephrine = 1, /datum/reagent/consumable/sugar = 1)
|
||||
required_temp = 266
|
||||
@@ -0,0 +1,34 @@
|
||||
//This action is technically a duplicate of /action/small_sprite
|
||||
//However, we do our own things...
|
||||
|
||||
/datum/action/sizecode_resize
|
||||
name = "Toggle Giant Sprite"
|
||||
desc = "Others will continue to see you giant."
|
||||
icon_icon = 'icons/mob/screen_gen_old.dmi'
|
||||
button_icon_state = "health1" //You can change this if you want
|
||||
background_icon_state = "bg_alien" //But keep this as a distinct background
|
||||
var/small = FALSE
|
||||
var/image/small_icon
|
||||
|
||||
/datum/action/sizecode_resize/Grant(mob/M, safety=FALSE)
|
||||
if(ishuman(M) && !safety) //this probably gets called before a person gets overlays on roundstart, so try again
|
||||
if(!LAZYLEN(M.overlays))
|
||||
addtimer(CALLBACK(src,PROC_REF(Grant), M, TRUE), 5) //https://www.youtube.com/watch?v=QQ-aYZzlDeo
|
||||
return
|
||||
|
||||
..()
|
||||
if(!owner)
|
||||
return
|
||||
var/image/I = image(icon=owner.icon,icon_state=owner.icon_state,loc=owner,layer=owner.layer,pixel_x=owner.pixel_x,pixel_y=owner.pixel_y)
|
||||
I.overlays += owner.overlays
|
||||
I.override = TRUE
|
||||
small_icon = I
|
||||
|
||||
/datum/action/sizecode_resize/Trigger()
|
||||
..()
|
||||
if(!small)
|
||||
owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic, "sizecode_smallsprite", small_icon)
|
||||
else
|
||||
owner.remove_alt_appearance("sizecode_smallsprite")
|
||||
small = !small
|
||||
return TRUE
|
||||
@@ -0,0 +1,271 @@
|
||||
//I am not a coder. Please fucking tear apart my code, and insult me for how awful I am at coding. Please and thank you. -Dahlular
|
||||
//alright bet -BoxBoy
|
||||
#define RESIZE_MACRO 6
|
||||
#define RESIZE_HUGE 4
|
||||
#define RESIZE_BIG 2
|
||||
#define RESIZE_NORMAL 1
|
||||
#define RESIZE_SMALL 0.75
|
||||
#define RESIZE_TINY 0.50
|
||||
#define RESIZE_MICRO 0.25
|
||||
|
||||
//Moving these here - Jay
|
||||
/mob/living
|
||||
var/size_multiplier = 1 //multiplier for the mob's icon size atm
|
||||
var/previous_size = 1
|
||||
|
||||
//Cyanosis - Action that resizes the sprite for the client but nobody else. Say goodbye to attacking yourself when someone's above you lmao
|
||||
var/datum/action/sizecode_resize/small_sprite
|
||||
|
||||
#define MOVESPEED_ID_SIZE "SIZECODE"
|
||||
#define MOVESPEED_ID_STOMP "STEPPY"
|
||||
|
||||
//averages
|
||||
#define RESIZE_A_MACROHUGE (RESIZE_MACRO + RESIZE_HUGE) / 2
|
||||
#define RESIZE_A_HUGEBIG (RESIZE_HUGE + RESIZE_BIG) / 2
|
||||
#define RESIZE_A_BIGNORMAL (RESIZE_BIG + RESIZE_NORMAL) / 2
|
||||
#define RESIZE_A_NORMALSMALL (RESIZE_NORMAL + RESIZE_SMALL) / 2
|
||||
#define RESIZE_A_SMALLTINY (RESIZE_SMALL + RESIZE_TINY) / 2
|
||||
#define RESIZE_A_TINYMICRO (RESIZE_TINY + RESIZE_MICRO) / 2
|
||||
|
||||
//Scale up a mob's icon by the size_multiplier
|
||||
/mob/living/update_transform()
|
||||
ASSERT(!iscarbon(src)) //the source isnt carbon should always be true
|
||||
var/matrix/M = matrix() //matrix (M) variable
|
||||
M.Scale(size_multiplier)
|
||||
M.Translate(0, 16*(size_multiplier-1)) //translate by 16 * size_multiplier - 1 on Y axis
|
||||
src.transform = M //the source of transform is M
|
||||
|
||||
/mob/proc/get_effective_size()
|
||||
return 100000
|
||||
|
||||
/mob/living/get_effective_size()
|
||||
return src.size_multiplier
|
||||
|
||||
/datum/movespeed_modifier/size
|
||||
id = MOVESPEED_ID_SIZE
|
||||
|
||||
/mob/living/proc/resize(var/new_size, var/animate = TRUE)
|
||||
size_multiplier = new_size //This will be passed into update_transform() and used to change health and speed.
|
||||
if(size_multiplier == previous_size)
|
||||
return TRUE
|
||||
src.update_transform() //WORK DAMN YOU
|
||||
src.update_mobsize()
|
||||
//Going to change the health and speed values too
|
||||
src.remove_movespeed_modifier(/datum/movespeed_modifier/size)
|
||||
src.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/size, multiplicative_slowdown = (abs(size_multiplier - 1) * 0.3 )) //GS Change, reduces speed penalties for size from *.4 to *.3
|
||||
var/healthmod_old = ((previous_size * 35) - 75) //Get the old value to see what we must change.
|
||||
var/healthmod_new = ((size_multiplier * 35) - 75) //A size of one would be zero. Big boys get health, small ones lose health. //GS Change, reduces health penalties/buffs for size from *75 to *35
|
||||
var/healthchange = healthmod_new - healthmod_old //Get ready to apply the new value, and subtract the old one. (Negative values become positive)
|
||||
src.maxHealth += healthchange
|
||||
src.health += healthchange
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
for(var/obj/item/organ/genital/G in C.internal_organs)
|
||||
G.update_appearance()
|
||||
//if(src.size_multiplier >= RESIZE_A_HUGEBIG || src.size_multiplier <= RESIZE_A_TINYMICRO) Will remove clothing when too big or small. Will do later.
|
||||
previous_size = size_multiplier //And, change this now that we are finally done.
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOBSIZE_CHANGED, src) //This SHOULD allow other shit to check when a mob changes size -Capn
|
||||
|
||||
//Now check if the mob can get the size action
|
||||
if(!small_sprite)
|
||||
small_sprite = new(src)
|
||||
small_sprite.Remove(src)
|
||||
if(size_multiplier >= 1.25) //Anything bigger will start to block things
|
||||
small_sprite.Grant(src)
|
||||
|
||||
//handle the big steppy, except nice
|
||||
/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob)
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
|
||||
if(tmob.pulledby == H)
|
||||
return FALSE
|
||||
|
||||
//Micro is on a table.
|
||||
var/turf/steppyspot = tmob.loc
|
||||
for(var/thing in steppyspot.contents)
|
||||
if(istype(thing, /obj/structure/table))
|
||||
return TRUE
|
||||
|
||||
//Both small.
|
||||
if(H.get_effective_size() <= RESIZE_A_TINYMICRO && tmob.get_effective_size() <= RESIZE_A_TINYMICRO)
|
||||
now_pushing = 0
|
||||
H.forceMove(tmob.loc)
|
||||
return TRUE
|
||||
|
||||
//Doing messages
|
||||
if(abs(get_effective_size()/tmob.get_effective_size()) >= 2) //if the initiator is twice the size of the micro
|
||||
now_pushing = 0
|
||||
H.forceMove(tmob.loc)
|
||||
|
||||
//Smaller person being stepped on
|
||||
if(get_effective_size() > tmob.get_effective_size() && iscarbon(src))
|
||||
// GS13: Import Fat Naga & Alt Naga from VoreStation
|
||||
if(istype(H) && H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle" || H.dna.features["taur"] == "Fat Naga" || H.dna.features["taur"] == "Alt Naga")
|
||||
tmob.visible_message("<span class='notice'>[src] carefully slithers around [tmob].</span>", "<span class='notice'>[src]'s huge tail slithers besides you.</span>")
|
||||
else
|
||||
tmob.visible_message("<span class='notice'>[src] carefully steps over [tmob].</span>", "<span class='notice'>[src] steps over you carefully.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
//Smaller person stepping under a larger person
|
||||
if(abs(tmob.get_effective_size()/get_effective_size()) >= 2)
|
||||
H.forceMove(tmob.loc)
|
||||
now_pushing = 0
|
||||
micro_step_under(tmob)
|
||||
return TRUE
|
||||
|
||||
//Stepping on disarm intent -- TO DO, OPTIMIZE ALL OF THIS SHIT
|
||||
/mob/living/proc/handle_micro_bump_other(var/mob/living/tmob)
|
||||
ASSERT(isliving(tmob))
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
|
||||
if(tmob.pulledby == H)
|
||||
return FALSE
|
||||
|
||||
//If on a table, don't
|
||||
var/turf/steppyspot = tmob.loc
|
||||
for(var/thing in steppyspot.contents)
|
||||
if(istype(thing, /obj/structure/table))
|
||||
return TRUE
|
||||
|
||||
//Both small
|
||||
if(H.get_effective_size() <= RESIZE_A_TINYMICRO && tmob.get_effective_size() <= RESIZE_A_TINYMICRO)
|
||||
now_pushing = 0
|
||||
H.forceMove(tmob.loc)
|
||||
return TRUE
|
||||
|
||||
if(abs(get_effective_size()/tmob.get_effective_size()) >= 2)
|
||||
if(H.a_intent == "disarm" && H.canmove && !H.buckled)
|
||||
now_pushing = 0
|
||||
H.forceMove(tmob.loc)
|
||||
sizediffStamLoss(tmob)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_STOMP, multiplicative_slowdown = 10) //Full stop
|
||||
addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/, remove_movespeed_modifier), MOVESPEED_ID_STOMP), 3) //0.3 seconds
|
||||
if(get_effective_size() > tmob.get_effective_size() && iscarbon(H))
|
||||
if(istype(H) && H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle" || H.dna.features["taur"] == "Fat Naga" || H.dna.features["taur"] == "Alt Naga")
|
||||
tmob.visible_message("<span class='danger'>[src] carefully rolls their tail over [tmob]!</span>", "<span class='danger'>[src]'s huge tail rolls over you!</span>")
|
||||
else
|
||||
tmob.visible_message("<span class='danger'>[src] carefully steps on [tmob]!</span>", "<span class='danger'>[src] steps onto you with force!</span>")
|
||||
|
||||
//horny traits
|
||||
/*
|
||||
if(HAS_TRAIT(src, TRAIT_MICROPHILE))
|
||||
src.adjust_arousal(8)
|
||||
if (src.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
src.mob_climax(forced_climax=TRUE)
|
||||
|
||||
if(HAS_TRAIT(tmob, TRAIT_MACROPHILE))
|
||||
tmob.adjust_arousal(10)
|
||||
if (tmob.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
tmob.mob_climax(forced_climax=TRUE)
|
||||
|
||||
return TRUE
|
||||
* commenting out for now.*/
|
||||
|
||||
if(H.a_intent == "harm" && H.canmove && !H.buckled)
|
||||
now_pushing = 0
|
||||
H.forceMove(tmob.loc)
|
||||
sizediffStamLoss(tmob)
|
||||
sizediffBruteloss(tmob)
|
||||
playsound(loc, 'sound/misc/splort.ogg', 50, 1)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_STOMP, multiplicative_slowdown = 10)
|
||||
addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/, remove_movespeed_modifier), MOVESPEED_ID_STOMP), 10) //1 second
|
||||
//H.Stun(20)
|
||||
if(get_effective_size() > tmob.get_effective_size() && iscarbon(H))
|
||||
if(istype(H) && H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle" || H.dna.features["taur"] == "Fat Naga" || H.dna.features["taur"] == "Alt Naga")
|
||||
tmob.visible_message("<span class='danger'>[src] mows down [tmob] under their tail!</span>", "<span class='userdanger'>[src] plows their tail over you mercilessly!</span>")
|
||||
else
|
||||
tmob.visible_message("<span class='danger'>[src] slams their foot down on [tmob], crushing them!</span>", "<span class='userdanger'>[src] crushes you under their foot!</span>")
|
||||
|
||||
//horny traits
|
||||
/*
|
||||
if(HAS_TRAIT(src, TRAIT_MICROPHILE))
|
||||
src.adjust_arousal((get_effective_size()/tmob.get_effective_size()*3))
|
||||
if (src.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
src.mob_climax(forced_climax=TRUE)
|
||||
|
||||
if(HAS_TRAIT(tmob, TRAIT_MACROPHILE))
|
||||
tmob.adjust_arousal((get_effective_size()/tmob.get_effective_size()*3))
|
||||
if (tmob.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
tmob.mob_climax(forced_climax=TRUE)
|
||||
|
||||
commenting out for now */
|
||||
return TRUE
|
||||
|
||||
// if(H.a_intent == "grab" && H.canmove && !H.buckled)
|
||||
// now_pushing = 0
|
||||
// H.forceMove(tmob.loc)
|
||||
// sizediffStamLoss(tmob)
|
||||
// sizediffStun(tmob)
|
||||
// H.add_movespeed_modifier(MOVESPEED_ID_STOMP, multiplicative_slowdown = 10)
|
||||
// addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/, remove_movespeed_modifier), MOVESPEED_ID_STOMP), 7)//About 3/4th a second
|
||||
// if(get_effective_size() > tmob.get_effective_size() && iscarbon(H))
|
||||
// var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET)))
|
||||
// if(feetCover)
|
||||
// if(istype(H) && H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle" || H.dna.features["taur"] == "Fat Naga" || H.dna.features["taur"] == "Alt Naga")
|
||||
// tmob.visible_message("<span class='danger'>[src] pins [tmob] under their tail!</span>", "<span class='danger'>[src] pins you beneath their tail!</span>")
|
||||
// else
|
||||
// tmob.visible_message("<span class='danger'>[src] pins [tmob] helplessly underfoot!</span>", "<span class='danger'>[src] pins you underfoot!</span>")
|
||||
// return TRUE
|
||||
// else
|
||||
// if(istype(H) && H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle" || H.dna.features["taur"] == "Fat Naga" || H.dna.features["taur"] == "Alt Naga")
|
||||
// tmob.visible_message("<span class='danger'>[src] snatches up [tmob] underneath their tail!</span>", "<span class='userdanger'>[src]'s tail winds around you and snatches you in its coils!</span>")
|
||||
// //tmob.mob_pickup_micro_feet(H)
|
||||
// SEND_SIGNAL(tmob, COMSIG_MICRO_PICKUP_FEET, H)
|
||||
// else
|
||||
// tmob.visible_message("<span class='danger'>[src] stomps down on [tmob], curling their toes and picking them up!</span>", "<span class='userdanger'>[src]'s toes pin you down and curl around you, picking you up!</span>")
|
||||
// //tmob.mob_pickup_micro_feet(H)
|
||||
// SEND_SIGNAL(tmob, COMSIG_MICRO_PICKUP_FEET, H)
|
||||
// return TRUE
|
||||
|
||||
if(abs(tmob.get_effective_size()/get_effective_size()) >= 2)
|
||||
H.forceMove(tmob.loc)
|
||||
now_pushing = 0
|
||||
micro_step_under(tmob)
|
||||
return TRUE
|
||||
|
||||
//smaller person stepping under another person... TO DO, fix and allow special interactions with naga legs to be seen
|
||||
/mob/living/proc/micro_step_under(var/mob/living/tmob)
|
||||
if(istype(tmob) && istype(tmob, /datum/sprite_accessory/taur/naga))
|
||||
src.visible_message("<span class='notice'>[src] bounds over [tmob]'s tail.</span>", "<span class='notice'>You jump over [tmob]'s thick tail.</span>")
|
||||
else
|
||||
src.visible_message("<span class='notice'>[src] runs between [tmob]'s legs.</span>", "<span class='notice'>You run between [tmob]'s legs.</span>")
|
||||
|
||||
//Proc for scaling stamina damage on size difference
|
||||
/mob/living/proc/sizediffStamLoss(var/mob/living/tmob)
|
||||
var/S = (get_effective_size()/tmob.get_effective_size()*25) //macro divided by micro, times 25
|
||||
tmob.Knockdown(S) //final result in stamina knockdown
|
||||
|
||||
//Proc for scaling stuns on size difference (for grab intent)
|
||||
/mob/living/proc/sizediffStun(var/mob/living/tmob)
|
||||
var/T = (get_effective_size()/tmob.get_effective_size()*2) //Macro divided by micro, times 2
|
||||
tmob.Stun(T)
|
||||
|
||||
//Proc for scaling brute damage on size difference
|
||||
/mob/living/proc/sizediffBruteloss(var/mob/living/tmob)
|
||||
var/B = (get_effective_size()/tmob.get_effective_size()*2) //macro divided by micro, times 3 //GS change, *2
|
||||
tmob.adjustBruteLoss(B) //final result in brute loss
|
||||
|
||||
//Proc for changing mob_size to be grabbed for item weight classes
|
||||
/mob/living/proc/update_mobsize(var/mob/living/tmob)
|
||||
if(size_multiplier <= 0.50)
|
||||
mob_size = 0
|
||||
else if(size_multiplier < 1)
|
||||
mob_size = 1
|
||||
else if(size_multiplier <= 2)
|
||||
mob_size = 2 //the default human size
|
||||
else if(size_multiplier > 2)
|
||||
mob_size = 3
|
||||
|
||||
//Proc for instantly grabbing valid size difference. Code optimizations soon(TM)
|
||||
/*
|
||||
/mob/living/proc/sizeinteractioncheck(var/mob/living/tmob)
|
||||
if(abs(get_effective_size()/tmob.get_effective_size())>=2.0 && get_effective_size()>tmob.get_effective_size())
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
*/
|
||||
//Clothes coming off at different sizes, and health/speed/stam changes as well
|
||||
@@ -0,0 +1,134 @@
|
||||
//Size Chemicals, now with better and less cringy names.
|
||||
//TO DO: USE BETTER FERMICHEM TO MAKE ALL OF THESE CHEMICALS MORE INTERACTIVE
|
||||
|
||||
//Sizechem reagent
|
||||
/datum/reagent/sizechem
|
||||
name = "Cell-Volume Altering Base"
|
||||
description = "A stabilized compound liquid, used as a basis for increasing or decreasing the size of living matter with more recipes."
|
||||
color = "#C900CC"
|
||||
taste_description = "regret"
|
||||
can_synth = FALSE
|
||||
metabolization_rate = 0.25
|
||||
|
||||
//Sizechem reaction
|
||||
/datum/chemical_reaction/sizechem
|
||||
name = "Cell-Volume Altering Base"
|
||||
id = /datum/reagent/sizechem
|
||||
mix_message = "the reaction rapidly alters in size!"
|
||||
required_reagents = list(/datum/reagent/growthserum = 0.15, /datum/reagent/medicine/clonexadone = 0.15, /datum/reagent/gold = 0.15, /datum/reagent/acetone = 0.15)
|
||||
results = list(/datum/reagent/sizechem = 0.3)
|
||||
required_temp = 1
|
||||
//Fermichem vars
|
||||
OptimalTempMin = 600 // Lower area of bell curve for determining heat based rate reactions
|
||||
OptimalTempMax = 630 // Upper end for above
|
||||
ExplodeTemp = 635 // Temperature at which reaction explodes
|
||||
OptimalpHMin = 5 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
|
||||
OptimalpHMax = 5.5 // Higest value for above
|
||||
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
|
||||
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
|
||||
CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
|
||||
CurveSharppH = 4 // How sharp the pH exponential curve is (to the power of value)
|
||||
ThermicConstant = -10 // Temperature change per 1u produced
|
||||
HIonRelease = 0.02 // pH change per 1u reaction (inverse for some reason)
|
||||
RateUpLim = 1 // Optimal/max rate possible if all conditions are perfect
|
||||
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
|
||||
FermiExplode = FALSE // If the chemical explodes in a special way
|
||||
PurityMin = 0.2
|
||||
|
||||
//Growthchem reagent
|
||||
/datum/reagent/growthchem
|
||||
name = "Prospacillin"
|
||||
description = "A stabilized altercation of size-altering liquids, this one appears to increase cell volume."
|
||||
color = "#E70C0C"
|
||||
taste_description = "a sharp, fiery and intoxicating flavour"
|
||||
overdose_threshold = 10
|
||||
metabolization_rate = 0.25
|
||||
can_synth = FALSE //DO NOT MAKE THIS SNYTHESIZABLE, THESE CHEMS ARE SUPPOSED TO NOT BE USED COMMONLY
|
||||
|
||||
//Growthchem reaction
|
||||
/datum/chemical_reaction/growthchem
|
||||
name = "Prospacillin"
|
||||
id = /datum/reagent/growthchem
|
||||
mix_message = "the reaction appears to grow!"
|
||||
required_reagents = list(/datum/reagent/sizechem = 0.15, /datum/reagent/consumable/condensedcapsaicin = 0.15, /datum/reagent/drug/aphrodisiac = 0.30)
|
||||
results = list(/datum/reagent/growthchem = 0.25)
|
||||
required_temp = 1
|
||||
OptimalTempMin = 700 // Lower area of bell curve for determining heat based rate reactions
|
||||
OptimalTempMax = 730 // Upper end for above
|
||||
ExplodeTemp = 735 // Temperature at which reaction explodes
|
||||
OptimalpHMin = 3 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
|
||||
OptimalpHMax = 3.5 // Higest value for above
|
||||
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
|
||||
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
|
||||
CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
|
||||
CurveSharppH = 4 // How sharp the pH exponential curve is (to the power of value)
|
||||
ThermicConstant = -10 // Temperature change per 1u produced
|
||||
HIonRelease = 0.02 // pH change per 1u reaction (inverse for some reason)
|
||||
RateUpLim = 1 // Optimal/max rate possible if all conditions are perfect
|
||||
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
|
||||
FermiExplode = FALSE // If the chemical explodes in a special way
|
||||
PurityMin = 0.2
|
||||
|
||||
//Growthchem effects
|
||||
/datum/reagent/growthchem/on_mob_add(mob/living/carbon/M)
|
||||
. = ..()
|
||||
if(ishuman(M))
|
||||
log_game("SIZECODE: [M] ckey: [M.key] has ingested growthchem.")
|
||||
|
||||
/datum/reagent/growthchem/on_mob_life(mob/living/carbon/M)
|
||||
if(!ishuman(M))
|
||||
return..()
|
||||
if(M.size_multiplier < RESIZE_MACRO)
|
||||
M.resize(M.size_multiplier+0.025)
|
||||
M.visible_message("<span class='danger'>[pick("[M] grows!", "[M] expands in size!", "[M] pushes outwards in stature!")]</span>", "<span class='danger'>[pick("You feel your body fighting for space and growing!", "The world contracts inwards in every direction!", "You feel your muscles expand, and your surroundings shrink!")]</span>")
|
||||
..()
|
||||
. = 1
|
||||
|
||||
//Shrinkchem reagent
|
||||
/datum/reagent/shrinkchem
|
||||
name = "Diminicillin"
|
||||
description = "A stabilized altercation of size-altering liquids, this one appears to decrease cell volume."
|
||||
color = "#0C26E7"
|
||||
taste_description = "a pungent, acidic and jittery flavour"
|
||||
overdose_threshold = 10
|
||||
metabolization_rate = 0.50
|
||||
can_synth = FALSE //SAME STORY AS ABOVE
|
||||
|
||||
//Shrinchem reaction
|
||||
/datum/chemical_reaction/shrinkchem
|
||||
name = "Diminicillin"
|
||||
id = /datum/reagent/shrinkchem
|
||||
mix_message = "the reaction appears to shrink!"
|
||||
required_reagents = list(/datum/reagent/sizechem = 0.15, /datum/reagent/consumable/frostoil = 0.15, /datum/reagent/drug/aphrodisiac = 0.30)
|
||||
results = list(/datum/reagent/shrinkchem = 0.25)
|
||||
required_temp = 1
|
||||
OptimalTempMin = 100 // Lower area of bell curve for determining heat based rate reactions
|
||||
OptimalTempMax = 150 // Upper end for above
|
||||
ExplodeTemp = 350 // Temperature at which reaction explodes
|
||||
OptimalpHMin = 3 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
|
||||
OptimalpHMax = 4.5 // Higest value for above
|
||||
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
|
||||
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
|
||||
CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
|
||||
CurveSharppH = 4 // How sharp the pH exponential curve is (to the power of value)
|
||||
ThermicConstant = -10 // Temperature change per 1u produced
|
||||
HIonRelease = 0.02 // pH change per 1u reaction (inverse for some reason)
|
||||
RateUpLim = 1 // Optimal/max rate possible if all conditions are perfect
|
||||
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
|
||||
FermiExplode = FALSE // If the chemical explodes in a special way
|
||||
PurityMin = 0.2
|
||||
|
||||
//Shrinkchem effects
|
||||
/datum/reagent/shrinkchem/on_mob_add(mob/living/carbon/M)
|
||||
. = ..()
|
||||
if(ishuman(M))
|
||||
log_game("SIZECODE: [M] ckey: [M.key] has ingested shrinkchem.")
|
||||
|
||||
/datum/reagent/shrinkchem/on_mob_life(mob/living/carbon/M)
|
||||
if(!ishuman(M))
|
||||
return..()
|
||||
if(M.size_multiplier > RESIZE_MICRO)
|
||||
M.resize(M.size_multiplier-0.025)
|
||||
M.visible_message("<span class='danger'>[pick("[M] shrinks down!", "[M] dwindles in size!", "[M] compresses down!")]</span>", "<span class='danger'>[pick("You feel your body compressing in size!", "The world pushes outwards in every direction!", "You feel your muscles contract, and your surroundings grow!")]</span>")
|
||||
..()
|
||||
. = 1
|
||||
@@ -0,0 +1,88 @@
|
||||
/obj/item/projectile/sizelaser
|
||||
name = "sizeray laser"
|
||||
icon_state = "omnilaser"
|
||||
hitsound = null
|
||||
damage = 5
|
||||
damage_type = STAMINA
|
||||
flag = "laser"
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
|
||||
//TO DO: make the size ray have a selection of a minimum size and maximum size, rather than two modes.
|
||||
/obj/item/projectile/sizelaser/shrinkray
|
||||
icon_state="bluelaser"
|
||||
|
||||
/obj/item/projectile/sizelaser/growthray
|
||||
icon_state="laser"
|
||||
|
||||
/obj/item/projectile/sizelaser/shrinkray/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/M = target
|
||||
switch(M.size_multiplier)
|
||||
if(RESIZE_MACRO to INFINITY)
|
||||
M.resize(RESIZE_HUGE)
|
||||
if(RESIZE_HUGE to RESIZE_MACRO)
|
||||
M.resize(RESIZE_BIG)
|
||||
if(RESIZE_BIG to RESIZE_HUGE)
|
||||
M.resize(RESIZE_NORMAL)
|
||||
if(RESIZE_NORMAL to RESIZE_BIG)
|
||||
M.resize(RESIZE_SMALL)
|
||||
if(RESIZE_SMALL to RESIZE_NORMAL)
|
||||
M.resize(RESIZE_TINY)
|
||||
if(RESIZE_TINY to RESIZE_SMALL)
|
||||
M.resize(RESIZE_MICRO)
|
||||
if((0 - INFINITY) to RESIZE_NORMAL)
|
||||
M.resize(RESIZE_MICRO)
|
||||
M.update_transform()
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/sizelaser/growthray/on_hit(var/atom/target, var/blocked = 0 )
|
||||
if(istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/M = target
|
||||
switch(M.size_multiplier)
|
||||
if(RESIZE_HUGE to RESIZE_MACRO)
|
||||
M.resize(RESIZE_MACRO)
|
||||
if(RESIZE_BIG to RESIZE_HUGE)
|
||||
M.resize(RESIZE_HUGE)
|
||||
if(RESIZE_NORMAL to RESIZE_BIG)
|
||||
M.resize(RESIZE_BIG)
|
||||
if(RESIZE_SMALL to RESIZE_NORMAL)
|
||||
M.resize(RESIZE_NORMAL)
|
||||
if(RESIZE_TINY to RESIZE_SMALL)
|
||||
M.resize(RESIZE_SMALL)
|
||||
if(RESIZE_MICRO to RESIZE_TINY)
|
||||
M.resize(RESIZE_TINY)
|
||||
if((0 - INFINITY) to RESIZE_MICRO)
|
||||
M.resize(RESIZE_MICRO)
|
||||
M.update_transform()
|
||||
return TRUE
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/growthray
|
||||
projectile_type = /obj/item/projectile/sizelaser/growthray
|
||||
select_name = "Growth"
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/shrinkray
|
||||
projectile_type = /obj/item/projectile/sizelaser/shrinkray
|
||||
select_name = "Shrink"
|
||||
|
||||
//Gun
|
||||
/obj/item/gun/energy/laser/sizeray
|
||||
name = "size ray"
|
||||
icon = 'icons/obj/guns/energy.dmi'
|
||||
icon_state = "sizeshrink"
|
||||
desc = "An extremely-dangerous, almost-illegal size-altering device. You've either stolen this, or have the permits for it."
|
||||
item_state = null
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/shrinkray, /obj/item/ammo_casing/energy/laser/growthray)
|
||||
selfcharge = EGUN_SELFCHARGE
|
||||
charge_delay = 5
|
||||
ammo_x_offset = 2
|
||||
clumsy_check = 1
|
||||
|
||||
attackby(obj/item/W, mob/user)
|
||||
if(W==src)
|
||||
if(icon_state=="sizeshrink")
|
||||
icon_state="sizegrow"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/growthray)
|
||||
else
|
||||
icon_state="sizeshrink"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/shrinkray)
|
||||
return ..()
|
||||
@@ -0,0 +1,25 @@
|
||||
/obj/item/organ/cyberimp/arm/mblade
|
||||
name = "arm-mounted scytheblade"
|
||||
desc = "An extremely dangerous implant which can be used in a variety of ways. Mostly killing."
|
||||
contents = newlist(/obj/item/melee/mblade)
|
||||
|
||||
/obj/item/organ/cyberimp/arm/mblade/l
|
||||
zone = BODY_ZONE_L_ARM
|
||||
|
||||
/obj/item/melee/mblade
|
||||
name = "mounted scytheblade"
|
||||
desc = "An extremely dangerous implant which can be used in a variety of ways. Mostly killing."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "mblade"
|
||||
item_state = "mblade"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
force = 45
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
throwforce = 45
|
||||
block_chance = 70
|
||||
armour_penetration = 80
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
attack_verb = list("slashed", "cut")
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
//Jay Sparrow
|
||||
/datum/quirk/cum_plus
|
||||
name = "Extra productive genitals"
|
||||
desc = "Your lower bits produce more and hold more than normal."
|
||||
value = 0
|
||||
category = CATEGORY_SEXUAL
|
||||
mob_trait = TRAIT_CUM_PLUS
|
||||
gain_text = "<span class='notice'>You feel pressure in your groin.</span>"
|
||||
lose_text = "<span class='notice'>You feel a weight lifted from your groin.</span>"
|
||||
medical_record_text = "Patient has greatly increased production of sexual fluids"
|
||||
|
||||
/datum/quirk/cum_plus/add()
|
||||
var/mob/living/carbon/M = quirk_holder
|
||||
if(M?.getorganslot("testicles"))
|
||||
var/obj/item/organ/genital/testicles/T = M?.getorganslot("testicles")
|
||||
T?.fluid_mult = 1.5 //Base is 1
|
||||
T?.fluid_max_volume = 5
|
||||
|
||||
/datum/quirk/cum_plus/remove()
|
||||
var/mob/living/carbon/M = quirk_holder
|
||||
if(quirk_holder.getorganslot("testicles"))
|
||||
var/obj/item/organ/genital/testicles/T = M?.getorganslot("testicles")
|
||||
T?.fluid_mult = 1 //Base is 1
|
||||
T?.fluid_max_volume = 3 //Base is 3
|
||||
|
||||
/datum/quirk/cum_plus/on_process()
|
||||
var/mob/living/carbon/M = quirk_holder //If you get balls later, then this will still proc
|
||||
if(M.getorganslot("testicles"))
|
||||
var/obj/item/organ/genital/testicles/T = M?.getorganslot("testicles")
|
||||
if(T?.fluid_max_volume <= 5 || T?.fluid_mult <= 0.2) //INVALID EXPRESSION?
|
||||
T?.fluid_mult = 1.5 //Base is 0.133
|
||||
T?.fluid_max_volume = 5
|
||||
@@ -0,0 +1,8 @@
|
||||
/datum/uplink_item/device_tools/tc_rod
|
||||
name = "Telecrystal Fuel Rod"
|
||||
desc = "This special fuel rod has eight material slots that can be inserted with telecrystals, \
|
||||
once the rod has been fully depleted, you will be able to harvest the extra telecrystals. \
|
||||
Please note: This Rod fissiles much faster than it's regular counterpart, it doesn't take \
|
||||
much to overload the reactor with these..."
|
||||
item = /obj/item/twohanded/required/fuel_rod/material/telecrystal
|
||||
cost = 7
|
||||
Reference in New Issue
Block a user