MultiZ Layenia Base

This commit is contained in:
Dahlular
2022-09-04 10:32:31 -06:00
parent ec54fb9c05
commit f45b4bfb4c
187 changed files with 260225 additions and 124296 deletions
+11
View File
@@ -0,0 +1,11 @@
///////////////
// PTO Types //
///////////////
#define PTO_COMMAND "Command"
#define PTO_SECURITY "Security"
#define PTO_MEDICAL "Medical"
#define PTO_ENGINEERING "Engineering"
#define PTO_SCIENCE "Science"
#define PTO_CARGO "Cargo"
#define PTO_CIVILIAN "Civilian"
#define PTO_CYBORG "Silicon"
@@ -0,0 +1,11 @@
/// Toggles time off for jobs
/datum/config_entry/flag/time_off
/// Toggles changing jobs with PTO
/datum/config_entry/flag/pto_job_change
/// PTO hour cap
/datum/config_entry/number/pto_cap
config_entry_value = 100 /// Total hours
min_val = 0 /// Minimum hourly value
integer = FALSE /// We can be a float for partial hours
@@ -0,0 +1,18 @@
/**
* Some modifications to the jobs subsystem, courtesy of SandPoot.
* If we pull from upstream we should have this somewhere at some point, so it's shoehorned
* in here for the moment.
* Insert unhelpful comment here.
*/
/datum/controller/subsystem/job/proc/get_job_name(job_name)
if (!job_name)
return "Unknown" // Invalid job
//var/all_alt_titles = get_all_alt_titles()
//if (job_name in all_alt_titles) // Check if the name is an alt title
//return get_job_name(all_alt_titles[job_name]) // Locate the original job title and return it
if (job_name in get_all_job_icons()) // Check if the job has a HUD icon
return job_name
if (job_name in get_all_centcom_jobs()) // Return the NT logo if it is a CentCom job
return "CentCom"
return "Unknown" // Return unknown if none of the above apply
@@ -0,0 +1,467 @@
/area/barber
name = "Barber's Shop"
icon_state = "barber"
/area/kinarisrep
name = "Kinaris Representative Office"
/area/crew_quarters/bar/cafe
name = "Cafe"
icon_state = "cafe"
/area/crew_quarters/bar/cafe/backroom
name = "Cafe Backroom"
icon_state = "bar"
/area/crew_quarters/bar/cafe/storage
name = "Cafe Storage"
icon_state = "bar"
/area/artatrium
name = "Art Atrium"
icon_state = "library"
/area/crew_quarters/spa
name = "Spa"
icon_state = "sauna"
/area/crew_quarters/spa/sauna
name = "Sauna"
/area/security/lambent
name = "Lambent's Quarters"
icon_state = "detective"
//In hindsight a lot of how this set up was stupid and I should probably redo it -Dahl
//Upper Hallways
/area/hallway/primary/aft/upper
name = "Upper Aft Primary Hallway"
icon_state = "hallA"
/area/hallway/primary/fore/upper
name = "Upper Fore Primary Hallway"
icon_state = "hallF"
/area/hallway/primary/starboard/upper
name = "Upper Starboard Primary Hallway"
icon_state = "hallS"
/area/hallway/primary/starboard/aft/upper
name = "Upper Starboard Quarter Primary Hallway"
icon_state = "hallAS"
/area/hallway/primary/starboard/fore/upper
name = "Upper Starboard Bow Primary Hallway"
icon_state = "hallFS"
/area/hallway/primary/port/upper
name = "Upper Port Primary Hallway"
icon_state = "hallP"
/area/hallway/primary/port/aft/upper
name = "Upper Port Quarter Primary Hallway"
icon_state = "hallAP"
/area/hallway/primary/port/fore/upper
name = "Upper Port Bow Primary Hallway"
icon_state = "hallFP"
/area/hallway/primary/central/upper
name = "Upper Central Primary Hallway"
icon_state = "hallC"
/area/hallway/secondary/command/upper
name = "Upper Command Hallway"
icon_state = "bridge_hallway"
/area/hallway/secondary/construction/upper
name = "Upper Construction Area"
icon_state = "construction"
/area/hallway/secondary/exit/upper
name = "Upper Escape Shuttle Hallway"
icon_state = "escape"
/area/hallway/secondary/exit/departure_lounge/upper
name = "Upper Departure Lounge"
icon_state = "escape_lounge"
/area/hallway/secondary/entry/upper
name = "Upper Arrival Shuttle Hallway"
icon_state = "entry"
/area/hallway/secondary/service/upper
name = "Upper Service Hallway"
icon_state = "hall_service"
//Upper Dorms
/area/crew_quarters/dorms/upper
name = "Upper Dormitories"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/toilet/upper
name = "Upper Dormitory Toilets"
icon_state = "toilet"
/area/crew_quarters/locker/upper
name = "Upper Locker Room"
icon_state = "locker"
//Upper Medbay
/area/medical/medbay/upper
name = "Upper Medbay"
icon_state = "medbay"
music = 'sound/ambience/signal.ogg'
//Upper Maints
//Departments
/area/maintenance/department/chapel/upper
name = "Upper Chapel Maintenance"
icon_state = "maint_chapel"
/area/maintenance/department/chapel/monastery/upper
name = "Upper Monastery Maintenance"
icon_state = "maint_monastery"
/area/maintenance/department/crew_quarters/bar/upper
name = "Upper Bar Maintenance"
icon_state = "maint_bar"
/area/maintenance/department/crew_quarters/dorms/upper
name = "Upper Dormitory Maintenance"
icon_state = "maint_dorms"
/area/maintenance/department/crew_quarters/locker/upper
name = "Upper Locker Room Maintenance"
icon_state = "maint_locker"
/area/maintenance/department/eva/upper
name = "Upper EVA Maintenance"
icon_state = "maint_eva"
/area/maintenance/department/electrical/upper
name = "Upper Electrical Maintenance"
icon_state = "maint_electrical"
/area/maintenance/department/engine/atmos/upper
name = "Upper Atmospherics Maintenance"
icon_state = "maint_atmos"
/area/maintenance/department/security/upper
name = "Upper Security Maintenance"
icon_state = "maint_sec"
/area/maintenance/department/security/brig/upper
name = "Upper Brig Maintenance"
icon_state = "maint_brig"
/area/maintenance/department/medical/upper
name = "Upper Medbay Maintenance"
icon_state = "medbay_maint"
/area/maintenance/department/medical/morgue/upper
name = "Upper Morgue Maintenance"
icon_state = "morgue_maint"
/area/maintenance/department/science/upper
name = "Upper Science Maintenance"
icon_state = "maint_sci"
/area/maintenance/department/cargo/upper
name = "Upper Cargo Maintenance"
icon_state = "maint_cargo"
/area/maintenance/department/bridge/upper
name = "Upper Bridge Maintenance"
icon_state = "maint_bridge"
/area/maintenance/department/engine/upper
name = "Upper Engineering Maintenance"
icon_state = "maint_engi"
/area/maintenance/department/science/xenobiology/upper
name = "Upper Xenobiology Maintenance"
icon_state = "xenomaint"
xenobiology_compatible = TRUE
//Generic
/area/maintenance/arrivals/north/upper
name = "Upper Arrivals North Maintenance"
icon_state = "fpmaint"
/area/maintenance/arrivals/north_2/upper
name = "Upper Arrivals North Maintenance"
icon_state = "fpmaint"
/area/maintenance/aft/upper
name = "Upper Aft Maintenance"
icon_state = "amaint"
/area/maintenance/aft/secondary/upper
name = "Upper Aft Maintenance"
icon_state = "amaint_2"
/area/maintenance/central/upper
name = "Upper Central Maintenance"
icon_state = "maintcentral"
/area/maintenance/central/secondary/upper
name = "Upper Central Maintenance"
icon_state = "maintcentral"
/area/maintenance/fore/upper
name = "Upper Fore Maintenance"
icon_state = "fmaint"
/area/maintenance/fore/secondary/upper
name = "Upper Fore Maintenance"
icon_state = "fmaint_2"
/area/maintenance/starboard/upper
name = "Upper Starboard Maintenance"
icon_state = "smaint"
/area/maintenance/starboard/central/upper
name = "Upper Central Starboard Maintenance"
icon_state = "smaint"
/area/maintenance/starboard/aft/upper
name = "Upper Starboard Quarter Maintenance"
icon_state = "asmaint"
/area/maintenance/starboard/fore/upper
name = "Upper Starboard Bow Maintenance"
icon_state = "fsmaint"
/area/maintenance/port/upper
name = "Upper Port Maintenance"
icon_state = "pmaint"
/area/maintenance/port/central/upper
name = "Upper Central Port Maintenance"
icon_state = "maintcentral"
/area/maintenance/port/aft/upper
name = "Upper Port Quarter Maintenance"
icon_state = "apmaint"
/area/maintenance/port/fore/upper
name = "Upper Port Bow Maintenance"
icon_state = "fpmaint"
/area/maintenance/disposal/upper
name = "Upper Waste Disposal"
icon_state = "disposal"
/area/maintenance/disposal/incinerator/upper
name = "Upper Incinerator"
icon_state = "disposal"
//Misc Maint
/area/maintenance/theatre
name = "Theatre Maintenance"
icon_state = "maintcentral"
/area/maintenance/theatre/upper
name = "Upper Theatre Maintenance"
icon_state = "maintcentral"
//Solar Maint
/area/maintenance/solars/upper
name = "Upper Solar Maintenance"
icon_state = "yellow"
/area/maintenance/solars/port/upper
name = "Upper Port Solar Maintenance"
icon_state = "SolarcontrolP"
/area/maintenance/solars/port/aft/upper
name = "Upper Port Quarter Solar Maintenance"
icon_state = "SolarcontrolAP"
/area/maintenance/solars/port/fore/upper
name = "Upper Port Bow Solar Maintenance"
icon_state = "SolarcontrolFP"
/area/maintenance/solars/starboard/upper
name = "Upper Starboard Solar Maintenance"
icon_state = "SolarcontrolS"
/area/maintenance/solars/starboard/aft/upper
name = "Upper Starboard Quarter Solar Maintenance"
icon_state = "SolarcontrolAS"
/area/maintenance/solars/starboard/fore/upper
name = "Upper Starboard Bow Solar Maintenance"
icon_state = "SolarcontrolFS"
/area/maintenance/solars/aux/port/upper
name = "Upper Port Auxiliary Solar Maintenance"
icon_state = "SolarcontrolA"
/area/maintenance/solars/aux/port/aft/upper
name = "Upper Port Quarter Auxiliary Solar Maintenance"
icon_state = "SolarcontrolAP"
/area/maintenance/solars/aux/port/fore/upper
name = "Upper Port Bow Auxiliary Solar Maintenance"
icon_state = "SolarcontrolA"
/area/maintenance/solars/aux/starboard/upper
name = "Upper Starboard Auxiliary Solar Maintenance"
icon_state = "SolarcontrolA"
/area/maintenance/solars/aux/starboard/aft/upper
name = "Upper Starboard Quarter Auxiliary Solar Maintenance"
icon_state = "SolarcontrolA"
/area/maintenance/solars/aux/starboard/fore/upper
name = "Upper Starboard Bow Auxiliary Solar Maintenance"
icon_state = "SolarcontrolA"
//Upper Security
/area/security/upper
name = "Upper Security"
icon_state = "security"
ambientsounds = HIGHSEC
/area/security/main/upper
name = "Upper Security Office"
icon_state = "security"
/area/security/brig/upper
name = "Upper Brig"
icon_state = "brig"
/area/security/courtroom/upper
name = "Upper Courtroom"
icon_state = "courtroom"
/area/security/prison/upper
name = "Upper Prison Wing"
icon_state = "sec_prison"
/area/security/processing/upper
name = "Upper Labor Shuttle Dock"
icon_state = "sec_prison"
/area/security/processing/cremation/upper
name = "Upper Security Crematorium"
icon_state = "sec_prison"
/area/security/warden/upper
name = "Upper Brig Control"
icon_state = "Warden"
/area/security/armory/upper
name = "Upper Armory"
icon_state = "armory"
/area/security/detectives_office/upper
name = "Detective's Office"
icon_state = "detective"
ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg')
/area/security/detectives_office/private_investigators_office/upper
name = "Upper Private Investigator's Office"
icon_state = "detective"
/area/security/range/upper
name = "Upper Firing Range"
icon_state = "firingrange"
//Misc security
/area/security/locker
name = "Security Locker Room"
icon_state = "brig"
/area/security/visitation
name = "Security Visitation"
icon_state = "brig"
//Misc Dorms
/area/crew_quarters/dorms/A
name = "Dormitories A"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/B
name = "Dormitories B"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/C
name = "Dormitories C"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/D
name = "Dormitories D"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/E
name = "Dormitories E"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/F
name = "Dormitories F"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/G
name = "Dormitories G"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/dorms/H
name = "Dormitories H"
icon_state = "Sleep"
safe = TRUE
/area/crew_quarters/park
name = "Park"
icon_state = "park"
/area/janitor/upper
name = "Upper Custodial Closet"
/area/storage/A
name = "Storage Office A"
icon_state = "storage"
/area/storage/B
name = "Storage Office B"
icon_state = "storage"
/area/storage/C
name = "Storage Office C"
icon_state = "storage"
/area/storage/D
name = "Storage Office D"
icon_state = "storage"
/area/theatre/blackbox
name = "Theatre Blackbox"
icon_state = "Theatre"
//Misc cargo
/area/quartermaster/mail
name = "Mail Office"
icon_state = "cargo_mail"
//Misc Engineering
/area/engine/custom
name = "Custom Engine Room"
icon_state = "engine"
/area/engine/tether
name = "Sky Tether Control"
icon_state = "engine"
@@ -0,0 +1,3 @@
/obj/machinery/announcement_system
var/onduty = "%PERSON has moved On-Duty as %RANK."
var/offduty = "%PERSON, %RANK, has moved Off-Duty."
@@ -0,0 +1,310 @@
/// Timeclock terminal, ported from VOREStation
/obj/machinery/computer/timeclock
name = "timeclock terminal" // Name of the object
icon = 'hyperstation/icons/obj/machinery/timeclock.dmi' // Spritesheet for the object's icon
icon_state = "timeclock" // Icon state from the spritesheet
icon_keyboard = null // Keyboard state because this is a computer and we need to tell it to not have a keyboard
light_color = "#0099ff" // TODO: Adjust this // Color for the light coming from the object
light_power = 0.5 // Brightness of the light coming from the object
layer = ABOVE_WINDOW_LAYER // Layer for the object
density = FALSE // Density of the object, so we can walk through it
circuit = /obj/item/circuitboard/computer/timeclock // Circuitboard for the object in case it gets destroyed
var/obj/item/card/id/card // Inserted ID card
/// For when we create a new timeclock
/obj/machinery/computer/timeclock/New()
..() // Let's do this just to be safe.
// For when a timeclock is destroyed
/obj/machinery/computer/timeclock/Destroy()
if (card) // If we're holding an ID and get destroyed
card.forceMove(get_turf(src)) // Get rid of the fucker
card = null // And make sure we know it's gone
. = ..() // Someone's gonna ask later, refer them here.
// This shit just sets our return value to our parent proc's return value.
// Determines what icon to used based on a couple factors
/obj/machinery/computer/timeclock/update_icon()
if (!process()) // If we can't process
icon_state = "[initial(icon_state)]_off" // we must be offline.
else if (card) // If we have an ID
icon_state = "[initial(icon_state)]_card" // display it!
else // All else fails?
icon_state = "[initial(icon_state)]" // We're just a clock.
/// Allows the timeclock to update its icon and lighting on power change, should power go out
/obj/machinery/computer/timeclock/power_change()
var/old_stat = stat // Save our old stats for later
..() // Call the parent proc to handle the actual powernet shit
if (old_stat != stat) // If our stat changed
update_icon() // update our icon
if (stat & NOPOWER) // If we no longer have power
set_light(0) // turn off our lights
else // Otherwise
set_light(brightness_on) // turn on our lights
/// Handle clicking with an object
/obj/machinery/computer/timeclock/attackby(obj/I, mob/user)
if (istype(I, /obj/item/card/id)) // If the user clicked with an ID in hand
if (!card && user.canUnEquip(I)) // Check if we already have an ID and that the user can drop the ID
I.forceMove(src) // Move the ID into our own location
card = I // Set our card to the ID
SStgui.update_uis(src) // Update all open UIs for us
update_icon() // Update our icon to reflect the new ID
else if (card) // There must've already been an ID inserted
to_chat(user, "<span class='warning'>There is already an ID card inside.</span>")
return // Quit doing shit so we don't hit the timeclock
. = ..() // Set our return value to that of the parent proc
/// Handle user clicking
/obj/machinery/computer/timeclock/attack_hand(var/mob/user as mob)
if (..()) // If for some reason the parent proc returns true
return // We won't do anything
user.set_machine(src) // Otherwise, set the mob's machine to us
ui_interact(user) // Provide a UI to the user
/// Handle UI interactions with this arcane shit known as tee gee yew eye
/obj/machinery/computer/timeclock/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui) // Attempt to update the UI
if (!ui) // If the UI doesn't exist
ui = new(user, src, "TimeClock", name) // Make a new one
ui.open() // And open it for the user
/// Handle UI data
/obj/machinery/computer/timeclock/ui_data(mob/user)
var/list/data = ..() // Call the parent object's data proc and assign that to the data list
// Data for showing user's own PTO
if (user.client) // If the client exists
data["department_hours"] = \
SANITIZE_LIST(user.client.department_hours) // Add the department hours list into data
data["user_name"] = "[user]" // Set the username to the user
// Data about the card we put into the timeclock
data["card"] = null // Add card data,
data["assignment"] = null // Assignment data,
data["job_datum"] = null // The job datum,
data["allow_change_job"] = null // Whether or not we can change jobs,
data["job_choices"] = null // And the possible jobs
if (card) // If we have a card
data["card"] = "[card]" // Set card data,
data["assignment"] = card.assignment // Assignment data,
var/datum/job/job = \
SSjob.GetJob(SSjob.get_job_name(card.assignment)) // Create a new job datum,
if (job) // If the job exists
data["job_datum"] = list( // Set job datum to a list with
"title" = job.title, // The job title,
"departments" = \
flags_to_english(job.department_flag, job.flag), // The job department,
"selection_color" = job.selection_color, // The selection color,
"timeoff_factor" = job.timeoff_factor, // The timeoff factor,
"pto_department" = job.pto_type // And the PTO type
)
if (CONFIG_GET(flag/time_off) \
&& CONFIG_GET(flag/pto_job_change)) // If we allow timeoff and job changing
data["allow_change_job"] = TRUE // Add that to the data
if (job && job.timeoff_factor < 0) // They're off duty so we have to lookup available jobs
data["job_choices"] = \
get_open_on_duty_jobs(user, job.pto_type) // Set the job choices
return data // Give back the data list for subprocs
/// The user interacted with me? owo!
/obj/machinery/computer/timeclock/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
if (..()) // Check if the parent UI had anything to say
return TRUE // If so, we don't care to do anything
add_fingerprint(usr) // Add the user's fingerprint to the list so sec can find them
switch (action) // Check the action completed
if ("id") // If the ID slot was clicked
if (card) // Check if we have an ID already
usr.put_in_hands(card) // If so, give the user the card
card = null // And make sure we don't have it
else // Otherwise
var/obj/item/I = usr.get_active_held_item() // Get the item in their active hand
if (istype(I, /obj/item/card/id) && usr.canUnEquip(I)) // Check if it's an ID and they can unequip the ID
I.forceMove(src) // If so, move it into us
card = I // And make sure we know we have it
update_icon() // Update our icon too because we did something
return TRUE // And stop handling any UI in this run
if ("switch-to-on-duty-rank") // If they switched to on-duty
if (check_face()) // Check that their face is visible
if (check_card_cooldown()) // And their card isn't on cooldown
make_on_duty(params["switch-to-on-duty-rank"], \
params["switch-to-on-duty-assignment"]) // Finally make them on-duty with the requested rank+assignment
usr.put_in_hands(card) // Give them their new card
card = null // And get it out of us
update_icon() // Update our icon in case the card was removed
return TRUE // And stop handling UI in this run
if ("switch-to-off-duty") // If they switched to off-duty
if (check_face()) // Check that their face is visible
if (check_card_cooldown()) // And that their card isn't on cooldown
make_off_duty() // Finally make them off-duty
usr.put_in_hands(card) // Shit out their ID into their hand
card = null // And get rid of that card
update_icon() // Update our icon in case the card was removed
return TRUE // And stop handling any UI in this run
/// Gets the open on-duty jobs available to a user in a specified department
/obj/machinery/computer/timeclock/proc/get_open_on_duty_jobs(var/mob/user, var/department)
var/list/available_jobs = list() // Make a list of available jobs
for (var/datum/job/job in SSjob.occupations) // For all jobs in existing occupations
if (is_open_onduty_job(user, department, job)) // Check if the job is open and on-duty for a user and given department
available_jobs[job.title] = list(job.title) // If it is, add it to the list of available jobs
if (job.alt_titles) // If the job has alt-titles (Like Station Engineer->Mechanic)
for (var/alt_job in job.alt_titles) // Go through all the alt titles
if (alt_job != job.title) // And if it isn't the current job's title (Station Engineer's alt title of Station Engineer)
available_jobs[job.title] += alt_job // Add it to the list under that job title
return available_jobs // Return the newly-filled list of available jobs
/// How does xenobio work again? Oh right, we're checking the user's face here to allow access and prevent ne'er-do-wells from using someone's PTO
/obj/machinery/computer/timeclock/proc/check_face()
if (!card) // If no card is inserted (why are we checking their face?)
to_chat(usr, "<span class='notice'>No ID is inserted.</span>")
return FALSE // Face check failed
var/mob/living/carbon/human/H = usr // Get the usr as a human data type
if (!(istype(H))) // If they somehow aren't a human??
to_chat(usr, "<span class='warning'>Invalid user detected. Access denied.</span>")
return FALSE // Face check failed
else if ((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) \
|| (H.head && (H.head.flags_inv & HIDEFACE))) // No, you can't hide your face
to_chat(usr, "<span class='warning'>Facial recognition scan failed due to physical obstruction. Access denied.</span>")
return FALSE // Face check failed
else if (H.get_face_name() == "Unknown" \
|| !(H.real_name == card.registered_name)) // If they're unknown or their real name isn't the name on the ID
to_chat(usr, "<span class='warning'>Facial recognition scan failed. Access denied.</span>")
return FALSE // Face check failed
else // Otherwise
return TRUE // Face check success!
/// Force users to wait 10 minutes between clocking in and out
/obj/machinery/computer/timeclock/proc/check_card_cooldown()
if (!card) // If we don't have a card
return FALSE // We can't check cooldown, fail the check
var/time_left = 10 MINUTES - (world.time - card.last_job_switch) // Determine how much time is left before the next switch
if (time_left > 0) // If there's any time left at all
to_chat(usr, "You need to wait another [round((time_left / 10) / 60, 1)] minute\s before you can switch.")
return FALSE // Fail the check
return TRUE // Otherwise pass the check
/// Makes the active card on-duty with a set rank and assignment
/obj/machinery/computer/timeclock/proc/make_on_duty(var/new_rank, var/new_assignment)
var/datum/job/old_job = \
SSjob.GetJob(SSjob.get_job_name(card.assignment)) // Get their old job from the card
var/datum/job/new_job = SSjob.GetJob(new_rank) // And their new job from the rank
if (!old_job \
|| !is_open_onduty_job(usr, old_job.pto_type, new_job)) // If there's no old job or it's not an open and on-duty job
return // Do nothing
if (new_assignment != new_job.title \
&& !(new_assignment in new_job.alt_titles)) // If the new assignment isn't the new job's title or alt-title
return // Do nothing
if (new_job) // As long as there's a new job
card.access = new_job.get_access() // Set the card's access to the new job's access
card.assignment = new_assignment // And the card's assignment to the new assignment
card.name = text(\
"[card.registered_name]'s ID Card ([card.assignment])") // And change the card's name
GLOB.data_core.manifest_modify(card.registered_name, \
card.assignment) // Apply the changes to the crew manifest
card.last_job_switch = world.time // Set the last job switch on the card to the current world time
new_job.current_positions++ // Add one to the current positions for the new job
var/mob/living/carbon/human/H = usr // Get the caller as a human data type
H.mind.assigned_role = card.assignment // Set the assigned role of the caller's mind to the assignment on the card
if (GLOB.announcement_systems.len) // If there are any announcement systems
var/obj/machinery/announcement_system/announcer = \
pick(GLOB.announcement_systems) // Pick an announcer, any announcer!
announcer.announce("ONDUTY", card.registered_name, \
card.assignment, list()) // Make the announcement for now on-duty personnel
/// Makes the active card off-duty
/obj/machinery/computer/timeclock/proc/make_off_duty()
var/datum/job/found_job = \
SSjob.GetJob(SSjob.get_job_name(card.assignment)) // Get the current job from the inserted card
if (!found_job) // If the card somehow doesn't have a job
return // https://www.youtube.com/watch?v=2k0SmqbBIpQ
var/new_dept = found_job.pto_type || PTO_CIVILIAN // New department is either the department's PTO type or civilian PTO
var/datum/job/pto_job = null // Create a new PTO job
for (var/datum/job/job in SSjob.occupations) // For all jobs in the list of occupations
if (job.pto_type == new_dept \
&& job.timeoff_factor < 0) // If the job is the department's PTO type and has a negative timeoff factor
pto_job = job // That's the new PTO job
break // And stop looking
if (pto_job) // If a PTO job was found
// Apparently we aren't using this? I don't fucking know
// var/old_title = card.assignment
card.access = pto_job.get_access() // Assign the PTO job's access to the ID
card.assignment = pto_job.title // And the PTO job's title to the ID
card.name = text(\
"[card.registered_name]'s ID Card ([card.assignment])") // Set the card's new name
GLOB.data_core.manifest_modify(card.registered_name, \
card.assignment) // And apply that change to the crew manifest
card.last_job_switch = world.time // Set the last job switch on the card to the world's current time
var/mob/living/carbon/human/H = usr // Get the caller as a human data type
H.mind.assigned_role = pto_job.title // Set their mind's assigned role to the PTO job's title
found_job.current_positions-- // Remove one from the found job's position count since they no longer have that job
if (GLOB.announcement_systems.len) // If there are any announcement systems
var/obj/machinery/announcement_system/announcer = \
pick(GLOB.announcement_systems) // Pick an announcement system, any announcement system!
announcer.announce("OFFDUTY", card.registered_name, \
card.assignment, list()) // Make an off-duty announcement with that system
return // I really don't know why this return exists we always return anyways lol
/// Check if a job is open and on-duty for a given user and department
/obj/machinery/computer/timeclock/proc/is_open_onduty_job(var/mob/user, var/department, var/datum/job/job)
return job \
&& job.current_positions <= job.total_positions \
&& !jobban_isbanned(user, SSjob.get_job_name(job.title)) \
&& job.player_old_enough(user.client) \
&& job.pto_type == department \
&& job.timeoff_factor > 0 // I feel like this requires some HEAVY explanation so here we go.
// First we check if the job exists
// Then we check that there are enough open slots
// Then we check if the user is jobbanned or not and negate that because it'll return positive if they're banned
// Then we have to check that they have enough playtime to actually join as that job
// Then we have to check that the PTO type matches the department requested (can't join security with a PTO type of medical)
// Then we have to check that there's a timeoff value so you can actually accrue hours of PTO by playing as that role
/// Convert a department and job flag to an english phrase
/obj/machinery/computer/timeclock/proc/flags_to_english(var/department,var/flag)
if (department == ENGSEC) // If the department flag is engineering or security (or silicon apparently?)
switch (flag) // Switch based on the flag
if (CAPTAIN, HOS, WARDEN, CHIEF) // Captain, Head of Security, Warden or Chief Engineer
return "Command" // Are all command
if (DETECTIVE, OFFICER) // Detectives and Officers
return "Security" // Are all security
//if (BRIGDOC) // Brig Docs
//return "Medsec" // Are medical and science
if (LAMBENT) // Lambent
return "Lambent" // Are obviously Lambent. Dunno what you expected fam
if (ENGINEER, ATMOSTECH) // Engineers and Atmos Technicians
return "Engineering" // Are engineering
if (ROBOTICIST) // Roboticist is defined here but I think it was supposed to be with medsci? Just in case.
return "Science" // They're science
else // Technically this won't always be silicon
return "Silicon" // But we're listing your ass as silicon anyways. Cope.
else if (department == MEDSCI) // Otherwise, if the department flag is medical or science
switch (flag) // Switch based on the flag (again)
if (RD_JF, CMO_JF) // Research Director or Chief Medical Officer
return "Command" // Are both command
if (SCIENTIST, ROBOTICIST) // Scientists and Roboticists (this is where I think this was meant to be but it's still with ENGSEC just in case)
return "Science" // Are obviously science
if (CHEMIST, DOCTOR, VIROLOGIST) // Chemists, Doctors, Virologists and Paramedics
return "Medical" // Are medical
if (GENETICIST) // Geneticists
return "Medsci" // Are kind of a special, middle of the road medical and science case
else // If you're landing here you're fucked
return "What the fuck?" // So what the fuck?
else if (department == CIVILIAN) // Otherwise you must be civilian, right? Right???
switch (flag) // Once again a switch based on the flag
if (HOP, QUARTERMASTER) // Head of Personnel and Quartermaster
return "Command" // Are command
//if (PRISONER) // Prisoners
//return "Prisoner" // Are... prisoners? They shouldn't be able to PTO but if they manage to break out they can access a console so no fuck you here
if (CARGOTECH, MINER) // Cargo Technicians and Miners
return "Cargo" // Are cargonians
else // Otherwise
return "Civilian" // You must be a civilian. You could be an assisstant or a clown or a bartender, I don't really care.
else // New department combo? Wack.
return "What the fuck?" // what the fuck?
@@ -0,0 +1,11 @@
/obj/effect/landmark/start/lambent
name = "Lambent"
icon_state = "Lambent"
/obj/effect/landmark/start/barber
name = "Barber"
icon_state = "Barber"
/obj/effect/landmark/start/barista
name = "Barista"
icon_state = "Barista"
@@ -0,0 +1,2 @@
/obj/item/card/id
var/last_job_switch /// Last job switch for card's owner
@@ -0,0 +1,3 @@
/obj/item/circuitboard/computer/timeclock
name = "Timeclock (Computer Board)"
build_path = /obj/machinery/computer/timeclock
@@ -1,3 +1,4 @@
//Farm things
/turf/open/floor/
var/farm_quality = 0 //all tiles have a farm quality, which is for farm animals to enjoy. 0 = worse 100 = best!
@@ -26,3 +27,11 @@
icon_state = "hay"
farm_quality = 100 //the best for farming!
floor_tile = /obj/item/stack/tile/hay
//Carpets
/obj/item/stack/tile/carpet/kinaris
name = "gilded carpet"
icon = 'hyperstation/icons/obj/tiles.dmi'
icon_state = "tile-carpet-kinaris"
turf_type = /turf/open/floor/carpet/kinaris
tableVariant = /obj/structure/table/wood/fancy/kinaris
@@ -9,3 +9,15 @@
icon_state = "bench_left"
/obj/structure/chair/bench/right
icon_state = "bench_right"
/obj/structure/chair/bench/metal
name = "bench"
icon_state = "bench_metal_middle"
icon = 'hyperstation/icons/obj/bench.dmi'
buildstackamount = 1
buildstacktype = /obj/item/stack/sheet/metal
/obj/structure/chair/bench/metal/left
icon_state = "bench_metal_left"
/obj/structure/chair/bench/metal/right
icon_state = "bench_metal_right"
@@ -165,3 +165,35 @@
/obj/effect/mob_spawn/human/villager/special(mob/living/carbon/human/new_spawn)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
//Prisoner
/obj/effect/mob_spawn/human/prisoner
name = "prisoner transfer cryoteleporter"
mob_name = "prisoner transfer"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
job_description = "Prisoner Transfer"
outfit = /datum/outfit/prisoner
id_job = "Prisoner Transfer"
assignedrole = "Prisoner Transfer"
short_desc = "You are a transferred prisoner to Layenia. Don't break out or otherwise act like an antag."
flavour_text = "For one reason or another, you are a prisoner. Kinaris has chosen to temporarily hold you within Layenia Station's holding area, \
until the end of the shift. You do not permanently reside here, but you may end up in this place from shift to shift. It is highly recommended to \
make a unique character slot for this role. Kinaris would not neuter or otherwise remove identifying features that make you who you are; such as \
altering your name, features, or physical appearance. As a prisoner, you still uphold a decent amount of rights."
important_info = "Do NOT attempt to break out, antagonize, or otherwise treat your role as anything to grief with. Should you find a scenario where you want to, AHELP."
objectives = "Do NOT attempt to break out or act like an antag. Serve your time until end of shift."
mirrorcanloadappearance = TRUE
roundstart = FALSE
death = FALSE
/datum/outfit/prisoner
name = "Prisoner"
uniform = /obj/item/clothing/under/rank/prisoner
shoes = /obj/item/clothing/shoes/sneakers/orange
id = /obj/item/card/id/prisoner
implants = list(/obj/item/implant/exile, /obj/item/implant/tracking)
/obj/effect/mob_spawn/human/prisoner/special(mob/living/carbon/human/new_spawn)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
@@ -0,0 +1,9 @@
/obj/structure/table/wood/fancy/kinaris
icon = 'hyperstation/icons/obj/structures.dmi'
icon_state = "fancy_table_kinaris"
buildstack = /obj/item/stack/tile/carpet/kinaris
canSmoothWith = list(/obj/structure/table/wood/fancy/kinaris)
/obj/structure/table/wood/fancy/kinaris/New()
. = ..()
icon = 'hyperstation/icons/obj/smooth_structures/fancy_table_kinaris.dmi'
+14
View File
@@ -0,0 +1,14 @@
/turf/open/indestructible/layenia/sand
name = "\improper crimson sand"
desc = "A reddish sand."
icon = 'hyperstation/icons/turf/floors/layeniasand.dmi'
icon_state = "mapping"
baseturfs = /turf/open/indestructible/layenia/crystal
slowdown = 1
barefootstep = FOOTSTEP_SAND
clawfootstep = FOOTSTEP_SAND
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
initial_gas_mix = FROZEN_ATMOS
planetary_atmos = TRUE
smooth = SMOOTH_TRUE | SMOOTH_BORDER | SMOOTH_MORE
canSmoothWith = list(/turf/open/indestructible/layenia/sand)
@@ -0,0 +1,4 @@
/turf/open/floor/carpet/kinaris
icon = 'hyperstation/icons/turf/floors/carpet_kinaris.dmi'
floor_tile = /obj/item/stack/tile/carpet/kinaris
canSmoothWith = list(/turf/open/floor/carpet/kinaris)
@@ -0,0 +1,78 @@
/turf/closed/wall/mineral/titanium/custom //For spicy custom shuttles
name = "whoops!"
desc = "Scream at Dahl please!"
icon = 'hyperstation/icons/turf/walls/customshuttles.dmi'
icon_state = "amogus"
explosion_block = 10
smooth = SMOOTH_FALSE
canSmoothWith = null
/turf/closed/wall/mineral/titanium/custom/window
opacity = FALSE
/turf/closed/wall/mineral/titanium/custom/AfterChange(flags, oldType)
. = ..()
// Manually add space underlay, in a way similar to turf_z_transparency,
// but we actually show the old content of the same z-level, as desired for shuttles
var/turf/underturf_path
// Grab previous turf icon
if(!ispath(oldType, /turf/closed/wall/mineral/titanium/custom))
underturf_path = oldType
else
// Else use whatever SSmapping tells us, like transparent open tiles do
underturf_path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
var/mutable_appearance/underlay_appearance = mutable_appearance(
initial(underturf_path.icon),
initial(underturf_path.icon_state),
layer = TURF_LAYER - 0.02, plane = initial(underturf_path.plane))
underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
underlays += underlay_appearance
/turf/closed/wall/mineral/titanium/custom/ferry
name = "\improper ferry wall"
desc = "A low tech hull for Layenia flight."
icon_state = "ferry"
/turf/closed/wall/mineral/titanium/custom/window/ferry
name = "\improper ferry wall"
desc = "A low tech hull for Layenia flight."
icon_state = "ferry"
/turf/closed/wall/mineral/titanium/custom/arrivals
name = "\improper shuttle wall"
desc = "A low tech hull for Layenia and space-flight"
icon = 'hyperstation/icons/turf/walls/customarrivals.dmi'
icon_state = "amogus"
/turf/closed/wall/mineral/titanium/custom/window/arrivals
name = "\improper shuttle wall"
desc = "A low tech hull for Layenia and space-flight"
icon = 'hyperstation/icons/turf/walls/customarrivals.dmi'
icon_state = "amogus"
/turf/closed/wall/mineral/titanium/custom/pod
name = "\improper pod wall"
desc = "A low tech hull for Layenia and space-flight"
icon = 'hyperstation/icons/turf/walls/custompod.dmi'
icon_state = "amogus"
/turf/closed/wall/mineral/titanium/custom/window/pod
name = "\improper pod wall"
desc = "A low tech hull for Layenia and space-flight"
icon = 'hyperstation/icons/turf/walls/custompod.dmi'
icon_state = "amogus"
/turf/closed/wall/mineral/titanium/custom/departures
name = "\improper pod wall"
desc = "A low tech hull for Layenia and space-flight"
icon = 'hyperstation/icons/turf/walls/customdepartures.dmi'
icon_state = "amogus"
/turf/closed/wall/mineral/titanium/custom/window/departures
name = "\improper pod wall"
desc = "A low tech hull for Layenia and space-flight"
icon = 'hyperstation/icons/turf/walls/customdepartures.dmi'
icon_state = "amogus"
@@ -0,0 +1,9 @@
/**
* Additional client defines. I needed somewhere to put these so here it is!
*/
/client
//////////////////////////////////////
// Things that require the database //
//////////////////////////////////////
var/list/department_hours = list() // Track hours of leave accrued for each department
var/list/play_hours = list() // Tracks total playtime hours for each department
+1 -1
View File
@@ -10,4 +10,4 @@
strip_delay = 40
equip_delay_other = 20
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
@@ -0,0 +1,3 @@
/datum/job
var/timeoff_factor = 3
var/pto_type
@@ -0,0 +1,52 @@
/datum/job/barista
title = "Barista"
flag = BARISTA
department_head = list("Head of Personnel")
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#bbe291"
outfit = /datum/outfit/job/barista
access = list(ACCESS_HYDROPONICS, ACCESS_BARISTA, ACCESS_KITCHEN, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_BARISTA, ACCESS_MINERAL_STOREROOM)
/datum/outfit/job/barista
name = "Barista"
jobtype = /datum/job/barista
belt = /obj/item/pda/bar
ears = /obj/item/radio/headset/headset_srv
uniform = /obj/item/clothing/under/lawyer/blacksuit
suit = /obj/item/clothing/suit/toggle/lawyer/black
backpack_contents = list(/obj/item/book/granter/action/drink_fling=1, /obj/item/clothing/accessory/waistcoat)
shoes = /obj/item/clothing/shoes/laceup
/datum/job/barber
title = "Barber"
flag = BARBER
department_head = list("Head of Personnel")
department_flag = CIVILIAN
faction = "Station"
total_positions = 2
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#bbe291"
outfit = /datum/outfit/job/barber
access = list(ACCESS_BARBER)
minimal_access = list(ACCESS_BARBER)
/datum/outfit/job/barber
name = "Barber"
jobtype = /datum/job/barber
glasses = /obj/item/clothing/glasses/sunglasses
ears = /obj/item/radio/headset/headset_srv
belt = /obj/item/pda
uniform = /obj/item/clothing/under/barber
shoes = /obj/item/clothing/shoes/laceup
@@ -0,0 +1,8 @@
/datum/job/lambent
alt_titles = list("Kinaris Protectorate", "Hardshield", "Asset Specialist", "Luminal")
/datum/job/barber
alt_titles = list("Cosmetologist", "Beautician", "Hairdresser", "Hair Stylist")
/datum/job/barista
alt_titles = list("Cafe Attendant", "Cafe Server")
@@ -0,0 +1,56 @@
/*
Lambent
*/
/datum/job/lambent
title = "Lambent"
flag = LAMBENT
department_head = list("CentCom")
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "Central Command and Kinaris officials"
selection_color = "#ffedcc"
req_admin_notify = 1
minimal_player_age = 30
exp_requirements = 9000
exp_type = EXP_TYPE_COMMAND
exp_type_department = EXP_TYPE_COMMAND
whitelist_type = "important"
custom_spawn_text = "You are a Kinaris Lambent; a person hired directly by Kinaris who has a high interest in asset security and the protection of the station. Unlike the station, your gear is official Kinaris items, not replicated Milky-Way Engrams. As such, you should keep them safe due to the power they hold. You answer directly to Central Command and Kinaris, and security matters should not involve you for the most part, unless staffing is low or there is a problem with securing assets. Thankfully, Layenia Station is one of Kinaris's most low-tech stations with hardly anything important to secure; not even the items in the vault are noteworthy due to the falsified, low-tech Engram they're under. Just ensure peace is kept and the station is functioning in a calm manner."
outfit = /datum/outfit/job/lambent
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_LAMBENT,
ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_BARISTA, ACCESS_BARBER,
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_LAMBENT,
ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_BARISTA, ACCESS_BARBER,
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
mind_traits = list(TRAIT_CAPTAIN_METABOLISM)
blacklisted_quirks = list(/datum/quirk/brainproblems, /datum/quirk/insanity, /datum/quirk/nonviolent)
/datum/outfit/job/lambent
name = "Lambent"
jobtype = /datum/job/lambent
id = /obj/item/card/id/silver
belt = /obj/item/pda/captain
glasses = /obj/item/clothing/glasses/hud/toggle/zao
ears = /obj/item/radio/headset/heads/captain/alt
gloves = /obj/item/clothing/gloves/lambent
uniform = /obj/item/clothing/under/rank/lambent
suit = /obj/item/clothing/suit/lambent
shoes = /obj/item/clothing/shoes/lambent
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced = 1)
backpack = /obj/item/storage/backpack/lambent
satchel = /obj/item/storage/backpack/satchel/lambent
duffelbag = /obj/item/storage/backpack/duffelbag/lambent
box = /obj/item/storage/box/security
implants = list(/obj/item/implant/mindshield)
@@ -0,0 +1,31 @@
/obj/item/wallframe/light_fixture/fairy
name = "fairy lights frame"
icon_state = "fairy-construct-item"
result_path = /obj/structure/light_construct/fairy
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT)
/obj/structure/light_construct/fairy
name = "fairy lights frame"
icon_state = "fairy-construct-stage1"
fixture_type = "fairy"
sheets_refunded = 1
/obj/machinery/light/fairy
icon_state = "fairy"
base_state = "fairy"
fitting = "fairy"
brightness = 3
desc = "Small fairy lights."
//light_type = /obj/item/light/fairy
/obj/machinery/light/fairy/broken
status = LIGHT_BROKEN
icon_state = "fairy-broken"
/obj/machinery/light/fairy/built
icon_state = "bulb-empty"
/obj/machinery/light/fairy/built/Initialize()
. = ..()
status = LIGHT_EMPTY
update(0)
+541
View File
@@ -0,0 +1,541 @@
//Proper modularity to come at a later date
/obj/structure/chair/barber_chair
name = "barbers chair"
desc = "You sit in this, and your hair shall be cut."
icon = 'icons/obj/chairs.dmi'
icon_state = "barber_chair"
/obj/structure/closet/secure_closet/barber
name = "Barber's locker"
icon_state = "barber"
icon = 'icons/obj/closet.dmi'
req_access = list(ACCESS_BARBER)
/obj/structure/closet/secure_closet/barber/PopulateContents()
new /obj/item/clothing/mask/surgical(src) // These three are here, so the barber can pick and choose what he's painting.
new /obj/item/clothing/under/rank/medical/blue(src)
new /obj/item/clothing/suit/apron/surgical(src)
new /obj/item/clothing/accessory/waistcoat(src)
//new /obj/item/clothing/under/rank/civilian/lawyer/purpsuit(src)
new /obj/item/clothing/suit/toggle/lawyer/purple(src)
new /obj/item/razor(src)
//new /obj/item/straight_razor(src)
new /obj/item/hairbrush/comb(src)
new /obj/item/scissors(src)
new /obj/item/fur_dyer(src)
new /obj/item/dyespray(src)
new /obj/item/storage/box/lipsticks(src)
new /obj/item/reagent_containers/spray/quantum_hair_dye(src)
new /obj/item/reagent_containers/spray/barbers_aid(src)
new /obj/item/reagent_containers/spray/cleaner(src)
new /obj/item/reagent_containers/rag(src)
new /obj/item/storage/firstaid/regular(src)
/obj/machinery/vending/barbervend
name = "Fab-O-Vend"
desc = "It would seem it vends dyes, and other stuff to make you pretty."
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "barbervend"
product_slogans = "Spread the colour, like butter, onto toast... Onto their hair.; Sometimes, I dream about dyes...; Paint 'em up and call me Mr. Painter.; Look brother, I'm a vendomat, I solve practical problems."
product_ads = "Cut 'em all!; To sheds!; Hair be gone!; Prettify!; Beautify!"
vend_reply = "Come again!; Buy another!; Dont you love your new look?"
req_access = list(ACCESS_BARBER)
refill_canister = /obj/item/vending_refill/barbervend
products = list(
/obj/item/reagent_containers/spray/quantum_hair_dye = 3,
// /obj/item/reagent_containers/spray/baldium = 3,
/obj/item/reagent_containers/spray/barbers_aid = 3,
/obj/item/dyespray = 5,
/obj/item/hairbrush = 3,
/obj/item/hairbrush/comb = 3,
/obj/item/fur_dyer = 1,
)
premium = list(
/obj/item/scissors = 3,
/obj/item/reagent_containers/spray/super_barbers_aid = 3,
/obj/item/storage/box/lipsticks = 3,
/obj/item/lipstick/quantum = 1,
/obj/item/razor = 1,
// /obj/item/storage/box/perfume = 1,
)
refill_canister = /obj/item/vending_refill/barbervend
/obj/item/vending_refill/barbervend
machine_name = "barber vend resupply"
icon_state = "refill_snack" //generic item refill because there isnt one sprited yet.
/obj/effect/landmark/start/barber
name = "Barber"
icon_state = "Barber"
//icon = 'modular_skyrat/master_files/icons/mob/landmarks.dmi'
//Brush
/obj/item/hairbrush
name = "hairbrush"
desc = "A small, circular brush with an ergonomic grip for efficient brush application."
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "brush"
//Put lefthand and righthand files here
w_class = WEIGHT_CLASS_TINY
var/brush_speed = 3 SECONDS
/obj/item/hairbrush/comb
name = "comb"
desc = "A rather simple tool, used to straighten out hair and knots in it."
icon_state = "blackcomb"
/obj/item/hairbrush/attack(mob/target, mob/user)
if(target.stat == DEAD)
to_chat(usr, "<span class='warning'>There isn't much point in brushing someone who can't appreciate it!</span>")
return
brush(target, user)
return COMPONENT_CANCEL_ATTACK_CHAIN
//Brushes someone
/obj/item/hairbrush/proc/brush(mob/living/target, mob/user)
if(ishuman(target))
var/mob/living/carbon/human/human_target = target
var/obj/item/bodypart/head = human_target.get_bodypart(BODY_ZONE_HEAD)
//Don't brush if you can't reach their head or cancel the action
if(!head) //No head? No bitches?
to_chat(usr, "<span class='warning'>[human_target] has no head!</span>")
return
if(human_target.is_mouth_covered(head_only = 1))
to_chat(usr, "<span class='warning'>You can't brush [human_target]'s hair while [human_target.p_their()] head is covered!</span>")
return
if(!do_after(user, brush_speed, human_target))
return
// Do 1 brute to their head if they're bald. Should've been more careful.
if(human_target.hair_style == "Bald" || human_target.hair_style == "Skinhead" && is_species(human_target, /datum/species/human)) //It can be assumed most anthros have hair on them!
human_target.visible_message("<span class='warning'>[usr] scrapes the bristles uncomfortably over [human_target]'s scalp.</span>","<span class='warning'>You scrape the bristles uncomfortably over [human_target]'s scalp.</span>")
playsound(target, 'hyperstation/sound/misc/bonk.ogg', 100, 1) //Until I fix it
return
//Brush their hair
if(human_target == user)
human_target.visible_message("<span class='notice'>[usr] brushes [usr.p_their()] hair!</span>","<span class='notice'>You brush your hair.</span>")
//SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "brushed", /datum/mood/brushed/self)
else
user.visible_message("<span class='notice'>[usr] brushes [human_target]'s hair!</span>","<span class='notice'>You brush [human_target]'s hair.</span>")
//SEND_SIGNAL(human_target, COMISG_ADD_MOOD_EVENT, "brushed", /datum/mood_event/brushed, user)
//fur dyer
#define COLOR_MODE_SPECIFIC "Specific Marking"
#define COLOR_MODE_GENERAL "General Color"
/obj/item/fur_dyer
name = "electric fur dyer"
desc = "Dye that is capable of recoloring fur in a mostly permanent way."
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "fur_sprayer"
w_class = WEIGHT_CLASS_TINY
var/mode = COLOR_MODE_GENERAL
/*
/obj/item/fur_dyer/Initialize(mapload)
. = ..()
AddComponent(/datum/component/cell)
*/
/obj/item/fur_dyer/attack_self(mob/user, modifiers)
. = ..()
if(mode == COLOR_MODE_SPECIFIC)
mode = COLOR_MODE_GENERAL
else
mode = COLOR_MODE_SPECIFIC
to_chat(user, "Set to [mode]!")
/obj/item/fur_dyer/attack(mob/living/M, mob/living/user, params)
if(!ishuman(M))
return ..()
var/mob/living/carbon/human/target_human = M
switch(mode)
if(COLOR_MODE_SPECIFIC)
to_chat(user, "The device resonates ominously, and stops. It seems to be interfered by an Engram.")
//dye_marking(target_human, user)
if(COLOR_MODE_GENERAL)
dye_general(target_human, user)
/obj/item/fur_dyer/proc/dye_general(mob/living/carbon/human/target_human, mob/living/user)
var/selected_mutant_color = tgalert(user, "Please select which mutant color you'd like to change", "Select Color", "One", "Two", "Three")
if(!selected_mutant_color)
return
var/selected_color = input(
user,
"Select marking color",
null,
"#FFFFFF"
) as color | null
if(!selected_color)
return
selected_color = sanitize_hexcolor(selected_color)
visible_message("<span class='notice'>[user] starts to masterfully paint [target_human]!</span>")
if(do_after(user, 20 SECONDS, target_human))
switch(selected_mutant_color)
if("One")
target_human.dna.features["mcolor"] = selected_color
if("Two")
target_human.dna.features["mcolor2"] = selected_color
if("Three")
target_human.dna.features["mcolor3"] = selected_color
target_human.regenerate_icons()
//use power
visible_message("<span class='notice'>[user] finishes painting [target_human]!</span>")
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE)
/* We don't have markings that can be colored separately yet, so this is not needed
/obj/item/fur_dyer/proc/dye_marking(mob/living/carbon/human/target_human, mob/living/user)
var/list/list/current_markings = target_human.dna.body_markings.Copy()
if(!current_markings.len)
to_chat(user, "<span class='warning'>[target_human] has no markings!</span>")
return
//power stuff here
/var/selected_marking_area = user.zone_selected
if(!current_markings[selected_marking_area])
to_chat(user, "<span class='danger'>[target_human] has no bodymarkings on this limb!</span>")
return
var/selected_marking_id = input(user, "Please select which marking you'd like to color!", "Select marking", current_markings[selected_marking_area])
if(!selected_marking_id)
return
var/selected_color = input(
user,
"Select marking color",
null,
"#FFFFFF"
) as color | null
if(!selected_color)
return
selected_color = sanitize_hexcolor(selected_color)
visible_message("<span class='notice'>[user] starts to masterfully paint [target_human]!</span>")
if(do_after(user, 20 SECONDS, target_human))
current_markings[selected_marking_area][selected_marking_id] = selected_color
target_human.dna.body_markings = current_markings.Copy()
target_human.regenerate_icons()
//item_use_power(power_use_amount, user)
visible_message("<span class='notice'>[user] finishes painting [target_human]!</span>")
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE)
*/
/obj/machinery/dryer
name = "hand dryer"
desc = "The Breath Of Lizards-3000, an experimental dryer."
icon = 'hyperstation/icons/obj/dryer.dmi'
icon_state = "dryer"
density = FALSE
anchored = TRUE
var/busy = FALSE
/obj/machinery/dryer/attack_hand(mob/user)
if(iscyborg(user) || isAI(user))
return
if(!can_interact(user))
return
if(busy)
to_chat(user, "<span class='warning'>Someone is already drying here.</span>")
return
to_chat(user, "<span class='notice'>You start drying your hands.</span>")
playsound(src, 'hyperstation/sound/salon/drying.ogg', 50)
add_fingerprint(user)
busy = TRUE
if(do_after(user, 4 SECONDS, src))
busy = FALSE
user.visible_message("[user] dried their hands using \the [src].")
else
busy = FALSE
/obj/item/reagent_containers/dropper/precision
name = "pipette"
desc = "A high precision pippette. Holds 1 unit."
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "pipette1"
amount_per_transfer_from_this = 1
possible_transfer_amounts = list(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1)
volume = 1
w_class = WEIGHT_CLASS_TINY
/obj/item/storage/box/lipsticks
name = "lipstick box"
/obj/item/storage/box/lipsticks/PopulateContents()
..()
new /obj/item/lipstick(src)
new /obj/item/lipstick/purple(src)
new /obj/item/lipstick/jade(src)
new /obj/item/lipstick/black(src)
/obj/item/lipstick/quantum
name = "quantum lipstick"
/obj/item/lipstick/quantum/attack(mob/attacked_mob, mob/user)
if(!open || !ismob(attacked_mob))
return
if(!ishuman(attacked_mob))
to_chat(user, "<span class='warning'>Where are the lips on that?</span>")
return
var/new_color = input(
user,
"Select lipstick color",
null,
"#FFFFFF"
) as color | null
var/mob/living/carbon/human/target = attacked_mob
if(target.is_mouth_covered())
to_chat(user, "<span class='warning'>Remove [ target == user ? "your" : "[target.p_their()]" ] mask!</span>")
return
if(target.lip_style) //if they already have lipstick on
to_chat(user, "<span class'warning'>You need to wipe off the old lipstick first!</span>")
return
if(target == user)
visible_message("<span class='notice'>[user] does [user.p_their()] lips with \the [src].</span>","<span class='notice'>You take a moment to apply \the [src]. Perfect!</span>")
target.lip_style = "lipstick"
target.lip_color = new_color
target.update_body()
return
visible_message("<span class='warning'>[user] begins to do [target]'s lips with \the [src].</span>","<span class='notice'>You begin to apply \the [src] on [target]'s lips...</span>")
if(!do_after(user, 2 SECONDS, target = target))
return
visible_message("<span class='notice'>[user] does [target]'s lips with \the [src].</span>","<span class='notice'>You apply \the [src] on [target]'s lips.</span>")
target.lip_style = "lipstick"
target.lip_color = new_color
target.update_body()
/obj/effect/decal/cleanable/hair
name = "hair cuttings"
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "cut_hair"
/obj/item/razor
name = "electric razor"
desc = "The latest and greatest power razor born from the science of shaving."
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "razor"
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
// How long do we take to shave someone's (facial) hair?
var/shaving_time = 10 SECONDS
/obj/item/razor/proc/shave(mob/living/carbon/human/target_human, location = BODY_ZONE_PRECISE_MOUTH)
if(location == BODY_ZONE_PRECISE_MOUTH)
target_human.facial_hair_style = "Shaved"
else
target_human.hair_style = "Bald"
target_human.update_hair()
playsound(loc, 'sound/items/unsheath.ogg', 20, TRUE)
/obj/item/razor/attack(mob/attacked_mob, mob/living/user)
if(ishuman(attacked_mob))
var/mob/living/carbon/human/target_human = attacked_mob
var/location = user.zone_selected
if(!(location in list(BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_HEAD)))
to_chat(user, "<span class='warning'>You stop, look down at what you're currently holding and ponder to yourself, \"This is probably to be used on their hair or their facial hair.\"</span>")
return
if((location in list(BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_HEAD)) && !target_human.get_bodypart(BODY_ZONE_HEAD))
to_chat(user, "<span class='warning'>[target_human] doesn't have a head!</span>")
return
if(location == BODY_ZONE_PRECISE_MOUTH)
if(!(FACEHAIR in target_human.dna.species.species_traits))
to_chat(user, "<span class='warning'>There is no facial hair to shave!</span>")
return
if(!get_location_accessible(target_human, location))
to_chat(user, "<span class'warning'>The mask is in the way!</span>")
return
if(target_human.facial_hair_style == "Shaved")
to_chat(user, "<span class='warning'>Already clean-shaven!</span>")
return
var/self_shaving = target_human == user // Shaving yourself?
visible_message("<span class='notice'>[user] starts to shave [self_shaving ? user.p_their() : "[target_human]'s"] hair with [src].</span>","<span class='notice'>You take a moment to shave [self_shaving ? "your" : "[target_human]'s" ] hair with [src]...</span>")
if(do_after(user, shaving_time, target = target_human))
visible_message("<span class='notice'>[user] shaves [self_shaving ? user.p_their() : "[target_human]'s"] hair clean with [src].</span>","<span class='notice'>You finish shaving [self_shaving ? "your" : " [target_human]'s"] hair with [src]. Fast and clean!</span>")
shave(target_human, location)
else if(location == BODY_ZONE_HEAD)
if(!(HAIR in target_human.dna.species.species_traits))
to_chat(user, "<span class='warning'>There is no hair to shave!</span>")
return
if(!get_location_accessible(target_human, location))
to_chat(user, "<span class='warning'>Their headgear is in the way!</span>")
return
if(target_human.hair_style == "Bald" || target_human.hair_style == "Balding Hair" || target_human.hair_style == "Skinhead")
to_chat(user, "<span class='warning'>There is not enough hair left to shave!</span>")
return
var/self_shaving = target_human == user // Shaving yourself?
visible_message("<span class='notice'>[user] starts to shave [self_shaving ? user.p_their() : "[target_human]'s"] hair with [src].</span>","<span class='notice'>You take a moment to shave [self_shaving ? "your" : "[target_human]'s" ] hair with [src]...</span>")
if(do_after(user, shaving_time, target = target_human))
visible_message("<span class='notice'>[user] shaves [self_shaving ? user.p_their() : "[target_human]'s"] hair clean with [src].</span>","<span class='notice'>You finish shaving [self_shaving ? "your" : " [target_human]'s"] hair with [src]. Fast and clean!</span>")
shave(target_human, location)
else
..()
else
..()
/obj/structure/sign/barber
name = "barbershop sign"
desc = "A glowing red-blue-white stripe you won't mistake for any other!"
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "barber"
buildable_sign = FALSE // Don't want them removed, they look too jank.
/obj/item/scissors
name = "barber's scissors"
desc = "Some say a barbers best tool is his electric razor, that is not the case. These are used to cut hair in a professional way!"
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "scissors"
w_class = WEIGHT_CLASS_TINY
sharpness = TRUE
// How long does it take to change someone's hairstyle?
var/haircut_duration = 1 MINUTES
// How long does it take to change someone's facial hair style?
var/facial_haircut_duration = 20 SECONDS
/obj/item/scissors/attack(mob/living/attacked_mob, mob/living/user, params)
if(!ishuman(attacked_mob))
return
var/mob/living/carbon/human/target_human = attacked_mob
var/location = user.zone_selected
if(!(location in list(BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_HEAD)))
to_chat(user, "<span class='warning'>You stop, look down at what you're currently holding and ponder to yourself, \"This is probably to be used on their hair or their facial hair.\"</span>")
return
if(target_human.hair_style == "Bald" && target_human.facial_hair_style == "Shaved")
to_chat(user, "<span class='warning'>What hair? They have none!</span>")
return
if(user.zone_selected != BODY_ZONE_HEAD)
return ..()
var/selected_part = tgalert(user, "Please select which part of [target_human] you would like to sculpt!", "It's sculpting time!", "Hair", "Facial Hair", "Cancel")
if(!selected_part || selected_part == "Cancel")
return
if(selected_part == "Hair")
if(!target_human.hair_style == "Bald" && target_human.head)
to_chat(user, "<span class='warning'>There is no hair to cut!</span>")
return
var/hair_id = input(user, "Please select what hairstyle you'd like to sculpt!", "Select masterpiece") as null|anything in GLOB.hair_styles_list //dear god help me please
if(!hair_id)
return
if(hair_id == "Bald")
to_chat(target_human, "<span class='warning'>[user] seems to be cutting all your hair off!</span>")
to_chat(user, "<span class='notice'>You begin to masterfully sculpt [target_human]'s hair!</span>")
playsound(target_human, 'hyperstation/sound/salon/haircut.ogg', 100)
if(do_after(user, haircut_duration, target_human))
target_human.hair_style = hair_id
target_human.update_hair()
visible_message("<span class='notice'>[user] successfully cuts [target_human]'s hair!</span>","<span class='notice'>You successfully cut [target_human]'s hair!</span>")
new /obj/effect/decal/cleanable/hair(get_turf(src))
else
if(!target_human.facial_hair_style == "Shaved" && target_human.wear_mask)
to_chat(user, "<span class='warning'>There is no hair to cut!</span>")
return
var/facial_hair_id = input(user, "Please select what facial hairstyle you'd like to sculpt!", "Select masterpiece") as null|anything in GLOB.facial_hair_styles_list
if(!facial_hair_id)
return
if(facial_hair_id == "Shaved")
to_chat(target_human, "<span class='warning'>[user] seems to be cutting all your facial hair off!</span>")
to_chat(user, "<span class='notice'>You begin to masterfully sculpt [target_human]'s facial hair!</span>")
playsound(target_human, 'hyperstation/sound/salon/haircut.ogg', 100)
if(do_after(user, facial_haircut_duration, target_human))
target_human.facial_hair_style = facial_hair_id
target_human.update_hair()
visible_message("<span class='notice'>[user] successfully cuts [target_human]'s facial hair!</span>","<span class='notice'>You successfully cut [target_human]'s facial hair!</span>")
new /obj/effect/decal/cleanable/hair(get_turf(src))
//reagents
/obj/item/reagent_containers/spray/quantum_hair_dye
name = "quantum hair dye"
desc = "Changes hair colour RANDOMLY! Don't forget to read the label!"
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "hairspraywhite"
amount_per_transfer_from_this = 1
possible_transfer_amounts = list(5,10)
list_reagents = list(/datum/reagent/hair_dye = 30)
volume = 50
/*
/obj/item/reagent_containers/spray/baldium
name = "baldium spray"
desc = "Causes baldness, exessive use may cause customer disatisfaction."
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "hairremoval"
amount_per_transfer_from_this = 1
possible_transfer_amounts = list(5,10)
list_reagents = list(/datum/reagent/baldium = 30)
volume = 50
*/
/obj/item/reagent_containers/spray/barbers_aid
name = "barber's aid"
desc = "Causes rapid hair and facial hair growth!"
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "hairaccelerator"
amount_per_transfer_from_this = 1
possible_transfer_amounts = list(5,10)
list_reagents = list(/datum/reagent/barbers_aid = 50)
volume = 50
/obj/item/reagent_containers/spray/super_barbers_aid
name = "super barber's aid"
desc = "Causes SUPER rapid hair and facial hair growth!"
icon = 'hyperstation/icons/obj/barber.dmi'
icon_state = "hairaccelerator"
amount_per_transfer_from_this = 1
possible_transfer_amounts = list(5,10)
list_reagents = list(/datum/reagent/concentrated_barbers_aid = 30)
volume = 50
@@ -0,0 +1,32 @@
/obj/machinery/vending/teavendomatic
name = "\improper Tea Vend-O-Matic"
desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one, this one is branded for tea and non-alcoholic beverages... Mostly."
icon_state = "boozeomat"
icon_deny = "boozeomat-deny"
products = list(
/obj/item/reagent_containers/food/drinks/mug/tea = 30,
/obj/item/reagent_containers/food/drinks/bottle/wine = 5,
/obj/item/reagent_containers/food/drinks/bottle/cognac = 5,
/obj/item/reagent_containers/food/drinks/bottle/grappa = 5,
/obj/item/reagent_containers/food/drinks/bottle/sake = 5,
/obj/item/reagent_containers/food/drinks/bottle/orangejuice = 8,
/obj/item/reagent_containers/food/drinks/bottle/tomatojuice = 8,
/obj/item/reagent_containers/food/drinks/bottle/limejuice = 8,
/obj/item/reagent_containers/food/drinks/bottle/grenadine = 4,
/obj/item/reagent_containers/food/drinks/bottle/cream = 8,
/obj/item/reagent_containers/food/drinks/soda_cans/tonic = 8,
/obj/item/reagent_containers/food/drinks/soda_cans/cola = 8,
/obj/item/reagent_containers/food/drinks/soda_cans/sodawater = 15,
/obj/item/reagent_containers/food/drinks/drinkingglass = 30,
/obj/item/reagent_containers/food/drinks/ice = 10,
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12,
/obj/item/reagent_containers/food/drinks/flask = 3)
contraband = list(/obj/item/reagent_containers/food/drinks/mug/tea = 12,)
premium = list(/obj/item/reagent_containers/glass/bottle/ethanol = 4,
/obj/item/reagent_containers/food/drinks/bottle/champagne = 5,
/obj/item/reagent_containers/food/drinks/bottle/trappist = 5)
product_slogans = "Keep a clear head and drink on.;It is a quite fine day to sit down and have a drink.;Remember to drink responsibly.;Products are assured to be GMO free."
product_ads = "Stay Radiant.;Remember to balance your intake.;Radiikist brands are not permitted in sectors 34-A through 59-B.;Keep a level head.;Refreshments are to be taken in modicum.;Let the day's stress melt away.;Please, enjoy.;In-service since the sixth Era."
req_access = list(ACCESS_BARISTA)
//refill_canister = /obj/item/vending_refill/teavendomatic
free = TRUE
@@ -0,0 +1,11 @@
/obj/machinery/reagentgrinder/reagentblender
name = "Stand mixer"
desc = "a stationary electric mixer for heavy-duty mixing various foods and other reagents."
icon = 'hyperstation/icons/obj/machinery/reagentblender.dmi'
icon_state = "mixer1"
/obj/machinery/reagentgrinder/reagentblender/update_icon()
if(beaker)
icon_state = "mixer1"
else
icon_state = "mixer0"
+16
View File
@@ -0,0 +1,16 @@
/obj/item/clothing/gloves/lambent
name = "Lambent's sleeves"
desc = "An elegant sleeve worn from the shoulder down. Despite missing anything on the palm and fingers, it seems to cast small hardlight protections over the hands, like a glove."
icon_state = "lambent"
item_state = "lambent"
icon = 'hyperstation/icons/obj/clothing/gloves.dmi'
alternate_worn_icon = 'hyperstation/icons/mobs/gloves.dmi'
armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
transfer_prints = FALSE
strip_delay = 40
body_parts_covered = ARMS|HANDS
cold_protection = ARMS|HANDS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
siemens_coefficient = 0
permeability_coefficient = 0.05
+14
View File
@@ -0,0 +1,14 @@
/obj/item/clothing/shoes/lambent
name = "Lambent's heels"
desc = "A sleek pair of leggings with high heels, gilded in golden strips. It seems to have an autobalancing matrix installed."
icon_state = "lambent"
item_state = "lambent"
icon = 'hyperstation/icons/obj/clothing/shoes.dmi'
alternate_worn_icon = 'hyperstation/icons/mobs/feet.dmi'
body_parts_covered = LEGS|FEET
cold_protection = LEGS|FEET
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
strip_delay = 70
resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
clothing_flags = NOSLIP
+13
View File
@@ -0,0 +1,13 @@
/obj/item/clothing/suit/lambent
name = "Lambent's coat"
desc = "A regal-esque coat outfitted with inert nanites, waiting to be activated at a moment's notice."
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
//alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
icon_state = "lambent"
item_state = "lambent"
body_parts_covered = CHEST|LEGS
cold_protection = CHEST|GROIN|LEGS|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
strip_delay = 70
resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
+14
View File
@@ -0,0 +1,14 @@
/obj/item/clothing/under/rank/lambent
name = "Lambent's outfitting"
desc = "A Hyperwoven outfitting meant for a Kinaris Lambent. It's gilded colors and ultratech weaving speak highly about status."
icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
//alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
icon_state = "lambent"
item_state = "lambent"
armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 20, "acid" = 60)
resistance_flags = LAVA_PROOF|FIRE_PROOF|UNACIDABLE
strip_delay = 50
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
//We'll add more alternative outfits here later. For now this'll be how it is!
+7
View File
@@ -0,0 +1,7 @@
/obj/item/clothing/under/barber
name = "barber's uniform"
desc = "A fancy pink shirt paired with light-catching white pants. Yet to be blood- and puke-stained."
icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
//alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
icon_state = "barber"
item_state = "barber"
+3
View File
@@ -160,6 +160,9 @@ obj/item/clothing/neck/stole/black
var/firstpickup = TRUE
var/pickupsound = TRUE
/obj/item/clothing/under/vaultsuit/no_sound
pickupsound = FALSE
/obj/item/clothing/under/vaultsuit/equipped(mob/user, slot)
. = ..()
if(!pickupsound)
+8 -1
View File
@@ -74,4 +74,11 @@
item_state = "enzor"
attack_verb = list("tail bapped", "whomped", "squeaked")
squeak_override = list('sound/effects/mousesqueek.ogg'= 1)
//End
//Arc is amazing and has helped Hyper in terms of spriting a ton. They deserve this
/obj/item/toy/plush/lizardplushie/arctaisia
name = "fat lizard plushie"
desc = "This lizard is a heckin' chonker!"
icon = 'hyperstation/icons/obj/plushes.dmi'
icon_state = "arc"
squeak_override = list('modular_citadel/sound/voice/weh.ogg' = 1)
@@ -0,0 +1,7 @@
/obj/structure/beacon
name = "beacon"
desc = "A small marker beacon"
anchored = TRUE
density = FALSE
icon = 'hyperstation/icons/obj/structures/beacons.dmi'
icon_state = "beacon"
+4 -3
View File
@@ -132,13 +132,14 @@ Code:
if(2) //med, can make you cum
to_chat(U, "<span class='love'>You feel intense pleasure surge through your [G.name]</span>")
U.do_jitter_animation()
U.mob_climax_instant()
if (U.getArousalLoss() >= 100 && ishuman(U) && U.has_dna())
U.mob_climax(forced_climax=TRUE)
if(3) //high, makes you stun
to_chat(U, "<span class='userdanger'>You feel overpowering pleasure surge through your [G.name]</span>")
U.Jitter(3)
U.Stun(30)
if (U.can_orgasm())
U.mob_climax_instant()
if (U.getArousalLoss() >= 100 && ishuman(U) && U.has_dna())
U.mob_climax(forced_climax=TRUE)
if(prob(50))
U.emote("moan")