Merge branch 'master' into upstream-merge-7756

This commit is contained in:
Novacat
2021-03-09 15:11:54 -05:00
committed by GitHub
806 changed files with 557589 additions and 66547 deletions
+1 -4
View File
@@ -40,10 +40,7 @@
return TRUE
/atom/movable/proc/has_buckled_mobs()
if(!buckled_mobs)
return FALSE
if(buckled_mobs.len)
return TRUE
return LAZYLEN(buckled_mobs)
/atom/movable/Destroy()
unbuckle_all_mobs()
+1 -1
View File
@@ -11,7 +11,7 @@
create_reagents(100)
/obj/effect/decal/cleanable/chemcoating/Initialize()
..()
. = ..()
var/turf/T = get_turf(src)
if(T)
for(var/obj/O in get_turf(src))
@@ -90,6 +90,39 @@
serial_number = given_serial
..(loc)
//Selectable subtype
/obj/item/weapon/contraband/poster/custom
name = "rolled-up poly-poster"
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. This one is made from some kind of e-paper, and could display almost anything!"
poster_type = /obj/structure/sign/poster/custom
/obj/item/weapon/contraband/poster/custom/New(turf/loc, var/given_serial = 0)
if(given_serial == 0)
serial_number = 1 //Decidedly unrandom
else
serial_number = given_serial
..(loc)
/obj/item/weapon/contraband/poster/custom/verb/select_poster()
set name = "Set Poster type"
set category = "Object"
set desc = "Click to choose a poster to display."
var/mob/M = usr
var/list/options = list()
for(var/datum/poster/posteroption in poster_designs)
options[posteroption.listing_name] = posteroption
var/choice = input(M,"Choose a poster!","Customize Poster") in options
if(src && choice && !M.stat && in_range(M,src))
var serial = poster_designs.Find(options[choice])
serial_number = serial
name = "rolled-up poly-poster - No.[serial]"
to_chat(M, "The poster is now: [choice].")
return 1
//############################## THE ACTUAL DECALS ###########################
/obj/structure/sign/poster
@@ -187,6 +220,7 @@
// Description suffix
var/desc=""
var/icon_state=""
var/listing_name=""
// NT poster subtype.
/obj/structure/sign/poster/nanotrasen
@@ -201,3 +235,8 @@
set_poster(design)
..(newloc, placement_dir, serial, itemtype)
//Non-Random Posters
/obj/structure/sign/poster/custom
roll_type = /obj/item/weapon/contraband/poster/custom
+115 -57
View File
@@ -1,290 +1,348 @@
// baystation12 posters
/datum/poster/bay_1
icon_state="bsposter1"
name = "Unlucky Space Explorer"
desc = "This particular one depicts a skeletal form within a space suit."
name = "PSA: Unlucky Space Explorer"
desc = "This grim PSA depicts a skeletal form within a space suit. Thousands die every year as a result of failing to follow EVA safety guidelines."
listing_name = "PSA - EVA Accidents"
/datum/poster/bay_2
icon_state="bsposter2"
name = "Positronic Logic Conflicts"
desc = "This particular one depicts the cold, unmoving stare of a particular advanced AI."
name = "PSA: Disobedient Drones"
desc = "This PSA depicts the cold, unmoving stare of a particularly advanced AI. Contact information for the Emergent Intelligence Oversight is included."
listing_name = "PSA - Emergent Drones"
/datum/poster/bay_3
icon_state="bsposter3"
name = "Paranoia"
desc = "This particular one warns of the dangers of trusting your co-workers too much."
name = "PSA: Corporate Espionage"
desc = "This PSA warns of the dangers of trusting your co-workers with sensitive department information. They may be spying for a rival corporation, or worse!"
listing_name = "PSA - Corporate Espionage"
/datum/poster/bay_4
icon_state="bsposter4"
name = "Keep Calm"
desc = "This particular one is of a famous New Earth design, although a bit modified. Someone has scribbled an O over the A on the poster."
desc = "An incredibly vague message, presented in a classic form. Someone has scribbled an O over the A on the poster."
listing_name = "PSA - Keep Calm"
/datum/poster/bay_5
icon_state="bsposter5"
name = "Martian Warlord"
desc = "This particular one depicts the cartoony mug of a certain Martial Warmonger."
name = "PSA: Saboteurs!"
desc = "A company PSA reminding employees to keep an eye out for suspicious activity, and report it immediately."
listing_name = "PSA - Saboteur"
/datum/poster/bay_6
icon_state="bsposter6"
name = "Technological Singularity"
desc = "This particular one is of the blood-curdling symbol of a long-since defeated enemy of humanity."
name = "Eradicator XV"
desc = "An ad for the fifteenth installment in the Eradicator movie franchise, about a violent robotic uprising hellbent on wiping out humanity."
listing_name = "Ad - Eradicator XV"
/datum/poster/bay_7
icon_state="bsposter7"
name = "Wasteland"
desc = "This particular one is of a couple of ragged gunmen, one male and one female, on top of a mound of rubble. The number \"12\" is visible on their blue jumpsuits."
name = "Wasteland: Battle for Earth"
desc = "This action movie ad shows a couple of ragged post-apocalyptic gunmen, one male and one female, on top of a mound of rubble."
listing_name = "Ad - Battle for Earth"
/datum/poster/bay_8
icon_state="bsposter8"
name = "Pinup Girl Cindy"
desc = "This particular one is of a historical corporate PR girl, Cindy, in a particularly feminine pose."
desc = "This is a vintage 2450s pin-up of NanoTrasen's PR girl, Cindy, in a particularly feminine pose."
listing_name = "Pin-up - Cindi"
/datum/poster/bay_9
icon_state="bsposter9"
name = "Pinup Girl Amy"
desc = "This particular one is of Amy, the nymphomaniac urban legend of deep space. How this photograph came to be is not known."
desc = "This pin-up is of Amy, one of NanoTrasen's most popular PR models."
listing_name = "Pin-up - Amy"
/datum/poster/bay_10
icon_state="bsposter10"
name = "Don't Panic"
desc = "This particular one depicts some sort of star in a grimace. The \"Don't Panic\" is written in big, friendly letters."
desc = "This ad for Vey-Medical anxiety pills depicts some sort of star in a grimace. The \"Don't Panic\" is written in big, friendly letters."
listing_name = "Ad - Don't panic."
/datum/poster/bay_11
icon_state="bsposter11"
name = "Underwater Laboratory"
desc = "This particular one is of the fabled last crew of a previous Company project."
name = "Underwater Living"
desc = "This immigration poster encourages you to move to Earth;s premiere underwater city, Atlantis. One bedroom apartments start at half your salary."
listing_name = "Ad - Atlantis"
/datum/poster/bay_12
icon_state="bsposter12"
name = "Rogue AI"
desc = "This particular one depicts the shell of the infamous AI that catastropically comandeered one of humanity's earliest space stations. Back then, the Company was just known as TriOptimum."
name = "Beware Rogue AI"
desc = "This ad for the Emergent Intelligence Oversight Recruitment Division depicts a menacing AI and asks if you're a bad enough dude to take it on."
listing_name = "Recruitment - EIO"
/datum/poster/bay_13
icon_state="bsposter13"
name = "User of the Arcane Arts"
desc = "This particular one depicts a wizard, casting a spell. You can't really make out if it's an actual photograph or a computer-generated image."
name = "Become A User of the Arcane Arts"
desc = "This ad for popular Virtual Reality online game 'Wiz Online' depicts a wizard, casting a spell. You can't really make out if it's an actual photograph or a computer-generated image. Incredible graphics!"
listing_name = "Ad - Wiz Online"
/datum/poster/bay_14
icon_state="bsposter14"
name = "Levitating Skull"
desc = "This particular one is the portrait of a flying enchanted skull. Its adventures along with its fabled companion are now fading through history..."
desc = "This tacky ad is a portrait of the flying enchanted skull, Bones. Its adventures along with its fabled companion are showing now on a broadcast service near you!"
listing_name = "Ad - Bones Adventures"
/datum/poster/bay_15
icon_state="bsposter15"
name = "Augmented Legend"
desc = "This particular one is of an obviously augmented individual, gazing towards the sky. The cyber-city in the backround is rather punkish."
desc = "This ad for Ward-Takahashi cybernetic implants shows obviously augmented individual, gazing towards the sky. Is your body augmented?"
listing_name = "Ad - Ward-Takahashi Augments"
/datum/poster/bay_16
icon_state="bsposter16"
name = "Dangerous Static"
desc = "This particular one depicts nothing remarkable other than a rather mesmerising pattern of monitor static. There's a tag on the sides of the poster, but it's ripped off."
name = "Snow Crash"
desc = "This particular one depicts nothing remarkable other than a rather mesmerising pattern of monitor static. You think it's an ad for something, but you're not sure what."
listing_name = "Ad - Snow Crash"
/datum/poster/bay_17
icon_state="bsposter17"
name = "Pinup Girl Val"
desc = "Luscious Val McNeil, the vertically challenged Legal Extraordinaire, winner of Miss Space two years running and favoured pinup girl of Lawyers Weekly."
listing_name = "Pin-up - Val"
/datum/poster/bay_18
icon_state="bsposter18"
name = "Derpman, Enforcer of the State"
desc = "Here to protect and serve... your donuts! A generously proportioned man, he teaches you the value of hiding your snacks."
desc = "An ad for Centauri Provisions donuts. Officer Derpman is here to protect and serve... your donuts! A generously proportioned man, he teaches you the value of hiding your snacks."
listing_name = "Ad - Officer Derpman Donuts"
/datum/poster/bay_19
icon_state="bsposter19"
name = "Respect an Unathi"
desc = "This poster depicts a well dressed looking Unathi receiving a prestigious award. It appears to espouse greater co-operation and harmony between the two races."
desc = "This poster depicts a sharply dressed Unathi receiving a prestigious award. It appears to espouse greater co-operation and harmony between humanity and the Unathi."
listing_name = "PSA - Unathi"
/datum/poster/bay_20
icon_state="bsposter20"
name = "Skrell Twilight"
desc = "This poster depicts a mysteriously inscrutable, alien scene. Numerous Skrell can be seen conversing amidst great, crystalline towers rising above crashing waves"
name = "Skrell Tourism"
desc = "This tourism poster depicts a mysteriously inscrutable, alien scene. Numerous Skrell can be seen conversing amidst great, crystalline towers rising above crashing waves."
listing_name = "Ad - Skrellian Tourism"
/datum/poster/bay_21
icon_state="bsposter21"
name = "Join the Fuzz!"
desc = "It's a nice recruitment poster of a white haired Chinese woman that says; \"Big Guns, Hot Women, Good Times. Security. We get it done.\""
listing_name = "Recruitment - NanoTrasen Security - Pinup"
/datum/poster/bay_22
icon_state="bsposter22"
name = "Looking for a career with excitement?"
desc = "A recruitment poster starring a dark haired woman with glasses and a purple shirt that has \"Got Brains? Got Talent? Not afraid of electric flying monsters that want to suck the soul out of you? Then Xenobiology could use someone like you!\" written on the bottom."
listing_name = "Recruitment - Xenobiology"
/datum/poster/bay_23
icon_state="bsposter23"
name = "Safety first: because electricity doesn't wait!"
desc = "A safety poster starring a clueless looking redhead with frazzled hair. \"Every year, hundreds of NT employees expose themselves to electric shock. Play it safe. Avoid suspicious doors after electrical storms, and always wear protection when doing electric maintenance.\""
listing_name = "Safety - Electric Shock"
/datum/poster/bay_24
icon_state="bsposter24"
name = "Responsible medbay habits, No #259"
desc = "A poster with a nervous looking geneticist on it states; \"Friends Tell Friends They're Clones. It can cause severe and irreparable emotional trauma if a person is not properly informed of their recent demise. Always follow your contractual obligation and inform them of their recent rejuvenation.\""
listing_name = "Medical - Clone Disclosure"
/datum/poster/bay_25
icon_state="bsposter25"
name = "Irresponsible medbay habits, No #2"
desc = "This is a safety poster starring a perverted looking naked doctor. \"Sexual harassment is never okay. REPORT any acts of sexual deviance or harassment that disrupt a healthy working environment.\""
listing_name = "Medical - Sexual Harassment"
/datum/poster/bay_26
icon_state="bsposter26"
name = "The Men We Knew"
desc = "This movie poster depicts a group of soldiers fighting a large mech, the movie seems to be a patriotic war movie."
desc = "This movie poster depicts a group of soldiers fighting a large mech, it seems to be some kind of movie set during the Hegemony War."
listing_name = "Ad - Men We Knew"
/datum/poster/bay_27
icon_state="bsposter27"
name = "Plastic Sheep Can't Scream"
desc = "This is a movie poster for an upcoming horror movie, it features an AI in the front of it."
desc = "This is a movie poster for an upcoming horror movie, featuring a frightening looking robotic creature."
listing_name = "Ad - Plastic Sheep Can't Scream"
/datum/poster/bay_28
icon_state="bsposter28"
name = "The Stars Know Love"
desc = "This is a movie poster. A bleeding woman is shown drawing a heart in her blood on the window of space ship, it seems to be a romantic Drama."
desc = "This is a movie poster. A bleeding woman is shown drawing a heart in her blood on the window of space ship, it seems to be a romantic drama."
listing_name = "Ad - The Stars Know Love"
/datum/poster/bay_29
icon_state="bsposter29"
name = "Winter Is Coming"
desc = "On the poster is a frighteningly large wolf, he warns: \"Only YOU can keep the station from freezing during planetary occultation!\""
desc = "On the poster is a frighteningly large wolf, he warns: \"Only YOU can keep yourself from freezing this winter!\". Below is the logo of NanoThreads clothing."
listing_name = "Ad - Cold-weather Gear"
/datum/poster/bay_30
icon_state="bsposter30"
name = "Ambrosia Vulgaris"
desc = "Just looking at this poster makes you feel a little bit dizzy."
desc = "It's an ad for getting absolutely shitfaced on psychadelics. Just looking at this poster makes you feel a little bit dizzy. Use responsibly."
listing_name = "Ad - Ambrosia Vulgaris"
/datum/poster/bay_31
icon_state="bsposter31"
name = "Donut Corp"
desc = "This is an advertisement for Donut Corp, the new innovation in donut technology!"
name = "Donut Panic"
desc = "This is an advertisement for Donut Panic, the bi-monthly periodical for donut lovers galaxy-wide."
listing_name = "Ad - Donuts Panic"
/datum/poster/bay_32
icon_state="bsposter32"
name = "Eat!"
desc = "A poster depicting a hamburger. The poster orders you to consume the hamburger."
desc = "A NanoPastures poster depicting a synthmeat hamburger. The poster COMMANDS you to consume the hamburger."
listing_name = "Ad - Hamburger"
/datum/poster/bay_33
icon_state="bsposter33"
name = "Tools, tools, tools"
desc = "You can never have enough tools, thats for sure!"
name = "Tools, tools, tools!"
desc = "Xion Manufacturing reminds you: Never trust an off-brand tool. "
listing_name = "Ad - Xion Tools"
/datum/poster/bay_34
icon_state="bsposter34"
name = "Power Up!"
desc = "High reward, higher risk!"
desc = "NanoTrasen are leaders in Phoron-based supermatter power! High reward, higher risk!"
listing_name = "Ad - Phoron Power"
/datum/poster/bay_35
icon_state="bsposter35"
name = "Lamarr"
desc = "This is a poster depicting the pet and mascot of the science department."
name = "Kendrick"
desc = "This is a poster depicting the pet and mascot of the science department, and national corporate ambassador for slime-based science solutions.."
listing_name = "Ad - Slime Science"
/datum/poster/bay_36
icon_state="bsposter36"
name = "Fancy Borg"
desc = "A poster depicting a cyborg using the service module. 'Fancy Borg' is written on it."
desc = "A poster depicting a cyborg dressed to the nines. An ad for cybernetics enthusiast magazine, Borg Fancy."
listing_name = "Ad - Borg Fancy A"
/datum/poster/bay_37
icon_state="bsposter37"
name = "Fancier Borg"
desc = "A poster depicting a cyborg using the service module. 'Fancy Borg' is written on it. This is even fancier than the first poster."
desc = "A poster depicting a cyborg dressed to the nines. An ad for cybernetics enthusiast magazine, Borg Fancy. This is even fancier than the other poster."
listing_name = "Ad - Borg Fancy B"
/datum/poster/bay_38
icon_state="bsposter38"
name = "Toaster Love"
desc = "This is a poster of a toaster containing two slices of bread. The word LOVE is written in big pink letters underneath."
desc = "This is a poster of a toaster containing two slices of bread. The word LOVE is written in big pink letters underneath. An ad for a cybernetics 'enthusiast' magazine. "
listing_name = "Ad - Toaster Love"
/datum/poster/bay_39
icon_state="bsposter39"
name = "Responsible medbay habits, No #91"
desc = "A safety poster with a chemist holding a vial. \"Always wear safety gear while handling dangerous chemicals, even if it concerns only small amounts.\""
listing_name = "Safety - Chemicals"
/datum/poster/bay_40
icon_state="bsposter40"
name = "Agreeable work environment"
desc = "This poster depicts a young woman in a stylish dress. \"Try to aim for a pleasant atmosphere in the workspace. A friendly word can do more than forms in triplicate.\""
listing_name = "PSA - Agreeable Work Environment"
/datum/poster/bay_41
icon_state="bsposter41"
name = "Professional work environment"
desc = "A safety poster featuring a green haired woman in a shimmering blue dress. \"As an Internal Affairs Agent, your job is to create a fair and agreeable work environment for the crewmembers, as discreetly and professionally as possible.\""
listing_name = "Recruitment - Internal Affairs"
/datum/poster/bay_42
icon_state="bsposter42"
name = "Engineering pinup"
desc = "This is pin-up poster. A half-naked girl with white hair, toned muscles and stunning blue eyes looks back at you from the poster. Her welding helmet, tattoos and grey jumpsuit hanging around her waist gives a bit of a rugged feel."
listing_name = "Pin-up - Engineer"
/datum/poster/bay_43
icon_state="bsposter43"
name = "Responsible medbay habits, No #3"
desc = "A safety poster with a purple-haired surgeon. She looks a bit cross. \"Let the surgeons do their work. NEVER replace or remove a surgery tool from where the surgeon put it.\""
listing_name = "Safety - Surgical Tools"
/datum/poster/bay_44
icon_state="bsposter44"
name = "Time for a drink?"
desc = "This poster depicts a friendly-looking Tajaran holding a tray of drinks."
desc = "This poster for a brand for \"Tajaran-style\" rum produced by Gilthari Exports depicts a friendly-looking Tajaran holding a tray of drinks."
listing_name = "Ad - Rarkajar Rum"
/datum/poster/bay_45
icon_state="bsposter45"
name = "Responsible engineering habits, No #1"
desc = "A safety poster featuring a blue haired engineer. \"When repairing a machine or construction, always aim for long-term solutions.\""
listing_name = "Safety - No Shortcut Fixes"
/datum/poster/bay_46
icon_state="bsposter46"
name = "Inspirational lawyer"
desc = "An inspirational poster depicting a Skrellian lawyer. He seems to be shouting something, while pointing fiercely to the right."
desc = "An inspirational poster depicting a Skrellian lawyer. He seems to be shouting something, while pointing fiercely to the right. It's an ad for a NanoTrasen subsidiary law firm."
listing_name = "Ad - NanoTrasen Law"
/datum/poster/bay_47
icon_state="bsposter47"
name = "Security pinup"
desc = "This is a pin-up poster. A dark skinned white haired girl poses in the sunlight wearing a tank top with her stomach exposed. The text on the poster states \"M, Succubus of Security.\" and a lipstick mark stains the top right corner, as if kissed by the model herself."
listing_name = "Pin-up - Security"
/datum/poster/bay_48
icon_state="bsposter48"
name = "Borg pinup?"
desc = "This is a.. pin-up poster? It is a diagram on an old model of cyborg with a note scribbled in marker on the bottom, on the top there is a large XO written in red marker."
name = "Remote Drones 4 U"
desc = "This is an ad for a fairly basic model of drone produced by Grayson Manufactories Ltd. for use in hazardous environments."
listing_name = "Ad - Grayson Drones"
/datum/poster/bay_49
icon_state="bsposter49"
name = "Engineering recruitment"
desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\""
listing_name = "Recruitment - Engineering"
/datum/poster/bay_50
icon_state="bsposter50"
name = "Pinup Girl Cindy Kate"
desc = "This particular one is of Cindy Kate, a seductive performer well known among less savoury circles."
desc = "This particular one is of Cindy Kate, a seductive virtual performer well known among less savoury exonet circles."
listing_name = "Pin-up - Cindi-Kate"
/datum/poster/bay_51
icon_state="bsposter51"
name = "space appreciation poster"
desc = "This is a poster produced by the Generic Space Company, as a part of a series of commemorative posters on the wonders of space. One of three."
name = "space tourism poster"
desc = "This is a poster produced by the Visit Space Society. This one is targeted at planet-dwellers, suggesting they generally visit space."
listing_name = "Tourism - Space"
/datum/poster/bay_52
icon_state="bsposter52"
name = "fire safety poster"
desc = "This is a poster reminding you of what you should do if you are on fire, or if you are at a dance party."
listing_name = "Safety - Stop Drop and Roll"
/datum/poster/bay_53
icon_state="bsposter53"
name = "fire extinguisher poster"
desc = "This is a poster reminding you of what you should use to put out a fire."
listing_name = "Safety - Fire Extinguishers"
/datum/poster/bay_54
icon_state="bsposter54"
name = "firefighter poster"
desc = "This is a poster of a particularly stern looking firefighter. The caption reads, \"Only you can prevent space fires.\""
listing_name = "Safety - Prevent Fires"
/datum/poster/bay_55
icon_state="bsposter55"
name = "Earth appreciation poster"
desc = "This is a poster produced by the Generic Space Company, as a part of a series of commemorative posters on the wonders of space. Two of three."
name = "Binma tourism poster"
desc = "This is a poster produced by the Visit Space Society. This one suggests you visit the exotic garden world of Binma, and try not to get eaten."
listing_name = "Tourism - Binma"
/datum/poster/bay_56
icon_state="bsposter56"
name = "Mars appreciation poster"
desc = "This is a poster produced by the Generic Space Company, as a part of a series of commemorative posters on the wonders of space. Three of three."
desc = "This is a poster produced by the Visit Space Society. This one suggests you visit historic Mars. Come for the domes, stay for the monuments to hubris!"
/datum/poster/bay_57
icon_state="bsposter57"
name = "space carp warning poster"
desc = "This poster tells of the dangers of space carp infestations."
listing_name = "Safety - Carp"
/datum/poster/bay_58
icon_state="bsposter58"
name = "space carp information poster"
desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
listing_name = "Safety - Carp Information"
@@ -2,41 +2,49 @@
icon_state="polposter1"
name = "Safety!"
desc = "A poster advising you to learn how to put on your internals at a moment's notice."
listing_name = "Safety - Internals"
/datum/poster/pol_2
icon_state="polposter2"
name = "Safety!"
desc = "A blue and white colored poster. This one advises you to wear your safety goggles when handling chemicals."
listing_name = "Safety - Goggles"
/datum/poster/pol_3
icon_state="polposter3"
name = "Safety!"
desc = "A safety poster instructing you to comply with the authorities, especially in an emergency."
listing_name = "Safety - Follow Instruction"
/datum/poster/pol_4
icon_state="polposter4"
name = "Clean Hands Save Lives"
desc = "A safety poster reminding you to wash your hands."
listing_name = "Safety - Hand Washing"
/datum/poster/pol_5
icon_state="polposter5"
name = "Help!"
desc = "This poster depicts a man helping another man get up."
listing_name = "Safety - Help Others"
/datum/poster/pol_6
icon_state="polposter6"
name = "Walk!"
desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls."
listing_name = "Safety - No Running"
/datum/poster/pol_7
icon_state="polposter7"
name = "Place your signs!"
desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded."
listing_name = "Safety - Wet Floor Signs"
/datum/poster/pol_8
icon_state="polposter8"
name = "Safety!"
desc = "An advertisement / safety poster for EVA training and certification. Training is available at your local Central Command."
listing_name = "Safety - EVA Training"
/datum/poster/pol_9
icon_state="poster10" //Recycling this icon
@@ -44,52 +52,138 @@
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
wire codes."
listing_name = "Safety - Airlock Maintenance"
/datum/poster/pol_10
icon_state="polposter9"
name = "orchid"
desc = "This poster appears strangely familiar, depicting the flower of a tree native to the planet Earth."
listing_name = "General - Orchid"
// A new subset of poster datum for Security posters.
/datum/poster/pol_11
icon_state="polposter10"
name = "firefighter pinup"
desc = "A buff firefighter with his shirt off. Maybe he's trying to raise awareness about fire safety, but you're a little distracted."
listing_name = "Pin-up - Firefighter"
/datum/poster/pol_12
icon_state="polposter11"
name = "CHUCK"
desc = "With the budget Cyber Solutions 'Chuck' model work drone, your days of menial labour are numbered! \"With Cyber Solutions, there's always someone beside you, helping you. You know their face. You know my face.\""
listing_name = "Ad - Chuck"
/datum/poster/pol_13
icon_state="polposter12"
name = "New You"
desc = "An ad for Kaleidoscope Cosmetics. \"The common factor in all your failed relationships is you. Fix it with affordable gene therapy!\""
listing_name = "Ad - Kaleidoscope"
/datum/poster/pol_14
icon_state="polposter13"
name = "Take a Taxi"
desc = "An ad for the Major Bill's Transportation drone-operated taxi service operating in most major cities throughout Solar space."
listing_name = "Ad - Taxi"
/datum/poster/pol_15
icon_state="polposter14"
name = "Adopt A Teshpet"
desc = "An ad for definitively racist virtual pet game, Teshpets."
listing_name = "Ad - Teshpets"
/datum/poster/pol_16
icon_state="polposter15"
name = "Train and Fight"
desc = "This poster of sweaty, near-naked wrestlers is the most masculine thing you've ever seen. You can barely tell where one man ends and the other begins. Always seek manliness!"
listing_name = "Pinup - Wrestling"
/datum/poster/nt_3
icon_state = "ntposter03"
name = "Mechatronic Safety"
desc = "This poster displays three cutting-edge gygaxes standing in line in front of a man in plain clothes.\
The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
The image seems important."
listing_name = "Safety - Mech Operation"
/datum/poster/nt_4
icon_state = "ntposter04"
name = "Beware Aetotheans"
desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
listing_name = "Safety - Aetothean Danger"
/datum/poster/nt_5
icon_state = "ntposter05"
name = "Promethean"
desc = "This poster displays a friendly-looking green Promethean in a labcoat. The fine-print around the edges talks about the benefits Prometheans give in laboratories."
listing_name = "Safety - Prometheans"
/datum/poster/nt_6
icon_state = "ntposter06"
name = "NanoTrasen"
desc = "This poster showcases an NT emblem. There is writing in the ring around the inner points, probably some sort of slogan no one bothers to memorize."
listing_name = "Ad - NanoTrasen"
/datum/poster/nt_7
icon_state = "ntposter07"
name = "SolGov"
desc = "This poster showcases an SCG emblem. The outer ring reads,\
\"<font face='times new roman ms'>NIL MORTALIBUS ARDUI EST</font>\".\
Solar Confederate Government."
listing_name = "Political - SolGov"
/datum/poster/nt_8
icon_state = "ntposter08"
name = "wildlife hazard"
desc = "This SifGov poster warns against attempting to kill a fully grown giant spider or other hostile life-form alone."
listing_name = "Safety - Spiders"
// A new subset of poster datum for ONLY 'Internal' NanoTrasen posters, given to Security.
/datum/poster/nanotrasen
icon_state = "polposter1"
name = "Safety!"
desc = "A poster advising you to learn how to put on your internals at a moment's notice."
listing_name = "Safety - Internals"
/datum/poster/nanotrasen/pol_2
icon_state="polposter2"
name = "Safety!"
desc = "A blue and white colored poster. This one advises you to wear your safety goggles when handling chemicals."
listing_name = "Safety - Goggles"
/datum/poster/nanotrasen/pol_3
icon_state="polposter3"
name = "Safety!"
desc = "A safety poster instructing you to comply with the authorities, especially in an emergency."
listing_name = "Safety - Follow Instruction"
/datum/poster/nanotrasen/pol_4
icon_state="polposter4"
name = "Clean Hands Save Lives"
desc = "A safety poster reminding you to wash your hands."
listing_name = "Safety - Hand Washing"
/datum/poster/nanotrasen/pol_5
icon_state="polposter5"
name = "Help!"
desc = "This poster depicts a man helping another man get up."
listing_name = "Safety - Help Others"
/datum/poster/nanotrasen/pol_6
icon_state="polposter6"
name = "Walk!"
desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls."
listing_name = "Safety - No Running"
/datum/poster/nanotrasen/pol_7
icon_state="polposter7"
name = "Place your signs!"
desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded."
listing_name = "Safety - Wet Floor Signs"
/datum/poster/nanotrasen/pol_8
icon_state="polposter8"
name = "Safety!"
desc = "An advertisement / safety poster for EVA training and certification. Training is available at your local Central Command."
listing_name = "Safety - EVA Training"
/datum/poster/nanotrasen/pol_9
icon_state="poster10"
@@ -97,81 +191,97 @@
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
wire codes."
listing_name = "Safety - Airlock Maintenance"
/datum/poster/nanotrasen/pol_10
icon_state="polposter9"
name = "orchid"
desc = "This poster suggests a feeling of peace. It depicts the flower of a tree native to the planet Earth."
listing_name = "General - Orchid"
/datum/poster/nanotrasen/bay_9
icon_state="bsposter9"
name = "Pinup Girl Amy"
desc = "This particular one is of Amy, the nymphomaniac urban legend of deep space. How this photograph came to be is not known."
listing_name = "Pin-up - Amy"
/datum/poster/nanotrasen/bay_21
icon_state="bsposter21"
name = "Join the Fuzz!"
desc = "It's a nice recruitment poster of a white haired Chinese woman that says; \"Big Guns, Hot Women, Good Times. Security. We get it done.\""
listing_name = "Recruitment - NanoTrasen Security - Pinup"
/datum/poster/nanotrasen/bay_22
icon_state="bsposter22"
name = "Looking for a career with excitement?"
desc = "A recruitment poster starring a dark haired woman with glasses and a purple shirt that has \"Got Brains? Got Talent? Not afraid of electric flying monsters that want to suck the soul out of you? Then Xenobiology could use someone like you!\" written on the bottom."
listing_name = "Recruitment - Xenobiology"
/datum/poster/nanotrasen/bay_23
icon_state="bsposter23"
name = "Safety first: because electricity doesn't wait!"
desc = "A safety poster starring a clueless looking redhead with frazzled hair. \"Every year, hundreds of NT employees expose themselves to electric shock. Play it safe. Avoid suspicious doors after electrical storms, and always wear protection when doing electric maintenance.\""
listing_name = "Safety - Electric Shock"
/datum/poster/nanotrasen/bay_24
icon_state="bsposter24"
name = "Responsible medbay habits, No #259"
desc = "A poster with a nervous looking geneticist on it states; \"Friends Tell Friends They're Clones. It can cause severe and irreparable emotional trauma if a person is not properly informed of their recent demise. Always follow your contractual obligation and inform them of their recent rejuvenation.\""
listing_name = "Medical - Clone Disclosure"
/datum/poster/nanotrasen/bay_25
icon_state="bsposter25"
name = "Irresponsible medbay habits, No #2"
desc = "This is a safety poster starring a perverted looking naked doctor. \"Sexual harassment is never okay. REPORT any acts of sexual deviance or harassment that disrupt a healthy working environment.\""
listing_name = "Medical - Sexual Harassment"
/datum/poster/nanotrasen/bay_49
icon_state="bsposter49"
name = "Engineering recruitment"
desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\""
listing_name = "Recruitment - Engineering"
/datum/poster/nanotrasen/bay_52
icon_state="bsposter52"
name = "fire safety poster"
desc = "This is a poster reminding you of what you should do if you are on fire, or if you are at a dance party."
listing_name = "Safety - Stop Drop And Roll"
/datum/poster/nanotrasen/bay_53
icon_state="bsposter53"
name = "fire extinguisher poster"
desc = "This is a poster reminding you of what you should use to put out a fire."
listing_name = "Safety - Extinguishers"
/datum/poster/nanotrasen/bay_54
icon_state="bsposter54"
name = "firefighter poster"
desc = "This is a poster of a particularly stern looking firefighter. The caption reads, \"Only you can prevent space fires.\""
listing_name = "Safety - Prevent Fires"
/datum/poster/nanotrasen/bay_57
icon_state="bsposter57"
name = "space carp warning poster"
desc = "This poster tells of the dangers of space carp infestations."
listing_name = "Safety - Carp"
/datum/poster/nanotrasen/bay_58
icon_state="bsposter58"
name = "space carp information poster"
desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
listing_name = "Safety - Carp Information"
/datum/poster/nanotrasen/nt_1
icon_state = "ntposter01"
name = "Security recruitment"
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about the importance of Security."
listing_name = "Recruitment - NanoTrasen Security - Importance"
/datum/poster/nanotrasen/nt_2
icon_state = "ntposter02"
name = "Security recruitment"
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about Security Employee benefits."
listing_name = "Recruitment - NanoTrasen Security - Benefits"
/datum/poster/nanotrasen/nt_3
icon_state = "ntposter03"
@@ -179,6 +289,7 @@
desc = "This poster displays three cutting-edge gygaxes standing in line in front of a man in plain clothes.\
The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
The image seems important."
listing_name = "Safety - Mech Operation"
//VOREStation Removal Start TFF 17/12/19 - lore not used in our station's own lore.
/*
@@ -186,6 +297,7 @@
icon_state = "ntposter04"
name = "Beware Aetotheans"
desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
listing_name = "Safety - Aetothean Danger"
*/
//VOREstation Removal End
@@ -193,11 +305,13 @@
icon_state = "ntposter05"
name = "Promethean"
desc = "This poster displays a friendly-looking green Promethean in a labcoat. The fine-print around the edges talks about the benefits Prometheans give in laboratories."
listing_name = "Safety - Prometheans"
/datum/poster/nanotrasen/nt_6
icon_state = "ntposter06"
name = "NanoTrasen"
desc = "This poster showcases an NT emblem. There is writing in the ring around the inner points, probably some sort of slogan no one bothers to memorize."
listing_name = "Ad - NanoTrasen"
/datum/poster/nanotrasen/nt_7
icon_state = "ntposter07"
@@ -205,13 +319,16 @@
desc = "This poster showcases an SCG emblem. The outer ring reads,\
\"<font face='times new roman ms'>NIL MORTALIBUS ARDUI EST</font>\".\
Solar Confederate Government."
listing_name = "Political - SolGov"
/datum/poster/nanotrasen/nt_8
icon_state = "ntposter08"
name = "wildlife hazard"
desc = "This poster warns against attempting to kill a fully grown giant spider or other hostile life-form alone."
listing_name = "Safety - Spiders"
/datum/poster/nanotrasen/nt_9
icon_state = "ntposter09"
name = "Regulations and You"
desc = "This poster showcases an NT security guard reading from her PDA. The blurb advocates for the reader to keep corporate regulations in mind at all times, as an emergency can occur at any time."
desc = "This SifGov poster showcases an NT security guard reading from her PDA. The blurb advocates for the reader to keep corporate regulations in mind at all times, as an emergency can occur at any time."
listing_name = "Safety - Corporate Regulations"
@@ -1,10 +1,10 @@
/obj/effect/decal/warning_stripes
icon = 'icons/effects/warning_stripes.dmi'
/obj/effect/decal/warning_stripes/New()
/obj/effect/decal/warning_stripes/Initialize()
. = ..()
var/turf/T=get_turf(src)
var/image/I=image(icon, icon_state = icon_state, dir = dir)
I.color=color
T.overlays += I
qdel(src)
return INITIALIZE_HINT_QDEL
@@ -33,6 +33,9 @@ would spawn and follow the beaker, even if it is carried or thrown.
proc/start()
Destroy()
holder = null
return ..()
/////////////////////////////////////////////
// GENERIC STEAM SPREAD SYSTEM
@@ -1,3 +1,6 @@
/obj/effect/landmark
var/abductor = 0
/obj/effect/landmark/late_antag
name = "Antag Latespawn"
var/antag_id
+116 -6
View File
@@ -7,29 +7,72 @@
icon_state = "uglymine"
var/triggered = 0
var/smoke_strength = 3
var/mineitemtype = /obj/item/weapon/mine
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
var/panel_open = 0
var/datum/wires/mines/wires = null
register_as_dangerous_object = TRUE
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
/obj/effect/mine/New()
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
var/obj/item/trap = null
/obj/effect/mine/Initialize()
icon_state = "uglyminearmed"
wires = new(src)
. = ..()
if(ispath(trap))
trap = new trap(src)
register_dangerous_to_step()
if(camo_net)
alpha = 50
/obj/effect/mine/Destroy()
unregister_dangerous_to_step()
if(trap)
QDEL_NULL(trap)
qdel_null(wires)
return ..()
/obj/effect/mine/Moved(atom/oldloc)
. = ..()
if(.)
var/turf/old_turf = get_turf(oldloc)
var/turf/new_turf = get_turf(src)
if(old_turf != new_turf)
old_turf.unregister_dangerous_object(src)
new_turf.register_dangerous_object(src)
/obj/effect/mine/proc/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
visible_message("\The [src.name] detonates!")
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/obj/effect/mine/proc/trigger_trap(var/mob/living/victim)
if(istype(trap, /obj/item/weapon/grenade))
var/obj/item/weapon/grenade/G = trap
trap = null
G.forceMove(get_turf(src))
if(victim.ckey)
msg_admin_attack("[key_name_admin(victim)] stepped on \a [src.name], triggering [trap]")
G.activate()
if(istype(trap, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TV = trap
trap = null
TV.forceMove(get_turf(src))
TV.toggle_valve()
/obj/effect/mine/bullet_act()
if(prob(50))
explode()
@@ -63,6 +106,9 @@
"<span class='notice'>You very carefully screw the mine's panel [panel_open ? "open" : "closed"].</span>")
playsound(src, W.usesound, 50, 1)
// Panel open, stay uncloaked, or uncloak if already cloaked. If you don't cloak on place, ignore it and just be normal alpha.
alpha = camo_net ? (panel_open ? 255 : 50) : 255
else if((W.is_wirecutter() || istype(W, /obj/item/device/multitool)) && panel_open)
interact(user)
else
@@ -74,6 +120,9 @@
user.set_machine(src)
wires.Interact(user)
/obj/effect/mine/camo
camo_net = TRUE
/obj/effect/mine/dnascramble
mineitemtype = /obj/item/weapon/mine/dnascramble
@@ -193,6 +242,9 @@
spawn(0)
qdel(src)
/obj/effect/mine/emp/camo
camo_net = TRUE
/obj/effect/mine/incendiary
mineitemtype = /obj/item/weapon/mine/incendiary
@@ -208,6 +260,26 @@
spawn(0)
qdel(src)
/obj/effect/mine/gadget
mineitemtype = /obj/item/weapon/mine/gadget
/obj/effect/mine/gadget/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 0, 2, 2)
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/////////////////////////////////////////////
// The held item version of the above mines
/////////////////////////////////////////////
@@ -219,6 +291,10 @@
var/countdown = 10
var/minetype = /obj/effect/mine //This MUST be an /obj/effect/mine type, or it'll runtime.
var/obj/item/trap = null
var/list/allowed_gadgets = null
/obj/item/weapon/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times
add_fingerprint(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
@@ -231,11 +307,39 @@
prime(user, TRUE)
return
/obj/item/weapon/mine/attackby(obj/item/W as obj, mob/living/user as mob)
if(W.is_screwdriver() && trap)
to_chat(user, "<span class='notice'>You begin removing \the [trap].</span>")
if(do_after(user, 10 SECONDS))
to_chat(user, "<span class='notice'>You finish disconnecting the mine's trigger.</span>")
trap.forceMove(get_turf(src))
trap = null
return
if(LAZYLEN(allowed_gadgets) && !trap)
var/allowed = FALSE
for(var/path in allowed_gadgets)
if(istype(W, path))
allowed = TRUE
break
if(allowed)
user.drop_from_inventory(W)
W.forceMove(src)
trap = W
..()
/obj/item/weapon/mine/proc/prime(mob/user as mob, var/explode_now = FALSE)
visible_message("\The [src.name] beeps as the priming sequence completes.")
var/obj/effect/mine/R = new minetype(get_turf(src))
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
if(trap)
R.trap = trap
trap = null
R.trap.forceMove(R)
if(explode_now)
R.explode(user)
spawn(0)
@@ -286,8 +390,14 @@
desc = "A small explosive mine with a fire symbol on the side."
minetype = /obj/effect/mine/incendiary
/obj/item/weapon/mine/gadget
name = "gadget mine"
desc = "A small pressure-triggered device. If no component is added, the internal release bolts will detonate in unison when triggered."
allowed_gadgets = list(/obj/item/weapon/grenade, /obj/item/device/transfer_valve)
// This tells AI mobs to not be dumb and step on mines willingly.
/obj/item/weapon/mine/is_safe_to_step(mob/living/L)
if(!L.hovering)
return FALSE
return ..()
return ..()
@@ -17,7 +17,7 @@
..()
/obj/effect/temporary_effect/eruption/Initialize()
..()
. = ..()
flick("[icon_state]_create",src)
/obj/effect/temporary_effect/eruption/Destroy()
@@ -159,7 +159,6 @@
/obj/effect/spawner/newbomb/Initialize(newloc)
..(newloc)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
@@ -183,19 +182,14 @@
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
OT.air_contents.update_values()
var/obj/item/device/assembly/S = new assembly_type(V)
V.attached_device = S
S.holder = V
S.toggle_secure()
V.update_icon()
qdel(src)
return INITIALIZE_HINT_QDEL
///////////////////////
+9 -3
View File
@@ -610,9 +610,6 @@ var/list/global/slot_flags_enumeration = list(
. = ..()
if(blood_overlay)
overlays.Remove(blood_overlay)
if(istype(src, /obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = src
G.transfer_blood = 0
/obj/item/reveal_blood()
if(was_bloodied && !fluorescent)
@@ -942,3 +939,12 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
/obj/item/proc/openTip(location, control, params, user)
openToolTip(user, src, params, title = name, content = desc)
// These procs are for RPEDs and part ratings. The concept for this was borrowed from /vg/station.
// Gets the rating of the item, used in stuff like machine construction.
/obj/item/proc/get_rating()
return FALSE
// Like the above, but used for RPED sorting of parts.
/obj/item/proc/rped_rating()
return get_rating()
@@ -1,3 +1,103 @@
// Etc UI-only vars
/obj/item/device/communicator
// Stuff for moving cameras
var/turf/last_camera_turf
// Stuff needed to render the map
var/map_name
var/obj/screen/map_view/cam_screen
var/list/cam_plane_masters
var/obj/screen/background/cam_background
var/obj/screen/skybox/local_skybox
// Proc: setup_tgui_camera()
// Parameters: None
// Description: This sets up all of the variables above to handle in-UI map windows.
/obj/item/device/communicator/proc/setup_tgui_camera()
map_name = "communicator_[REF(src)]_map"
// Initialize map objects
cam_screen = new
cam_screen.name = "screen"
cam_screen.assigned_map = map_name
cam_screen.del_on_map_removal = FALSE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_masters = get_tgui_plane_masters()
for(var/plane in cam_plane_masters)
var/obj/screen/instance = plane
instance.assigned_map = map_name
instance.del_on_map_removal = FALSE
instance.screen_loc = "[map_name]:CENTER"
local_skybox = new()
local_skybox.assigned_map = map_name
local_skybox.del_on_map_removal = FALSE
local_skybox.screen_loc = "[map_name]:CENTER,CENTER"
cam_plane_masters += local_skybox
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
// Proc: update_active_camera_screen()
// Parameters: None
// Description: This refreshes the camera location
/obj/item/device/communicator/proc/update_active_camera_screen()
if(!video_source?.can_use())
show_static()
return
var/newturf = get_turf(video_source)
if(!is_on_same_plane_or_station(get_z(newturf), get_z(src)))
show_static()
return
var/obj/item/device/communicator/communicator = video_source.loc
if(istype(communicator))
if(communicator.selfie_mode)
var/mob/target = get(communicator, /mob)
if(istype(target))
cam_screen.vis_contents = list(target)
else
cam_screen.vis_contents = list(communicator)
cam_background.fill_rect(1, 1, 1, 1)
cam_background.icon_state = "clear"
local_skybox.cut_overlays()
return
// If we're not forcing an update for some reason and the cameras are in the same location,
// we don't need to update anything.
if(last_camera_turf == newturf)
return
// We get a new turf in case they've moved in the last half decisecond (it's BYOND, it might happen)
last_camera_turf = get_turf(video_source)
if(!is_on_same_plane_or_station(get_z(last_camera_turf), get_z(src)))
show_static()
return
var/list/visible_turfs = list()
var/list/visible_things = view(video_range, last_camera_turf)
for(var/turf/visible_turf in visible_things)
visible_turfs += visible_turf
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, (video_range * 2), (video_range * 2))
local_skybox.cut_overlays()
local_skybox.add_overlay(SSskybox.get_skybox(get_z(last_camera_turf)))
local_skybox.scale_to_view(video_range * 2)
local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - last_camera_turf.x, (world.maxy>>1) - last_camera_turf.y)
/obj/item/device/communicator/proc/show_static()
cam_screen.vis_contents.Cut()
cam_background.icon_state = "scanline2"
cam_background.fill_rect(1, 1, (video_range * 2), (video_range * 2))
local_skybox.cut_overlays()
// Proc: tgui_state()
// Parameters: User
// Description: This tells TGUI to only allow us to be interacted with while in a mob inventory.
@@ -9,7 +109,15 @@
// Description: This proc handles opening the UI. It's basically just a standard stub.
/obj/item/device/communicator/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
// Update the camera every SStgui tick in case it moves
update_active_camera_screen()
if(!ui)
// Register map objects
user.client.register_map_obj(cam_screen)
for(var/plane in cam_plane_masters)
user.client.register_map_obj(plane)
user.client.register_map_obj(cam_background)
// Setup UI
ui = new(user, src, "Communicator", name)
if(custom_state)
ui.set_state(custom_state)
@@ -188,6 +296,7 @@
data["target_feed"] = data["feeds"][newsfeed_channel]
else
data["target_feed"] = null
data["selfie_mode"] = selfie_mode
return data
@@ -200,6 +309,7 @@
if(data_core)
data_core.get_manifest_list()
data["manifest"] = PDA_Manifest
data["mapRef"] = map_name
return data
// Proc: tgui-act()
@@ -231,6 +341,9 @@
if("toggle_ringer")
ringer = !ringer
if("selfie_mode")
selfie_mode = !selfie_mode
if("add_hex")
var/hex = params["add_hex"]
add_to_EPv2(hex)
@@ -324,3 +437,4 @@
if("newsfeed")
newsfeed_channel = text2num(params["newsfeed"])
#undef DEFAULT_MAP_SIZE
@@ -28,7 +28,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
origin_tech = list(TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_DATA = 2)
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10)
var/video_range = 4
var/video_range = 3
var/obj/machinery/camera/communicator/video_source // Their camera
var/obj/machinery/camera/communicator/camera // Our camera
@@ -72,6 +72,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
var/update_ticks = 0
var/newsfeed_channel = 0
// If you turn this on, it changes the way communicator video works. User configurable option.
var/selfie_mode = FALSE
// Proc: New()
// Parameters: None
// Description: Adds the new communicator to the global list of all communicators, sorts the list, obtains a reference to the Exonet node, then tries to
@@ -86,6 +89,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
camera.name = "[src] #[rand(100,999)]"
camera.c_tag = camera.name
setup_tgui_camera()
//This is a pretty terrible way of doing this.
addtimer(CALLBACK(src, .proc/register_to_holder), 5 SECONDS)
@@ -124,9 +129,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/obj/item/device/communicator/examine(mob/user)
. = ..()
if(Adjacent(user) && video_source)
. += "<span class='notice'>It looks like it's on a video call: <a href='?src=\ref[src];watchvideo=1'>\[view\]</a></span>"
for(var/mob/living/voice/voice in contents)
. += "<span class='notice'>On the screen, you can see a image feed of [voice].</span>"
@@ -142,17 +144,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
else
. += "<span class='notice'>The device doesn't appear to be transmitting any data.</span>"
// Proc: Topic()
// Parameters: href, href_list - Data from a link
// Description: Used by the above examine.
/obj/item/device/communicator/Topic(href, href_list)
if(..())
return 1
if(href_list["watchvideo"])
if(video_source)
watch_video(usr)
// Proc: emp_act()
// Parameters: None
// Description: Drops all calls when EMPed, so the holder can then get murdered by the antagonist.
@@ -234,8 +225,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
alert_called = 0
update_icon()
tgui_interact(user)
if(video_source)
watch_video(user)
// Proc: MouseDrop()
//Same thing PDAs do
@@ -316,6 +305,11 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
QDEL_NULL(camera)
QDEL_NULL(exonet)
last_camera_turf = null
qdel(cam_screen)
QDEL_LIST(cam_plane_masters)
qdel(cam_background)
return ..()
// Proc: update_icon()
@@ -332,12 +332,15 @@
if(video_source) //Already in a video
to_chat(user, "<span class='danger'>You are already connected to a video call!</span>")
return
if(user.blinded) //User is blinded
to_chat(user, "<span class='danger'>You cannot see well enough to do that!</span>")
return
if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something
to_chat(user, "<span class='danger'>[bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.</span>")
return
to_chat(user, "<span class='notice'>[bicon(src)] Attempting to start video over existing call.</span>")
sleep(30)
@@ -345,42 +348,16 @@
video_source = comm.camera
comm.visible_message("<span class='danger'>[bicon(src)] New video connection from [comm].</span>")
watch_video(user)
update_active_camera_screen()
GLOB.moved_event.register(video_source, src, .proc/update_active_camera_screen)
update_icon()
// Proc: watch_video()
// Parameters: user - the mob doing the viewing of video
// Description: Moves a mob's eye to the far end for the duration of viewing the far end
/obj/item/device/communicator/proc/watch_video(mob/user)
if(!Adjacent(user) || !video_source) return
user.set_machine(video_source)
user.reset_view(video_source)
to_chat(user, "<span class='notice'>Now viewing video session. To leave camera view, close the communicator window OR: OOC -> Cancel Camera View</span>")
to_chat(user, "<span class='notice'>To return to an active video session, use the communicator in your hand.</span>")
spawn(0)
while(user.machine == video_source && Adjacent(user))
var/turf/T = get_turf(video_source)
if(!T || !is_on_same_plane_or_station(T.z, user.z) || !video_source.can_use())
to_chat(user, "<span class='warning'>The screen bursts into static, then goes black.</span>")
video_cleanup(user)
return
sleep(10)
video_cleanup(user)
// Proc: video_cleanup()
// Parameters: user - the mob who doesn't want to see video anymore
// Description: Cleans up mob's client when they stop watching a video
/obj/item/device/communicator/proc/video_cleanup(mob/user)
if(!user) return
user.reset_view(null)
user.unset_machine()
// Proc: end_video()
// Parameters: reason - the text reason to print for why it ended
// Description: Ends the video call by clearing video_source
/obj/item/device/communicator/proc/end_video(var/reason)
GLOB.moved_event.unregister(video_source, src, .proc/update_active_camera_screen)
show_static()
video_source = null
. = "<span class='danger'>[bicon(src)] [reason ? reason : "Video session ended"].</span>"
+2 -2
View File
@@ -509,8 +509,8 @@
return // Still no brain.
// If the brain'd `defib_timer` var gets below this number, brain damage will happen at a linear rate.
// This is measures in `Life()` ticks. E.g. 10 minute defib timer = 6000 world.time units = 3000 `Life()` ticks.
var/brain_damage_timer = ((config.defib_timer MINUTES) / 2) - ((config.defib_braindamage_timer MINUTES) / 2)
// This is measures in `Life()` ticks. E.g. 10 minute defib timer = 300 `Life()` ticks. // Original math was VERY off. Life() tick occurs every ~2 seconds, not every 2 world.time ticks.
var/brain_damage_timer = ((config.defib_timer MINUTES) / 20) - ((config.defib_braindamage_timer MINUTES) / 20)
if(brain.defib_timer > brain_damage_timer)
return // They got revived before brain damage got a chance to set in.
+1 -1
View File
@@ -33,7 +33,7 @@
var/cell_type = /obj/item/weapon/cell/device
/obj/item/device/flash/Initialize()
..()
. = ..()
power_supply = new cell_type(src)
/obj/item/device/flash/attackby(var/obj/item/W, var/mob/user)
@@ -84,7 +84,6 @@
desc = "A headset used by pilots, has access to the explorer channel."
icon_state = "pilot_headset"
adhoc_fallback = TRUE
ks2type = /obj/item/device/encryptionkey/pilot
/obj/item/device/radio/headset/pilot/alt
name = "pilot's bowman headset"
@@ -120,7 +119,7 @@
desc = "A headset used by volunteers to expedition teams, has access to the exploration channel."
icon_state = "pilot_headset"
adhoc_fallback = TRUE
ks2type = /obj/item/device/encryptionkey/pilot
ks2type = /obj/item/device/encryptionkey/explorer
/obj/item/device/radio/headset/talon
name = "talon headset"
@@ -297,7 +297,8 @@ var/global/list/default_medbay_channels = list(
playsound(src, "button", 10)
GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels)
if(!GLOB.autospeaker)
return
var/datum/radio_frequency/connection = null
@@ -308,7 +309,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
else
connection = radio_connection
channel = null
if (!istype(connection))
if(!istype(connection))
return
if(!LAZYLEN(zlevels))
@@ -507,7 +508,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
else if(adhoc_fallback) //Less huzzah, we have to fallback
to_chat(loc, "<span class='warning'>\The [src] pings as it falls back to local radio transmission.</span>")
subspace_transmission = FALSE
else //Oh well
return FALSE
@@ -594,7 +595,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
/obj/item/device/radio/examine(mob/user)
. = ..()
if((in_range(src, user) || loc == user))
if(b_stat)
. += "<span class='notice'>\The [src] can be attached and modified!</span>"
@@ -88,6 +88,14 @@
if(get_dist(user, src) == 0)
. += "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional."
/obj/item/device/camerabug/update_icon()
..()
if(anchored) // Standard versions are relatively obvious if not hidden in a container. Anchoring them is advised, to disguise them.
alpha = 50
else
alpha = 255
/obj/item/device/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/bug_monitor))
var/obj/item/device/bug_monitor/SM = W
@@ -101,6 +109,15 @@
linkedmonitor = null
else
to_chat(user, "Error: The device is linked to another monitor.")
else if(W.is_wrench() && user.a_intent != I_HURT)
if(isturf(loc))
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "" : "un"]secure \the [src].</span>")
update_icon()
return
else
if(W.force >= 5)
visible_message("\The [src] lens shatters!")
+20 -36
View File
@@ -1,5 +1,3 @@
GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
// I placed this here because of how relevant it is.
// You place this in your uplinkable item to check if an uplink is active or not.
// If it is, it will display the uplink menu and return 1, else it'll return false.
@@ -14,29 +12,19 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/uplink
var/welcome = "Welcome, Operative" // Welcoming menu message
var/uses // Numbers of crystals
var/list/ItemsCategory // List of categories with lists of items
var/list/ItemsReference // List of references with an associated item
var/list/nanoui_items // List of items for NanoUI use
var/faction = "" //Antag faction holder.
var/list/purchase_log = new
var/datum/mind/uplink_owner = null
var/used_TC = 0
var/offer_time = 10 MINUTES //The time increment per discount offered
var/next_offer_time
var/datum/uplink_item/discount_item //The item to be discounted
var/discount_amount //The amount as a percent the item will be discounted by
var/compact_mode = FALSE
/obj/item/device/uplink/Initialize(var/mapload, var/datum/mind/owner = null, var/telecrystals = DEFAULT_TELECRYSTAL_AMOUNT)
/obj/item/device/uplink/Initialize(var/mapload)
. = ..()
uplink_owner = owner
purchase_log = list()
if(owner)
uses = owner.tcrystals
else
uses = telecrystals
addtimer(CALLBACK(src, .proc/next_offer), offer_time) //It seems like only the /hidden type actually makes use of this...
/obj/item/device/uplink/get_item_cost(var/item_type, var/item_cost)
@@ -85,7 +73,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/uplink/hidden/proc/trigger(mob/user as mob)
if(!active)
toggle()
interact(user)
tgui_interact(user)
// Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset.
// If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the
@@ -93,8 +81,8 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/uplink/hidden/proc/check_trigger(mob/user as mob, var/value, var/target)
if(value == target)
trigger(user)
return 1
return 0
return TRUE
return FALSE
// Legacy
/obj/item/device/uplink/hidden/interact(mob/user)
@@ -107,12 +95,11 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
return loc
/obj/item/device/uplink/hidden/tgui_state(mob/user)
return GLOB.tgui_inventory_state
return GLOB.tgui_deep_inventory_state
/obj/item/device/uplink/hidden/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
if(!active)
toggle()
uses = user.mind.tcrystals
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Uplink", "Remote Uplink")
@@ -127,7 +114,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
var/list/data = ..()
data["telecrystals"] = uses
data["telecrystals"] = user.mind.tcrystals
data["lockable"] = TRUE
data["compactMode"] = compact_mode
@@ -177,22 +164,19 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
data["categories"] = list()
for(var/datum/uplink_category/category in uplink.categories)
if(category.can_view(src))
var/list/cat = list(
var/list/cat = list(
"name" = category.name,
"items" = (category == selected_cat ? list() : null)
)
for(var/datum/uplink_item/item in category.items)
if(!item.can_view(src))
continue
var/cost = item.cost(uses, src) || "???"
cat["items"] += list(list(
"name" = item.name,
"cost" = cost,
"desc" = item.description(),
"ref" = REF(item),
))
data["categories"] += list(cat)
for(var/datum/uplink_item/item in category.items)
var/cost = item.cost(src, user) || "???"
cat["items"] += list(list(
"name" = item.name,
"cost" = cost,
"desc" = item.description(),
"ref" = REF(item),
))
data["categories"] += list(cat)
return data
@@ -228,9 +212,9 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
//
// Includes normal radio uplink, multitool uplink,
// implant uplink (not the implant tool) and a preset headset uplink.
/obj/item/device/radio/uplink/New(atom/loc, datum/mind/target_mind, telecrystals)
..(loc)
hidden_uplink = new(src, target_mind, telecrystals)
/obj/item/device/radio/uplink/New()
..()
hidden_uplink = new(src)
icon_state = "radio"
/obj/item/device/radio/uplink/attack_self(mob/user as mob)
@@ -238,6 +222,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
hidden_uplink.trigger(user)
/obj/item/device/multitool/uplink/New()
..()
hidden_uplink = new(src)
/obj/item/device/multitool/uplink/attack_self(mob/user as mob)
@@ -250,4 +235,3 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/radio/headset/uplink/New()
..()
hidden_uplink = new(src)
hidden_uplink.uses = DEFAULT_TELECRYSTAL_AMOUNT
@@ -34,11 +34,11 @@ var/datum/uplink_random_selection/all_uplink_selection = new/datum/uplink_random
if(!prob(RI.keep_probability))
continue
var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
if(I.cost(telecrystals, U) > telecrystals)
if(I.cost(U) > telecrystals)
continue
if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
continue
if(U && !I.can_buy(U))
if(U && !I.can_buy(U, telecrystals))
continue
return I
+1 -1
View File
@@ -241,7 +241,7 @@
M.initial_icon = new_icon
if(new_icon_file)
M.icon = new_icon_file
M.reset_icon()
M.update_icon()
use(1, user)
/obj/mecha/attackby(var/obj/item/weapon/W, var/mob/user)
@@ -8,6 +8,7 @@
w_class = ITEMSIZE_SMALL
/obj/item/pizzavoucher/New()
..()
var/list/descstrings = list("24/7 PIZZA PIE HEAVEN",
"WE ALWAYS DELIVER!",
"24-HOUR PIZZA PIE POWER!",
@@ -31,8 +31,8 @@
return 1
/obj/item/borg/upgrade/bellysizeupgrade
name = "robotic Hound process capacity upgrade Module"
desc = "Used to upgrade a hound belly capacity. This only affects total volume and such, you won't be able to support more than one patient. Usable once."
name = "robohound capacity expansion module"
desc = "Used to double a robohound's belly capacity. This only affects total volume, and won't allow support of more than one patient in case of sleeper bellies. Can only be applied once."
icon_state = "cyborg_upgrade2"
item_state = "cyborg_upgrade"
require_module = 1
@@ -7,15 +7,12 @@
var/obj/item/stack/type_to_spawn = null
/obj/fiftyspawner/Initialize()
..() //We're not returning . because we're going to ask to be deleted.
..()
var/turf/T = get_turf(src)
var/obj/item/stack/M = new type_to_spawn(T)
var/obj/structure/closet/C = locate() in T
var/obj/item/stack/M = new type_to_spawn(C || T)
M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty
M.update_icon() // Some stacks have different sprites depending on how full they are.
var/obj/structure/closet/C = locate() in T
if(C)
C.contents += M
return INITIALIZE_HINT_QDEL //Bye!
/obj/fiftyspawner/rods
@@ -56,3 +56,6 @@
name = "Bandage Synthesizer"
max_energy = 10
recharge_rate = 1
/datum/matter_synth/cloth
name = "Cloth Synthesizer"
+2 -2
View File
@@ -24,8 +24,8 @@
stacktype = /obj/item/stack/rods
no_variants = TRUE
/obj/item/stack/rods/New()
..()
/obj/item/stack/rods/Initialize()
. = ..()
recipes = rods_recipes
update_icon()
+150
View File
@@ -0,0 +1,150 @@
/obj/item/stack/sandbags
name = "sandbag"
desc = "Filled sandbags. Fortunately pre-filled."
singular_name = "sandbag"
icon = 'icons/obj/sandbags.dmi'
icon_state = "sandbag"
w_class = ITEMSIZE_LARGE
force = 10.0
throwforce = 20.0
throw_speed = 5
throw_range = 3
drop_sound = 'sound/items/drop/clothing.ogg'
pickup_sound = 'sound/items/pickup/clothing.ogg'
matter = list(MAT_CLOTH = SHEET_MATERIAL_AMOUNT * 2)
max_amount = 30
attack_verb = list("hit", "bludgeoned", "pillowed")
no_variants = TRUE
stacktype = /obj/item/stack/sandbags
pass_color = TRUE
var/bag_material = "cloth"
/obj/item/stack/sandbags/cyborg
name = "sandbag synthesizer"
desc = "A device that makes filled sandbags. Don't ask how."
gender = NEUTER
matter = null
uses_charge = 1
charge_costs = list(500)
stacktype = /obj/item/stack/sandbags
bag_material = MAT_SYNCLOTH
/obj/item/stack/sandbags/Initialize(var/ml, var/amt, var/bag_mat)
. = ..(ml, amt)
recipes = sandbag_recipes
update_icon()
if(bag_mat)
bag_material = bag_mat
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
return INITIALIZE_HINT_QDEL
color = M.icon_colour
/obj/item/stack/sandbags/update_icon()
var/amount = get_amount()
slowdown = round(amount / 10, 0.1)
var/global/list/datum/stack_recipe/sandbag_recipes = list( \
new/datum/stack_recipe("barricade", /obj/structure/barricade/sandbag, 3, time = 5 SECONDS, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE))
/obj/item/stack/sandbags/produce_recipe(datum/stack_recipe/recipe, var/quantity, mob/user)
var/required = quantity*recipe.req_amount
var/produced = min(quantity*recipe.res_amount, recipe.max_res_amount)
if (!can_use(required))
if (produced>1)
to_chat(user, "<span class='warning'>You haven't got enough [src] to build \the [produced] [recipe.title]\s!</span>")
else
to_chat(user, "<span class='warning'>You haven't got enough [src] to build \the [recipe.title]!</span>")
return
if (recipe.one_per_turf && (locate(recipe.result_type) in user.loc))
to_chat(user, "<span class='warning'>There is another [recipe.title] here!</span>")
return
if (recipe.on_floor && !isfloor(user.loc))
to_chat(user, "<span class='warning'>\The [recipe.title] must be constructed on the floor!</span>")
return
if (recipe.time)
to_chat(user, "<span class='notice'>Building [recipe.title] ...</span>")
if (!do_after(user, recipe.time))
return
if (use(required))
var/atom/O = new recipe.result_type(user.loc, bag_material)
if(istype(O, /obj))
var/obj/Ob = O
if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
Ob.matter.Cut()
else
Ob.matter = list()
var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
Ob.matter[recipe.use_material] = mattermult / produced * required
O.set_dir(user.dir)
O.add_fingerprint(user)
if (istype(O, /obj/item/stack))
var/obj/item/stack/S = O
S.amount = produced
S.add_to_stacks(user)
if (istype(O, /obj/item/weapon/storage)) //BubbleWrap - so newly formed boxes are empty
for (var/obj/item/I in O)
qdel(I)
if ((pass_color || recipe.pass_color))
if(!color)
if(recipe.use_material)
var/datum/material/MAT = get_material_by_name(recipe.use_material)
if(MAT.icon_colour)
O.color = MAT.icon_colour
else
return
else
O.color = color
// Empty bags. Yes, you need to fill them.
/obj/item/stack/emptysandbag
name = "sandbag"
desc = "Empty sandbags. You know what must be done."
singular_name = "sandbag"
icon = 'icons/obj/sandbags.dmi'
icon_state = "sandbag_e"
w_class = ITEMSIZE_LARGE
strict_color_stacking = TRUE
max_amount = 30
stacktype = /obj/item/stack/emptysandbag
pass_color = TRUE
var/bag_material = "cloth"
/obj/item/stack/emptysandbag/Initialize(var/ml, var/amt, var/bag_mat)
. = ..(ml, amt)
if(bag_mat)
bag_material = bag_mat
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
return INITIALIZE_HINT_QDEL
color = M.icon_colour
/obj/item/stack/emptysandbag/attack_self(var/mob/user)
while(do_after(user, 1 SECOND) && can_use(1) && istype(get_turf(src), /turf/simulated/floor/outdoors))
use(1)
var/obj/item/stack/sandbags/SB = new (get_turf(src), 1, bag_material)
SB.color = color
if(user)
to_chat(user, "<span class='notice'>You fill a sandbag.</span>")
@@ -83,6 +83,30 @@
icon = 'icons/mob/alien.dmi'
icon_state = "weed_extract"
//Step one - dehairing.
/obj/item/stack/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(has_edge(W) || is_sharp(W))
//visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message)
user.visible_message("<span class='notice'>\The [user] starts cutting hair off \the [src]</span>", "<span class='notice'>You start cutting the hair off \the [src]</span>", "You hear the sound of a knife rubbing against flesh")
if(do_after(user,50))
to_chat(user, "<span class='notice'>You cut the hair from this [src.singular_name]</span>")
//Try locating an exisitng stack on the tile and add to there if possible
for(var/obj/item/stack/hairlesshide/HS in user.loc)
if(HS.amount < 50 && istype(HS, process_type))
HS.amount++
src.use(1)
return
//If it gets to here it means it did not find a suitable stack on the tile.
var/obj/item/stack/HS = new process_type(usr.loc)
if(istype(HS))
HS.amount = 1
src.use(1)
else
..()
//Step two - washing..... it's actually in washing machine code, and ere.
/obj/item/stack/hairlesshide
name = "hairless hide"
desc = "This hide was stripped of it's hair, but still needs tanning."
@@ -106,6 +130,19 @@
return
/obj/item/stack/hairlesshide/proc/rapidcure(var/stacknum = 1)
stacknum = min(stacknum, amount)
while(stacknum)
var/obj/item/stack/wetleather/I = new wet_type(get_turf(src))
if(istype(I))
I.dry()
use(1)
stacknum -= 1
//Step three - drying
/obj/item/stack/wetleather
name = "wet leather"
desc = "This leather has been cleaned but still needs to be dried."
@@ -119,31 +156,6 @@
var/dry_type = /obj/item/stack/material/leather
//Step one - dehairing.
/obj/item/stack/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(has_edge(W) || is_sharp(W))
//visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message)
usr.visible_message("<span class='notice'>\The [usr] starts cutting hair off \the [src]</span>", "<span class='notice'>You start cutting the hair off \the [src]</span>", "You hear the sound of a knife rubbing against flesh")
if(do_after(user,50))
to_chat(usr, "<span class='notice'>You cut the hair from this [src.singular_name]</span>")
//Try locating an exisitng stack on the tile and add to there if possible
for(var/obj/item/stack/hairlesshide/HS in usr.loc)
if(HS.amount < 50 && istype(HS, process_type))
HS.amount++
src.use(1)
return
//If it gets to here it means it did not find a suitable stack on the tile.
var/obj/item/stack/HS = new process_type(usr.loc)
if(istype(HS))
HS.amount = 1
src.use(1)
else
..()
//Step two - washing..... it's actually in washing machine code.
//Step three - drying
/obj/item/stack/wetleather/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
if(exposed_temperature >= drying_threshold_temperature)
+5 -6
View File
@@ -29,14 +29,13 @@
var/pass_color = FALSE // Will the item pass its own color var to the created item? Dyed cloth, wood, etc.
var/strict_color_stacking = FALSE // Will the stack merge with other stacks that are different colors? (Dyed cloth, wood, etc)
/obj/item/stack/New(var/loc, var/amount=null)
..()
if (!stacktype)
/obj/item/stack/Initialize(var/ml, var/amount)
. = ..()
if(!stacktype)
stacktype = type
if (amount)
if(amount)
src.amount = amount
update_icon()
return
/obj/item/stack/Destroy()
if(uses_charge)
@@ -163,7 +162,7 @@
if (recipe.time)
to_chat(user, "<span class='notice'>Building [recipe.title] ...</span>")
if (!do_after(user, recipe.time, exclusive = TRUE))
if (!do_after(user, recipe.time))
return
if (use(required))
+1 -1
View File
@@ -7,7 +7,7 @@
w_class = ITEMSIZE_TINY
max_amount = 30
/obj/item/stack/arcadeticket/New(loc, amount = null)
/obj/item/stack/arcadeticket/Initialize()
. = ..()
update_icon()
@@ -8,6 +8,10 @@
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif
/obj/fiftyspawner/grass/sif/forest
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif/forest
/obj/fiftyspawner/wood
name = "stack of wood"
type_to_spawn = /obj/item/stack/tile/wood
@@ -20,8 +20,8 @@
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
/obj/item/stack/tile/New()
..()
/obj/item/stack/tile/Initialize()
. = ..()
randpixel_xy()
/*
@@ -47,6 +47,11 @@
singular_name = "sivian grass floor tile"
desc = "A patch of grass like those that decorate the plains of Sif."
/obj/item/stack/tile/grass/sif/forest
name = "sivian overgrowth tile"
singular_name = "sivian overgrowth floor tile"
desc = "A patch of dark overgrowth like those that decorate the plains of Sif."
/*
* Wood
*/
+33
View File
@@ -1,3 +1,9 @@
/obj/item/toy/mistletoe
name = "mistletoe"
desc = "You are supposed to kiss someone under these"
icon = 'icons/obj/toy_vr.dmi'
icon_state = "mistletoe"
/obj/item/toy/plushie/lizardplushie
name = "lizard plushie"
desc = "An adorable stuffed toy that resembles a lizardperson."
@@ -50,6 +56,14 @@
/obj/item/toy/plushie/borgplushie/scrubpuppy
icon_state = "scrubpuppy"
/obj/item/toy/plushie/borgplushie/drakiesec
icon = 'icons/obj/drakietoy_vr.dmi'
icon_state = "secdrake"
/obj/item/toy/plushie/borgplushie/drakiemed
icon = 'icons/obj/drakietoy_vr.dmi'
icon_state = "meddrake"
/obj/item/toy/plushie/foxbear
name = "toy fox"
desc = "Issa fox!"
@@ -68,3 +82,22 @@
desc = "A perfectly sized snuggable river weasel! Keep away from Clams."
icon = 'icons/obj/toy_vr.dmi'
icon_state = "plushie_otter"
/obj/item/toy/plushie/vox
name = "vox plushie"
desc = "A stitched-together vox, fresh from the skipjack. Press its belly to hear it skree!"
icon = 'icons/obj/toy_vr.dmi'
icon_state = "plushie_vox"
var/cooldown = 0
/obj/item/toy/plushie/vox/attack_self(mob/user as mob)
if(!cooldown)
playsound(user, 'sound/voice/shriek1.ogg', 10, 0)
src.visible_message("<span class='danger'>Skreee!</span>")
cooldown = 1
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
return ..()
/obj/item/toy/plushie/vox/proc/cooldownreset()
cooldown = 0
@@ -24,6 +24,7 @@
throw_range = 5
w_class = ITEMSIZE_NORMAL
matter = list(MAT_STEEL = 50000, MAT_GLASS = 25000)
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
var/datum/effect/effect/system/spark_spread/spark_system
var/p_dir = NORTH // Next pipe will be built with this dir
var/p_flipped = FALSE // If the next pipe should be built flipped
+4 -3
View File
@@ -22,11 +22,12 @@
/obj/item/weapon/cane/concealed
var/concealed_blade
/obj/item/weapon/cane/concealed/New()
..()
/obj/item/weapon/cane/concealed/Initialize()
. = ..()
var/obj/item/weapon/material/butterfly/switchblade/temp_blade = new(src)
concealed_blade = temp_blade
temp_blade.attack_self()
temp_blade.active = TRUE
temp_blade.update_force()
/obj/item/weapon/cane/concealed/attack_self(var/mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
+14 -5
View File
@@ -6,12 +6,12 @@
*/
/*
* Banana Peals
* Banana Peels
*/
/obj/item/weapon/bananapeel/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if (istype(AM, /mob/living))
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the [src.name]",4)
/*
@@ -28,7 +28,7 @@
/obj/item/weapon/soap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if (istype(AM, /mob/living))
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the [src.name]",3)
@@ -68,11 +68,20 @@
/*
* Bike Horns
*/
/obj/item/weapon/bikehorn
var/honk_sound = 'sound/items/bikehorn.ogg'
/obj/item/weapon/bikehorn/attack_self(mob/user as mob)
if (spam_flag == 0)
if(spam_flag == 0)
spam_flag = 1
playsound(src, 'sound/items/bikehorn.ogg', 50, 1)
playsound(src, honk_sound, 50, 1)
src.add_fingerprint(user)
spawn(20)
spam_flag = 0
return
/obj/item/weapon/bikehorn/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
playsound(src, honk_sound, 50, 1)
@@ -77,7 +77,7 @@
/obj/item/weapon/lipstick/random,
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/corncob,
/obj/item/weapon/contraband/poster,
/obj/item/weapon/contraband/poster/custom,
/obj/item/weapon/book/manual/barman_recipes,
/obj/item/weapon/book/manual/chef_recipes,
/obj/item/weapon/bikehorn,
@@ -0,0 +1,10 @@
/obj/item/weapon/card/emag/examine(mob/user)
. = ..()
. += "[uses] uses remaining."
/obj/item/weapon/card/emag/used
uses = 1
/obj/item/weapon/card/emag/used/Initialize()
. = ..()
uses = rand(1, 5)
@@ -1,2 +1,102 @@
/obj/item/weapon/card/id/gold/captain/spare/fakespare
rank = "null"
rank = "null"
/obj/item/weapon/card/id/itg
name = "identification card"
desc = "A small card designating affiliation with the Ironcrest Transport Group."
icon = 'icons/obj/card_vr.dmi'
icon_state = "itg"
item_state = "itg_id"
/obj/item/weapon/card/id/itg/green
icon_state = "itg_green"
item_state = "itg_green_id"
/obj/item/weapon/card/id/itg/red
icon_state = "itg_red"
item_state = "itg_red_id"
/obj/item/weapon/card/id/itg/purple
icon_state = "itg_purple"
item_state = "itg_purple_id"
/obj/item/weapon/card/id/itg/white
icon_state = "itg_white"
item_state = "itg_white_id"
/obj/item/weapon/card/id/itg/orange
icon_state = "itg_orange"
item_state = "itg_orange_id"
/obj/item/weapon/card/id/itg/blue
icon_state = "itg_blue"
item_state = "itg_blue_id"
/obj/item/weapon/card/id/itg/event
name = "\improper ITG Crew ID"
assignment = "Crew"
rank = "Crew"
access = list(777)
/obj/item/weapon/card/id/itg/event/pilot
name = "\improper ITG Pilot's ID"
desc = "An ID card belonging to the Pilot of an ITG vessel. The Pilot's responsibility is primarily to fly the ship. They may also be tasked to assist with cargo movement duties."
assignment = "Pilot"
rank = "Pilot"
/obj/item/weapon/card/id/itg/event/service
name = "\improper ITG Cook's ID"
desc = "An ID card belonging to the Cook of an ITG vessel. The Cook's responsibility is primarily to provide sustinence to the crew and passengers. The Cook answers to the Passenger Liason. In the absence of a Passenger Liason, the Cook is also responsible for tending to passenger related care and duties."
assignment = "Cook"
rank = "Cook"
icon_state = "itg_green"
item_state = "itg_green_id"
/obj/item/weapon/card/id/itg/event/security
name = "\improper ITG Security's ID"
desc = "An ID card belonging to Security of an ITG vessel. Security's responsibility is primarily to protect the ship, cargo, or facility. They may also be tasked to assist with cargo movement duties and rescue operations. ITG Security is almost exclusively defensive. They should not start fights, but they are very capable of finishing them."
assignment = "Security"
rank = "Security"
icon_state = "itg_red"
item_state = "itg_red_id"
/obj/item/weapon/card/id/itg/event/research
name = "\improper ITG Research's ID"
desc = "An ID card belonging to ITG Research staff. ITG Research staff primarily specializes in starship and starship engine design, and overcoming astronomic phenomena."
assignment = "Research"
rank = "Research"
icon_state = "itg_purple"
item_state = "itg_purple_id"
/obj/item/weapon/card/id/itg/event/medical
name = "\improper ITG Medic's ID"
desc = "An ID card belonging to the Medic of an ITG vessel. The Medic's responsibility is primarily to treat crew and passenger injuries. They may also be tasked with rescue operations."
assignment = "Medic"
rank = "Medic"
icon_state = "itg_white"
item_state = "itg_white_id"
/obj/item/weapon/card/id/itg/event/engineer
name = "\improper ITG Engineer's ID"
desc = "An ID card belonging to the Engineer of an ITG vessel. The Engineer's responsibility is primarily to maintain the ship. They may also be tasked to assist with cargo movement duties."
assignment = "Engineer"
rank = "Engineer"
icon_state = "itg_orange"
item_state = "itg_orange_id"
/obj/item/weapon/card/id/itg/event/passengerliason
name = "\improper ITG Passenger Liason's ID"
desc = "An ID card belonging to the Passenger Liason of an ITG vessel. The Passenger Liason's responsibility is primarily to manage and tend to passenger needs and maintain supplies and facilities for passenger use."
assignment = "Passenger Liason"
rank = "Passenger Liason"
icon_state = "itg_blue"
item_state = "itg_blue_id"
/obj/item/weapon/card/id/itg/event/captain
name = "\improper ITG Captain's ID"
desc = "An ID card belonging to the Captain of an ITG vessel. The Captain's responsibility is primarily to manage crew to ensure smooth ship operations. Captains often also often pilot the vessel when no dedicated pilot is assigned."
assignment = "Captain"
rank = "Captain"
icon_state = "itg_blue"
item_state = "itg_blue_id"
access = list(777, 778)
@@ -299,3 +299,13 @@
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return
/obj/item/weapon/implantcase/restrainingbolt
name = "glass case - 'Restraining Bolt'"
desc = "A case containing a restraining bolt."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/restrainingbolt/New()
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
..()
return
@@ -4,18 +4,6 @@
icon = 'icons/obj/device.dmi'
icon_state = "implant"
initialize_loc = BP_HEAD
var/roundstart = TRUE
/obj/item/weapon/implant/dud/torso
name = "unknown implant"
desc = "A small device with small connector wires."
icon = 'icons/obj/device.dmi'
icon_state = "implant"
initialize_loc = BP_TORSO
/obj/item/weapon/implant/dud/old
name = "old implant"
desc = "A small device with small connector wires."
icon = 'icons/obj/device.dmi'
icon_state = "implant"
roundstart = FALSE
@@ -150,3 +150,12 @@
S.remove_from_storage(A)
A.loc.contents.Remove(A)
update()
/obj/item/weapon/implanter/restrainingbolt
name = "implanter (bolt)"
/obj/item/weapon/implanter/restrainingbolt/New()
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
..()
update()
return
@@ -0,0 +1,5 @@
/obj/item/weapon/implant/restrainingbolt
name = "\improper restraining bolt"
icon = 'icons/obj/device.dmi'
icon_state = "implant"
+300 -1
View File
@@ -42,4 +42,303 @@
</html>
"}
"}
//accurate as of 2/17/21 Extra credit to document editting and proofreading editing to Luna
/obj/item/weapon/book/manual/cook_guide
name = "Food for Dummies 2"
desc = "A helpful guide to the world of cooking."
icon_state = "cook-guide"
icon = 'icons/obj/library_vr.dmi'
author = "Ali Big"
title = "Food for Dummies 2"
/obj/item/weapon/book/manual/cook_guide/New()
..()
dat = {"
<html>
<html>
<head>
<style>
h1 {font-size: 23px; margin: 15px 0px 5px; text-align: center;}
h2 {font-size: 20px; margin: 15px 0px 5px;}
h3 {font-size: 18px; margin: 15px 0px 5px;}
h4 {font-size: 14px; margin: 15px 0px 5px;}
h5 {font-size: 10px; margin: 15px 0px 5px; text-align: center;}
li {margin: 2px 0px 2px 15px;}
ul {margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
body {font-size: 13px; font-family: Garamond;}
</style>
</head>
<body>
<center><h1>Food for Dummies 2</h1></center>
<h5>Penned by Ali Big</h5>
<p><b>Hello Newbie</b>, congratz on deciding to make food! This guide assumes you know absolutely nothing, so fret not, the information here will help you prepare food for your hungry crewmates!</p>
<h3>Workspace prep:</h3>
This step is simple: merely go to the Grill, Oven, and Fryer and turn everything on so you do not need to wait for them to warm up later; they wont start a fire unless food is left in them unchecked. It is also highly suggested to lay out at least a few Measuring Cups on the counters for ease of use.
<h3>Basic ingredient prep:</h3>
In the lockers and fridges, you have all your needed supplies for this guide, so look through them and familiarize yourself! This guide will only use ingredients you already have access to, so don't worry about missing items!
<h2>Part 1: How to Create Various Essential Ingredients with What You Have</h2>
<h3>Dough Creation:</h3>
The basis for a large quantity of meals. Simply take an Egg, crack it into a Beaker or Measuring Cup, and then add 10 units of Flour to create Dough.
<h3>Dough Creation part 2:</h3>
With Dough, you can make a wide variety of base ingredients. Flattening it with a Rolling Pin makes Flat Dough. Flat Dough can be cooked in a Microwave for Flatbread, or if one adds Water and Flour in with the Flat Dough in the Microwave you get a Tortilla. Water can be obtained by filling a Cup at the Sink or Soda Machine.
<h3>Dough Creation Part 3:</h3>
Alternatively, Flat Dough can be cut with a Knife to make Dough Slices, and those can be cut to make Spaghetti.
<h3>Cheese Creation:</h3>
A common topping. Take a bottle of Universal Enzyme, put it in a Beaker or Measuring Cup, and add Milk until a Cheese Wheel pops out. Then cut the Cheese Wheel with a Knife to make Cheese Wedges, all recipes use Wedges not the full Wheel.
<h3>Tofu Creation:</h3>
Same as cheese, but with Soymilk!
<h3>Meatball Creation:</h3>
Mix Animal protein and Flour, to create Animal Protein grind down some Meat in the grinder, then remove the beaker and add Flour.
<h3>Meat Uses:</h3>
Full pieces of Meat can be cut for Raw Cutlets, which can be cut once more to make Raw Bacon. Though be sure not to cut all of your meat, plenty of recipes need a full uncut piece!
<h2>Part 2: Putting It All Together</h2>
<p>Now that you know the fundamentals of how to make the base ingredients, here are some fairly easy recipes to put them together into something enjoyable for the crew.</p>
<h4>Warning: recipes are upscale able, so you can add multiple of the same ingredients in the same ratio to cook lots of food at once!</h4>
<h4>Warning: do not try and cook multiple recipes at once as it is very likely it will default to a different recipe or will just cook the one and just "grill, bake, etc." the rest of the ingredients.</h4>
<h2>Burgers:</h2>
<b>The cornerstone of basic food:</b> to prepare these, microwave a piece of Dough to get a bun and grab a piece of Meat. Open the Grill, remove the Rack, and add both Bun and Meat to the Rack. Then, place the Rack back into the Grill to cook and remove it once finished. If you feel fancy, you can add cheese afterwards for a cheeseburger.
<h2>Meat Pie:</h2>
Flat Dough and Meat in an Oven Pan, same way you use the Grill; take the Pan out, put the ingredients in, and place it back to cook. Simple, but very good looking and tasty!
<h2>Burritos:</h2>
Burritos: A personal favorite due to flexibility of options: Use a Tortilla as a base for all of these. For a Chili one, add 2 Meatballs and 1 Space Spice (found near the Flour) to the Microwave; very simple and filling! Add a Cheese Wedge instead of the spice to make a queso burrito. For a Breakfast Wrap, add a whole Egg, Cooked Bacon (Raw Bacon cooked in the Microwave), and Cheese in with the Tortilla. For Vegan Burritos, just cook a Tortilla and Tofu together in the Microwave.
<h2>Tacos:</h2>
Use a tortilla then 1 cooked Cutlet, and a Cheese Wedge. Very easy to mass produce, great in a pinch!
<h2>Cheesy Nachos:</h2>
Tortilla, Cheese and 1 unit of Salt in the microwave, the perfect Finger Food!
<h2>Spaghetti:</h2>
Without Tomatos from Botany it's not going to be the flashiest, but one can make Boiled Spaghetti with Spaghetti and Water in the Microwave. Kitsune Udon can be made with Spaghetti, Egg Yolk (crack egg in beaker then add to microwave), and Tofu. Spaghetti and Meatballs can be made by doing the Boiled Spaghetti Recipe and adding 2 Meatballs; adding 4 Meatballs into the initial mix makes Spesslaw. Lastly, Spaghetti, Milk, and Cheese in the Oven makes Macaroni and Cheese.
<h2>Steak:</h2>
For the pure meat eaters, just add Meat, 1 Salt, and 1 Pepper into the grill for them, and try not to cry as they use up all your Meat quickly. (There's a second Meat Locker in the freezer room if you do run out!)
<h2>Donk Pockets:</h2>
Dough and Meatball in the Microwave, though we already have plenty lying around the station.
<h2>Eggs:</h2>
Fried Egg, 1 Egg 1 Salt, 1 Pepper in a Microwave. Bacon and Eggs if you combine Cooked Bacon and Fried Egg in the Microwave. Great way to start the shift!
<h2>Part 3: Final Notes</h2>
<p>These recipes only scratch the surface, but it's all things that can be done with what is pre-provided. If you have a partner in Botany, feel free to request more meat or any other supplies to try new recipes!</p>
<p>The Fryer, CondiMaster3000, and other nearby devices have been deliberately left out of this guide; as you get more advanced feel free to experiment with them, though be careful with the Fryer especially as it's the #1 source of fires for learning chefs, myself included. The one other machine that is worth understanding is the <b>Gibber</b> in the freezer room. If you are delivered fish or such they can be gibbed for extra Meat, though you may need to butcher the parts with a Knife afterwards to get usable Meat! Though if the meat is purple or comes from Koi or Spacecarp <b>do not directly serve it to crew!</b> It contains toxins that are better taken care of by other departments. </p>
<p>Some wonderful websites share recipes and tips for learning chefs on the Extranet! Look on your PDA or preferred device at https://wiki.vore-station.net/Guide_to_Food_and_Drink and https://vore-station.net/infodump/recipes_food.html for further tips, though do note the latter is more accurate in regard to recipes. Happy cooking!</p>
<h4>Pro Tips:</h4>
<h4>((The Food Bags in the Chef's Closet are great for moving a lot of food at once!))</h4>
<h4>((Stay out of the Freezer if you're Cold Blooded!))</h4>
<h4>((The websites linked above are also on our stations wiki. Which is always in need of helping heads to fix it up. The recipes listed on the web link may not be fully accurate so please don't be afraid to pop into the discord wiki channel and lend a hand!))</h4>
</body>
</html>
"}
//accurate as of 2/23/21
/obj/item/weapon/book/manual/bar_guide
name = "How to Alcohol (And other Drinks)"
desc = "A helpful guide to the world of barkeeping."
icon_state = "bar-guide"
icon = 'icons/obj/library_vr.dmi'
author = "Ali Big"
title = "How to Alcohol (And other Drinks)"
/obj/item/weapon/book/manual/bar_guide/New()
..()
dat = {"
<html>
<head>
<style>
h1 {font-size: 23px; margin: 15px 0px 5px; text-align: center;}
h2 {font-size: 20px; margin: 15px 0px 5px;}
h3 {font-size: 18px; margin: 15px 0px 5px;}
h4 {font-size: 14px; margin: 15px 0px 5px;}
h5 {font-size: 10px; margin: 15px 0px 5px; text-align: center;}
h6 {font-size: 8px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
body {font-size: 13px; font-family: arial;}
</style>
</head>
<body>
<h1>How to Alcohol (And other Drinks)</h1>
<h5>Penned by Ali Big</h5>
<p>Hello, and congratulations on taking on the admirable, and often thankless task of making Drinks for your fellow crewmates (or perhaps yourself if you hopped the bar, how rude!).</p>
<p>This guide will walk through the essentials of drink making... don't worry, it's not too complex! Recipes have been placed at the top for ease of use, but further down there is an actual guide as to how to make drinks, so give it a read if you don't know how, or just want some tips!</p>
<h1>Part 0: Recipes Quick Reference (Ordered by strength, non-exhaustive list)</h1>
<h1>Low Alcohol:</h1>
<h3>Grog :</h3>
1 part Rum, 1 part Water
<h3>Sui Dream:</h3>
1 part Space-Up, 1 part Miss Blue Curacao, 1 part Emeraldine Melon Liquor
<h3>Baloon:</h3>
1 part Cream, 1 part Miss Blue Curacao
<h3>Gin and Tonic:</h3>
1 part Gin, 1 part Tonic
<h3>Appletini:</h3>
2 parts Apple Juice, 1 part Vodka
<h1>Medium Alcohol</h1>
<h3>Giant Beer:</h3
1 part Syndicate Bomb, 1 part Manly Dorf, 1 part Grog
<h3>Chrysanthemum:</h3>
1 part Sake, 1 part Emeraldine Melon Liquor
<h3>Barefoot:</h3>
1 part Berry Juice, 1 part Cream, 1 part Vermouth.
<h3>Clover Club:</h3>
1 part Berry Juice, 1 Part Lemon Juice, 3 parts Gin
<h3>Cold Front:</h3>
1 part Iced Coffee, 1 part Whiskey, 1 part Mint <b>(Allergy Warning: do not give to any species with less cold tolerance than Teshari, they will die if you do, if unsure do not serve)</b>
<h3>Cuba Libre (Often called Rum and Coke):</h3>
1 part Space Cola, 2 parts Rum.
<h3>Negroni Sbagliato:</h3>
1 part Wine, 1 part Bermouth, 1 part Soda Water
<h3>Slow Comfortable Screw Against the Wall (Stop giggling!):</h3>
3 parts Screwdriver, 1 part Rum, 1 part Whiskey, 1 part Gin
<h3>Space Bulldog:</h3>
4 parts White Russian, 1 part Cola
<h3>Sweet Rush:</h3>
1 part Sugar, 1 part Soda Water, 1 part Vodka.
<h3>Allies Cocktail:</h3>
1 part Classic Martini, 1 part Vodka
<h3>Bahama Mama:</h3>
1 part Ice, 2 parts Orange Juice, 1 part Lime Juice, 2 parts Rum
<h3>Classic Martini:</h3>
2 parts Gin, 1 part Vermouth
<h3>Daiquiri:</h3>
3 Rum, 2 Lime Juice, 1 Sugar
<h3>Ginza Mary:</h3>
2 part Sake, 2 part Vodka, 1 part Tomato Juice
<h3>Irish Cream:</h3>
2 parts Whiskey, 1 part Cream
<h3>Lotus:</h3>
1 part Negroni Sbagliato, 1 part Sweet Rush
<h3>Tequila Sunrise:</h3>
2 parts Tequila, 1 part Orange Juice
<h3>The Manly Dorf:</h3>
1 part Beer, 2 parts Ale
<h3>Whiskey Cola:</h3>
2 parts Whiskey, 1 part Space Cola
<h3>Binman Bliss:</h3>
1 part Sake, 1 part Tequila
<h1>High Alcohol</h1>
<h3>Elysium Facepunch:</h3>
1 part Kahlua, 1 part Lemon Juice
<h3>Italian Crisis:</h3>
1 part Space Bulldog, 1 part Negroni Sbagliato
<h3>Whiskey Sour:</h3>
2 Whiskey, 1 Lemon Juice, 1 Sugar
<h3>Aloe:</h3>
1 part Cream, 1 part Watermelon Juice, 1 part Whiskey <b>(in that order)</b>
<h3>Andalusia:</h3>
1 part Lemon Juice, 1 part Rum, 1 part Whiskey
<h3>Black Russian:</h3>
2 part Vodka, 1 part Kahlua
<h3>Bloody Mary:</h3>
3 parts Tomato Juice, 2 part Vodka, 1 part Lime Juice
<h3>Brave Bull:</h3>
2 parts Tequila, 1 part Kahlua
<h3>Irish Car Bomb:</h3>
1 part Ale, 1 part Irish Cream
<h3>Irish Coffee:</h3>
1 parts Irish Cream, 1 parts Coffee
<h3>Manhattan:</h3>
2 parts Whiskey, 1 part Vermouth
<h3>Margarita:</h3>
2 parts Tequila, 1 part Lime Juice
<h3>Screwdriver:</h3>
2 parts Vodka, 1 part Orange Juice
<h3>Sex On The Beach:</h3>
3 part Orange Juice, 2 part Grenadine Syrup, 1 part Vodka
<h3>Vodka and Tonic:</h3>
2 parts Vodka, 1 part Tonic
<h3>Whiskey Soda:</h3>
2 parts Whiskey, 1 part Soda Water
<h3>White Russian:</h3>
2 Black Russian, 1 part Cream
<h3>WND-Garita:</h3>
3 Margarita, 2 Mountain Wind, 1 Emeraldine Melon Liquor
<h3>Mudslide:</h3>
1 Black Russian, 1 Irish Cream
<h1>Very High Alcohol (Serve sparingly unless a patron proves they can handle a lot)</h1>
<h3>Anti-Freeze:</h3>
1 part Cream, 1 part Ice, 1 parts Vodka <b>(Feels cold but actually warms. Allergy Warning: Do not serve to Teshari or Promethians, or other heat vulnerable species, they will die if you do, if unsure do not serve)</b>
<h3>B-52:</h3>
1 part Irish Cream, 1 part Cognac, 1 part Kahlua
<h3>Long Island Iced Tea:</h3>
3 part Cuba Libre, 1 part Vodka, 1 part Gin, 1 part Tequila
<h3>Vodka Martini:</h3>
2 parts Vodka, 1 part Vermouth
<h3>Changeling Sting:</h3>
1 part Screwdriver, 1 part Lemon Juice, 1 part Lime Juice
<h3>Deathbell:</h3>
1 part Anti-Freeze, 1 part Pan-Galactic Gargle Blaster, 1 part Syndicate Bomb <b>(Allergy Warning: Poisonous to Teshari and other heat vulnerable species. Literally explodes Promethians. Metabolizes very quickly so it can kill a liver easily, be very careful with this one.)</b>
<h3>Erebus Moonrise:</h3>
1 part Whiskey, 1 part Vodka, 1 part Tequila
<h3>Pan-Galactic Gargle Blaster:</h3>
1 part Gin, 2 part Vodka, 1 part Whiskey, 1 part Cognac, 1 part Lime Juice <b>(Causes halucinations, don't slip it into other drinks you animal)</b>
<h3>Syndicate Bomb:</h3>
1 part Whiskey Cola, 1 part Beer
<h3>Euphoria:</h3>
1 part Special Blend Whiskey, 2 part Cognac
<h3>Screaming Viking:</h3>
Vodka, Vermouth, Lime Juice, Rum, Gin, and Tonic
<h6>Good Luck figuring out the order and ratio :)</h6>
<h3>Fire Punch:</h3>
1 part Sugar, 2 part Rum <b>(Technically the strongest thing you can make, but it metabolizes slowish so it's slightly less dangerous than some others)</b>
<h1>Non Alcoholic Drinks</h1>
<h3>Appleade:</h3>
1 part Apple Juice, 1 part Sugar, 1 part Soda Water
<h3>Arnold Palmer:</h3>
1 Iced Tea, 1 Lemonade
<h3>Berry Cordial:</h3>
4 Berry Juice, 1 unit Sugar, 1 Lemon Juice
<h3>Berry shake:</h3>
1 part Milkshake, 1 part Berry Juice
<h3>Brown Star:</h3>
2 parts Orange Juice, 1 part Space Cola
<h3>Cafe Latte:</h3>
1 part Coffee, 1 part Milk
<h3>Coffee Milkshake:</h3>
1 part Milkshake, 1 part Coffee
<h3>Driver's Punch:</h3>
1 part Appleade, 1 part Orange Juice, 1 part Mint, 1 part Soda Water
<h3>Graveyard:</h3>
All 4 Sodas in your Soft Drink Dispenser in equal parts, haha it go woosh.
<h3>Grenadine Syrup:</h3>
10 parts berry juice, 5 parts Universal Enzyme <b>(Get Enzyme from Kitchen)</b>
<h3>Iced Coffee:</h3>
1 part Ice, 2 parts Coffee
<h3>Kira Special:</h3>
1 part Orange Juice, 1 part Lime Juice, 1 part Soda Water
<h3>Lemonade:</h3>
1 part Lemon juice, 1 part Sugar, 1 part Water
<h3>Melonade:</h3>
1 part Watermelon Juice, 1 part Sugar, 1 part Soda Water
<h3>Milkshake:</h3>
1 part Cream, 2 parts Ice, 2 parts Milk
<h3>Sweet Tea:</h3>
2 parts Ice Tea, 1 part Sugar
<p><b>Note:</b> There are many more drinks you can mix, these are just ones using resources you will almost always have available, the Extranet has good websites to check found here: https://wiki.vore-station.net/Guide_to_Food_and_Drink ass well as here: https://vore-station.net/infodump/recipes_drinks.html
<h1>Part 1: The Basics</h1>
<p>First and foremost, making drinks is about understanding measurements. Drinks are measured in units a pint is 60 units, a half pint 30, and ratios of those units can create certain drinks.</p>
<p>The ratios of these drinks are denoted in "Parts". For example, Grog is 1 part rum and 1 part water mixed in a container that holds liquid. This means 1 unit of Rum and 1 unit of Water can make Grog, as can 30 units of Rum and 30 units of Water. Ratios aren't picky, if you have 5 units of Rum and 10 of Water in a glass, it will turn as much as possible into Grog, and the rest will remain as water (In this case, 10 units of Grog and 5 units of Water will be in the glass). When mixing drinks, you may accidentally have extra of an ingredient such as in the previous example, but this can easily be rectified by placing the drink in one of the Dispensers, and using the interface at the bottom to remove however many units you put extra, so don't worry about sloppiness as long as you clean up your mistakes!</p>
<p>Actually mixing drinks is simple enough, the vast majority of mixing should be done in a Dispenser, it can be done by hand outside of one, but generally you only want to be doing so for when the Dispenser lacks an ingredient to make life easier. Drinks automatically mix when placed into a container together, so you don't have to do anything special, think of it like a chemical reaction, it even bubbles when it works!</p>
<h2>Part 2: General Tips/FAQ</h2>
<p><b>"I don't have X item for the drink my patron wants."</b> - If it's on the quick reference, you probably do, just be sure to check the Booze-O-Mat if it cannot be found in the dispenser. If it's not in either Dispenser or in the Coffee Dispenser in the Surface 1 Bar (Such as Berry Juice). If you still lack the materials, you may need to ask another department (Cargo, Science, or perhaps Med usually) for a delivery of them.</p>
<p><b>"I don't want to run to the Surface 1 Bar every time to make this specific drink."</b> - You don't have to! A good practice as a bartender if you want to make your life easier is to take a screwdriver, use it on the machine, and select the cartridges you want to have in your bar. If you do this you will remove them, and are free to insert them into your own machines, but do be considerate if there are more bartenders around, don't steal their supplies if they need them! Another good practice is to move, or have someone else move the machine up to your bar instead of removing the cartridges, ultimately the choice is yours as to how best set up your bar!</p>
<p><b>"How do I deal with a rowdy patron?"</b> - Ask Security for help, just because you have a shotgun doesn't mean you are the law in your bar. Respect procedure!</p>
<p><b>"What does the Grinder do?"</b> - What it says on the tin, if you get Iron, Uranium, or something else needed for a drink that isn't already liquefied, you have to grind it down first to add it!</p>
<p><b>"Do I have to wear the hat?"</b> - No, but you can if it looks good on you!</p>
<p><b>"How do I unlock the good music on the Jukebox?"</b> - Get a Screwdriver and use it on the Jukebox to open the hatch, then use Wirecutters and cut/remend wires until you cut the one that turns the Parental Guidance light off. Beware of shocks (Insulated Gloves Suggested)! Be sure to close it again after.</p>
<p><b>"How do I make my drinks look pretty?"</b> - Use the Metamorphic Glasses, though do note some drinks don't look any different even in one.</p>
<p><b>"Oh god my patron is convulsing, what do I do?"</b> - Rush them to Medbay. If they're too big to move get a rolling chair from the Library, or get medical staff to come to the Bar.</p>
<p><b>"My patron drank too much and is definitely going to start convulsing, what do I do?"</b> - Either rush them to Medbay, or get Medbay to give you pills that neutralize alcohol, it's ok to be the fun police to save a life.</p>
<p><b>"Nobody wants to stay at my bar!"</b> - Try adopting a gimmick to spruce things up! Everyone's will be different, but doing something fun is a good way to attract customers. Creating your own unique mixes is another fun way to distinguish yourself.</p>
<p><b>"I don't like the way the bar looks with the lights dimmed/I don't like the way the bar looks with the lights bright!"</b> - Enable or disable the night lighting on the APC by the bar then!</p>
<p><b>"A patron said they don't drink, woe is me, my job is now useless!"</b> - Have you tried offering them a non-alcoholic drink? Or just talking to them? As long as you're providing a good time, you're still doing great!</p>
<p><b>"Somebody messed with a drink I left lying out on the counter, I think it's been spiked!"</b> - Don't leave drinks lying on the counter. Not only is it a spiking hazzard, but inevitably somebody is gonna try to chug them all. If you want to do a pretty display, make it non alcoholic, or on the back bar counter out of easy reach!</p>
<p><b>"My patrons are all hungry because we have no Chef!"</b> - Well, you have access to the Kitchen if you feel like trying to solve that, I have a guide for that there too!</p>
<p><b>"I feel like a hamster in a wheel, running hopelessly but never quite getting anywhere. No matter what I do, things just don't seem to change, I don't seem to change, and I worry, that maybe... they won't."</b> - Try drinking some of your own booze until that feeling goes away.</p>
<h2>Part 3: Closing Remarks</h2>
<p>This all may seem daunting at a glance; so many recipes to learn, and a "lot" to keep in mind. But really it's not - tending the Bar is mostly about going with the flow of things and providing a good times, and drinks just provide liquid courage to make a good time easier. Take a deep breath if you ever feel overwhelmed, and handle one order at a time. You can do it! Don't feel the need to know every recipe, just learn your favorites and go from there; the rest is here or online if someone asks for it! If somebody asks you to give them anything without a specific request, don't panic: evalulate their likes and tolerance level, and try your best to give them something nice!</p>
</body>
</html> "}
@@ -45,13 +45,15 @@
/obj/item/weapon/material/butterfly/attack_self(mob/user)
active = !active
if(active)
to_chat(user, "<span class='notice'>You flip out \the [src].</span>")
playsound(src, 'sound/weapons/flipblade.ogg', 15, 1)
else
to_chat(user, "<span class='notice'>\The [src] can now be concealed.</span>")
update_force()
add_fingerprint(user)
if(user)
if(active)
to_chat(user, "<span class='notice'>You flip out \the [src].</span>")
playsound(src, 'sound/weapons/flipblade.ogg', 15, 1)
else
to_chat(user, "<span class='notice'>\The [src] can now be concealed.</span>")
add_fingerprint(user)
/*
* Kitchen knives
@@ -97,6 +97,8 @@
/obj/item/weapon/material/proc/check_health(var/consumed)
if(health<=0)
health = 0
if(fragile)
shatter(consumed)
else if(!dulled && can_dull)
@@ -77,14 +77,14 @@
//visible_message("[user] has smashed the snowball in their hand!", "You smash the snowball in your hand.")
to_chat(user, "<span class='notice'>You smash the snowball in your hand.</span>")
var/atom/S = new /obj/item/stack/material/snow(user.loc)
del(src)
qdel(src)
user.put_in_hands(S)
else
//visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.")
to_chat(user, "<span class='notice'>You start compacting the snowball.</span>")
if(do_after(user, 2 SECONDS))
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
del(src)
qdel(src)
user.put_in_hands(S)
/obj/item/weapon/material/snow/snowball/reinforced
@@ -93,3 +93,118 @@
//icon_state = "reinf-snowball"
force_divisor = 0.20
thrown_force_divisor = 0.25
/obj/item/weapon/material/whip
name = "whip"
desc = "A tool used to discipline animals, or look cool. Mostly the latter."
description_info = "Help - Standard attack, no modifiers.<br>\
Disarm - Disarming strike. Attempts to disarm the target at range, similar to an unarmed disarm. Additionally, will force the target (if possible) to move away from you.<br>\
Grab - Grappling strike. Attempts to pull the target toward you. This can also move objects.<br>\
Harm - A standard strike with a small chance to disarm."
icon = 'icons/obj/weapons.dmi'
icon_state = "whip"
item_state = "chain"
default_material = MAT_LEATHER
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 2)
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
force_divisor = 0.15
thrown_force_divisor = 0.25
reach = 2
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
/obj/item/weapon/material/whip/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
..()
if(!proximity)
return
if(istype(A, /atom/movable))
var/atom/movable/AM = A
if(AM.anchored)
to_chat(user, "<span class='notice'>\The [AM] won't budge.</span>")
return
else
if(!istype(AM, /obj/item))
user.visible_message("<span class='warning'>\The [AM] is pulled along by \the [src]!</span>")
AM.Move(get_step(AM, get_dir(AM, src)))
return
else
user.visible_message("<span class='warning'>\The [AM] is snatched by \the [src]!</span>")
AM.throw_at(user, reach, 0.1, user)
/obj/item/weapon/material/whip/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
if(user.a_intent)
switch(user.a_intent)
if(I_HURT)
if(prob(10) && istype(target, /mob/living/carbon/human) && user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
to_chat(target, "<span class='warning'>\The [src] rips at your hands!</span>")
ranged_disarm(target)
if(I_DISARM)
if(prob(min(90, force * 3)) && istype(target, /mob/living/carbon/human) && user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
ranged_disarm(target)
else
target.visible_message("<span class='danger'>\The [src] sends \the [target] stumbling away.</span>")
target.Move(get_step(target,get_dir(user,target)))
if(I_GRAB)
var/turf/STurf = get_turf(target)
spawn(2)
playsound(STurf, 'sound/effects/snap.ogg', 60, 1)
target.visible_message("<span class='critical'>\The [src] yanks \the [target] towards \the [user]!</span>")
target.throw_at(get_turf(get_step(user,get_dir(user,target))), 2, 1, src)
..()
/obj/item/weapon/material/whip/proc/ranged_disarm(var/mob/living/carbon/human/H, var/mob/living/user)
if(istype(H))
var/list/holding = list(H.get_active_hand() = 40, H.get_inactive_hand() = 20)
if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
for(var/obj/item/weapon/gun/W in holding)
if(W && prob(holding[W]))
var/list/turfs = list()
for(var/turf/T in view())
turfs += T
if(turfs.len)
var/turf/target = pick(turfs)
visible_message("<span class='danger'>[H]'s [W] goes off due to \the [src]!</span>")
return W.afterattack(target,H)
if(!(H.species.flags & NO_SLIP) && prob(10) && user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))
var/armor_check = H.run_armor_check(user.zone_sel, "melee")
H.apply_effect(3, WEAKEN, armor_check)
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(armor_check < 60)
visible_message("<span class='danger'>\The [src] has tripped [H]!</span>")
else
visible_message("<span class='warning'>\The [src] attempted to trip [H]!</span>")
return
else
if(H.break_all_grabs(user))
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
for(var/obj/item/I in holding)
if(I && prob(holding[I]))
H.drop_from_inventory(I)
visible_message("<span class='danger'>\The [src] has disarmed [H]!</span>")
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
/obj/item/weapon/material/whip/suicide_act(mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message(span("danger", "\The [user] [T.is] strangling [T.himself] with \the [src]! It looks like [T.he] [T.is] trying to commit suicide."), span("danger", "You start to strangle yourself with \the [src]!"), span("danger", "You hear the sound of someone choking!"))
return (OXYLOSS)
/obj/item/weapon/material/whip/attack_self(mob/user)
user.visible_message("<span class='warning'>\The [user] cracks \the [src]!</span>")
playsound(src, 'sound/effects/snap.ogg', 50, 1)
@@ -9,10 +9,12 @@
origin_tech = list(TECH_COMBAT = 4)
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
suicide_act(mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message(span("danger", "\The [user] [T.is] strangling [T.himself] with \the [src]! It looks like [T.he] [T.is] trying to commit suicide."), span("danger", "You start to strangle yourself with \the [src]!"), span("danger", "You hear the sound of someone choking!"))
return (OXYLOSS)
reach = 2
/obj/item/weapon/melee/chainofcommand/suicide_act(mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message(span("danger", "\The [user] [T.is] strangling [T.himself] with \the [src]! It looks like [T.he] [T.is] trying to commit suicide."), span("danger", "You start to strangle yourself with \the [src]!"), span("danger", "You hear the sound of someone choking!"))
return (OXYLOSS)
/obj/item/weapon/melee/umbrella
name = "umbrella"
@@ -65,7 +65,6 @@
light_applied = 0
update_icon(user)
user.update_action_buttons()
light = !light
playsound(src, 'sound/weapons/empty.ogg', 15, 1, -3)
/obj/item/weapon/shield/riot/explorer/update_icon()
@@ -92,4 +91,4 @@
if(on)
icon_state = "explorer_shield_P_lighted"
else
icon_state = "explorer_shield_P"
icon_state = "explorer_shield_P"
@@ -6,7 +6,7 @@
item_state = "saddlebag"
icon_state = "saddlebag"
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
slowdown = 1 //And are slower, too...Unless you're a macro, that is.
slowdown = 1 //And are slower, too...
var/taurtype = /datum/sprite_accessory/tail/taur/horse //Acceptable taur type to be wearing this
var/no_message = "You aren't the appropriate taur type to wear this!"
@@ -35,7 +35,7 @@
icon_state = "saddlebag"
var/icon_base = "saddlebag"
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
slowdown = 1 //And are slower, too...Unless you're a macro, that is.
slowdown = 1 //And are slower, too...
var/no_message = "You aren't the appropriate taur type to wear this!"
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
@@ -44,11 +44,6 @@
log_runtime("[H] was not a valid human!")
return
if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? If yes, they get no slowdown.
slowdown = 0
else
slowdown = initial(slowdown)
var/datum/sprite_accessory/tail/taur/TT = H.tail_style
item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer"
return 1
@@ -124,7 +124,7 @@
to_chat(user, "<span class='notice'>You fill the [src].</span>")
else if(!silent)
to_chat(user, "<span class='notice'>You fail to pick anything up with \the [src].</span>")
if(istype(user.pulling, /obj/structure/ore_box/)) //Bit of a crappy way to do this, as it doubles spam for the user, but it works.
if(istype(user.pulling, /obj/structure/ore_box)) //Bit of a crappy way to do this, as it doubles spam for the user, but it works.
var/obj/structure/ore_box/O = user.pulling
O.attackby(src, user)
@@ -0,0 +1,202 @@
//Item type vorepanel egg release containers.
/obj/item/weapon/storage/vore_egg
name = "egg"
desc = "It's an egg; it's smooth to the touch." //This is the default egg.
icon = 'icons/obj/egg_new_vr.dmi'
icon_state = "egg"
var/open_egg_icon = 'icons/obj/egg_open_vr.dmi'
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
)
w_class = 2
max_w_class = 0
show_messages = 0
allow_quick_empty = TRUE
use_sound = 'sound/items/drop/flesh.ogg'
/obj/item/weapon/storage/vore_egg/open(mob/user as mob)
icon = open_egg_icon
..()
/obj/item/weapon/storage/vore_egg/proc/hatch(mob/living/user as mob)
visible_message("<span class='danger'>\The [src] begins to shake as something pushes out from within!</span>")
animate_shake()
if(do_after(user, 50))
if(use_sound)
playsound(src, src.use_sound, 50, 0, -5)
animate_shake()
drop_contents()
icon = open_egg_icon
/obj/item/weapon/storage/vore_egg/proc/animate_shake()
var/init_px = pixel_x
var/shake_dir = pick(-1, 1)
animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
/obj/item/weapon/storage/vore_egg/unathi
name = "unathi egg"
desc = "Some species of Unathi apparently lay soft-shelled eggs!"
icon_state = "egg_unathi"
/obj/item/weapon/storage/vore_egg/nevrean
name = "nevrean egg"
desc = "Most Nevreans lay hard-shelled eggs!"
icon_state = "egg_nevrean"
/obj/item/weapon/storage/vore_egg/human
name = "human egg"
desc = "Some humans lay eggs that are--wait, what?"
icon_state = "egg_human"
/obj/item/weapon/storage/vore_egg/tajaran
name = "tajaran egg"
desc = "Apparently that's what a Tajaran egg looks like. Weird."
icon_state = "egg_tajaran"
/obj/item/weapon/storage/vore_egg/skrell
name = "skrell egg"
desc = "Its soft and squishy"
icon_state = "egg_skrell"
/obj/item/weapon/storage/vore_egg/shark
name = "akula egg"
desc = "Its soft and slimy to the touch"
icon_state = "egg_akula"
/obj/item/weapon/storage/vore_egg/sergal
name = "sergal egg"
desc = "An egg with a slightly fuzzy exterior, and a hard layer beneath."
icon_state = "egg_sergal"
/obj/item/weapon/storage/vore_egg/slime
name = "slime egg"
desc = "An egg with a soft and squishy interior, coated with slime."
icon_state = "egg_slime"
/obj/item/weapon/storage/vore_egg/special //Not actually used, but the sprites are in, and it's there in case any admins need to spawn in the egg for any specific reasons.
name = "special egg"
desc = "This egg has a very unique look to it."
icon_state = "egg_unique"
/obj/item/weapon/storage/vore_egg/scree
name = "Chimera egg"
desc = "...You don't know what type of creature laid this egg."
icon_state = "egg_scree"
/obj/item/weapon/storage/vore_egg/xenomorph
name = "Xenomorph egg"
desc = "Some type of pitch black egg. It has a slimy exterior coating."
icon_state = "egg_xenomorph"
/obj/item/weapon/storage/vore_egg/chocolate
name = "chocolate egg"
desc = "Delicious. May contain a choking hazard."
icon_state = "egg_chocolate"
/obj/item/weapon/storage/vore_egg/owlpellet
name = "boney egg"
desc = "Can an egg shell be made of bones and hair?"
icon_state = "egg_pellet"
/obj/item/weapon/storage/vore_egg/slimeglob
name = "glob of slime"
desc = "Very squishy."
icon_state = "egg_slimeglob"
/obj/item/weapon/storage/vore_egg/chicken
name = "chicken egg"
desc = "Looks like chickens come in all sizes and shapes."
icon_state = "egg_chicken"
/obj/item/weapon/storage/vore_egg/synthetic
name = "synthetic egg"
desc = "Smells like Easter morning."
icon_state = "egg_synthetic"
/obj/item/weapon/storage/vore_egg/escapepod
name = "small escape pod"
desc = "Someone left in a hurry."
icon_state = "egg_escapepod"
/obj/item/weapon/storage/vore_egg/floppy
name = "blue space floppy disc"
desc = "Probably shouldn't copy THIS floppy."
icon_state = "egg_floppy"
/obj/item/weapon/storage/vore_egg/cd
name = "blue space cd"
desc = "What could even be on this?!"
icon_state = "egg_cd"
/obj/item/weapon/storage/vore_egg/file
name = "blue space file"
desc = "Gotta wonder how much is compressed in there."
icon_state = "egg_file"
/obj/item/weapon/storage/vore_egg/badrecipe
name = "Burned mess"
desc = "Someone didn't cook this egg quite right..."
icon_state = "egg_badrecipe"
/obj/item/weapon/storage/vore_egg/cocoon
name = "web cocoon"
desc = "It straight up smells like spiders in here."
icon_state = "egg_cocoon"
/obj/item/weapon/storage/vore_egg/honeycomb
name = "honeycomb"
desc = "Smells delicious!"
icon_state = "egg_honeycomb"
/obj/item/weapon/storage/vore_egg/bugcocoon
name = "bug cocoon"
desc = "Metamorphosis!"
icon_state = "egg_bugcocoon"
/obj/item/weapon/storage/vore_egg/rock
name = "rock egg"
desc = "It looks like a small boulder."
icon_state = "egg_rock"
/obj/item/weapon/storage/vore_egg/yellow
name = "yellow egg"
desc = "It is a nice yellow egg."
icon_state = "egg_yellow"
/obj/item/weapon/storage/vore_egg/blue
name = "blue egg"
desc = "It is a nice blue egg."
icon_state = "egg_blue"
/obj/item/weapon/storage/vore_egg/green
name = "green egg"
desc = "It is a nice green egg."
icon_state = "egg_green"
/obj/item/weapon/storage/vore_egg/orange
name = "orange egg"
desc = "It is a nice orange egg."
icon_state = "egg_orange"
/obj/item/weapon/storage/vore_egg/purple
name = "purple egg"
desc = "It is a nice purple egg."
icon_state = "egg_purple"
/obj/item/weapon/storage/vore_egg/red
name = "red egg"
desc = "It is a nice red egg."
icon_state = "egg_red"
/obj/item/weapon/storage/vore_egg/rainbow
name = "rainbow egg"
desc = "It looks so colorful."
icon_state = "egg_rainbow"
/obj/item/weapon/storage/vore_egg/pinkspots
name = "spotted pink egg"
desc = "It is a cute pink egg with white spots."
icon_state = "egg_pinkspots"
@@ -523,9 +523,11 @@
if(((!(ishuman(usr) || isrobot(usr))) && (src.loc != usr)) || usr.stat || usr.restrained())
return
drop_contents()
var/turf/T = get_turf(src)
/obj/item/weapon/storage/proc/drop_contents() // why is this a proc? literally just for RPEDs
hide_from(usr)
var/turf/T = get_turf(src)
for(var/obj/item/I in contents)
remove_from_storage(I, T)
@@ -174,7 +174,7 @@
gauge_icon = "indicator_emergency"
/obj/item/weapon/tank/emergency/nitrogen/Initialize()
..()
. = ..()
src.air_contents.adjust_gas("nitrogen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/weapon/tank/emergency/nitrogen/double
@@ -341,6 +341,8 @@ var/list/global/tank_gauge_cache = list()
return remove_air(moles_needed)
/obj/item/weapon/tank/process()
if(!air_contents)
return
//Allow for reactions
air_contents.react() //cooking up air tanks - add phoron and oxygen, then heat above PHORON_MINIMUM_BURN_TEMPERATURE
if(gauge_icon)
@@ -671,7 +671,7 @@
always_process = TRUE
/obj/item/weapon/weldingtool/electric/mounted/exosuit/Initialize()
..()
. = ..()
if(istype(loc, /obj/item/mecha_parts/mecha_equipment))
equip_mount = loc
+241
View File
@@ -1,3 +1,9 @@
/*
* Beartraps.
* Buckles crossing individuals, doing moderate brute damage.
*/
/obj/item/weapon/beartrap
name = "mechanical trap"
throw_speed = 2
@@ -158,3 +164,238 @@
color = "#C9DCE1"
origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 1)
/*
* Barbed-Wire.
* Slows individuals crossing it. Barefoot individuals will be cut. Can be electrified by placing over a cable node.
*/
/obj/item/weapon/material/barbedwire
name = "barbed wire"
desc = "A coil of wire."
icon = 'icons/obj/trap.dmi'
icon_state = "barbedwire"
anchored = FALSE
layer = TABLE_LAYER
w_class = ITEMSIZE_LARGE
explosion_resistance = 1
can_dull = TRUE
fragile = TRUE
force_divisor = 0.20
thrown_force_divisor = 0.25
sharp = TRUE
/obj/item/weapon/material/barbedwire/set_material(var/new_material)
..()
if(!QDELETED(src))
health = round(material.integrity / 3)
name = (material.get_edge_damage() * force_divisor > 15) ? "[material.display_name] razor wire" : "[material.display_name] [initial(name)]"
/obj/item/weapon/material/barbedwire/proc/can_use(mob/user)
return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained())
/obj/item/weapon/material/barbedwire/attack_hand(mob/user as mob)
if(anchored && can_use(user))
user.visible_message(
"<span class='danger'>[user] starts to collect \the [src].</span>",
"<span class='notice'>You begin collecting \the [src]!</span>",
"You hear the sound of rustling [material.name]."
)
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, health))
user.visible_message(
"<span class='danger'>[user] has collected \the [src].</span>",
"<span class='notice'>You have collected \the [src]!</span>"
)
anchored = 0
update_icon()
else
..()
/obj/item/weapon/material/barbedwire/attack_self(mob/user as mob)
..()
if(!anchored && can_use(user))
user.visible_message(
"<span class='danger'>[user] starts to deploy \the [src].</span>",
"<span class='danger'>You begin deploying \the [src]!</span>",
"You hear the rustling of [material.name]."
)
if (do_after(user, 60))
user.visible_message(
"<span class='danger'>[user] has deployed \the [src].</span>",
"<span class='danger'>You have deployed \the [src]!</span>",
"You hear the rustling of [material.name]."
)
playsound(src, 'sound/items/Wirecutter.ogg',70, 1)
spawn(2)
playsound(src, 'sound/items/Wirecutter.ogg',40, 1)
user.drop_from_inventory(src)
forceMove(get_turf(src))
anchored = 1
update_icon()
/obj/item/weapon/material/barbedwire/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(W))
return
if((W.flags & NOCONDUCT) || !shock(user, 70, pick(BP_L_HAND, BP_R_HAND)))
user.setClickCooldown(user.get_attack_speed(W))
user.do_attack_animation(src)
playsound(src, 'sound/effects/grillehit.ogg', 40, 1)
var/inc_damage = W.force
if(W.is_wirecutter())
if(!shock(user, 100, pick(BP_L_HAND, BP_R_HAND)))
playsound(src, W.usesound, 100, 1)
inc_damage *= 3
if(W.damtype != BRUTE)
inc_damage *= 0.3
health -= inc_damage
check_health()
..()
/obj/item/weapon/material/barbedwire/update_icon()
..()
if(anchored)
icon_state = "[initial(icon_state)]-out"
else
icon_state = "[initial(icon_state)]"
/obj/item/weapon/material/barbedwire/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(anchored && isliving(AM))
var/mob/living/L = AM
if(L.m_intent == "run")
L.visible_message(
"<span class='danger'>[L] steps in \the [src].</span>",
"<span class='danger'>You step in \the [src]!</span>",
"<b>You hear a sharp rustling!</b>"
)
attack_mob(L)
update_icon()
..()
/obj/item/weapon/material/barbedwire/proc/shock(mob/user as mob, prb, var/target_zone = BP_TORSO)
if(!anchored || health == 0) // anchored/destroyed grilles are never connected
return 0
if(material.conductivity <= 0)
return 0
if(!prob(prb))
return 0
if(!in_range(src, user))//To prevent TK and mech users from getting shocked
return 0
var/turf/T = get_turf(src)
var/obj/structure/cable/C = T.get_cable_node()
if(C)
if(C.powernet)
var/datum/powernet/PN = C.powernet
if(PN)
PN.trigger_warning()
var/PN_damage = PN.get_electrocute_damage() * (material.conductivity / 50)
var/drained_energy = PN_damage * 10 / CELLRATE
PN.draw_power(drained_energy)
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/external/affected = H.get_organ(check_zone(target_zone))
H.electrocute_act(PN_damage, src, H.get_siemens_coefficient_organ(affected))
else
if(isliving(user))
var/mob/living/L = user
L.electrocute_act(PN_damage, src, 0.8)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if(user.stunned)
return 1
else
return 0
return 0
/obj/item/weapon/material/barbedwire/proc/attack_mob(mob/living/L)
var/target_zone
if(L.lying)
target_zone = ran_zone()
else
target_zone = pick("l_foot", "r_foot", "l_leg", "r_leg")
//armour
var/blocked = L.run_armor_check(target_zone, "melee")
var/soaked = L.get_armor_soak(target_zone, "melee")
if(blocked >= 100)
return
if(soaked >= 30)
return
if(L.buckled) //wheelchairs, office chairs, rollerbeds
return
shock(L, 100, target_zone)
L.add_modifier(/datum/modifier/entangled, 3 SECONDS)
if(!L.apply_damage(force * (issilicon(L) ? 0.25 : 1), BRUTE, target_zone, blocked, soaked, src, sharp, edge))
return
playsound(src, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.species.siemens_coefficient<0.5) //Thick skin.
return
if( H.shoes || ( H.wear_suit && (H.wear_suit.body_parts_covered & FEET) ) )
return
if(H.species.flags & NO_MINOR_CUT)
return
to_chat(H, "<span class='danger'>You step directly on \the [src]!</span>")
var/list/check = list("l_foot", "r_foot")
while(check.len)
var/picked = pick(check)
var/obj/item/organ/external/affecting = H.get_organ(picked)
if(affecting)
if(affecting.robotic >= ORGAN_ROBOT)
return
if(affecting.take_damage(force, 0))
H.UpdateDamageIcon()
H.updatehealth()
if(affecting.organ_can_feel_pain())
H.Weaken(3)
return
check -= picked
if(material.is_brittle() && prob(material.hardness))
health = 0
else if(!prob(material.hardness))
health--
check_health()
return
/obj/item/weapon/material/barbedwire/plastic
name = "snare wire"
default_material = MAT_PLASTIC
-18
View File
@@ -19,29 +19,11 @@
var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak.
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
var/register_as_dangerous_object = FALSE // Should this tell its turf that it is dangerous automatically?
/obj/Initialize()
if(register_as_dangerous_object)
register_dangerous_to_step()
return ..()
/obj/Destroy()
STOP_PROCESSING(SSobj, src)
if(register_as_dangerous_object)
unregister_dangerous_to_step()
return ..()
/obj/Moved(atom/oldloc)
. = ..()
if(register_as_dangerous_object)
var/turf/old_turf = get_turf(oldloc)
var/turf/new_turf = get_turf(src)
if(old_turf != new_turf)
old_turf.unregister_dangerous_object(src)
new_turf.register_dangerous_object(src)
/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
if(usr && ..())
return 1
+1 -1
View File
@@ -8,7 +8,7 @@
// creates a new object and deletes itself
/obj/random/Initialize()
. = ..()
..()
if (!prob(spawn_nothing_percentage))
spawn_item()
return INITIALIZE_HINT_QDEL
+2
View File
@@ -92,6 +92,8 @@
return pick(prob(30);/obj/effect/mine,
prob(25);/obj/effect/mine/frag,
prob(25);/obj/effect/mine/emp,
prob(15);/obj/effect/mine/camo,
prob(15);/obj/effect/mine/emp/camo,
prob(10);/obj/effect/mine/stun,
prob(10);/obj/effect/mine/incendiary,)
+5 -2
View File
@@ -262,7 +262,7 @@
prob(8);/obj/item/weapon/haircomb,
prob(4);/obj/item/weapon/storage/pill_bottle/happy,
prob(4);/obj/item/weapon/storage/pill_bottle/zoom,
prob(10);/obj/item/weapon/contraband/poster,
prob(10);/obj/item/weapon/contraband/poster/custom,
prob(4);/obj/item/weapon/material/butterfly,
prob(6);/obj/item/weapon/material/butterflyblade,
prob(6);/obj/item/weapon/material/butterflyhandle,
@@ -673,7 +673,10 @@
/obj/item/toy/plushie/borgplushie/scrubpuppy,
/obj/item/toy/plushie/foxbear,
/obj/item/toy/plushie/nukeplushie,
/obj/item/toy/plushie/otter)
/obj/item/toy/plushie/otter,
/obj/item/toy/plushie/vox,
/obj/item/toy/plushie/borgplushie/drakiesec,
/obj/item/toy/plushie/borgplushie/drakiemed)
//VOREStation Add End
/obj/random/plushielarge
+185
View File
@@ -0,0 +1,185 @@
//Barricades!
/obj/structure/barricade
name = "barricade"
desc = "This space is blocked off by a barricade."
icon = 'icons/obj/structures.dmi'
icon_state = "barricade"
anchored = 1.0
density = 1.0
var/health = 100
var/maxhealth = 100
var/datum/material/material
/obj/structure/barricade/New(var/newloc, var/material_name)
..(newloc)
if(!material_name)
material_name = "wood"
material = get_material_by_name("[material_name]")
if(!material)
qdel(src)
return
name = "[material.display_name] barricade"
desc = "This space is blocked off by a barricade made of [material.display_name]."
color = material.icon_colour
maxhealth = material.integrity
health = maxhealth
/obj/structure/barricade/get_material()
return material
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
user.setClickCooldown(user.get_attack_speed(W))
if(istype(W, /obj/item/stack))
var/obj/item/stack/D = W
if(D.get_material_name() != material.name)
return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
if(health < maxhealth)
if(D.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one sheet of [material.display_name] to repair \the [src].</span>")
return
visible_message("<span class='notice'>[user] begins to repair \the [src].</span>")
if(do_after(user,20) && health < maxhealth)
if(D.use(1))
health = maxhealth
visible_message("<span class='notice'>[user] repairs \the [src].</span>")
return
return
else
switch(W.damtype)
if("fire")
health -= W.force * 1
if("brute")
health -= W.force * 0.75
if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
CheckHealth()
..()
/obj/structure/barricade/proc/CheckHealth()
if(health <= 0)
dismantle()
health = min(health, maxhealth)
return
/obj/structure/barricade/take_damage(var/damage)
health -= damage
CheckHealth()
return
/obj/structure/barricade/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
if(material == get_material_by_name("resin"))
playsound(src, 'sound/effects/attackblob.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_CLOTH) || get_material_by_name(MAT_SYNCLOTH)))
playsound(src, 'sound/items/drop/clothing.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
user.do_attack_animation(src)
health -= damage
CheckHealth()
return
/obj/structure/barricade/proc/dismantle()
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>\The [src] falls apart!</span>")
qdel(src)
return
/obj/structure/barricade/ex_act(severity)
switch(severity)
if(1.0)
dismantle()
if(2.0)
health -= 25
CheckHealth()
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(istype(mover) && mover.checkpass(PASSTABLE))
return TRUE
return FALSE
/obj/structure/barricade/sandbag
name = "sandbags"
desc = "Bags. Bags of sand. It's rough and coarse and somehow stays in the bag."
icon = 'icons/obj/sandbags.dmi'
icon_state = "blank"
/obj/structure/barricade/sandbag/New(var/newloc, var/material_name)
if(!material_name)
material_name = "cloth"
..(newloc, material_name)
material = get_material_by_name("[material_name]")
if(!material)
qdel(src)
return
name = "[material.display_name] [initial(name)]"
desc = "This space is blocked off by a barricade made of [material.display_name]."
color = null
maxhealth = material.integrity * 2 // These things are, commonly, used to stop bullets where possible.
health = maxhealth
update_connections(1)
/obj/structure/barricade/sandbag/Destroy()
update_connections(1, src)
..()
/obj/structure/barricade/sandbag/dismantle()
update_connections(1, src)
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>\The [src] falls apart!</span>")
qdel(src)
return
/obj/structure/barricade/sandbag/update_icon()
if(!material)
return
cut_overlays()
var/image/I
for(var/i = 1 to 4)
I = image('icons/obj/sandbags.dmi', "sandbags[connections[i]]", dir = 1<<(i-1))
I.color = material.icon_colour
add_overlay(I)
return
/obj/structure/barricade/sandbag/update_connections(propagate = 0, var/obj/structure/barricade/sandbag/ignore = null)
if(!material)
return
var/list/dirs = list()
for(var/obj/structure/barricade/sandbag/S in orange(src, 1))
if(!S.material)
continue
if(S == ignore)
continue
if(propagate >= 1)
S.update_connections(propagate - 1, ignore)
if(can_join_with(S))
dirs += get_dir(src, S)
connections = dirs_to_corner_states(dirs)
update_icon()
/obj/structure/barricade/sandbag/proc/can_join_with(var/obj/structure/barricade/sandbag/S)
if(material == S.material)
return 1
return 0
/obj/structure/barricade/sandbag/CanPass(atom/movable/mover, turf/target)
. = ..()
if(.)
if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
if(P.firer && get_dist(P.firer, src) > 1) // If you're firing from adjacent turfs, you are unobstructed.
if(P.armor_penetration < (material.protectiveness + material.hardness) || prob(33))
return FALSE
+4 -4
View File
@@ -133,13 +133,13 @@
return FALSE
if(istype(consumed_fuel, /obj/item/stack/material/log))
next_fuel_consumption = world.time + 2 MINUTES
next_fuel_consumption = world.time + 6 MINUTES //VOREStation Edit
qdel(consumed_fuel)
update_icon()
return TRUE
else if(istype(consumed_fuel, /obj/item/stack/material/wood)) // One log makes two planks of wood.
next_fuel_consumption = world.time + 1 MINUTE
next_fuel_consumption = world.time + 3 MINUTE //VOREStation Edit
qdel(consumed_fuel)
update_icon()
return TRUE
@@ -330,13 +330,13 @@
return FALSE
if(istype(consumed_fuel, /obj/item/stack/material/log))
next_fuel_consumption = world.time + 2 MINUTES
next_fuel_consumption = world.time + 6 MINUTES //VOREStation Edit
qdel(consumed_fuel)
update_icon()
return TRUE
else if(istype(consumed_fuel, /obj/item/stack/material/wood)) // One log makes two planks of wood.
next_fuel_consumption = world.time + 1 MINUTE
next_fuel_consumption = world.time + 3 MINUTES //VOREStation Edit
qdel(consumed_fuel)
update_icon()
return TRUE
+252 -236
View File
@@ -1,236 +1,252 @@
GLOBAL_LIST_EMPTY(cliff_icon_cache)
/*
Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
Flying mobs can pass over all cliffs with no risk of falling.
Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
This makes fighting something that is on top of a cliff more challenging.
As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
two tiles on initialization, and which way a cliff is facing may change during maploading.
*/
/obj/structure/cliff
name = "cliff"
desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.<br>\
You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.<br>\
Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
on top."
icon = 'icons/obj/flora/rocks.dmi'
anchored = TRUE
density = TRUE
opacity = FALSE
climbable = TRUE
climb_delay = 10 SECONDS
block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
register_as_dangerous_object = TRUE
var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
var/corner = FALSE // Used for icon things.
var/ramp = FALSE // Ditto.
var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
/obj/structure/cliff/automatic
icon_state = "cliffbuilder"
dir = NORTH
/obj/structure/cliff/automatic/corner
icon_state = "cliffbuilder-corner"
dir = NORTHEAST
corner = TRUE
// Tiny part that doesn't block, used for making 'ramps'.
/obj/structure/cliff/automatic/ramp
icon_state = "cliffbuilder-ramp"
dir = NORTHEAST
density = FALSE
ramp = TRUE
// Made automatically as needed by automatic cliffs.
/obj/structure/cliff/bottom
bottom = TRUE
/obj/structure/cliff/automatic/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
/obj/structure/cliff/automatic/LateInitialize()
if(dir in GLOB.cardinal)
icon_variant = pick("a", "b", "c")
if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
make_bottom()
update_icon()
/obj/structure/cliff/proc/make_bottom()
// First, make sure there's room to put the bottom side.
var/turf/T = locate(x, y - 1, z)
if(!istype(T))
return FALSE
// Now make the bottom cliff have mostly the same variables.
var/obj/structure/cliff/bottom/bottom = new(T)
is_double_cliff = TRUE
climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
bottom.dir = dir
bottom.is_double_cliff = TRUE
bottom.climb_delay = climb_delay
bottom.icon_variant = icon_variant
bottom.corner = corner
bottom.ramp = ramp
bottom.layer = layer - 0.1
bottom.density = density
bottom.update_icon()
/obj/structure/cliff/set_dir(new_dir)
..()
update_icon()
/obj/structure/cliff/update_icon()
icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
// Now for making the top-side look like a different turf.
var/turf/T = get_step(src, dir)
if(!istype(T))
return
var/subtraction_icon_state = "[icon_state]-subtract"
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
if(T && subtraction_icon_state in cached_icon_states(icon))
cut_overlays()
// If we've made the same icon before, just recycle it.
if(cache_string in GLOB.cliff_icon_cache)
add_overlay(GLOB.cliff_icon_cache[cache_string])
else // Otherwise make a new one, but only once.
var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
var/icon/subtract = icon(icon, subtraction_icon_state)
underlying_ground.Blend(subtract, ICON_SUBTRACT)
var/image/final = image(underlying_ground)
final.layer = src.layer - 0.2
GLOB.cliff_icon_cache[cache_string] = final
add_overlay(final)
// Movement-related code.
/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
if(isliving(mover))
var/mob/living/L = mover
if(L.hovering) // Flying mobs can always pass.
return TRUE
return ..()
// Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
else if(istype(mover, /obj))
var/obj/O = mover
if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
return FALSE
return TRUE
/obj/structure/cliff/Bumped(atom/A)
if(isliving(A))
var/mob/living/L = A
if(should_fall(L))
fall_off_cliff(L)
return
..()
/obj/structure/cliff/proc/should_fall(mob/living/L)
if(L.hovering)
return FALSE
var/turf/T = get_turf(L)
if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
return TRUE
return FALSE
/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
if(!istype(L))
return FALSE
var/turf/T = get_step(src, reverse_dir[dir])
var/displaced = FALSE
if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
for(var/i = 1 to 2)
var/turf/new_T = locate(T.x, T.y - i, T.z)
if(!new_T || locate(/obj/structure/cliff) in new_T)
break
T = new_T
displaced = TRUE
if(istype(T))
visible_message(span("danger", "\The [L] falls off \the [src]!"))
L.forceMove(T)
// Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
var/harm = !is_double_cliff ? 1 : 0.5
if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
var/obj/vehicle/vehicle = L.buckled
vehicle.adjust_health(40 * harm)
to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
harm /= 2
playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
L.Weaken(5 * harm)
var/fall_time = 3
if(displaced) // Make the fall look more natural when falling sideways.
L.pixel_z = 32 * 2
animate(L, pixel_z = 0, time = fall_time)
sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
playsound(L, "punch", 70, 1)
shake_camera(L, 1, 1)
visible_message(span("danger", "\The [L] hits the ground!"))
// The bigger they are, the harder they fall.
// They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
// This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
var/damage = between(20, L.getMaxHealth() * 0.4, 100)
var/target_zone = ran_zone()
var/blocked = L.run_armor_check(target_zone, "melee") * harm
var/soaked = L.get_armor_soak(target_zone, "melee") * harm
L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
// Now fall off more cliffs below this one if they exist.
var/obj/structure/cliff/bottom_cliff = locate() in T
if(bottom_cliff)
visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
sleep(5)
bottom_cliff.fall_off_cliff(L)
/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
// Cliff climbing requires climbing gear.
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/clothing/shoes/shoes = H.shoes
if(shoes && shoes.rock_climbing)
return ..() // Do the other checks too.
to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
return FALSE
// This tells AI mobs to not be dumb and step off cliffs willingly.
/obj/structure/cliff/is_safe_to_step(mob/living/L)
if(should_fall(L))
return FALSE
return ..()
GLOBAL_LIST_EMPTY(cliff_icon_cache)
/*
Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
Flying mobs can pass over all cliffs with no risk of falling.
Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
This makes fighting something that is on top of a cliff more challenging.
As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
two tiles on initialization, and which way a cliff is facing may change during maploading.
*/
/obj/structure/cliff
name = "cliff"
desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.<br>\
You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.<br>\
Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
on top."
icon = 'icons/obj/flora/rocks.dmi'
anchored = TRUE
density = TRUE
opacity = FALSE
climbable = TRUE
climb_delay = 10 SECONDS
block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
var/corner = FALSE // Used for icon things.
var/ramp = FALSE // Ditto.
var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
/obj/structure/cliff/Initialize()
. = ..()
register_dangerous_to_step()
/obj/structure/cliff/Destroy()
unregister_dangerous_to_step()
. = ..()
/obj/structure/cliff/Moved(atom/oldloc)
. = ..()
if(.)
var/turf/old_turf = get_turf(oldloc)
var/turf/new_turf = get_turf(src)
if(old_turf != new_turf)
old_turf.unregister_dangerous_object(src)
new_turf.register_dangerous_object(src)
// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
/obj/structure/cliff/automatic
icon_state = "cliffbuilder"
dir = NORTH
/obj/structure/cliff/automatic/corner
icon_state = "cliffbuilder-corner"
dir = NORTHEAST
corner = TRUE
// Tiny part that doesn't block, used for making 'ramps'.
/obj/structure/cliff/automatic/ramp
icon_state = "cliffbuilder-ramp"
dir = NORTHEAST
density = FALSE
ramp = TRUE
// Made automatically as needed by automatic cliffs.
/obj/structure/cliff/bottom
bottom = TRUE
/obj/structure/cliff/automatic/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
/obj/structure/cliff/automatic/LateInitialize()
if(dir in GLOB.cardinal)
icon_variant = pick("a", "b", "c")
if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
make_bottom()
update_icon()
/obj/structure/cliff/proc/make_bottom()
// First, make sure there's room to put the bottom side.
var/turf/T = locate(x, y - 1, z)
if(!istype(T))
return FALSE
// Now make the bottom cliff have mostly the same variables.
var/obj/structure/cliff/bottom/bottom = new(T)
is_double_cliff = TRUE
climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
bottom.dir = dir
bottom.is_double_cliff = TRUE
bottom.climb_delay = climb_delay
bottom.icon_variant = icon_variant
bottom.corner = corner
bottom.ramp = ramp
bottom.layer = layer - 0.1
bottom.density = density
bottom.update_icon()
/obj/structure/cliff/set_dir(new_dir)
..()
update_icon()
/obj/structure/cliff/update_icon()
icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
// Now for making the top-side look like a different turf.
var/turf/T = get_step(src, dir)
if(!istype(T))
return
var/subtraction_icon_state = "[icon_state]-subtract"
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
if(T && subtraction_icon_state in cached_icon_states(icon))
cut_overlays()
// If we've made the same icon before, just recycle it.
if(cache_string in GLOB.cliff_icon_cache)
add_overlay(GLOB.cliff_icon_cache[cache_string])
else // Otherwise make a new one, but only once.
var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
var/icon/subtract = icon(icon, subtraction_icon_state)
underlying_ground.Blend(subtract, ICON_SUBTRACT)
var/image/final = image(underlying_ground)
final.layer = src.layer - 0.2
GLOB.cliff_icon_cache[cache_string] = final
add_overlay(final)
// Movement-related code.
/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
if(isliving(mover))
var/mob/living/L = mover
if(L.hovering) // Flying mobs can always pass.
return TRUE
return ..()
// Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
else if(istype(mover, /obj))
var/obj/O = mover
if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
return FALSE
return TRUE
/obj/structure/cliff/Bumped(atom/A)
if(isliving(A))
var/mob/living/L = A
if(should_fall(L))
fall_off_cliff(L)
return
..()
/obj/structure/cliff/proc/should_fall(mob/living/L)
if(L.hovering)
return FALSE
var/turf/T = get_turf(L)
if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
return TRUE
return FALSE
/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
if(!istype(L))
return FALSE
var/turf/T = get_step(src, reverse_dir[dir])
var/displaced = FALSE
if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
for(var/i = 1 to 2)
var/turf/new_T = locate(T.x, T.y - i, T.z)
if(!new_T || locate(/obj/structure/cliff) in new_T)
break
T = new_T
displaced = TRUE
if(istype(T))
visible_message(span("danger", "\The [L] falls off \the [src]!"))
L.forceMove(T)
// Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
var/harm = !is_double_cliff ? 1 : 0.5
if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
var/obj/vehicle/vehicle = L.buckled
vehicle.adjust_health(40 * harm)
to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
harm /= 2
playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
L.Weaken(5 * harm)
var/fall_time = 3
if(displaced) // Make the fall look more natural when falling sideways.
L.pixel_z = 32 * 2
animate(L, pixel_z = 0, time = fall_time)
sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
playsound(L, "punch", 70, 1)
shake_camera(L, 1, 1)
visible_message(span("danger", "\The [L] hits the ground!"))
// The bigger they are, the harder they fall.
// They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
// This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
var/damage = between(20, L.getMaxHealth() * 0.4, 100)
var/target_zone = ran_zone()
var/blocked = L.run_armor_check(target_zone, "melee") * harm
var/soaked = L.get_armor_soak(target_zone, "melee") * harm
L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
// Now fall off more cliffs below this one if they exist.
var/obj/structure/cliff/bottom_cliff = locate() in T
if(bottom_cliff)
visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
sleep(5)
bottom_cliff.fall_off_cliff(L)
/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
// Cliff climbing requires climbing gear.
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/clothing/shoes/shoes = H.shoes
if(shoes && shoes.rock_climbing)
return ..() // Do the other checks too.
to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
return FALSE
// This tells AI mobs to not be dumb and step off cliffs willingly.
/obj/structure/cliff/is_safe_to_step(mob/living/L)
if(should_fall(L))
return FALSE
return ..()
@@ -37,7 +37,6 @@
/obj/structure/closet/Initialize()
..()
// Closets need to come later because of spawners potentially creating objects during init.
return INITIALIZE_HINT_LATELOAD
/obj/structure/closet/LateInitialize()
@@ -260,7 +259,20 @@
return
/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(opened)
if(W.is_wrench())
if(opened)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
if(do_after(user, 20 * W.toolspeed))
if(!src) return
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
anchored = !anchored
return
else
to_chat(user, "<span class='notice'>You can't reach the anchoring bolts when the door is closed!</span>")
else if(opened)
if(istype(W, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = W
MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
@@ -316,17 +328,6 @@
update_icon()
for(var/mob/M in viewers(src))
M.show_message("<span class='warning'>[src] has been [sealed?"sealed":"unsealed"] by [user.name].</span>", 3)
else if(W.is_wrench())
if(sealed)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
playsound(src, W.usesound, 50)
if(do_after(user, 20 * W.toolspeed))
if(!src) return
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
anchored = !anchored
else
attack_hand(user)
return
@@ -36,11 +36,11 @@
icon_opened = "egg_unathi_open"
/obj/structure/closet/secure_closet/egg/nevrean
name = "nevarean egg"
desc = "Most Nevareans lay hard-shelled eggs!"
icon_state = "egg_nevarean"
icon_closed = "egg_nevarean"
icon_opened = "egg_nevarean_open"
name = "nevrean egg"
desc = "Most Nevreans lay hard-shelled eggs!"
icon_state = "egg_nevrean"
icon_closed = "egg_nevrean"
icon_opened = "egg_nevrean_open"
/obj/structure/closet/secure_closet/egg/human
name = "human egg"
@@ -133,7 +133,6 @@
/obj/item/clothing/gloves/fingerless,
/obj/item/device/radio/headset/pilot,
/obj/item/device/radio/headset/pilot/alt,
/obj/item/weapon/cartridge/explorer,
/obj/item/device/flashlight,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
@@ -54,7 +54,20 @@
to_chat(user, "<span class='notice'>Access Denied</span>")
/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(opened)
if(W.is_wrench())
if(opened)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
if(do_after(user, 20 * W.toolspeed))
if(!src) return
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
anchored = !anchored
return
else
to_chat(user, "<span class='notice'>You can't reach the anchoring bolts when the door is closed!</span>")
else if(opened)
if(istype(W, /obj/item/weapon/storage/laundry_basket))
return ..(W,user)
if(istype(W, /obj/item/weapon/grab))
@@ -77,17 +90,6 @@
spark_system.start()
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src, "sparks", 50, 1)
else if(W.is_wrench())
if(sealed)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
if(do_after(user, 20 * W.toolspeed))
if(!src) return
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
anchored = !anchored
return
else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool))
return ..(W,user)
else
@@ -0,0 +1,25 @@
//Dance pole
/obj/structure/dancepole
name = "dance pole"
desc = "Engineered for your entertainment"
icon = 'icons/obj/objects_vr.dmi'
icon_state = "dancepole"
density = 0
anchored = 1
/obj/structure/dancepole/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.is_screwdriver())
anchored = !anchored
playsound(src, O.usesound, 50, 1)
if(anchored)
to_chat(user, "<font color='blue'>You secure \the [src].</font>")
else
to_chat(user, "<font color='blue'>You unsecure \the [src].</font>")
if(O.is_wrench())
playsound(src, O.usesound, 50, 1)
to_chat(user, "<span class='notice'>Now disassembling \the [src]...</span>")
if(do_after(user, 30 * O.toolspeed))
if(!src) return
to_chat(user, "<span class='notice'>You dissasembled \the [src]!</span>")
new /obj/item/stack/material/steel(src.loc, 1)
qdel(src)
+1 -1
View File
@@ -14,7 +14,7 @@
var/smashed = 0
/obj/structure/fireaxecabinet/Initialize()
..()
. = ..()
fireaxe = new /obj/item/weapon/material/twohanded/fireaxe()
/obj/structure/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
+1 -1
View File
@@ -22,7 +22,7 @@
var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
/obj/structure/flora/Initialize()
..()
. = ..()
if(randomize_size)
icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
@@ -0,0 +1,101 @@
/obj/structure/ghost_pod/ghost_activated/maintpred
name = "maintenance hole"
desc = "Looks like some creature dug its way into station's maintenance..."
icon = 'icons/effects/effects.dmi'
icon_state = "tunnel_hole"
icon_state_opened = "tunnel_hole"
density = FALSE
ghost_query_type = /datum/ghost_query/maints_pred
anchored = TRUE
invisibility = INVISIBILITY_OBSERVER
spawn_active = TRUE
var/announce_prob = 35
var/list/possible_mobs = list("Space Bumblebee" = /mob/living/simple_mob/vore/bee,
"Voracious Lizard" = /mob/living/simple_mob/vore/aggressive/dino,
"Giant Frog" = /mob/living/simple_mob/vore/aggressive/frog,
"Giant Rat" = /mob/living/simple_mob/vore/aggressive/rat,
"Juvenile Solargrub" = /mob/living/simple_mob/vore/solargrub,
"Red Panda" = /mob/living/simple_mob/vore/redpanda,
"Fennec" = /mob/living/simple_mob/vore/fennec,
"Fennix" = /mob/living/simple_mob/vore/fennix,
"Jelly Blob" = /mob/living/simple_mob/animal/space/jelly,
"Wolf" = /mob/living/simple_mob/animal/wolf,
"Sect Queen" = /mob/living/simple_mob/vore/sect_queen,
"Defanged Xenomorph" = /mob/living/simple_mob/vore/xeno_defanged,
)
/obj/structure/ghost_pod/ghost_activated/maintpred/create_occupant(var/mob/M)
..()
var/choice
var/randomize
var/finalized = "No"
while(finalized == "No" && M.client)
choice = input(M,"What type of predator do you want to play as?") as null|anything in possible_mobs
if(!choice)
randomize = TRUE
break
if(choice)
finalized = alert(M, "Are you sure you want to play as [choice]?","Confirmation","No","Yes")
if(randomize)
choice = pick(possible_mobs)
var/mobtype = possible_mobs[choice]
var/mob/living/simple_mob/newPred = new mobtype(get_turf(src))
qdel(newPred.ai_holder)
newPred.ai_holder = null
//newPred.movement_cooldown = 0 // The "needless artificial speed cap" exists for a reason
if(M.mind)
M.mind.transfer_to(newPred)
to_chat(M, "<span class='notice'>You are <b>[newPred]</b>, somehow having gotten aboard the station in search of food. \
You are wary of environment around you, but you do feel rather peckish. Stick around dark, secluded places to avoid danger or, \
if you are cute enough, try to make friends with this place's inhabitants.</span>")
newPred.ckey = M.ckey
newPred.visible_message("<span class='warning'>[newPred] emerges from somewhere!</span>")
if(prob(announce_prob))
spawn(2 MINUTES)
command_announcement.Announce("Unexpected biosignature detected in the maintenance tunnels of [station_name()].", "Lifesign Alert")
qdel(src)
/obj/structure/ghost_pod/ghost_activated/maintpred/no_announce
announce_prob = 0
/obj/structure/ghost_pod/ghost_activated/morphspawn
name = "weird goo"
desc = "A pile of weird gunk... Wait, is it actually moving?"
icon = 'icons/mob/animal_vr.dmi'
icon_state = "morph"
icon_state_opened = "morph_dead"
density = FALSE
ghost_query_type = /datum/ghost_query/morph
anchored = TRUE
invisibility = INVISIBILITY_OBSERVER
spawn_active = TRUE
var/announce_prob = 50
/obj/structure/ghost_pod/ghost_activated/morphspawn/create_occupant(var/mob/M)
..()
var/mob/living/simple_mob/vore/hostile/morph/newMorph = new /mob/living/simple_mob/vore/hostile/morph(get_turf(src))
if(M.mind)
M.mind.transfer_to(newMorph)
to_chat(M, "<span class='notice'>You are a <b>Morph</b>, somehow having gotten aboard the station in your wandering. \
You are wary of environment around you, but your primal hunger still calls for you to find prey. Seek a convincing disguise, \
using your amorphous form to traverse vents to find and consume weak prey.</span>")
to_chat(M, "<span class='notice'>You can use shift + click on objects to disguise yourself as them, but your strikes are nearly useless when you are disguised. \
You can undisguise yourself by shift + clicking yourself, but disguise being switched, or turned on and off has a short cooldown. You can also ventcrawl, \
by using alt + click on the vent or scrubber.</span>")
newMorph.ckey = M.ckey
newMorph.visible_message("<span class='warning'>A morph appears to crawl out of somewhere.</span>")
if(prob(announce_prob))
spawn(2 MINUTES)
command_announcement.Announce("Unexpected biosignature detected in the maintenance tunnels of [station_name()].", "Lifesign Alert")
qdel(src)
/obj/structure/ghost_pod/ghost_activated/morphspawn/no_announce
announce_prob = 0
@@ -28,7 +28,7 @@
icon_state = icon_state_opened
if(needscharger)
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
del(src)
qdel(src)
return TRUE
else
return FALSE
@@ -36,6 +36,10 @@
// Override this to create whatever mob you need. Be sure to call ..() if you don't want it to make infinite mobs.
/obj/structure/ghost_pod/proc/create_occupant(var/mob/M)
used = TRUE
//VOREStation Addition Start
if(src in active_ghost_pods)
active_ghost_pods -= src
//VOREStation Addition End
return TRUE
@@ -52,6 +56,7 @@
// VOREStation Addition Start
if(!used)
activated = TRUE
ghostpod_startup(FALSE)
// VOREStation Addition End
/obj/structure/ghost_pod/manual/attack_ai(var/mob/living/silicon/user)
@@ -1,3 +1,11 @@
/obj/structure/ghost_pod/Destroy()
if(src in active_ghost_pods)
active_ghost_pods -= src
..()
/obj/structure/ghost_pod
var/spawn_active = FALSE
/obj/structure/ghost_pod/manual
var/remains_active = FALSE
var/activated = FALSE
@@ -28,4 +36,14 @@
busy = FALSE
create_occupant(user)
create_occupant(user)
/obj/structure/ghost_pod/proc/ghostpod_startup(var/notify = FALSE)
if(!(src in active_ghost_pods))
active_ghost_pods += src
if(notify)
trigger()
/obj/structure/ghost_pod/ghost_activated/Initialize()
. = ..()
ghostpod_startup(spawn_active)
@@ -8,9 +8,10 @@
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper_1"
icon_state_opened = "sleeper_0"
density = TRUE
density = FALSE
ghost_query_type = /datum/ghost_query/stowaway
anchored = FALSE
anchored = TRUE
invisibility = 60
var/occupant_type = "stowaway"
@@ -24,7 +25,7 @@
var/list/clothing_possibilities
/obj/structure/ghost_pod/ghost_activated/human/Initialize()
..()
. = ..()
handle_clothing_setup()
@@ -123,7 +124,9 @@
if(allow_appearance_change)
H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 1)
visible_message("<span class='aliem'>\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!</span>")
// visible_message("<span class='aliem'>\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!</span>")
qdel(src)
// Manual Variant
// This one lacks the emag option due to the fact someone has to activate it, and they will probably help the person.
@@ -150,7 +153,7 @@
var/list/clothing_possibilities
/obj/structure/ghost_pod/manual/human/Initialize()
..()
. = ..()
handle_clothing_setup()
@@ -89,7 +89,7 @@
qdel(src)
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/Initialize()
..()
. = ..()
var/turf/T = get_turf(src)
say_dead_object("A <span class='notice'>[drone_class] swarm drone</span> shell is now available in \the [T.loc].", src)
+1 -1
View File
@@ -254,8 +254,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/stack/material/steel{amount = 5},
/obj/item/stack/material/cardboard{amount = 5},
/obj/item/weapon/contraband/poster,
/obj/item/weapon/contraband/poster/custom,
/obj/item/weapon/material/wirerod,
/obj/item/weapon/contraband/poster,
/obj/item/weapon/newspaper,
/obj/item/weapon/paper/crumpled,
/obj/item/weapon/paper/crumpled/bloody
@@ -10,4 +10,8 @@
desc = "This seems to be a container for something."
icon = 'icons/obj/abductor_vr.dmi'
icon_state = "experiment"
interaction_message = "<span class='warning'>You don't see any mechanism to open this thing. Probably for the best.</span>"
interaction_message = "<span class='warning'>You don't see any mechanism to open this thing. Probably for the best.</span>"
/obj/structure/prop/alien/dispenser/twoway
icon = 'icons/obj/abductor_vr.dmi'
icon_state = "dispenser_2way"
@@ -130,3 +130,122 @@
<B>A repeating ping, before silence.</B><BR>
<B>End of second log.</B>
"}
//VOREStation additions below this line - Killian's wrecks
/obj/structure/prop/blackbox/mackerel_wreck
catalogue_data = list(/datum/category_item/catalogue/information/blackbox/mackerel_wreck)
/datum/category_item/catalogue/information/blackbox/mackerel_wreck
name = "Black Box Data - ITV Phish Phood"
desc = {"
<BR>
<B>BEGIN LOG</B><BR>
<B>(blaring alarms)</B><BR>
<B>Shipboard Computer:</B> Collision warning. Collision warning.<BR>
<B>Shipboard Computer:</B> High speed impact detected.<BR>
<B>Shipboard Computer:</B> Extensive damage detected.<BR>
<B>Shipboard Computer:</B> Starboard nacelle offline.<BR>
<B>Shipboard Computer:</B> Port nacelle damaged.<BR>
<B>Shipboard Computer:</B> Fore starboard impact buffer shattered.<BR>
<B>Shipboard Computer:</B> Fore port impact buffer critically damaged.<BR>
<B>Shipboard Computer:</B> Warning. Canopy breached. Warning. Canopy breached.<BR>
<B>Shipboard Computer:</B> Danger. Canopy depressurized.<BR>
<B>Shipboard Computer:</B> Warning. Sensors indicate crawlspaces exposed to vacuum.<BR>
<B>Unknown Voice 1:</B> Wow, that thing really did a number on this ship for a fifty year old piece of shit warhead huh?<BR>
<B>Unknown Voice 2:</B> No kidding!<BR>
<B>Shipboard Computer:</B> Danger. Lethal trauma to operator detected.<BR>
<B>Unknown Voice 1:</B> Fucking hell, will you shut that thing up?<BR>
<B>(several loud metallic impacts)</B><BR>
<B>Shipboard Computer:</B> Warning. Intruders detec--*kzzzht*<BR>
<B>(alarms cease)</B><BR>
<B>Unknown Voice 2:</B> There. Fuck. Finally. Sorry.<BR>
<B>Unknown Voice 2:</B> I hope whatever this idiot was hauling is here. Why were they in such a hurry anyway?<BR>
<B>Unknown Voice 1:</B> Beats me- and hand me that crowbar already.<BR>
<B>Unknown Voice 2:</B> Here, catch.<BR>
<B>Unknown Voice 1:</B> \'cha, nice. Let's see...<BR>
<B>(sound of metal creaking, then a loud snapping sound)</B><BR>
<B>Unknown Voice 1:</B> And here she is.<BR>
<B>Unknown Voice 2:</B> (whistling) What a beauty. How much you think it\'ll go for?<BR>
<B>Unknown Voice 1:</B> Enough we\'ll never have to worry about doing another job all the way out here ever again.<BR>
<B>Unknown Voice 2:</B> Shiny. Now let\'s bounce before the ess-defs show up.<BR>
<B>Unknown Voice 1:</B> I hear that, <U>brat</U>.<BR>
<B>END LOG</B><BR>
<BR>
<B>CATALOGUER VOICE RECOGNITION RESULTS:</B><BR>
No match found for either speaker, but contextual clues and use of Old Earth russian (\'brat\', approximately \'brother\' or \'pal\') suggests out-of-sector criminal elements.
"}
/obj/structure/prop/blackbox/gecko_wreck
catalogue_data = list(/datum/category_item/catalogue/information/blackbox/gecko_wreck)
/datum/category_item/catalogue/information/blackbox/gecko_wreck
name = "Black Box Data - ITV Sticky Situation"
desc = {"
<BR>
<B>BEGIN LOG</B><BR>
<B>(blaring alarms)</B><BR>
<B>Shipboard Computer:</B> Alert. Multiple impacts detected along starboard side.<BR>
<B>Shipboard Computer:</B> Multiple hull breaches detected. Starboard cargo hatches have been breached.<BR>
<B>Shipboard Computer:</B> Warning. Nacelle engines offline. Thrust reduced by thirty-five-point-three percent.<BR>
<B>Unknown Voice 1:</B> Agh! Shit! How'd they know-<BR>
<B>(loud explosion, sound of rushing air)</B><BR>
<B>Shipboard Computer:</B> Danger. Canopy breached.<BR>
<B>(mechanical whine, followed by a deep hiss)</B><BR>
<B>Shipboard Computer:</B> Automatic lockdown successfully engaged.<BR>
<B>Unknown Voice 1:</B> (wheezing) Mother<U>fucker!</U> Jackson, Phelps, stand by to repel boarders!<BR>
<B>Unknown Voice 2:</B> Roger!<BR>
<B>Unknown Voice 3:</B> Already there.<BR>
<B>Shipboard Computer:</B> Warning. Minor breach in Engineering. Local depressurization in five minutes.<BR>
<B>Unknown Voice 1:</B> Shit, shit, shit.<BR>
<B>Unknown Voice 3:</B> Jackson\'s down!<BR>
<B>Unknown Voice 1:</B> Motherf-<BR>
<B>Unknown Voice 4:</B> <U>Captain</U>. Enough. You know why we\'re here, and we have your engineer. Tell us where you hid the goods and maybe we\'ll let you live.<BR>
<B>Unknown Voice 5:</B> Let me go you son of a-<BR>
<B>(gunshot, ballistic)</B><BR>
<B>Unknown Voice 4:</B> You fucking idiot!<BR>
<B>Unknown Voice 6:</B> Don\'t you start, you said-<BR>
<B>Unknown Voice 4:</B> I don\'t care what I fucking said, shit-for-brains!<BR>
<B>Unknown Voice 7:</B> Boss, I <U>hate</U> to rain on your little parade but SDF just popped up on my scopes, \'bout... fifty klicks out, closing fast. Be on top of us in a few minutes tops.<BR>
<B>Unknown Voice 4:</B> Fuck! You, dumbass! Link up with the others and grab as many crates as you can! Pray for your sake that we get the right one!<BR>
<B>END LOG</B><BR>
<BR>
<B>CATALOGUER DATA ANALYSIS RESULTS:</B><BR>
No matches found for any of the voices involved. Ship manifest suggests a crew of at least six, but under the circumstances three of the recorded voices are clearly not from the crew.<BR>
<BR>
Audio resynthesis of firearm discharge matches common high-caliber ballistic sidearm cartridges, best match 10mm Watson Special. An uncommon cartridge, one not manufactured locally.
"}
/obj/structure/prop/blackbox/salamander_wreck
catalogue_data = list(/datum/category_item/catalogue/information/blackbox/salamander_wreck)
/datum/category_item/catalogue/information/blackbox/salamander_wreck
name = "Black Box Data - ITV Unity"
desc = {"
<BR>
<B>BEGIN LOG</B><BR>
<B>Unknown Speaker 1:</B> Hey cap, you seeing this?<BR>
<B>Unknown Speaker 2 (\"Cap\"):</B> Yea-- what the fuck?<BR>
<B>Unknown Speaker 1:</B> Yeah that was my reaction.<BR>
<B>Unknown Speaker 3:</B> What are you tw-- holy shit, what <U>is</U> that?<BR>
<B>Unknown Speakers 1 & 2:</B> We don't know!<BR>
<B>Unknown Speaker 4:</B> What\'s all the yel-- fuck me sideways, what the hell?<BR>
<B>Unknown Speaker 2 (\"Cap\"):</B> Stars above and fucking below, they never said anything like this was in the cans... shouldn't the port bioscanners have picked this up?<BR>
<B>Unknown Speaker 3:</B> I <U>told</U> you that guy was one shady motherfucker, and whaddaya know.<BR>
<B>Unknown Speaker 1:</B> No kidding. Christ. What\'s the play, cap?<BR>
<B>Unknown Speaker 4:</B> I say we shoot this crap into the nearest star. Or gas giant maybe.<BR>
<B>Unknown Speaker 2 (\"Cap\"):</B> Pretty much. Get in one of the voidsuits and rig the can up with some spare O2 canisters -- plot it a course that\'ll sling it right into V3\'s atmosphere.<BR>
<B>Unknown Speaker 1:</B> Yeah, sure. That shouldn\'t take long. Then what?<BR>
<B>Unknown Speaker 2 (\"Cap\"):</B> Let\'s see... ah, perfect. There's another ship passing close by, and I know the captain. We'll take our suits out and have her pick us up. Max, you still got those old cutting charges I told you to get rid of?<BR>
<B>Unknown Speaker 4 (\"Max\"):</B> No. (pause) ...but also yes.<BR>
<B>Unknown Speaker 2 (\"Cap\"):</B> Your propensity for ignoring my orders has once again paid off... man, I\'m gonna miss the Unity, but... better this way. I want holes in both sides of the engine bay and one in the portside crawlspace. Lock all the doors open and depressurize the main cabins. Drain as much fuel as you can, break up the main power block, and scatter the parts.<BR>
<B>Unknown Speaker 1:</B> You want us to scuttle her, chief?<BR>
<B>Unknown Speaker 2 (\"Cap\"):</B> Nail on the head, my friend.<BR>
<B>Unknown Speaker 3:</B> Let\'s get rid of that fucking can first, I think it just blinked at me.<BR>
<B>END LOG</B><BR>
<BR>
<B>CATALOGUER VOICE RECOGNITION RESULTS:</B><BR>
<B>SPEAKER ONE:</B> No match.<BR>
<B>SPEAKER TWO, \"CAP\":</B> Predicted to be Jeremiah Wells, human, last registered owner of the ITV Unity and small-time smuggler of fake alien artefacts. Wanted for smuggling and sale of said (fake) alien artefacts. 87% confidence.<BR>
<B>SPEAKER THREE:</B> Predicted to be Allie Wells, human, niece of Captain Wells. 90% confidence.<BR>
<B>SPEAKER FOUR, \"MAX\":</B> Predicted to be Maxwell Ulysses Sarevic, zorren, known smuggler, and wanted in the Elysian Colonies for liberation of slaves and, quote, \'harshing my vibe, and being a, like, <U>total lamer</U>, dude\', unquote. 99% confidence.
"}
+1 -1
View File
@@ -20,7 +20,7 @@
var/total_creature_max //If set, it can spawn this many creatures, total, ever.
/obj/structure/prop/nest/Initialize()
..()
. = ..()
den_mobs = list()
START_PROCESSING(SSobj, src)
last_spawn = world.time
+1 -1
View File
@@ -23,7 +23,7 @@
return ..()
/obj/structure/cult/pylon/swarm/Initialize()
..()
. = ..()
active_beams = list()
/obj/structure/cult/pylon/swarm/Destroy()
+303 -32
View File
@@ -321,73 +321,344 @@
desc = "A warning sign which reads XENOBIOLOGY."
icon_state = "xenobio3"
//direction signs presented by the order they appear in the dmi
/obj/structure/sign/directions
name = "direction sign"
desc = "A direction sign, claiming to know the way."
desc = "A direction sign, claiming to know the way to... somewhere?"
icon_state = "direction"
icon = 'icons/obj/decals_directions.dmi'
//TODO: set up overlay systems, inc. interactions (e.g. vines clear w/ plantbgone or fire, snow can be brushed off or melted, and so on)
//disabled this proc, it serves no purpose except to overwrite the description that already exists. may have been intended for making your own signs?
//seems to defeat the point of having a generic directional sign that mappers could edit and use in POIs? left it here in case something breaks.
/*
/obj/structure/sign/directions/New()
..()
desc = "A direction sign, pointing out which way \the [src] is."
/obj/structure/sign/directions/science
name = "\improper Science department"
desc = "A direction sign, pointing out which way the Science department is."
icon_state = "direction_sci"
desc = "A direction sign, pointing out the way to \the [src]."
*/
//engineering signs
/obj/structure/sign/directions/engineering
name = "\improper Engineering department"
desc = "A direction sign, pointing out which way the Engineering department is."
name = "\improper Engineering Department"
desc = "A direction sign, pointing out the way to the Engineering Department."
icon_state = "direction_eng"
/obj/structure/sign/directions/engineering/reactor
name = "\improper Reactor"
desc = "A direction sign, pointing out the way to the Reactor."
icon_state = "direction_core"
/obj/structure/sign/directions/engineering/solars
name = "\improper Solar Array"
desc = "A direction sign, pointing out the way to the nearest Solar Array."
icon_state = "direction_solar"
/obj/structure/sign/directions/engineering/atmospherics
name = "\improper Atmospherics Department"
desc = "A direction sign, pointing out the way to the Atmospherics Department."
icon_state = "direction_atmos"
/obj/structure/sign/directions/engineering/gravgen
name = "\improper Gravity Generator"
desc = "A direction sign, pointing out the way to the Artificial Gravity Generator."
icon_state = "direction_grav"
/obj/structure/sign/directions/engineering/engeqp
name = "\improper Engineering Equipment Storage"
desc = "A direction sign, pointing out the way to Engineering Equipment Storage."
icon_state = "direction_engeqp"
//security signs
/obj/structure/sign/directions/security
name = "\improper Security department"
desc = "A direction sign, pointing out which way the Security department is."
name = "\improper Security Department"
desc = "A direction sign, pointing out the way to the Security Department."
icon_state = "direction_sec"
/obj/structure/sign/directions/security/armory
name = "\improper Armory"
desc = "A direction sign, pointing out the way to the Armory."
icon_state = "direction_armory"
/obj/structure/sign/directions/security/brig
name = "\improper Brig"
desc = "A direction sign, pointing out the way to the Brig."
icon_state = "direction_brig"
/obj/structure/sign/directions/security/seceqp
name = "\improper Security Equipment Storage"
desc = "A direction sign, pointing out the way to Security Equipment Storage."
icon_state = "direction_seceqp"
/obj/structure/sign/directions/security/internal_affairs
name = "\improper Internal Affairs Office"
desc = "A direction sign, pointing out the way to the Internal Affairs Office."
icon_state = "direction_intaff"
/obj/structure/sign/directions/security/forensics
name = "\improper Forensics Lab"
desc = "A direction sign, pointing out the way to the Forensics Lab."
icon_state = "direction_forensics"
/obj/structure/sign/directions/security/forensics/alt
icon_state = "direction_lab"
/obj/structure/sign/directions/security/interrogation
name = "\improper Interrogations"
desc = "A direction sign, pointing out the way to Interrogations."
icon_state = "direction_interrogation"
//science signs
/obj/structure/sign/directions/science
name = "\improper Science Department"
desc = "A direction sign, pointing out the way to the Science Department."
icon_state = "direction_sci"
/obj/structure/sign/directions/science/rnd
name = "\improper Research & Development"
desc = "A direction sign, pointing out the way to Research & Development."
icon_state = "direction_rnd"
/obj/structure/sign/directions/science/toxins
name = "\improper Toxins Lab"
desc = "A direction sign, pointing out the way to the Toxins Lab."
icon_state = "direction_sci"
/obj/structure/sign/directions/science/robotics
name = "\improper Robotics Workshop"
desc = "A direction sign, pointing out the way to the Robotics Workshop."
icon_state = "direction_robotics"
/obj/structure/sign/directions/science/xenoarch
name = "\improper Xenoarchaeology Lab"
desc = "A direction sign, pointing out the way to the Xenoarchaeology Lab."
icon_state = "direction_xenoarch"
/obj/structure/sign/directions/science/xenobiology
name = "\improper Xenobiology Lab"
desc = "A direction sign, pointing out the way to the Xenobiology Lab."
icon_state = "direction_xbio"
/obj/structure/sign/directions/science/xenoflora
name = "\improper Xenoflora Lab"
desc = "A direction sign, pointing out the way to the Xenoflora Lab."
icon_state = "direction_xflora"
/obj/structure/sign/directions/science/exploration
name = "\improper Exploration Department"
desc = "A direction sign, pointing out the way to the Exploration Department."
icon_state = "direction_explo"
//medical signs
/obj/structure/sign/directions/medical
name = "\improper Medical Bay"
desc = "A direction sign, pointing out which way the Medical Bay is."
desc = "A direction sign, pointing out the way to the Medical Bay."
icon_state = "direction_med"
/obj/structure/sign/directions/medical/chemlab
name = "\improper Chemistry Lab"
desc = "A direction sign, pointing out the way to the Chemistry Lab."
icon_state = "direction_med"
/obj/structure/sign/directions/medical/surgery
name = "\improper Surgery"
desc = "A direction sign, pointing out the way to Surgery."
icon_state = "direction_surgery"
/obj/structure/sign/directions/medical/operating_1
name = "\improper Operating Theatre 1"
desc = "A direction sign, pointing out the way to Operating Theatre 1."
icon_state = "direction_op1"
/obj/structure/sign/directions/medical/operating_2
name = "\improper Operating Theatre 2"
desc = "A direction sign, pointing out the way to Operating Theatre 2."
icon_state = "direction_op2"
/obj/structure/sign/directions/medical/virology
name = "\improper Virology"
desc = "A direction sign, pointing out the way to the Virology Lab."
icon_state = "direction_viro"
/obj/structure/sign/directions/medical/medeqp
name = "\improper Medical Equipment Storage"
desc = "A direction sign, pointing out the way to Medical Equipment Storage."
icon_state = "direction_medeqp"
/obj/structure/sign/directions/medical/morgue
name = "\improper Morgue"
desc = "A direction sign, pointing out the way to the Morgue."
icon_state = "direction_morgue"
/obj/structure/sign/directions/medical/cloning
name = "\improper Cloning Lab"
desc = "A direction sign, pointing out the way to the Cloning Lab."
icon_state = "direction_cloning"
/obj/structure/sign/directions/medical/resleeving
name = "\improper Resleeving Lab"
desc = "A direction sign, pointing out the way to the Resleeving Lab."
icon_state = "direction_resleeve"
//special signs
/obj/structure/sign/directions/evac
name = "\improper Evacuation"
desc = "A direction sign, pointing out which way the Escape Shuttle dock is."
desc = "A direction sign, pointing out the way to the Escape Shuttle Dock."
icon_state = "direction_evac"
/obj/structure/sign/directions/eva
name = "\improper Extra-Vehicular Activity"
desc = "A direction sign, pointing out the way to the EVA Bay."
icon_state = "direction_eva"
//command signs
/obj/structure/sign/directions/ai_core
name = "\improper AI Core"
desc = "A direction sign, pointing out the way to the AI Core."
icon_state = "direction_ai_core"
/obj/structure/sign/directions/bridge
name = "\improper Bridge"
desc = "A direction sign, pointing out the way to the Bridge."
icon_state = "direction_bridge"
/obj/structure/sign/directions/command
name = "\improper Command"
desc = "A direction sign, pointing out the way to the Command Center."
icon_state = "direction_command"
/obj/structure/sign/directions/teleporter
name = "\improper Teleporter"
desc = "A direction sign, pointing out the way to the Teleporter."
icon_state = "direction_teleport"
/obj/structure/sign/directions/telecomms
name = "\improper Telecommunications Hub"
desc = "A direction sign, pointing out the way to the Telecommunications Hub."
icon_state = "direction_tcomms"
//cargonia signs
/obj/structure/sign/directions/cargo
name = "\improper Cargo department"
desc = "A direction sign, pointing out which way the Cargo department is."
name = "\improper Cargo Department"
desc = "A direction sign, pointing out the way to the Cargo Department."
icon_state = "direction_crg"
// VOREStation Edit - New signs for us
/obj/structure/sign/directions/command
icon = 'icons/obj/decals_vr.dmi'
name = "\improper Command department"
desc = "A direction sign, pointing out which way the Command department is."
icon_state = "direction_cmd"
/obj/structure/sign/directions/cargo/mining
name = "\improper Mining Department"
desc = "A direction sign, pointing out the way to the Mining Department."
icon_state = "direction_mining"
/obj/structure/sign/directions/elevator
icon = 'icons/obj/decals_vr.dmi'
name = "\improper Space Elevator"
desc = "A direction sign, pointing out which way the Space Elevator is."
icon_state = "direction_elv"
// VOREStation Edit End
/obj/structure/sign/directions/cryo
name = "\improper Cryogenic Storage"
desc = "A direction sign, pointing out which way cryogenic storage is."
icon_state = "direction_cry"
/obj/structure/sign/directions/cargo/refinery
name = "\improper Refinery"
desc = "A direction sign, pointing out the way to the Refinery."
icon_state = "direction_refinery"
//civilian/misc signs
/obj/structure/sign/directions/roomnum
name = "room number"
desc = "A sign detailing the number of the room beside it."
icon_state = "roomnum"
/obj/structure/sign/directions/cryo
name = "\improper Cryogenic Storage"
desc = "A direction sign, pointing out the way to Cryogenic Storage."
icon_state = "direction_cry"
/obj/structure/sign/directions/elevator
name = "\improper Elevator"
desc = "A direction sign, pointing out the way to the nearest elevator."
icon_state = "direction_elv"
/obj/structure/sign/directions/bar
name = "\improper Bar"
desc = "A direction sign, pointing out the way to the nearest watering hole."
icon_state = "direction_bar"
/obj/structure/sign/directions/kitchen
name = "\improper Kitchen"
desc = "A pictographic direction sign with a knife, plate, and fork, pointing out the way to the nearest dining establishment."
icon_state = "direction_kitchen"
/obj/structure/sign/directions/tram
name = "\improper Public Transit Station"
desc = "A direction sign, pointing out the way to the nearest public transit station."
icon_state = "direction_tram"
/obj/structure/sign/directions/janitor
name = "\improper Custodial Closet"
desc = "A direction sign, pointing out the way to the Custodial Closet."
icon_state = "direction_janitor"
/obj/structure/sign/directions/chapel
name = "\improper Chapel"
desc = "A direction sign, pointing out the way to the Chapel."
icon_state = "direction_chapel"
/obj/structure/sign/directions/dorms
name = "\improper Dormitories"
desc = "A direction sign, pointing out the way to the Dormitories."
icon_state = "direction_dorms"
/obj/structure/sign/directions/library
name = "\improper Library"
desc = "A direction sign, pointing out the way to the Library."
icon_state = "direction_library"
/obj/structure/sign/directions/dock
name = "\improper Dock"
desc = "A direction sign, pointing out the way to the nearest docking area."
icon_state = "direction_dock"
/obj/structure/sign/directions/gym
name = "\improper Gym"
desc = "A direction sign, pointing out the way to the Gym."
icon_state = "direction_gym"
/obj/structure/sign/directions/pool
name = "\improper Pool"
desc = "A direction sign, pointing out the way to the Pool."
icon_state = "direction_pool"
/obj/structure/sign/directions/recreation
name = "\improper Recreation Area"
desc = "A direction sign, pointing out the way to the nearest Recreation Area."
icon_state = "direction_recreation"
/obj/structure/sign/directions/stairwell
name = "\improper Stairwell"
desc = "A direction sign with stairs and a door, pointing out the way to the nearest stairwell."
icon_state = "stairwell"
/obj/structure/sign/directions/stairs_up
name = "\improper Stairs Up"
desc = "A direction sign with stairs and an upward-slanted arrow, pointing out the way to the nearest set of stairs that go up."
icon_state = "stairs_up"
/obj/structure/sign/directions/stairs_down
name = "\improper Stairs Down"
desc = "A direction sign with stairs and a downward-slanted arrow, pointing out the way to the nearest set of stairs that go down."
icon_state = "stairs_down"
/obj/structure/sign/directions/ladderwell
name = "\improper Access Shaft"
desc = "A direction sign with a ladder and a door, pointing out the way to the nearest access shaft."
icon_state = "ladderwell"
/obj/structure/sign/directions/ladder_up
name = "\improper Ladder Up"
desc = "A direction sign with a ladder and an upward arrow, pointing out the way to the nearest ladder that goes up."
icon_state = "ladder_up"
/obj/structure/sign/directions/ladder_down
name = "\improper Ladder Down"
desc = "A direction sign with a ladder and a downward arrow, pointing out the way to the nearest ladder that goes down."
icon_state = "ladder_down"
/obj/structure/sign/directions/exit
name = "\improper Emergency Exit"
desc = "A lurid green sign that unmistakably identifies that the door it's next to as an emergency exit route."
icon_state = "exit_sign"
//OTHER STUFF
/obj/structure/sign/christmas/lights
name = "Christmas lights"
desc = "Flashy and pretty."
+5
View File
@@ -0,0 +1,5 @@
/obj/structure/sign/itg
icon = 'icons/obj/decals_vr.dmi'
name = "\improper ITG"
desc = "A polished metal sign which reads 'Ironcrest Transport Group'."
icon_state = "itg"
@@ -1,26 +1,59 @@
/obj/structure/bed/chair/wheelchair
name = "wheelchair"
desc = "You sit in this. Either by will or force."
icon = 'icons/obj/wheelchair.dmi'
icon_state = "wheelchair"
anchored = 0
buckle_movable = 1
var/folded_type = /obj/item/wheelchair
var/driving = 0
var/mob/living/pulling = null
var/bloodiness
var/min_mob_buckle_size = MOB_SMALL
var/max_mob_buckle_size = MOB_LARGE
/obj/structure/bed/chair/wheelchair/Initialize()
. = ..()
update_icon()
/obj/structure/bed/chair/wheelchair/motor
name = "electric wheelchair"
desc = "A motorized wheelchair controlled with a joystick on one armrest"
icon_state = "motorchair"
folded_type = /obj/item/wheelchair/motor
/obj/structure/bed/chair/wheelchair/smallmotor
name = "small electric wheelchair"
desc = "A small motorized wheelchair, it looks around the right size for a Teshari"
icon_state = "teshchair"
min_mob_buckle_size = MOB_SMALL
max_mob_buckle_size = MOB_MEDIUM
folded_type = /obj/item/wheelchair/motor/small
/obj/structure/bed/chair/wheelchair/can_buckle_check(mob/living/M, forced = FALSE)
. = ..()
if(.)
if(M.mob_size < min_mob_buckle_size)
to_chat(M, SPAN_WARNING("You are too small to use \the [src]."))
. = FALSE
else if(M.mob_size >= max_mob_buckle_size)
to_chat(M, SPAN_WARNING("You are too large to use \the [src]."))
. = FALSE
/obj/structure/bed/chair/wheelchair/update_icon()
return
cut_overlays()
var/image/O = image(icon = icon, icon_state = "[icon_state]_overlay", layer = ABOVE_MOB_LAYER)
O.plane = MOB_PLANE
add_overlay(O)
/obj/structure/bed/chair/wheelchair/set_dir()
..()
cut_overlays()
var/image/O = image(icon = 'icons/obj/furniture.dmi', icon_state = "w_overlay", layer = FLY_LAYER, dir = src.dir)
add_overlay(O)
if(has_buckled_mobs())
for(var/A in buckled_mobs)
var/mob/living/L = A
L.set_dir(dir)
. = ..()
if(.)
if(has_buckled_mobs())
for(var/A in buckled_mobs)
var/mob/living/L = A
L.set_dir(dir)
/obj/structure/bed/chair/wheelchair/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.is_wrench() || W.is_wirecutter() || istype(W,/obj/item/stack))
@@ -93,8 +126,6 @@
/obj/structure/bed/chair/wheelchair/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
cut_overlays()
playsound(src, 'sound/effects/roll.ogg', 75, 1)
if(has_buckled_mobs())
for(var/A in buckled_mobs)
@@ -203,28 +234,13 @@
usr.pulledby = null
..()
/obj/item/wheelchair
name = "wheelchair"
desc = "A folded wheelchair that can be carried around."
icon = 'icons/obj/furniture.dmi'
icon_state = "wheelchair_folded"
item_state = "wheelchair"
w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
/obj/item/wheelchair/attack_self(mob/user)
var/obj/structure/bed/chair/wheelchair/R = new /obj/structure/bed/chair/wheelchair(user.loc)
R.add_fingerprint(user)
R.name = src.name
R.color = src.color
qdel(src)
/obj/structure/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location)
..()
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
if(!ishuman(usr)) return
if(has_buckled_mobs()) return 0
visible_message("[usr] collapses \the [src.name].")
var/obj/item/wheelchair/R = new/obj/item/wheelchair(get_turf(src))
var/obj/item/wheelchair/R = new folded_type(get_turf(src))
R.name = src.name
R.color = src.color
spawn(0)
@@ -0,0 +1,29 @@
/obj/item/wheelchair
name = "wheelchair"
desc = "A folded wheelchair that can be carried around."
icon = 'icons/obj/wheelchair.dmi'
icon_state = "wheelchair_folded"
item_state = "wheelchair"
w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
var/unfolded_type = /obj/structure/bed/chair/wheelchair
/obj/item/wheelchair/attack_self(mob/user)
var/obj/structure/bed/chair/wheelchair/R = new unfolded_type(user.loc)
R.add_fingerprint(user)
R.name = src.name
R.color = src.color
qdel(src)
/obj/item/wheelchair/motor
name = "electric wheelchair"
desc = "A motorized wheelchair controlled with a joystick on one armrest"
icon_state = "motorchair_folded"
item_state = "motorchair"
unfolded_type = /obj/structure/bed/chair/wheelchair/motor
/obj/item/wheelchair/motor/small
name = "small electric wheelchair"
desc = "A small motorized wheelchair, it looks around the right size for a Teshari."
icon_state = "teshchair_folded"
item_state = "teshchair"
unfolded_type = /obj/structure/bed/chair/wheelchair/smallmotor
@@ -180,6 +180,7 @@
prob(2);/obj/item/clothing/shoes/galoshes,
prob(2);/obj/item/clothing/under/pants/camo,
prob(2);/obj/item/clothing/under/syndicate/tacticool,
prob(2);/obj/item/clothing/under/hyperfiber,
prob(2);/obj/item/device/camera,
prob(2);/obj/item/device/flashlight/flare,
prob(2);/obj/item/device/flashlight/glowstick,
@@ -240,6 +241,7 @@
prob(2);/obj/item/weapon/handcuffs/legcuffs/fuzzy,
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
prob(2);/obj/item/weapon/grenade/anti_photon,
prob(2);/obj/item/clothing/under/hyperfiber/bluespace,
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
prob(1);/obj/item/device/nif/bad,
prob(1);/obj/item/device/radio_jammer,
+4 -71
View File
@@ -215,82 +215,14 @@
L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily
if(iscarbon(O))
var/mob/living/carbon/M = O
if(M.r_hand)
M.r_hand.clean_blood()
if(M.l_hand)
M.l_hand.clean_blood()
if(M.back)
if(M.back.clean_blood())
M.update_inv_back(0)
//flush away reagents on the skin
var/mob/living/carbon/M = O
if(M.touching)
var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first
M.touching.remove_any(remove_amount)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/washgloves = 1
var/washshoes = 1
var/washmask = 1
var/washears = 1
var/washglasses = 1
if(H.wear_suit)
washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES)
washshoes = !(H.wear_suit.flags_inv & HIDESHOES)
if(H.head)
washmask = !(H.head.flags_inv & HIDEMASK)
washglasses = !(H.head.flags_inv & HIDEEYES)
washears = !(H.head.flags_inv & HIDEEARS)
if(H.wear_mask)
if (washears)
washears = !(H.wear_mask.flags_inv & HIDEEARS)
if (washglasses)
washglasses = !(H.wear_mask.flags_inv & HIDEEYES)
if(H.head)
if(H.head.clean_blood())
H.update_inv_head(0)
if(H.wear_suit)
if(H.wear_suit.clean_blood())
H.update_inv_wear_suit(0)
else if(H.w_uniform)
if(H.w_uniform.clean_blood())
H.update_inv_w_uniform(0)
if(H.gloves && washgloves)
if(H.gloves.clean_blood())
H.update_inv_gloves(0)
if(H.shoes && washshoes)
if(H.shoes.clean_blood())
H.update_inv_shoes(0)
if(H.wear_mask && washmask)
if(H.wear_mask.clean_blood())
H.update_inv_wear_mask(0)
if(H.glasses && washglasses)
if(H.glasses.clean_blood())
H.update_inv_glasses(0)
if(H.l_ear && washears)
if(H.l_ear.clean_blood())
H.update_inv_ears(0)
if(H.r_ear && washears)
if(H.r_ear.clean_blood())
H.update_inv_ears(0)
if(H.belt)
if(H.belt.clean_blood())
H.update_inv_belt(0)
H.clean_blood(washshoes)
else
if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags
if(M.wear_mask.clean_blood())
M.update_inv_wear_mask(0)
M.clean_blood()
else
O.clean_blood()
M.clean_blood()
if(isturf(loc))
var/turf/tile = loc
for(var/obj/effect/E in tile)
@@ -451,6 +383,7 @@
busy = 0
O.clean_blood()
O.water_act(rand(1,10))
user.visible_message( \
"<span class='notice'>[user] washes \a [I] using \the [src].</span>", \
"<span class='notice'>You wash \a [I] using \the [src].</span>")
@@ -0,0 +1,41 @@
//Flushable toilets on station levels. Flushing sends stuff directly to a trashpit landmark without stinking up the cargo office.
//Only on-station toilets are affected and only if the trashpit landmark also exists. Otherwise toilets will stay normal.
/obj/structure/toilet
var/teleplumbed = FALSE
var/exit_landmark
/obj/structure/toilet/Initialize()
if(z in global.using_map.map_levels)
teleplumbed = TRUE
exit_landmark = locate(/obj/effect/landmark/teleplumb_exit)
if(teleplumbed && exit_landmark)
desc = "The BS-500, a bluespace rift-rotation-based waste disposal unit for small matter. This one seems remarkably clean."
return ..()
/obj/structure/toilet/attack_hand(mob/living/user as mob)
if(open && teleplumbed && exit_landmark)
var/list/bowl_contents = list()
for(var/obj/item/I in loc.contents)
if(istype(I) && !I.anchored)
bowl_contents += I
if(bowl_contents.len)
user.visible_message("<span class='notice'>[user] flushes the toilet.</span>", "<span class='notice'>You flush the toilet.</span>")
playsound(src, 'sound/vore/death7.ogg', 50, 1) //Got lazy about getting new sound files. Have a sick remix lmao.
playsound(src, 'sound/effects/bubbles.ogg', 50, 1)
playsound(src, 'sound/mecha/powerup.ogg', 30, 1)
for(var/obj/item/F in bowl_contents)
F.forceMove(get_turf(exit_landmark))
bowl_contents -= F
return
return ..()
/obj/structure/toilet/attack_ai(mob/user as mob)
if(isrobot(user))
if(user.client && user.client.eye == user)
return attack_hand(user)
else
return attack_hand(user)
/obj/effect/landmark/teleplumb_exit
name = "teleplumbing exit"
@@ -27,11 +27,10 @@
return FALSE
/obj/effect/wingrille_spawn/Initialize()
. = ..()
if(!win_path)
return
if(ticker && ticker.current_state < GAME_STATE_PLAYING)
if(win_path && ticker && ticker.current_state < GAME_STATE_PLAYING)
activate()
..()
return INITIALIZE_HINT_QDEL
/obj/effect/wingrille_spawn/proc/activate()
if(activated) return
@@ -58,7 +57,8 @@
activated = 1
for(var/obj/effect/wingrille_spawn/other in neighbours)
if(!other.activated) other.activate()
qdel(src)
if(initialized && !QDELETED(src))
qdel(src)
/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W)
return