Merge branch 'master' into herms

This commit is contained in:
kcin2001
2018-04-27 17:00:09 -07:00
committed by GitHub
223 changed files with 40462 additions and 87334 deletions
+1 -1
View File
@@ -1264,7 +1264,7 @@ var/datum/announcement/minor/admin_min_announcer = new
usr << "<b>AI [key_name(S, usr)]'s laws:</b>"
else if(isrobot(S))
var/mob/living/silicon/robot/R = S
usr << "<b>CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:</b>"
usr << "<b>CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independent)"]: laws:</b>"
else if (ispAI(S))
usr << "<b>pAI [key_name(S, usr)]'s laws:</b>"
else
@@ -11,12 +11,14 @@
S["all_underwear_metadata"] >> pref.all_underwear_metadata
S["backbag"] >> pref.backbag
S["pdachoice"] >> pref.pdachoice
S["communicator_visibility"] >> pref.communicator_visibility
/datum/category_item/player_setup_item/general/equipment/save_character(var/savefile/S)
S["all_underwear"] << pref.all_underwear
S["all_underwear_metadata"] << pref.all_underwear_metadata
S["backbag"] << pref.backbag
S["pdachoice"] << pref.pdachoice
S["communicator_visibility"] << pref.communicator_visibility
// Moved from /datum/preferences/proc/copy_to()
/datum/category_item/player_setup_item/general/equipment/copy_to_mob(var/mob/living/carbon/human/character)
@@ -86,6 +88,7 @@
. += "<br>"
. += "Backpack Type: <a href='?src=\ref[src];change_backpack=1'><b>[backbaglist[pref.backbag]]</b></a><br>"
. += "PDA Type: <a href='?src=\ref[src];change_pda=1'><b>[pdachoicelist[pref.pdachoice]]</b></a><br>"
. += "Communicator Visibility: <a href='?src=\ref[src];toggle_comm_visibility=1'><b>[(pref.communicator_visibility) ? "Yes" : "No"]</b></a><br>"
return jointext(.,null)
@@ -139,5 +142,10 @@
if(new_metadata)
set_metadata(underwear, gt, new_metadata)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["toggle_comm_visibility"])
if(CanUseTopic(user))
pref.communicator_visibility = !pref.communicator_visibility
return TOPIC_REFRESH
return ..()
@@ -1,26 +0,0 @@
/datum/category_item/player_setup_item/player_global/communicators
name = "Communicators"
sort_order = 4
/datum/category_item/player_setup_item/player_global/communicators/load_preferences(var/savefile/S)
S["communicator_visibility"] >> pref.communicator_visibility
/datum/category_item/player_setup_item/player_global/communicators/save_preferences(var/savefile/S)
S["communicator_visibility"] << pref.communicator_visibility
/datum/category_item/player_setup_item/player_global/communicators/sanitize_preferences()
pref.communicator_visibility = sanitize_integer(pref.communicator_visibility, 0, 1, initial(pref.communicator_visibility))
/datum/category_item/player_setup_item/player_global/communicators/content(var/mob/user)
. += "<b>Communicator Identity:</b><br>"
. += "Visibility: <a href='?src=\ref[src];toggle_comm_visibility=1'><b>[(pref.communicator_visibility) ? "Yes" : "No"]</b></a><br>"
/datum/category_item/player_setup_item/player_global/communicators/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["toggle_comm_visibility"])
if(CanUseTopic(user))
pref.communicator_visibility = !pref.communicator_visibility
return TOPIC_REFRESH
return ..()
@@ -1,6 +1,6 @@
/datum/category_item/player_setup_item/player_global/ooc
name = "OOC"
sort_order = 5
sort_order = 4
/datum/category_item/player_setup_item/player_global/ooc/load_preferences(var/savefile/S)
S["ignored_players"] >> pref.ignored_players
@@ -4,7 +4,7 @@
/datum/category_item/player_setup_item/player_global/media
name = "Media"
sort_order = 6
sort_order = 5
/datum/category_item/player_setup_item/player_global/media/load_preferences(var/savefile/S)
S["media_volume"] >> pref.media_volume
@@ -46,6 +46,12 @@
path = /obj/item/weapon/book/codex/corp_regs
cost = 0
*/
/datum/gear/utility/robutt
display_name = "a buyer's guide to artificial bodies"
path = /obj/item/weapon/book/codex/lore/robutt
cost = 0
/datum/gear/utility/folder_blue
display_name = "folder, blue"
path = /obj/item/weapon/folder/blue
@@ -73,8 +73,10 @@
if(!(path in negative_traits))
pref.neg_traits -= path
if(!pref.custom_base || !(pref.custom_base in custom_species_bases))
pref.custom_base = "Human"
if(pref.species == pref.custom_base && pref.species != SPECIES_CUSTOM)
// Allowed!
else if(!pref.custom_base || !(pref.custom_base in custom_species_bases))
pref.custom_base = SPECIES_HUMAN
/datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character)
character.custom_species = pref.custom_species
@@ -148,8 +150,11 @@
return TOPIC_REFRESH
else if(href_list["custom_base"])
var/text_choice = input("Pick an icon set for your species:","Icon Base") in custom_species_bases
if(text_choice in custom_species_bases)
var/list/choices = custom_species_bases
if(pref.species != SPECIES_CUSTOM)
choices = (choices | pref.species)
var/text_choice = input("Pick an icon set for your species:","Icon Base") in choices
if(text_choice in choices)
pref.custom_base = text_choice
return TOPIC_REFRESH_UPDATE_PREVIEW
@@ -0,0 +1,42 @@
/obj/item/clothing/shoes/griffin
name = "griffon boots"
desc = "A pair of costume boots fashioned after bird talons."
icon_state = "griffinboots"
item_state = "griffinboots"
icon = 'icons/obj/clothing/shoes_vr.dmi'
icon_override = 'icons/mob/feet_vr.dmi' // This appends "_r" "_l" to icon state
/obj/item/clothing/shoes/bhop
name = "jump boots"
desc = "A specialized pair of combat boots with a built-in propulsion system for rapid foward movement."
icon_state = "jetboots"
item_state = "jetboots"
icon = 'icons/obj/clothing/shoes_vr.dmi'
icon_override = 'icons/mob/feet_vr.dmi' // This appends "_r" "_l" to icon state
// resistance_flags = FIRE_PROOF
action_button_name = "Activate Jump Boots"
permeability_coefficient = 0.05
var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles
var/jumpspeed = 3
var/recharging_rate = 60 //default 6 seconds between each dash
var/recharging_time = 0 //time until next dash
// var/jumping = FALSE //are we mid-jump? We have no throw_at callback, so we have to check user.throwing.
/obj/item/clothing/shoes/bhop/ui_action_click()
var/mob/living/user = loc
if(!isliving(user))
return
if(user.throwing)
return // User is already being thrown
if(recharging_time > world.time)
to_chat(user, "<span class='warning'>The boot's internal propulsion needs to recharge still!</span>")
return
var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction
playsound(src, 'sound/effects/stealthoff.ogg', 50, 1, 1)
user.visible_message("<span class='warning'>[user] dashes forward into the air!</span>")
user.throw_at(target, jumpdistance, jumpspeed)
recharging_time = world.time + recharging_rate
-11
View File
@@ -47,17 +47,6 @@
#define GEAR_EVA 15
/var/list/economic_species_modifier = list(
/datum/species/human = 10,
/datum/species/human/vatgrown = 10,
/datum/species/skrell = 12,
/datum/species/unathi = 7,
/datum/species/tajaran = 7,
/datum/species/teshari = 6,
/datum/species/diona = 4,
/datum/species/shapeshifter/promethean = 3
)
//---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel:
//Corporation NanoTrasen - Generalised / high tech research and phoron exploitation.
//Corporation Vessel Contracting - Ship and station construction, materials research.
+1 -13
View File
@@ -26,19 +26,7 @@
// gas_choices += "volatile_fuel" // Dangerous and no default atmos setup!
gas_type = pick(gas_choices)
// Assemble areas that all exists (See DM reference if you are confused about loop labels)
var/list/area/grand_list_of_areas = list()
looping_station_areas:
for(var/parentpath in global.the_station_areas)
// Check its not excluded
for(var/excluded_path in excluded)
if(ispath(parentpath, excluded_path))
continue looping_station_areas
// Otherwise add it and all subtypes that exist on the map to our grand list
for(var/areapath in typesof(parentpath))
var/area/A = locate(areapath) // Check if it actually exists
if(istype(A) && A.z in using_map.player_levels)
grand_list_of_areas += A
var/list/area/grand_list_of_areas = get_station_areas(excluded)
// Okay, now lets try and pick a target! Lets try 10 times, otherwise give up
for(var/i in 1 to 10)
+33
View File
@@ -0,0 +1,33 @@
/datum/event/electrified_door
var/obj/machinery/door/airlock/chosen_door
var/list/area/excluded = list(
/area/shuttle,
/area/crew_quarters
)
/datum/event/electrified_door/setup()
var/list/area/grand_list_of_areas = get_station_areas(excluded)
//try 10 times
for(var/i in 1 to 10)
var/area/A = pick(grand_list_of_areas)
var/list/obj/machinery/door/airlock/target_doors = list()
for(var/obj/machinery/door/airlock/target_door in A.contents)
target_doors += target_door
target_doors = shuffle(target_doors)
for(var/obj/machinery/door/airlock/target_door in target_doors)
if(!target_door.isElectrified() && target_door.arePowerSystemsOn() && target_door.maxhealth == target_door.health)
chosen_door = target_door
return
/datum/event/electrified_door/start()
if(!chosen_door)
return
chosen_door.set_safeties(0)
if(severity >= EVENT_LEVEL_MODERATE)
chosen_door.electrify(-1)
chosen_door.lock()
chosen_door.health = chosen_door.maxhealth / 6
chosen_door.aiControlDisabled = 1
chosen_door.update_icon()
+44
View File
@@ -0,0 +1,44 @@
/datum/event/escaped_slimes
announceWhen = 90
endWhen = 90 + 15 + 1
var/spawncount
var/list/possible_slimes = list(
/mob/living/simple_animal/slime/purple,
/mob/living/simple_animal/slime/orange,
/mob/living/simple_animal/slime/metal,
/mob/living/simple_animal/slime/yellow,
/mob/living/simple_animal/slime/dark_purple,
/mob/living/simple_animal/slime/silver,
/mob/living/simple_animal/slime/ruby,
/mob/living/simple_animal/slime/cerulean,
/mob/living/simple_animal/slime/red,
/mob/living/simple_animal/slime/green,
/mob/living/simple_animal/slime/pink,
/mob/living/simple_animal/slime/gold,
/mob/living/simple_animal/slime/oil,
/mob/living/simple_animal/slime/emerald,
)
/datum/event/escaped_slimes/setup()
announceWhen = rand(announceWhen, announceWhen + 60)
spawncount = rand(2 * severity, 4 * severity) //spiderlings only have a 50% chance to grow big and strong
/datum/event/escaped_slimes/announce()
command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
sleep(15)
command_announcement.Announce("The previously unidentified lifesigns have been identified as escaped slimes from Xenobiology. Secure any exterior access, including ducting and ventilation, taking care to return the slimes to their proper confinement.", "Lifesign Alert")
/datum/event/escaped_slimes/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.network && temp_vent.loc.z in using_map.station_levels) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents
vents += temp_vent
while((spawncount > 0) && vents.len)
var/obj/vent = pick(vents)
var/slime_type = pick(possible_slimes)
new slime_type(vent.loc, 1)
vents -= vent
spawncount--
+16 -12
View File
@@ -1,20 +1,24 @@
datum/event/wallrot/setup()
/datum/event/wallrot
var/turf/simulated/wall/center
/datum/event/wallrot/setup()
announceWhen = rand(0, 300)
endWhen = announceWhen + 1
datum/event/wallrot/announce()
command_announcement.Announce("Harmful fungi detected on the colony. Station structures may be contaminated.", "Biohazard Alert")
// 100 attempts
for(var/i=0, i<100, i++)
var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), 1)
if(istype(candidate, /turf/simulated/wall))
center = candidate
return 1
return 0
datum/event/wallrot/start()
/datum/event/wallrot/announce()
if(center)
command_announcement.Announce("Harmful fungi detected on the colony nearby [center.loc.name]. Station structures may be contaminated.", "Biohazard Alert")
/datum/event/wallrot/start()
spawn()
var/turf/simulated/wall/center = null
// 100 attempts
for(var/i=0, i<100, i++)
var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), 1)
if(istype(candidate, /turf/simulated/wall))
center = candidate
if(center)
// Make sure at least one piece of wall rots!
center.rot()
+73
View File
@@ -0,0 +1,73 @@
/datum/event/window_break
var/obj/structure/window/chosen_window
var/list/obj/structure/window/collateral_windows
var/turf/chosen_location
var/list/area/excluded = list(
/area/shuttle,
/area/crew_quarters
)
/datum/event/window_break/setup()
var/list/area/grand_list_of_areas = get_station_areas(excluded)
//try 10 times
for(var/i in 1 to 10)
var/area/A = pick(grand_list_of_areas)
var/list/obj/structure/window/possible_target_windows = list()
for(var/obj/structure/window/target_window in A.contents)
possible_target_windows += target_window
possible_target_windows = shuffle(possible_target_windows)
for(var/obj/structure/window/target_window in possible_target_windows)
//if() don't have any conditions, for isn't strictly necessary
chosen_window = target_window
chosen_location = chosen_window.loc
collateral_windows = gather_collateral_windows(chosen_window)
announceWhen = (collateral_windows.len + 1) * 20
endWhen = announceWhen + 1
return
//TL;DR: breadth first search for all connected turfs with windows
/datum/event/window_break/proc/gather_collateral_windows(var/obj/structure/window/target_window)
var/list/turf/frontier_set = list(target_window.loc)
var/list/obj/structure/window/result_set = list()
var/list/turf/explored_set = list()
while(frontier_set.len > 0)
var/turf/current = frontier_set[1]
frontier_set -= current
explored_set += current
var/contains_windows = 0
for(var/obj/structure/window/to_add in current.contents)
contains_windows = 1
result_set += to_add
if(contains_windows)
//add adjacent turfs to be checked for windows as well
var/turf/neighbor = locate(current.x + 1, current.y, current.z)
if(!(neighbor in frontier_set) && !(neighbor in explored_set))
frontier_set += neighbor
neighbor = locate(current.x - 1, current.y, current.z)
if(!(neighbor in frontier_set) && !(neighbor in explored_set))
frontier_set += neighbor
neighbor = locate(current.x, current.y + 1, current.z)
if(!(neighbor in frontier_set) && !(neighbor in explored_set))
frontier_set += neighbor
neighbor = locate(current.x, current.y - 1, current.z)
if(!(neighbor in frontier_set) && !(neighbor in explored_set))
frontier_set += neighbor
return result_set
/datum/event/window_break/start()
if(!chosen_window)
return
chosen_window.shatter(0)
for(var/obj/structure/window/current_collateral in collateral_windows)
sleep(rand(1,20))
current_collateral.take_damage(current_collateral.health - (current_collateral.maxhealth / 5)) //set to 1/5th health
/datum/event/window_break/announce()
command_announcement.Announce("Structural integrity of windows at [chosen_location.loc.name] is failing. Immediate repair or replacement is advised.", "Structural Alert")
+9
View File
@@ -0,0 +1,9 @@
/datum/event/wormholes
startWhen = 0
endWhen = 80
/datum/event/wormholes/start()
wormhole_event()
/datum/event/wormholes/end()
command_announcement.Announce("There are no more space-time anomalies detected on the station.", "Anomaly Alert")
+4 -4
View File
@@ -870,7 +870,7 @@
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_POTENCY,1)
set_trait(TRAIT_PRODUCT_ICON,"vine")
set_trait(TRAIT_PRODUCT_COLOUR,"#326B30")
set_trait(TRAIT_PRODUCT_COLOUR,"#3D8C3A")
set_trait(TRAIT_PLANT_COLOUR,"#257522")
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_FLESH_COLOUR,"#F22C2C")
@@ -892,9 +892,9 @@
set_trait(TRAIT_PRODUCTION,6)
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_POTENCY,10)
set_trait(TRAIT_PRODUCT_ICON,"vine")
set_trait(TRAIT_PRODUCT_COLOUR,"#B4D4B9")
set_trait(TRAIT_PLANT_COLOUR,"#BAE8C1")
set_trait(TRAIT_PRODUCT_ICON,"vine2")
set_trait(TRAIT_PRODUCT_COLOUR,"#DBAC02")
set_trait(TRAIT_PLANT_COLOUR,"#21661E")
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
@@ -168,6 +168,8 @@
else if(ispath(build_type, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/IC = build_type
cost = initial(IC.w_class)
else
return
if(metal - cost < 0)
to_chat(usr, "<span class='warning'>You need [cost] metal to build that!.</span>")
+7
View File
@@ -25,6 +25,13 @@
icon_state = "codex"
root_type = /datum/lore/codex/category/main_virgo_lore
/obj/item/weapon/book/codex/lore/robutt
name = "A Buyer's Guide to Artificial Bodies"
desc = "Recommended reading for the newly cyborgified, new positronics, and the upwardly-mobile FBP."
icon_state = "codex_robutt"
root_type = /datum/lore/codex/category/main_robutts
/obj/item/weapon/book/codex/lore/news
name = "Daedalus Pocket Newscaster"
desc = "A regularly-updating compendium of articles on current events. Essential for new arrivals in the Vir system and anyone interested in politics."
@@ -0,0 +1,85 @@
/datum/lore/codex/category/pros_by_brand
name = "Prosthetics By Brand"
data = "Here you'll find our analysis of the most popular and noteworthy brands of prosthetics. These analyses are performed by industry experts unconnected to the corporations and other entities responsible for the following designs."
children = list(
/datum/lore/codex/page/robo_unbranded,
/datum/lore/codex/page/robo_cyber,
/datum/lore/codex/page/robo_nt,
/datum/lore/codex/page/robo_wt,
/datum/lore/codex/page/robo_heph,
/datum/lore/codex/page/robo_xion,
/datum/lore/codex/page/robo_grayson,
/datum/lore/codex/page/robo_morph,
/datum/lore/codex/page/robo_bishop,
/datum/lore/codex/page/robo_zh,
/datum/lore/codex/page/robo_veymed,
)
/datum/lore/codex/page/robo_unbranded
name = "\"Unbranded\""
data = "Based on hundreds of years of open-source development, \"Unbranded\" prosthetics are a low-price powered prosthesis option available throughout human space, even in the most desolate or newly settled systems. Occasionally, a popular unbranded design will be taken down due to claims of copyright infringement, but a new one invariably springs back up within a few months. Because Unbranded designs have a very loosely structured development process, bugs inevitably crop up, leading to a reputation for unreliability.\
<br><br>\
Unbranded prosthetics are extremely inexpensive but are sought out by those seriously dedicated to the Unbranded ethos. Due to their open-sourced nature, Unbranded prosthetics run the gamut of quality and style, though it's safe to assume that they're relatively poorly made. The ones that last longest on the Exonet tend to be glitchy; those that function are often removed on claims of copyright infringement."
/datum/lore/codex/page/robo_cyber
name = "Cyber Solutions"
data = "Morpheus Cyberkinetics makes the cheapest functioning prosthetics on the market. Cyber Solutions makes the cheapest prosthetics, period. Notoriously buggy and poorly-constructed, Cyber Solutions has been the target of a number of class action lawsuits by positronics whose bodies had literally fallen apart on them. While their quality has improved slightly since their most recent lawsuit, Cyber Solutions parts remain so low-quality that the company refuses to use them for their own low-price drone lines. Some tinkerers have managed to improve the parts far beyond the factory quality, and in some Mercurial subgroups Cyber Solutions modding is considered an art form.\
<br><br>\
Cyber Solutions prosthetics are only recommended for the truly destitute and dedicated tinkers."
/datum/lore/codex/page/robo_nt
name = "NanoTrasen"
data = "A fairly unremarkable prosthetic design, NanoTrasen health plans provide these as part of their famous corporate medical insurance. These are also provided to NanoTrasen-produced positronics at the end of their indenture and are considered fairly high quality for entry-level prosthesis. Outside of NanoTrasen facilities, NanoTrasen-brand prosthetics are fairly rare and not often sought out-- NanoTrasen's grey-black prosthetics are a visual sign of association with the company itself.\
<br><br>\
NanoTrasen prosthetics are a solid choice for any NanoTrasen employee. They're easy to come across in the event of a workplace accident and comfortable enough that many never feel the need to upgrade."
/datum/lore/codex/page/robo_wt
name = "Ward-Takahashi GMB"
data = "The manufacturing giant's prosthetic line is functionally quite similar to Nanotrasen, but is directed at the consumer market and cheaper than Nanotrasen's own product. Aesthetically, of course, they are worlds apart, trading Nanotrasen's black gunmetal for rounded white plastic. The design endeavors to avoid the \"uncanny valley\" that plagues humaniform robot designs, by abstracting away the human shape into a series of connected ovals. Artists debate whether or not it succeeds, while normal people are more concerned with WT's tendency to accrue dirt and scratches with hard use.\
<br><br>\
Ward-Takahashi is popular through all economic classes, from poor to wealthy. Though it takes more wear-and-tear from heavy labor than dedicated industrial chassis, some use it for these tasks regardless."
/datum/lore/codex/page/robo_heph
name = "Hephaestus Industries"
data = "Hephaestus joined the civilian prosthetic market in earnest after the First Contact War. Wartime amputees and fully-prosthetic Mechanized Division veterans found themselves looking for the Hephaestus parts that they had access to during the conflict. Hephaestus responded by producing the first civilian model of their rugged green prosthetics, leveraging their ties with SolGov to offer discounts to many of those returning from war. HI-Civilian is not quite as durable or easily maintained as the military model, to conform with most systems' legal restrictions on the capacities of prosthetic limbs, but maintains an unmatched reputation for resilience to damage and ease of repair.\
<br><br>\
Hephaestus prosthetics are somewhat expensive, but are a reasonable investment for many of average or above economic status. It has sufficient manual dexterity for most tasks, without sacrificing the rugged durability that made the brand popular."
/datum/lore/codex/page/robo_xion
name = "Xion Manufacturing Group"
data = "Xion's prosthetic designs are normally seen fairly rarely outside of Xion's extensive mining facilities, but have managed to proliferate because of the sheer number of positronics it creates and employs. Xion's limbs are cheap and rugged, but come with a number of drawbacks. Even positronic users complain about Xion's lack of sensitivity, but more problematic still is Xion's habit of leasing out their prosthetics as they do the rest of their equipment. Most people find the idea of not owning their own body extremely distressing, and because of this (and because Xion spearheads most anti-Unbranded lawsuits) Xion and Xion-like prosthetic designs are frequently available on pirate sites.\
<br><br>\
Xion prosthetics are most appropriate for the poor and underpaid. More wealthy people, and those whose jobs require precision works, are encouraged to pick a more open brand."
/datum/lore/codex/page/robo_grayson
name = "Grayson Manufacturing"
data = "Grayson is a new entrant into the prosthetics market. Their debut line is a rugged design built using polymers and alloys originally developed for Wulf Aeronautics, giving their parts a reputation for extremely solid construction. Unfortunately, the use of high-density materials in the construction process gives them an uncomfortable weight, something that Grayson has promised to correct in their next release. The parts are fairly cheap, but require a robotics specialist to put them together by hand before they're ready for use.\
<br><br>\
Grayson parts are appropriate for those of any income class, so long as they are willing to deal with the design's unwieldiness. This makes them most popular for those involved in construction or other manual labor, and some in police and private security have taken to using Grayson as a \"discount Hephaestus\"."
/datum/lore/codex/page/robo_morph
name = "Morpheus Cyberkinetics"
data = "One of the two TSCs with the most investment in the prosthetics market, Morpheus' design ethos sets them far apart from Bishop Cybernetics. Morpheus chassis are supposed to be the cheapest and most streamlined prosthetic bodies imaginable. Due to their minimalist construction methods, the chassis is often called 'skeletal' or 'insectoid', the parts often remaining unpainted, with wiring being run externally, rather than through the joints. Morpheus was also the first company to pioneer the now-popular \"monitorhead\" design, replacing time and material-intensive facial sculpting with a single mass-produced monitor.\
<br><br>\
Morpheus prosthetics are a popular choice for the positronic underclass. Richer synthetics usually upgrade to a more aesthetically pleasing design, while most humans find the distinctly inhuman sensory response from Morpheus products unnerving."
/datum/lore/codex/page/robo_bishop
name = "Bishop Cybernetics"
data = "Bishop is the other big-name prosthesis manufacturer. Despite their obviously mechanical appearance, Bishop products have a range of sensation rivaling that of Vey Medical, with proponents calling it even more comfortable and responsive. Simply occupying a Bishop chassis gives some the same sort of sensation one would get from a fast, well-maintained car or aircraft. Bishop products are most commonly sold in \"boutiques\" found throughout the richer regions of human space, and are custom-fit for the end-user's specifications.Externally, Bishop prosthetics have a distinctive chrome or airbrushed aluminum design, with carefully fitted blue lighting.\
<br><br>\
Bishop's exclusivity leads to them being most common among the wealthy, although upper-middle class technophiles have been known to invest in a high-quality prosthetic. \"Knock-offs\", usually chrome-plated NanoTrasen prosthetics with painted-on lines, are sometimes worn by poseurs."
/datum/lore/codex/page/robo_zh
name = "Zeng-Hu Pharmaceuticals"
data = "Zeng-Hu produces most of the \"lifelike\" prosthetics on the market. Unfortunately for those looking to return to their lives after a catastrophic accident, Zeng-Hu only maintains its profit margins on this product line by cutting corners. Zeng-Hu synthskin is significantly thicker than human skin and has been described as \"rubbery\". Zeng-Hu bodies also have obvious seam lines at the joints to lessen the structural stress on the synthskin covering. Additionally, Zeng-Hu standard facial sculpts all look fairly similar, though custom orders often avoid this problem. Nonetheless, ZH parts are the only option most people have for lifelike prosthetic limbs, and are lifelike enough to pass for human to casual inspection.\
<br><br>\
Zeng-Hu is available to individuals of average means and is a popular choice for drones designed for social interaction, who will probably have been paid for by their creators."
/datum/lore/codex/page/robo_veymed //the deed is done
name = "Vey-Medical"
data = "The most advanced humanoid prosthetic on the market, Vey-Med prides itself on its highly realistic synthskin, near-seamlessly integrated with the most sensitive tactile suite yet created (aside from that of Bishop, with whom they have a long-running friendly rivalry). Vey-Med seeks to be indistinguishable from a human body by both outside observers and by the patient themself, a point at which it succeeds handily.\
The main downside to Vey-Med is its incredibly high pricetag-- easily comparable with that of a large house. Every Vey-Med piece is custom-sculpted for its individual owner, usually based on scans of the owner's previous body or the owner's family. Vey-Med also requires regular maintenance, lest the partially-organic synthskin that coats each piece begin to rot.\
Many nouveau riche and lottery winners have splurged on a Vey-Med chassis, only to discover that they couldn't keep it maintained. Such individuals contribute to the large and semi-legal market of second, third, and fourth-hand Vey-Med chasses, which are cheaper than a store-bought one, but not by very much. Vey-Medical forbids resale of its prosthetics line, and works hard to shut down illicit sales. Potential buyers of a pre-owned Vey-Medical chassis should avoid deals that seem too good to be true, lest they discover that their new body is a Zeng-Hu with a layer of epoxy.\
<br><br>\
Vey-Med bodies are only accessible to the extremely wealthy, almost exclusively humans. Positronics find them unsettling in much the same way humans do Morpheus, and the idea of putting a drone in a Vey-Med body, if not a crude joke, is utterly ridiculous to anyone with any sort of sense. They are absolutely inappropriate for manual labor or combat, being fragile and usually fairly weak compared to other prosthetics."
@@ -0,0 +1,7 @@
/datum/lore/codex/category/main_robutts // The top-level categories for the robot guide
name = "Index"
data = "Temporary death, emancipation, and even basic body migration can be a stressful period in anyone's life. The prosthetics market is complicated, and many corporations view misleading or outright decieving potential clients as \"part of the game\". This Buyer's Guide was compiled in 2542 to serve as an easy reference to the most popular prosthetics available, with consideration paid to every use-case and price point. This is our 12th edition, and much has changed in the field of prosthetics since we first set out. We hope you find the information in this guide helpful."
children = list(
/datum/lore/codex/category/pros_by_brand,
/datum/lore/codex/category/other_information,
)
@@ -0,0 +1,34 @@
/datum/lore/codex/category/other_information
name = "More Information"
data = "Here you'll find articles designed to aid your decision making process, narrowing down the brands outlined in the main body."
children = list(
/datum/lore/codex/page/humansvbeeps,
/datum/lore/codex/page/posiage,
/datum/lore/codex/page/variants,
/datum/lore/codex/page/kitbashing,
)
/datum/lore/codex/page/humansvbeeps
name = "Humans vs Positronics vs Drones"
data = "Most brands are clearly associated with either humans (amputees or voluntary cyber-augmentation patients) or positronics. Despite the fact that MMI and posibrain interfaces are quite similar, and most brands are equally comfortable for both species, this stratification persists. The main reason for this is that human-seeming prosthetics are usually regarded as important for human mental well-being. Medical insurance often pays out more for humans than for positronics in the event of an accident, and humans are often more willing to pay higher prices for humanoid prosthetics. Some positronics regard this as discriminatory, and most believe that maintaining a divide between the two species does not help with social integration.\
<br><br>\
Drones completely eschew this divide-- their chassis are based on what is the most profitable for the group that maintains them. Usually, this means some sort of non-anthropomorphic lawbound chassis. When a humanoid body is required, it's usually the cheapest one available that meets the minimum requirements for the drone to do its job."
/datum/lore/codex/page/posiage
name = "Positronics and Age"
data = "Young positronics are unlikely to have much in the way of expensive belongings, including prosthetics. Most positronics come into the working world outside of a well-defined familial structure and are still paying off the debt from their first body.\
Even those who do come into a family mature very quickly, not providing time for relatives to save up for an expensive chassis before they begin adulthood and working life. Because of these logistical concerns, even a positronic who has been in a well-paying job for a few years is unable to afford a high-quality chassis.\
<br><br>\
Most positronics buy their second chassis at around 10 to 15 years of age, and it is at these age that positronics in more middling chassis come into being. Positronics who want a high-end body must save for decades while scrambling for advancement in a galaxy that is rather bigoted more often than not."
/datum/lore/codex/page/variants
name = "Variants"
data = "Most prosthetic manufacturers produce more than one design, though they usually share significant design elements and exist in the same price-point. Monitor heads remain noticeably cheaper than proper heads, so those interested in penny-pinching will usually opt for a variant with a screen instead of a face."
/datum/lore/codex/page/kitbashing
name = "Kitbashing"
data = "Different corporations' prosthetics are not designed to be slotted together.\
There are exceptions: most industrial brands utilize a shared standard set of connectors, and of course there are Unbranded models that play well with any and all parts.\
Nonetheless, attempting to splice together parts across these lines runs into a variety of technical problems. Most common are sensory and motor cross-wirings, leading to synthesia, uncontrollable jitters, and occasional paralysis. These are uncomfortable enough that most amateur bodymodders give up after one too many hallucinations. Certain combinations of parts run into structural issues-- putting a Hephestus torso on a pair of Morpheus legs is likely to deform those legs badly. Any cross-design kitbashing is likely to result in some level of structural instabilty and poor balance without hard work being put into the design.\
<br><br>\
Most of these can be addressed by a talented roboticist, but nonetheless most people tend to stick to a single brand of prosthetics. People who see their body's makeup as a means of self-expression, or as a machine to be optimized, are much more likely to take risks in pursuit of these goals."
+3
View File
@@ -12,6 +12,9 @@
desc = "A device that synthesises [material.display_name]."
matter = null
/obj/item/stack/material/cyborg/update_strings()
return
/obj/item/stack/material/cyborg/plastic
icon_state = "sheet-plastic"
default_type = "plastic"
+191
View File
@@ -0,0 +1,191 @@
var/global/list/total_extraction_beacons = list()
/obj/item/extraction_pack
name = "fulton extraction pack"
desc = "A balloon that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand."
icon = 'icons/obj/fulton.dmi'
icon_state = "extraction_pack"
w_class = ITEMSIZE_NORMAL
var/obj/structure/extraction_point/beacon
var/list/beacon_networks = list("station")
var/uses_left = 3
var/can_use_indoors
var/safe_for_living_creatures = 1
/obj/item/extraction_pack/examine()
. = ..()
usr.show_message("It has [uses_left] use\s remaining.", 1)
/obj/item/extraction_pack/attack_self(mob/user)
var/list/possible_beacons = list()
for(var/B in global.total_extraction_beacons)
var/obj/structure/extraction_point/EP = B
if(EP.beacon_network in beacon_networks)
possible_beacons += EP
if(!possible_beacons.len)
to_chat(user, "There are no extraction beacons in existence!")
return
else
var/A
A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) as null|anything in possible_beacons
if(!A)
return
beacon = A
to_chat(user, "You link the extraction pack to the beacon system.")
/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params)
if(!beacon)
to_chat(user, "[src] is not linked to a beacon, and cannot be used.")
return
if(!can_use_indoors)
var/turf/T = get_turf(A)
if(T && !T.outdoors)
to_chat(user, "[src] can only be used on things that are outdoors!")
return
if(!flag)
return
if(!istype(A))
return
else
if(!safe_for_living_creatures && check_for_living_mobs(A))
to_chat(user, "[src] is not safe for use with living creatures, they wouldn't survive the trip back!")
return
if(!isturf(A.loc)) // no extracting stuff inside other stuff
return
if(A.anchored)
return
to_chat(user, "<span class='notice'>You start attaching the pack to [A]...</span>")
if(do_after(user,50,target=A))
to_chat(user, "<span class='notice'>You attach the pack to [A] and activate it.</span>")
/* No components, sorry. No convienence for you!
if(loc == user && istype(user.back, /obj/item/storage/backpack))
var/obj/item/storage/backpack/B = user.back
B.SendSignal(COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE)
*/
uses_left--
if(uses_left <= 0)
user.drop_from_inventory(src, A)
var/mutable_appearance/balloon
var/mutable_appearance/balloon2
var/mutable_appearance/balloon3
if(isliving(A))
var/mob/living/M = A
M.AdjustStunned(20) // Keep them from moving during the duration of the extraction
if(M.buckled)
M.buckled.unbuckle_mob(M)
else
A.anchored = TRUE
A.density = FALSE
var/obj/effect/extraction_holder/holder_obj = new(A.loc)
holder_obj.appearance = A.appearance
A.forceMove(holder_obj)
balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand")
balloon2.pixel_y = 10
balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
holder_obj.add_overlay(balloon2)
sleep(4)
balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon")
balloon.pixel_y = 10
balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
holder_obj.cut_overlay(balloon2)
holder_obj.add_overlay(balloon)
playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3)
animate(holder_obj, pixel_z = 10, time = 20)
sleep(20)
animate(holder_obj, pixel_z = 15, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 10, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 15, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 10, time = 10)
sleep(10)
playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3)
animate(holder_obj, pixel_z = 1000, time = 30)
if(ishuman(A))
var/mob/living/carbon/human/L = A
L.AdjustStunned(20)
L.drowsyness = 0
sleep(30)
var/list/flooring_near_beacon = list()
for(var/turf/simulated/floor/floor in orange(1, beacon))
flooring_near_beacon += floor
holder_obj.forceMove(pick(flooring_near_beacon))
animate(holder_obj, pixel_z = 10, time = 50)
sleep(50)
animate(holder_obj, pixel_z = 15, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 10, time = 10)
sleep(10)
balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract")
balloon3.pixel_y = 10
balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
holder_obj.cut_overlay(balloon)
holder_obj.add_overlay(balloon3)
sleep(4)
holder_obj.cut_overlay(balloon3)
A.anchored = FALSE // An item has to be unanchored to be extracted in the first place.
A.density = initial(A.density)
animate(holder_obj, pixel_z = 0, time = 5)
sleep(5)
A.forceMove(holder_obj.loc)
qdel(holder_obj)
if(uses_left <= 0)
qdel(src)
/obj/item/fulton_core
name = "extraction beacon signaller"
desc = "Emits a signal which fulton recovery devices can lock onto. Activate in hand to create a beacon."
icon = 'icons/obj/stock_parts.dmi'
icon_state = "subspace_amplifier"
/obj/item/fulton_core/attack_self(mob/user)
if(do_after(user,15,target = user) && !QDELETED(src))
new /obj/structure/extraction_point(get_turf(user))
qdel(src)
/obj/structure/extraction_point
name = "fulton recovery beacon"
desc = "A beacon for the fulton recovery system. Activate a pack in your hand to link it to a beacon."
icon = 'icons/obj/fulton.dmi'
icon_state = "extraction_point"
anchored = TRUE
density = FALSE
var/beacon_network = "station"
/obj/structure/extraction_point/initialize()
. = ..()
name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])"
global.total_extraction_beacons += src
/obj/structure/extraction_point/Destroy()
global.total_extraction_beacons -= src
..()
/obj/effect/extraction_holder
name = "extraction holder"
desc = "you shouldnt see this"
var/atom/movable/stored_obj
/obj/item/extraction_pack/proc/check_for_living_mobs(atom/A)
if(isliving(A))
var/mob/living/L = A
if(L.stat != DEAD)
return 1
for(var/thing in A.GetAllContents())
if(isliving(A))
var/mob/living/L = A
if(L.stat != DEAD)
return 1
return 0
/obj/effect/extraction_holder/singularity_pull()
return
/obj/effect/extraction_holder/singularity_pull()
return
+116 -44
View File
@@ -1,43 +1,71 @@
/**********************Mineral processing unit console**************************/
#define PROCESS_NONE 0
#define PROCESS_SMELT 1
#define PROCESS_COMPRESS 2
#define PROCESS_ALLOY 3
/obj/machinery/mineral/processing_unit_console
name = "production machine console"
icon = 'icons/obj/machines/mining_machines.dmi'
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "console"
density = 1
anchored = 1
density = TRUE
anchored = TRUE
var/obj/item/weapon/card/id/inserted_id // VOREStation Edit - Inserted Id card
var/obj/machinery/mineral/processing_unit/machine = null
//var/machinedir = EAST //Dumb
var/show_all_ores = 0
var/show_all_ores = FALSE
/obj/machinery/mineral/processing_unit_console/New()
/obj/machinery/mineral/processing_unit_console/initialize()
. = ..()
src.machine = locate(/obj/machinery/mineral/processing_unit) in range(5, src)
if (machine)
machine.console = src
else
log_debug("Ore processing machine console at [src.x], [src.y], [src.z] could not find its machine!")
qdel(src)
// VOREStation Add Start
/obj/machinery/mineral/processing_unit_console/Destroy()
if(inserted_id)
inserted_id.forceMove(loc) //Prevents deconstructing from deleting whatever ID was inside it.
. = ..()
/obj/machinery/mineral/processing_unit_console/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/card/id))
if(!powered())
return
if(!inserted_id && user.unEquip(I))
I.forceMove(src)
inserted_id = I
interact(user)
return
..()
spawn(7)
//src.machine = locate(/obj/machinery/mineral/processing_unit, get_step(src, machinedir))
src.machine = locate(/obj/machinery/mineral/processing_unit) in range(5,src)
if (machine)
machine.console = src
else
world << "<span class='danger'>Warning: Ore processing machine console at [src.x], [src.y], [src.z] could not find its machine!</span>"
qdel(src)
// VOREStation Add End
/obj/machinery/mineral/processing_unit_console/attack_hand(mob/user)
add_fingerprint(user)
if(..())
return
interact(user)
/obj/machinery/mineral/processing_unit_console/interact(mob/user)
if(..())
return
if(!allowed(user))
user << "<font color='red'>Access denied.</font>"
to_chat(user, "<span class='warning'>Access denied.</span>")
return
user.set_machine(src)
var/dat = "<h1>Ore processor console</h1>"
// VOREStation Add Start
dat += "Current unclaimed points: [machine.points]<br>"
if(istype(inserted_id))
dat += "You have [inserted_id.mining_points] mining points collected. <A href='?src=\ref[src];choice=eject'>Eject ID.</A><br>"
dat += "<A href='?src=\ref[src];choice=claim'>Claim points.</A><br>"
else
dat += "No ID inserted. <A href='?src=\ref[src];choice=insert'>Insert ID.</A><br>"
// VOREStation Add End
dat += "<hr><table>"
@@ -49,13 +77,13 @@
dat += "<tr><td width = 40><b>[capitalize(O.display_name)]</b></td><td width = 30>[machine.ores_stored[ore]]</td><td width = 100>"
if(machine.ores_processing[ore])
switch(machine.ores_processing[ore])
if(0)
if(PROCESS_NONE)
dat += "<font color='red'>not processing</font>"
if(1)
if(PROCESS_SMELT)
dat += "<font color='orange'>smelting</font>"
if(2)
if(PROCESS_COMPRESS)
dat += "<font color='blue'>compressing</font>"
if(3)
if(PROCESS_ALLOY)
dat += "<font color='gray'>alloying</font>"
else
dat += "<font color='red'>not processing</font>"
@@ -80,10 +108,10 @@
if(!choice) return
switch(choice)
if("Nothing") choice = 0
if("Smelting") choice = 1
if("Compressing") choice = 2
if("Alloying") choice = 3
if("Nothing") choice = PROCESS_NONE
if("Smelting") choice = PROCESS_SMELT
if("Compressing") choice = PROCESS_COMPRESS
if("Alloying") choice = PROCESS_ALLOY
machine.ores_processing[href_list["toggle_smelting"]] = choice
@@ -95,6 +123,29 @@
show_all_ores = !show_all_ores
// VOREStation Add Start
if(href_list["choice"])
if(istype(inserted_id))
if(href_list["choice"] == "eject")
usr.put_in_hands(inserted_id)
inserted_id = null
if(href_list["choice"] == "claim")
if(access_mining_station in inserted_id.access)
inserted_id.mining_points += machine.points
machine.points = 0
else
to_chat(usr, "<span class='warning'>Required access not found.</span>")
else if(href_list["choice"] == "insert")
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I))
if(!usr.drop_item())
return 1
I.forceMove(src)
inserted_id = I
else
to_chat(usr, "<span class='warning'>No valid ID.</span>")
// VOREStation Add End
src.updateUsrDialog()
return
@@ -103,10 +154,10 @@
/obj/machinery/mineral/processing_unit
name = "material processor" //This isn't actually a goddamn furnace, we're in space and it's processing platinum and flammable phoron...
icon = 'icons/obj/machines/mining_machines.dmi'
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "furnace"
density = 1
anchored = 1
density = TRUE
anchored = TRUE
light_range = 3
var/obj/machinery/mineral/input = null
var/obj/machinery/mineral/output = null
@@ -115,17 +166,31 @@
var/list/ores_processing[0]
var/list/ores_stored[0]
var/static/list/alloy_data
var/active = 0
var/active = FALSE
// VOREStation Add Start
var/points = 0
var/static/list/ore_values = list(
"sand" = 1,
"hematite" = 1,
"carbon" = 1,
"phoron" = 15,
"silver" = 16,
"gold" = 18,
"uranium" = 30,
"diamond" = 50,
"platinum" = 40,
"mhydrogen" = 40)
// VOREStation Add End
/obj/machinery/mineral/processing_unit/New()
..()
// initialize static alloy_data list
if(!alloy_data)
alloy_data = list()
for(var/alloytype in typesof(/datum/alloy)-/datum/alloy)
alloy_data += new alloytype()
// TODO - Initializing this here is insane. Put it in global lists init or something. ~Leshana
if(!ore_data || !ore_data.len)
for(var/oretype in typesof(/ore)-/ore)
var/ore/OD = new oretype()
@@ -133,20 +198,21 @@
ores_processing[OD.name] = 0
ores_stored[OD.name] = 0
/obj/machinery/mineral/processing_unit/initialize()
. = ..()
// TODO - Eschew input/output machinery and just use dirs ~Leshana
//Locate our output and input machinery.
spawn(5)
for (var/dir in cardinal)
src.input = locate(/obj/machinery/mineral/input, get_step(src, dir))
if(src.input) break
for (var/dir in cardinal)
src.output = locate(/obj/machinery/mineral/output, get_step(src, dir))
if(src.output) break
return
for (var/dir in cardinal)
src.input = locate(/obj/machinery/mineral/input, get_step(src, dir))
if(src.input) break
for (var/dir in cardinal)
src.output = locate(/obj/machinery/mineral/output, get_step(src, dir))
if(src.output) break
return
/obj/machinery/mineral/processing_unit/process()
if (!src.output || !src.input) return
if(!src.output || !src.input) return
if(panel_open || !powered()) return // VOREStation Edit - Don't work when unpowered
var/list/tick_alloys = list()
@@ -156,6 +222,7 @@
if(!O) break
if(!isnull(ores_stored[O.material]))
ores_stored[O.material]++
points += ore_values[O.material] // VOREStation Edit - Give Points!
qdel(O)
@@ -174,7 +241,7 @@
if(!O) continue
if(ores_processing[metal] == 3 && O.alloy) //Alloying.
if(ores_processing[metal] == PROCESS_ALLOY && O.alloy) //Alloying.
for(var/datum/alloy/A in alloy_data)
@@ -190,7 +257,7 @@
for(var/needs_metal in A.requires)
//Check if we're alloying the needed metal and have it stored.
if(ores_processing[needs_metal] != 3 || ores_stored[needs_metal] < A.requires[needs_metal])
if(ores_processing[needs_metal] != PROCESS_ALLOY || ores_stored[needs_metal] < A.requires[needs_metal])
enough_metal = 0
break
@@ -207,7 +274,7 @@
for(var/i=0,i<total,i++)
new A.product(output.loc)
else if(ores_processing[metal] == 2 && O.compresses_to) //Compressing.
else if(ores_processing[metal] == PROCESS_COMPRESS && O.compresses_to) //Compressing.
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
if(can_make%2>0) can_make--
@@ -222,7 +289,7 @@
sheets+=2
new M.stack_type(output.loc)
else if(ores_processing[metal] == 1 && O.smelts_to) //Smelting.
else if(ores_processing[metal] == PROCESS_SMELT && O.smelts_to) //Smelting.
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
@@ -242,3 +309,8 @@
continue
console.updateUsrDialog()
#undef PROCESS_NONE
#undef PROCESS_SMELT
#undef PROCESS_COMPRESS
#undef PROCESS_ALLOY
+2 -2
View File
@@ -2,7 +2,7 @@
/obj/machinery/mineral/stacking_unit_console
name = "stacking machine console"
icon = 'icons/obj/machines/mining_machines.dmi'
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "console"
density = 1
anchored = 1
@@ -71,7 +71,7 @@
/obj/machinery/mineral/stacking_machine
name = "stacking machine"
icon = 'icons/obj/machines/mining_machines.dmi'
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "stacker"
density = 1
anchored = 1.0
+1 -1
View File
@@ -3,7 +3,7 @@
/obj/machinery/mineral/unloading_machine
name = "unloading machine"
icon = 'icons/obj/machines/mining_machines.dmi'
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "unloader"
density = 1
anchored = 1.0
@@ -0,0 +1,12 @@
#ifndef T_BOARD
#error T_BOARD macro is not defined but we need it!
#endif
/obj/item/weapon/circuitboard/mining_equipment_vendor
name = T_BOARD("Mining Equipment Vendor")
board_type = new /datum/frame/frame_types/machine
build_path = /obj/machinery/mineral/equipment_vendor
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 3)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/matter_bin = 3)
@@ -0,0 +1,205 @@
/**********************Mining Equipment Locker**************************/
/obj/machinery/mineral/equipment_vendor
name = "mining equipment vendor"
desc = "An equipment vendor for miners, points collected at an ore redemption machine can be spent here."
icon = 'icons/obj/machines/mining_machines_vr.dmi'
icon_state = "mining"
density = TRUE
anchored = TRUE
circuit = /obj/item/weapon/circuitboard/mining_equipment_vendor
var/icon_deny = "mining-deny"
var/obj/item/weapon/card/id/inserted_id
var/list/prize_list = list(
new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10),
new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100),
new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300),
new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125),
new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125),
new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150),
new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200),
new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900),
new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300),
// TODO new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800),
new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500),
new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 500),
// TODO new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500),
new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500),
new /datum/data/mining_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 500),
new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200),
// new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750),
new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900),
new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900),
new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200),
new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200),
//new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000),
new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000),
new /datum/data/mining_equipment("Industrial Hardsuit - Control Module", /obj/item/weapon/rig/industrial, 2000),
new /datum/data/mining_equipment("Industrial Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800),
new /datum/data/mining_equipment("Industrial Hardsuit - Drill", /obj/item/rig_module/device/drill, 2000),
new /datum/data/mining_equipment("Industrial Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000),
new /datum/data/mining_equipment("Industrial Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500),
new /datum/data/mining_equipment("Industrial Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250),
new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000),
new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500),
new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500),
new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100),
new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125),
new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 175),
new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250),
new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300),
new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000),
new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000),
new /datum/data/mining_equipment("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200),
new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000)
)
/datum/data/mining_equipment
var/equipment_name = "generic"
var/equipment_path = null
var/cost = 0
/datum/data/mining_equipment/New(name, path, cost)
src.equipment_name = name
src.equipment_path = path
src.cost = cost
/obj/machinery/power/quantumpad/initialize()
. = ..()
default_apply_parts()
/obj/machinery/mineral/equipment_vendor/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()
if(inserted_id && !powered())
visible_message("<span class='notice'>The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.</span>")
inserted_id.forceMove(get_turf(src))
/obj/machinery/mineral/equipment_vendor/update_icon()
if(panel_open)
icon_state = "[initial(icon_state)]-open"
else if(powered())
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]-off"
/obj/machinery/mineral/equipment_vendor/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user)
interact(user)
/obj/machinery/mineral/equipment_vendor/interact(mob/user)
user.set_machine(src)
var/dat
dat +="<div class='statusDisplay'>"
if(istype(inserted_id))
dat += "You have [inserted_id.mining_points] mining points collected. <A href='?src=\ref[src];choice=eject'>Eject ID.</A><br>"
else
dat += "No ID inserted. <A href='?src=\ref[src];choice=insert'>Insert ID.</A><br>"
dat += "</div>"
dat += "<br><b>Equipment point cost list:</b><BR><table border='0' width='100%'>"
for(var/datum/data/mining_equipment/prize in prize_list)
dat += "<tr><td>[prize.equipment_name]</td><td>[prize.cost]</td><td><A href='?src=\ref[src];purchase=\ref[prize]'>Purchase</A></td></tr>"
dat += "</table>"
var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 600)
popup.set_content(dat)
popup.open()
/obj/machinery/mineral/equipment_vendor/Topic(href, href_list)
if(..())
return 1
if(href_list["choice"])
if(istype(inserted_id))
if(href_list["choice"] == "eject")
to_chat(usr, "<span class='notice'>You eject the ID from [src]'s card slot.</span>")
usr.put_in_hands(inserted_id)
inserted_id = null
else if(href_list["choice"] == "insert")
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I) && !inserted_id && usr.unEquip(I))
I.forceMove(src)
inserted_id = I
interact(usr)
to_chat(usr, "<span class='notice'>You insert the ID into [src]'s card slot.</span>")
else
to_chat(usr, "<span class='warning'>No valid ID.</span>")
flick(icon_deny, src)
if(href_list["purchase"])
if(istype(inserted_id))
var/datum/data/mining_equipment/prize = locate(href_list["purchase"])
if (!prize || !(prize in prize_list))
to_chat(usr, "<span class='warning'>Error: Invalid choice!</span>")
flick(icon_deny, src)
return
if(prize.cost > inserted_id.mining_points)
to_chat(usr, "<span class='warning'>Error: Insufficent points for [prize.equipment_name]!</span>")
flick(icon_deny, src)
else
inserted_id.mining_points -= prize.cost
to_chat(usr, "<span class='notice'>[src] clanks to life briefly before vending [prize.equipment_name]!</span>")
new prize.equipment_path(drop_location())
else
to_chat(usr, "<span class='warning'>Error: Please insert a valid ID!</span>")
flick(icon_deny, src)
updateUsrDialog()
/obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, I))
updateUsrDialog()
return
if(default_part_replacement(user, I))
return
if(default_deconstruction_crowbar(user, I))
return
if(istype(I, /obj/item/mining_voucher))
if(!powered())
return
RedeemVoucher(I, user)
return
if(istype(I,/obj/item/weapon/card/id))
if(!powered())
return
else if(!inserted_id && user.unEquip(I))
I.forceMove(src)
inserted_id = I
interact(user)
return
..()
/obj/machinery/mineral/equipment_vendor/dismantle()
if(inserted_id)
inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it.
. = ..()
/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer)
var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Kinetic Accelerator", "Resonator", "Mining Drone", "Advanced Scanner", "Crusher")
if(!selection || !Adjacent(redeemer) || voucher.loc != redeemer)
return
var/drop_location = drop_location()
switch(selection)
if("Kinetic Accelerator")
new /obj/item/weapon/gun/energy/kinetic_accelerator(drop_location)
if("Resonator")
new /obj/item/resonator(drop_location)
// if("Mining Drone")
// new /obj/item/storage/box/drone_kit(drop_location)
// if("Advanced Scanner")
// new /obj/item/device/t_scanner/adv_mining_scanner(drop_location)
// if("Crusher")
// new /obj/item/twohanded/required/mining_hammer(drop_location)
qdel(voucher)
/obj/machinery/mineral/equipment_vendor/ex_act(severity, target)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if(prob(50 / severity) && severity < 3)
qdel(src)
@@ -0,0 +1,33 @@
/**********************Mining Equipment Locker Items**************************/
/**********************Mining Equipment Voucher**********************/
/obj/item/mining_voucher
name = "mining voucher"
desc = "A token to redeem a piece of equipment. Use it on a mining equipment vendor."
icon = 'icons/obj/mining_vr.dmi'
icon_state = "mining_voucher"
w_class = ITEMSIZE_TINY
/**********************Mining Point Card**********************/
/obj/item/weapon/card/mining_point_card
name = "mining point card"
desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard."
icon_state = "data"
var/points = 500
/obj/item/weapon/card/mining_point_card/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/card/id))
if(points)
var/obj/item/weapon/card/id/C = I
C.mining_points += points
to_chat(user, "<span class='info'>You transfer [points] points to [C].</span>")
points = 0
else
to_chat(user, "<span class='info'>There's no points left on [src].</span>")
..()
/obj/item/weapon/card/mining_point_card/examine(mob/user)
..(user)
to_chat(user, "There's [points] points on the card.")
+111
View File
@@ -0,0 +1,111 @@
/**********************Resonator**********************/
/obj/item/resonator
name = "resonator"
icon = 'icons/obj/mining_vr.dmi'
icon_state = "resonator"
item_state = "resonator"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
)
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3)
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in low temperature."
w_class = ITEMSIZE_NORMAL
force = 8
throwforce = 10
var/cooldown = 0
var/fieldsactive = 0
var/burst_time = 50
var/fieldlimit = 3
/obj/item/resonator/upgraded
name = "upgraded resonator"
desc = "An upgraded version of the resonator that can produce more fields at once."
icon_state = "resonator_u"
origin_tech = list(TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 3, TECH_ENGINEERING = 3)
fieldlimit = 5
/obj/item/resonator/proc/CreateResonance(var/target, var/creator)
var/turf/T = get_turf(target)
if(locate(/obj/effect/resonance) in T)
return
if(fieldsactive < fieldlimit)
playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
new /obj/effect/resonance(T, creator, burst_time)
fieldsactive++
spawn(burst_time)
fieldsactive--
/obj/item/resonator/attack_self(mob/user)
if(burst_time == 50)
burst_time = 30
to_chat(user, "<span class='info'>You set the resonator's fields to detonate after 3 seconds.</span>")
else
burst_time = 50
to_chat(user, "<span class='info'>You set the resonator's fields to detonate after 5 seconds.</span>")
/obj/item/resonator/afterattack(atom/target, mob/user, proximity_flag)
if(proximity_flag)
if(!check_allowed_items(target, 1))
return
CreateResonance(target, user)
/obj/effect/resonance
name = "resonance field"
desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures."
icon = 'icons/effects/effects.dmi'
icon_state = "shield1"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
mouse_opacity = 0
var/resonance_damage = 20
/obj/effect/resonance/initialize(mapload, var/creator = null, var/timetoburst)
. = ..()
// Start small and grow to big size as we are about to burst
transform = matrix()*0.75
animate(src, transform = matrix()*1.5, time = timetoburst)
// Queue the actual bursting
spawn(timetoburst)
if(!QDELETED(src))
burst(creator)
/obj/effect/resonance/proc/burst(var/creator = null)
var/turf/T = get_turf(src)
if(!T)
return
playsound(src, 'sound/weapons/resonator_blast.ogg', 50, 1)
// Make the collapsing effect
new /obj/effect/temp_visual/resonance_crush(T)
// Mineral turfs get drilled!
if(istype(T, /turf/simulated/mineral))
var/turf/simulated/mineral/M = T
M.GetDrilled()
qdel(src)
return
// Otherwise we damage mobs! Boost damage if low tempreature
var/datum/gas_mixture/environment = T.return_air()
if(environment.temperature < 250)
name = "strong resonance field"
resonance_damage = 50
for(var/mob/living/L in src.loc)
if(creator)
add_attack_logs(creator, L, "used a resonator field on")
to_chat(L, "<span class='danger'>\The [src] ruptured with you in it!</span>")
L.apply_damage(resonance_damage, BRUTE)
qdel(src)
/obj/effect/temp_visual/resonance_crush
icon_state = "shield1"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
duration = 4
/obj/effect/temp_visual/resonance_crush/initialize()
. = ..()
transform = matrix()*1.5
animate(src, transform = matrix()*0.1, alpha = 50, time = 4)
+255
View File
@@ -0,0 +1,255 @@
/*****************************Survival Pod********************************/
/area/survivalpod
name = "\improper Emergency Shelter"
icon_state = "away"
dynamic_lighting = TRUE
requires_power = FALSE
has_gravity = TRUE
//Survival Capsule
/obj/item/device/survivalcapsule
name = "surfluid shelter capsule"
desc = "An emergency shelter programmed into construction nanomachines. It has a license for use printed on the bottom."
icon_state = "houseball"
icon = 'icons/obj/device_alt.dmi'
w_class = ITEMSIZE_TINY
var/template_id = "shelter_alpha"
var/datum/map_template/shelter/template
var/used = FALSE
/obj/item/device/survivalcapsule/proc/get_template()
if(template)
return
template = SSmapping.shelter_templates[template_id]
if(!template)
throw EXCEPTION("Shelter template ([template_id]) not found!")
qdel(src)
/obj/item/device/survivalcapsule/Destroy()
template = null // without this, capsules would be one use. per round.
. = ..()
/obj/item/device/survivalcapsule/examine(mob/user)
. = ..()
get_template()
to_chat(user, "This capsule has the [template.name] stored.")
to_chat(user, template.description)
/obj/item/device/survivalcapsule/attack_self()
//Can't grab when capsule is New() because templates aren't loaded then
get_template()
if(!used)
loc.visible_message("<span class='warning'>\The [src] begins to shake. Stand back!</span>")
used = TRUE
sleep(5 SECONDS)
var/turf/deploy_location = get_turf(src)
var/status = template.check_deploy(deploy_location)
switch(status)
if(SHELTER_DEPLOY_BAD_AREA)
src.loc.visible_message("<span class='warning'>\The [src] will not function in this area.</span>")
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS)
var/width = template.width
var/height = template.height
src.loc.visible_message("<span class='warning'>\The [src] doesn't have room to deploy! You need to clear a [width]x[height] area!</span>")
if(status != SHELTER_DEPLOY_ALLOWED)
used = FALSE
return
var/turf/T = deploy_location
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.attach(T)
smoke.set_up(10, 0, T)
smoke.start()
sleep(4 SECONDS)
playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1)
log_and_message_admins("[key_name_admin(usr)] activated a bluespace capsule at [get_area(T)]!")
template.load(deploy_location, centered = TRUE)
qdel(src)
/obj/item/device/survivalcapsule/luxury
name = "luxury surfluid shelter capsule"
desc = "An exorbitantly expensive luxury suite programmed into construction nanomachines. There's a license for use printed on the bottom."
template_id = "shelter_beta"
//Pod objects
//Walls
/turf/simulated/shuttle/wall/voidcraft/survival
name = "survival shelter"
stripe_color = "#efbc3b"
//Doors
/obj/machinery/door/airlock/voidcraft/survival_pod
name = "survival airlock"
block_air_zones = 1
//Windows
/obj/structure/window/reinforced/survival_pod
name = "pod window"
icon = 'icons/obj/survival_pod.dmi'
icon_state = "pwindow"
basestate = "pwindow"
//The windows have diagonal versions, and will never be a full window
/obj/structure/window/reinforced/survival_pod/is_full_window()
return FALSE
/obj/structure/window/reinforced/survival_pod/update_icon()
icon_state = basestate
//Windoor
/obj/machinery/door/window/survival_pod
icon = 'icons/obj/survival_pod.dmi'
icon_state = "windoor"
base_state = "windoor"
//Table
/obj/structure/table/survival_pod
name = "table"
icon = 'icons/obj/survival_pod.dmi'
icon_state = "table"
/obj/structure/table/survival_pod/update_icon()
icon_state = "table"
//Sleeper
/obj/machinery/sleeper/survival_pod
icon = 'icons/obj/survival_pod.dmi'
icon_state = "sleeper"
stasis_level = 100 //Just one setting
/obj/machinery/sleeper/survival_pod/update_icon()
if(occupant)
add_overlay("sleeper_cover")
else
cut_overlays()
//Computer
/obj/item/device/gps/computer
name = "pod computer"
icon_state = "pod_computer"
icon = 'icons/obj/survival_pod_comp.dmi'
anchored = TRUE
density = TRUE
pixel_y = -32
/obj/item/device/gps/computer/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/weapon/wrench))
user.visible_message("<span class='warning'>[user] disassembles [src].</span>",
"<span class='notice'>You start to disassemble [src]...</span>", "You hear clanking and banging noises.")
if(do_after(user,4 SECONDS,src))
new /obj/item/device/gps(loc)
qdel(src)
return TRUE
return FALSE
/obj/item/device/gps/computer/attack_hand(mob/user)
attack_self(user)
//Bed
/obj/structure/bed/pod
icon = 'icons/obj/survival_pod.dmi'
icon_state = "bed"
//Survival Storage Unit
/obj/machinery/smartfridge/survival_pod
name = "survival pod storage"
desc = "A heated storage unit."
icon_state = "donkvendor"
icon = 'icons/obj/survival_pod_vend.dmi'
icon_on = "donkvendor"
icon_off = "donkvendor"
light_range = 5
light_power = 1.2
light_color = "#DDFFD3"
pixel_y = -4
max_n_of_items = 10
var/empty = FALSE
/obj/machinery/smartfridge/survival_pod/initialize(mapload)
. = ..()
if(empty)
return
for(var/i in 1 to 5)
var/obj/item/weapon/reagent_containers/food/snacks/liquidfood/W = new(src)
stock(W)
if(prob(50))
var/obj/item/weapon/storage/pill_bottle/dice/D = new(src)
stock(D)
else
var/obj/item/device/violin/V = new(src)
stock(V)
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
return isitem(O)
/obj/machinery/smartfridge/survival_pod/empty
name = "dusty survival pod storage"
desc = "A heated storage unit. This one's seen better days."
empty = TRUE
//Fans
/obj/structure/fans
icon = 'icons/obj/survival_pod.dmi'
icon_state = "fans"
name = "environmental regulation system"
desc = "A large machine releasing a constant gust of air."
anchored = TRUE
density = TRUE
var/buildstacktype = /obj/item/stack/material/steel
var/buildstackamount = 5
/obj/structure/fans/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(!height)
return FALSE
return TRUE
/obj/structure/fans/proc/deconstruct()
new buildstacktype(loc,buildstackamount)
qdel(src)
/obj/structure/fans/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/weapon/wrench))
user.visible_message("<span class='warning'>[user] disassembles [src].</span>",
"<span class='notice'>You start to disassemble [src]...</span>", "You hear clanking and banging noises.")
if(do_after(user,4 SECONDS,src))
deconstruct()
return TRUE
return TRUE
/obj/structure/fans/tiny
name = "tiny fan"
desc = "A tiny fan, releasing a thin gust of air."
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
density = FALSE
icon_state = "fan_tiny"
buildstackamount = 2
//Signs
/obj/structure/sign/mining
name = "nanotrasen mining corps sign"
desc = "A sign of relief for weary miners, and a warning for would-be competitors to Nanotrasen's mining claims."
icon = 'icons/obj/survival_pod.dmi'
icon_state = "ntpod"
/obj/structure/sign/mining/survival
name = "shelter sign"
desc = "A high visibility sign designating a safe shelter."
icon = 'icons/obj/survival_pod.dmi'
icon_state = "survival"
//Fluff
/obj/structure/tubes
icon_state = "tubes"
icon = 'icons/obj/survival_pod.dmi'
name = "tubes"
anchored = TRUE
layer = BELOW_MOB_LAYER
density = FALSE
+60
View File
@@ -0,0 +1,60 @@
/datum/map_template/shelter
var/shelter_id
var/description
var/blacklisted_turfs
var/whitelisted_turfs
var/banned_areas
var/banned_objects
/datum/map_template/shelter/New()
. = ..()
blacklisted_turfs = typecacheof(/turf/unsimulated)
whitelisted_turfs = list()
banned_areas = typecacheof(/area/shuttle)
banned_objects = list()
/datum/map_template/shelter/proc/check_deploy(turf/deploy_location)
var/affected = get_affected_turfs(deploy_location, centered=TRUE)
for(var/turf/T in affected)
var/area/A = get_area(T)
if(is_type_in_typecache(A, banned_areas))
return SHELTER_DEPLOY_BAD_AREA
var/banned = is_type_in_typecache(T, blacklisted_turfs)
var/permitted = is_type_in_typecache(T, whitelisted_turfs)
if(banned && !permitted)
return SHELTER_DEPLOY_BAD_TURFS
for(var/obj/O in T)
if((O.density && O.anchored) || is_type_in_typecache(O, banned_objects))
return SHELTER_DEPLOY_ANCHORED_OBJECTS
return SHELTER_DEPLOY_ALLOWED
/datum/map_template/shelter/alpha
name = "Shelter Alpha"
shelter_id = "shelter_alpha"
description = "A cosy self-contained pressurized shelter, with \
built-in navigation, entertainment, medical facilities and a \
sleeping area! Order now, and we'll throw in a TINY FAN, \
absolutely free!"
mappath = "maps/submaps/shelters/shelter_1.dmm"
/datum/map_template/shelter/alpha/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/simulated/mineral)
banned_objects = list()
/datum/map_template/shelter/beta
name = "Shelter Beta"
shelter_id = "shelter_beta"
description = "An extremely luxurious shelter, containing all \
the amenities of home, including carpeted floors, hot and cold \
running water, a gourmet three course meal, cooking facilities, \
and a deluxe companion to keep you from getting lonely during \
an ash storm."
mappath = "maps/submaps/shelters/shelter_2.dmm"
/datum/map_template/shelter/beta/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/simulated/mineral)
banned_objects = list()
+202 -238
View File
@@ -1,22 +1,6 @@
/mob/living/carbon/human/examine(mob/user)
var/skipgloves = 0
var/skipsuitstorage = 0
var/skipjumpsuit = 0
var/skipshoes = 0
var/skipmask = 0
var/skiptie = 0
var/skipholster = 0
var/skipears = 0
var/skipeyes = 0
var/skipface = 0
var/skipchest = 0
var/skipgroin = 0
var/skiphands = 0
var/skiplegs = 0
var/skiparms = 0
var/skipfeet = 0
var/skip_gear = 0
var/skip_body = 0
if(alpha <= 50)
src.loc.examine(user)
@@ -26,97 +10,101 @@
//exosuits and helmets obscure our view and stuff.
if(wear_suit)
skipsuitstorage |= wear_suit.flags_inv & HIDESUITSTORAGE
if(wear_suit.flags_inv & HIDESUITSTORAGE)
skip_gear |= EXAMINE_SKIPSUITSTORAGE
if(wear_suit.flags_inv & HIDEJUMPSUIT)
skiparms |= 1
skiplegs |= 1
skipchest |= 1
skipgroin |= 1
skipjumpsuit |= 1
skiptie |= 1
skipholster |= 1
skip_body |= EXAMINE_SKIPARMS | EXAMINE_SKIPLEGS | EXAMINE_SKIPBODY | EXAMINE_SKIPGROIN
skip_gear |= EXAMINE_SKIPJUMPSUIT | EXAMINE_SKIPTIE | EXAMINE_SKIPHOLSTER
else if(wear_suit.flags_inv & HIDETIE)
skiptie |= 1
skipholster |= 1
skip_gear |= EXAMINE_SKIPTIE | EXAMINE_SKIPHOLSTER
else if(wear_suit.flags_inv & HIDEHOLSTER)
skipholster |= 1
skip_gear |= EXAMINE_SKIPHOLSTER
if(wear_suit.flags_inv & HIDESHOES)
skipshoes |= 1
skipfeet |= 1
skip_gear |= EXAMINE_SKIPSHOES
skip_body |= EXAMINE_SKIPFEET
if(wear_suit.flags_inv & HIDEGLOVES)
skipgloves |= 1
skiphands |= 1
skip_gear |= EXAMINE_SKIPGLOVES
skip_body |= EXAMINE_SKIPHANDS
if(w_uniform)
skiplegs |= w_uniform.body_parts_covered & LEGS
skiparms |= w_uniform.body_parts_covered & ARMS
skipchest |= w_uniform.body_parts_covered & UPPER_TORSO
skipgroin |= w_uniform.body_parts_covered & LOWER_TORSO
if(w_uniform.body_parts_covered & LEGS)
skip_body |= EXAMINE_SKIPLEGS
if(w_uniform.body_parts_covered & ARMS)
skip_body |= EXAMINE_SKIPARMS
if(w_uniform.body_parts_covered & UPPER_TORSO)
skip_body |= EXAMINE_SKIPBODY
if(w_uniform.body_parts_covered & LOWER_TORSO)
skip_body |= EXAMINE_SKIPGROIN
if(gloves)
skiphands |= gloves.body_parts_covered & HANDS
if(gloves && (gloves.body_parts_covered & HANDS))
skip_body |= EXAMINE_SKIPHANDS
if(shoes)
skipfeet |= shoes.body_parts_covered & FEET
if(shoes && (shoes.body_parts_covered & FEET))
skip_body |= EXAMINE_SKIPFEET
if(head)
skipmask |= head.flags_inv & HIDEMASK
skipeyes |= head.flags_inv & HIDEEYES
skipears |= head.flags_inv & HIDEEARS
skipface |= head.flags_inv & HIDEFACE
if(head.flags_inv & HIDEMASK)
skip_gear |= EXAMINE_SKIPMASK
if(head.flags_inv & HIDEEYES)
skip_gear |= EXAMINE_SKIPEYEWEAR
skip_body |= EXAMINE_SKIPEYES
if(head.flags_inv & HIDEEARS)
skip_gear |= EXAMINE_SKIPEARS
if(head.flags_inv & HIDEFACE)
skip_body |= EXAMINE_SKIPFACE
if(wear_mask)
skipface |= wear_mask.flags_inv & HIDEFACE
if(wear_mask && (wear_mask.flags_inv & HIDEFACE))
skip_body |= EXAMINE_SKIPFACE
//This is what hides what
var/list/hidden = list(
BP_GROIN = skipgroin,
BP_TORSO = skipchest,
BP_HEAD = skipface,
BP_L_ARM = skiparms,
BP_R_ARM = skiparms,
BP_L_HAND= skiphands,
BP_R_HAND= skiphands,
BP_L_FOOT= skipfeet,
BP_R_FOOT= skipfeet,
BP_L_LEG = skiplegs,
BP_R_LEG = skiplegs)
BP_GROIN = skip_body & EXAMINE_SKIPGROIN,
BP_TORSO = skip_body & EXAMINE_SKIPBODY,
BP_HEAD = skip_body & EXAMINE_SKIPHEAD,
BP_L_ARM = skip_body & EXAMINE_SKIPARMS,
BP_R_ARM = skip_body & EXAMINE_SKIPARMS,
BP_L_HAND= skip_body & EXAMINE_SKIPHANDS,
BP_R_HAND= skip_body & EXAMINE_SKIPHANDS,
BP_L_FOOT= skip_body & EXAMINE_SKIPFEET,
BP_R_FOOT= skip_body & EXAMINE_SKIPFEET,
BP_L_LEG = skip_body & EXAMINE_SKIPLEGS,
BP_R_LEG = skip_body & EXAMINE_SKIPLEGS)
var/list/msg = list("<span class='info'>*---------*\nThis is ")
var/list/msg = list("<span class='info'>*---------*<br>This is ")
var/datum/gender/T = gender_datums[get_visible_gender()]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
else if(species && species.ambiguous_genders)
var/can_detect_gender = FALSE
if(isobserver(user)) // Ghosts are all knowing.
can_detect_gender = TRUE
if(issilicon(user)) // Borgs are too because science.
can_detect_gender = TRUE
else if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.species && istype(species, H.species))
can_detect_gender = TRUE
if(!can_detect_gender)
T = gender_datums[PLURAL] // Species with ambiguous_genders will not show their true gender upon examine if the examiner is not also the same species.
else
if(icon)
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
if(!T)
// Just in case someone VVs the gender to something strange. It'll runtime anyway when it hits usages, better to CRASH() now with a helpful message.
CRASH("Gender datum was null; key was '[(skipjumpsuit && skipface) ? PLURAL : gender]'")
if(icon)
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
msg += "<EM>[src.name]</EM>"
if(!(skipjumpsuit && skipface))
if(src.custom_species)
var/datum/gender/T = gender_datums[get_visible_gender()]
if((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
else if(species && species.ambiguous_genders)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.species && !istype(species, H.species))
T = gender_datums[PLURAL]// Species with ambiguous_genders will not show their true gender upon examine if the examiner is not also the same species.
if(!(issilicon(user) || isobserver(user))) // Ghosts and borgs are all knowing
T = gender_datums[PLURAL]
if(!T)
// Just in case someone VVs the gender to something strange. It'll runtime anyway when it hits usages, better to CRASH() now with a helpful message.
CRASH("Gender datum was null; key was '[((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)) ? PLURAL : gender]'")
if(!((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)))
//VOREStation Add Start
if(custom_species)
msg += ", a <b>[src.custom_species]</b>"
else if(looks_synth)
//VOREStation Add End
var/use_gender = "a synthetic"
if(gender == MALE)
use_gender = "an android"
@@ -130,37 +118,41 @@
var/extra_species_text = species.get_additional_examine_text(src)
if(extra_species_text)
msg += "[extra_species_text]<br>"
msg += "[extra_species_text]"
msg += "<br>"
//uniform
if(w_uniform && !skipjumpsuit && w_uniform.show_examine)
if(w_uniform && !(skip_gear & EXAMINE_SKIPJUMPSUIT) && w_uniform.show_examine)
//Ties
var/tie_msg
if(istype(w_uniform,/obj/item/clothing/under) && !skiptie)
if(istype(w_uniform,/obj/item/clothing/under) && !(skip_gear & EXAMINE_SKIPTIE))
var/obj/item/clothing/under/U = w_uniform
if(U.accessories.len)
if(skipholster)
var/list/accessories_visible = new/list() //please let this fix the stupid fucking runtimes
var/list/accessories_visible = list() //please let this fix the stupid fucking runtimes
if(skip_gear & EXAMINE_SKIPHOLSTER)
for(var/obj/item/clothing/accessory/A in U.accessories)
if(A.show_examine && !istype(A, /obj/item/clothing/accessory/holster)) // If we're supposed to skip holsters, actually skip them
accessories_visible.Add(A)
else
for(var/obj/item/clothing/accessory/A in U.accessories)
if(A.concealed_holster == 0 && A.show_examine)
accessories_visible.Add(A)
if(accessories_visible.len)
tie_msg += ". Attached to it is [english_list(accessories_visible)]"
else tie_msg += ". Attached to it is [english_list(U.accessories)]"
if(accessories_visible.len)
tie_msg += " Attached to it is [english_list(accessories_visible)]."
if(w_uniform.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [w_uniform.name]![tie_msg]</span><br>"
else
msg += "[T.He] [T.is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
msg += "[T.He] [T.is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].<br>"
//head
if(head && head.show_examine)
if(head && !(skip_gear & EXAMINE_SKIPHELMET) && head.show_examine)
if(head.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [head.name] on [T.his] head!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [head.name] on [T.his] head!</span><br>"
else
msg += "[T.He] [T.is] wearing \icon[head] \a [head] on [T.his] head.\n"
msg += "[T.He] [T.is] wearing \icon[head] \a [head] on [T.his] head.<br>"
//suit/armour
if(wear_suit)
@@ -168,102 +160,102 @@
if(istype(wear_suit,/obj/item/clothing/suit))
var/obj/item/clothing/suit/U = wear_suit
if(U.accessories.len)
tie_msg += ". Attached to it is [english_list(U.accessories)]"
tie_msg += " Attached to it is [english_list(U.accessories)]."
if(wear_suit.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_suit.name][tie_msg]!</span><br>"
else
msg += "[T.He] [T.is] wearing \icon[wear_suit] \a [wear_suit][tie_msg].\n"
msg += "[T.He] [T.is] wearing \icon[wear_suit] \a [wear_suit].[tie_msg]<br>"
//suit/armour storage
if(s_store && !skipsuitstorage && s_store.show_examine)
if(s_store && !(skip_gear & EXAMINE_SKIPSUITSTORAGE) && s_store.show_examine)
if(s_store.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!</span><br>"
else
msg += "[T.He] [T.is] carrying \icon[s_store] \a [s_store] on [T.his] [wear_suit.name].\n"
msg += "[T.He] [T.is] carrying \icon[s_store] \a [s_store] on [T.his] [wear_suit.name].<br>"
//back
if(back && back.show_examine)
if(back && !(skip_gear & EXAMINE_SKIPBACKPACK) && back.show_examine)
if(back.blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [back] on [T.his] back.</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [back] on [T.his] back.</span><br>"
else
msg += "[T.He] [T.has] \icon[back] \a [back] on [T.his] back.\n"
msg += "[T.He] [T.has] \icon[back] \a [back] on [T.his] back.<br>"
//left hand
if(l_hand && l_hand.show_examine)
if(l_hand.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!</span><br>"
else
msg += "[T.He] [T.is] holding \icon[l_hand] \a [l_hand] in [T.his] left hand.\n"
msg += "[T.He] [T.is] holding \icon[l_hand] \a [l_hand] in [T.his] left hand.<br>"
//right hand
if(r_hand && r_hand.show_examine)
if(r_hand.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!</span><br>"
else
msg += "[T.He] [T.is] holding \icon[r_hand] \a [r_hand] in [T.his] right hand.\n"
msg += "[T.He] [T.is] holding \icon[r_hand] \a [r_hand] in [T.his] right hand.<br>"
//gloves
if(gloves && !skipgloves && gloves.show_examine)
if(gloves && !(skip_gear & EXAMINE_SKIPGLOVES) && gloves.show_examine)
if(gloves.blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!</span><br>"
else
msg += "[T.He] [T.has] \icon[gloves] \a [gloves] on [T.his] hands.\n"
else if(blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!</span>\n"
msg += "[T.He] [T.has] \icon[gloves] \a [gloves] on [T.his] hands.<br>"
else if(blood_DNA && !(skip_body & EXAMINE_SKIPHANDS))
msg += "<span class='warning'>[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!</span><br>"
//handcuffed?
if(handcuffed && handcuffed.show_examine)
if(istype(handcuffed, /obj/item/weapon/handcuffs/cable))
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] restrained with cable!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] restrained with cable!</span><br>"
else
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] handcuffed!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] handcuffed!</span><br>"
//buckled
if(buckled)
msg += "<span class='warning'>[T.He] [T.is] \icon[buckled] buckled to [buckled]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] \icon[buckled] buckled to [buckled]!</span><br>"
//belt
if(belt && belt.show_examine)
if(belt && !(skip_gear & EXAMINE_SKIPBELT) && belt.show_examine)
if(belt.blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!</span><br>"
else
msg += "[T.He] [T.has] \icon[belt] \a [belt] about [T.his] waist.\n"
msg += "[T.He] [T.has] \icon[belt] \a [belt] about [T.his] waist.<br>"
//shoes
if(shoes && !skipshoes && shoes.show_examine)
if(shoes && !(skip_gear & EXAMINE_SKIPSHOES) && shoes.show_examine)
if(shoes.blood_DNA)
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!</span><br>"
else
msg += "[T.He] [T.is] wearing \icon[shoes] \a [shoes] on [T.his] feet.\n"
else if(feet_blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] [(feet_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained feet!</span>\n"
msg += "[T.He] [T.is] wearing \icon[shoes] \a [shoes] on [T.his] feet.<br>"
else if(feet_blood_DNA && !(skip_body & EXAMINE_SKIPHANDS))
msg += "<span class='warning'>[T.He] [T.has] [(feet_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained feet!</span><br>"
//mask
if(wear_mask && !skipmask && wear_mask.show_examine)
if(wear_mask && !(skip_gear & EXAMINE_SKIPMASK) && wear_mask.show_examine)
var/descriptor = "on [T.his] face"
if(istype(wear_mask, /obj/item/weapon/grenade) && check_has_mouth())
descriptor = "in [T.his] mouth"
if(wear_mask.blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!</span><br>"
else
msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] [descriptor].\n"
msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] [descriptor].<br>"
//eyes
if(glasses && !skipeyes && glasses.show_examine)
if(glasses && !(skip_gear & EXAMINE_SKIPEYEWEAR) && glasses.show_examine)
if(glasses.blood_DNA)
msg += "<span class='warning'>[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!</span><br>"
else
msg += "[T.He] [T.has] \icon[glasses] \a [glasses] covering [T.his] eyes.\n"
msg += "[T.He] [T.has] \icon[glasses] \a [glasses] covering [T.his] eyes.<br>"
//left ear
if(l_ear && !skipears && l_ear.show_examine)
msg += "[T.He] [T.has] \icon[l_ear] \a [l_ear] on [T.his] left ear.\n"
if(l_ear && !(skip_gear & EXAMINE_SKIPEARS) && l_ear.show_examine)
msg += "[T.He] [T.has] \icon[l_ear] \a [l_ear] on [T.his] left ear.<br>"
//right ear
if(r_ear && !skipears && r_ear.show_examine)
msg += "[T.He] [T.has] \icon[r_ear] \a [r_ear] on [T.his] right ear.\n"
if(r_ear && !(skip_gear & EXAMINE_SKIPEARS) && r_ear.show_examine)
msg += "[T.He] [T.has] \icon[r_ear] \a [r_ear] on [T.his] right ear.<br>"
//ID
if(wear_id && wear_id.show_examine)
@@ -275,27 +267,27 @@
var/obj/item/weapon/card/id/idcard = wear_id
id = idcard.registered_name
if(id && (id != real_name) && (get_dist(src, usr) <= 1) && prob(10))
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span><br>"
else*/
msg += "[T.He] [T.is] wearing \icon[wear_id] \a [wear_id].\n"
msg += "[T.He] [T.is] wearing \icon[wear_id] \a [wear_id].<br>"
//Jitters
if(is_jittery)
if(jitteriness >= 300)
msg += "<span class='warning'><B>[T.He] [T.is] convulsing violently!</B></span>\n"
msg += "<span class='warning'><B>[T.He] [T.is] convulsing violently!</B></span><br>"
else if(jitteriness >= 200)
msg += "<span class='warning'>[T.He] [T.is] extremely jittery.</span>\n"
msg += "<span class='warning'>[T.He] [T.is] extremely jittery.</span><br>"
else if(jitteriness >= 100)
msg += "<span class='warning'>[T.He] [T.is] twitching ever so slightly.</span>\n"
msg += "<span class='warning'>[T.He] [T.is] twitching ever so slightly.</span><br>"
//splints
for(var/organ in BP_ALL)
var/obj/item/organ/external/o = get_organ(organ)
if(o && o.splinted && o.splinted.loc == o)
msg += "<span class='warning'>[T.He] [T.has] \a [o.splinted] on [T.his] [o.name]!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \a [o.splinted] on [T.his] [o.name]!</span><br>"
if(suiciding)
msg += "<span class='warning'>[T.He] appears to have commited suicide... there is no hope of recovery.</span>\n"
msg += "<span class='warning'>[T.He] appears to have commited suicide... there is no hope of recovery.</span><br>"
msg += attempt_vr(src,"examine_weight",args) //VOREStation Code
msg += attempt_vr(src,"examine_nutrition",args) //VOREStation Code
@@ -305,56 +297,39 @@
msg += attempt_vr(src,"examine_nif",args) //VOREStation Code
if(mSmallsize in mutations)
msg += "[T.He] [T.is] small halfling!\n"
msg += "[T.He] [T.is] very short!<br>"
var/distance = get_dist(usr,src)
if(istype(usr, /mob/observer/dead) || usr.stat == 2) // ghosts can see anything
distance = 1
if (src.stat)
msg += "<span class='warning'>[T.He] [T.is]n't responding to anything around [T.him] and seems to be asleep.</span>\n"
if((stat == 2 || src.losebreath) && distance <= 3)
msg += "<span class='warning'>[T.He] [T.does] not appear to be breathing.</span>\n"
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
msg += "<span class='warning'>[T.He] [T.is]n't responding to anything around [T.him] and seems to be asleep.</span><br>"
if((stat == 2 || src.losebreath) && get_dist(user, src) <= 3)
msg += "<span class='warning'>[T.He] [T.does] not appear to be breathing.</span><br>"
if(istype(user, /mob/living/carbon/human) && !user.stat && Adjacent(user))
user.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(isobserver(user) || (Adjacent(user) && !user.stat)) // If you're a corpse then you can't exactly check their pulse, but ghosts can see anything
if(pulse == PULSE_NONE)
usr << "<span class='deadsay'>[T.He] [T.has] no pulse[src.client ? "" : " and [T.his] soul has departed"]...</span>"
to_chat(user, "<span class='deadsay'>[T.He] [T.has] no pulse[src.client ? "" : " and [T.his] soul has departed"]...</span>")
else
usr << "<span class='deadsay'>[T.He] [T.has] a pulse!</span>"
to_chat(user, "<span class='deadsay'>[T.He] [T.has] a pulse!</span>")
if(fire_stacks)
msg += "[T.He] [T.is] covered in some liquid.\n"
msg += "[T.He] [T.is] covered in some liquid.<br>"
if(on_fire)
msg += "<span class='warning'>[T.He] [T.is] on fire!.</span>\n"
msg += "<span class='warning'>"
/*
if(nutrition < 100)
msg += "[T.He] [T.is] severely malnourished.\n"
else if(nutrition >= 500)
/*if(usr.nutrition < 100)
msg += "[T.He] [T.is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
else*/
msg += "[T.He] [T.is] quite chubby.\n"
*/
msg += "</span>"
msg += "<span class='warning'>[T.He] [T.is] on fire!.</span><br>"
var/ssd_msg = species.get_ssd(src)
if(stat != DEAD)
if(ssd_msg && (!should_have_organ("brain") || has_brain()))
if(!key)
msg += "<span class='deadsay'>[T.He] [T.is] [ssd_msg]. It doesn't look like [T.he] [T.is] waking up anytime soon.</span>\n"
else if(!client)
msg += "<span class='deadsay'>[T.He] [T.is] [ssd_msg].</span>\n"
if(client && ((client.inactivity / 10) / 60 > 10)) //10 Minutes
msg += "\[Inactive for [round((client.inactivity/10)/60)] minutes\]\n"
else if(disconnect_time)
msg += "\[Disconnected/ghosted [round(((world.realtime - disconnect_time)/10)/60)] minutes ago\]\n"
if(ssd_msg && (!should_have_organ("brain") || has_brain()) && stat != DEAD)
if(!key)
msg += "<span class='deadsay'>[T.He] [T.is] [ssd_msg]. It doesn't look like [T.he] [T.is] waking up anytime soon.</span><br>"
else if(!client)
msg += "<span class='deadsay'>[T.He] [T.is] [ssd_msg].</span><br>"
//VOREStation Add Start
if(client && ((client.inactivity / 10) / 60 > 10)) //10 Minutes
msg += "\[Inactive for [round((client.inactivity/10)/60)] minutes\]\n"
else if(disconnect_time)
msg += "\[Disconnected/ghosted [round(((world.realtime - disconnect_time)/10)/60)] minutes ago\]\n"
//VOREStation Add End
var/list/wound_flavor_text = list()
var/list/is_bleeding = list()
var/applying_pressure = ""
@@ -366,9 +341,9 @@
var/obj/item/organ/external/E = organs_by_name[organ_tag]
if(!E)
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [organ_descriptor].</b></span>\n"
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [organ_descriptor].</b></span><br>"
else if(E.is_stump())
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.has] a stump where [T.his] [organ_descriptor] should be.</b></span>\n"
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.has] a stump where [T.his] [organ_descriptor] should be.</b></span><br>"
else
continue
@@ -377,13 +352,14 @@
if((temp.organ_tag in hidden) && hidden[temp.organ_tag])
continue //Organ is hidden, don't talk about it
if(temp.status & ORGAN_DESTROYED)
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [temp.name].</b></span>\n"
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [temp.name].</b></span><br>"
continue
if(!looks_synth && temp.robotic == ORGAN_ROBOT)
if(!(temp.brute_dam + temp.burn_dam))
wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a [temp.name].\n"
wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a [temp.name].<br>"
else
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] a [temp.name] with [temp.get_wounds_desc()]!</span>\n"
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] a [temp.name] with [temp.get_wounds_desc()]!</span><br>"
continue
else if(temp.wounds.len > 0 || temp.open)
if(temp.is_stump() && temp.parent_organ && organs_by_name[temp.parent_organ])
@@ -395,7 +371,7 @@
wound_flavor_text["[temp.name]"] = ""
if(temp.dislocated == 2)
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.joint] is dislocated!</span><br>"
if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
if(temp.brute_dam > temp.min_broken_damage || (temp.status & (ORGAN_BROKEN | ORGAN_MUTATED)))
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.name] is dented and swollen!</span><br>"
if(temp.germ_level > INFECTION_LEVEL_TWO && !(temp.status & ORGAN_DEAD))
@@ -403,8 +379,8 @@
else if(temp.status & ORGAN_DEAD)
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.name] looks rotten!</span><br>"
if(!wound_flavor_text["[temp.name]"] && (temp.status & ORGAN_BLEEDING))
is_bleeding["[temp.name]"] = "<span class='danger'>[T.His] [temp.name] is bleeding!</span><br>"
if(temp.status & ORGAN_BLEEDING)
is_bleeding["[temp.name]"] += "<span class='danger'>[T.His] [temp.name] is bleeding!</span><br>"
if(temp.applied_pressure == src)
applying_pressure = "<span class='info'>[T.He] is applying pressure to [T.his] [temp.name].</span><br>"
@@ -414,58 +390,51 @@
for(var/limb in is_bleeding)
msg += is_bleeding[limb]
for(var/implant in get_visible_implants(0))
msg += "<span class='danger'>[src] [T.has] \a [implant] sticking out of [T.his] flesh!</span>\n"
msg += "<span class='danger'>[src] [T.has] \a [implant] sticking out of [T.his] flesh!</span><br>"
if(digitalcamo)
msg += "[T.He] [T.is] repulsively uncanny!\n"
msg += "[T.He] [T.is] repulsively uncanny!<br>"
if(hasHUD(usr,"security"))
var/perpname = "wot"
if(hasHUD(user,"security"))
var/perpname = name
var/criminal = "None"
if(wear_id)
var/obj/item/weapon/card/id/I = wear_id.GetID()
if(I)
if(istype(wear_id, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/I = wear_id
perpname = I.registered_name
else
perpname = name
else
perpname = name
else if(istype(wear_id, /obj/item/device/pda))
var/obj/item/device/pda/P = wear_id
perpname = P.owner
if(perpname)
for (var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.security)
if(R.fields["id"] == E.fields["id"])
criminal = R.fields["criminal"]
for (var/datum/data/record/R in data_core.security)
if(R.fields["name"] == perpname)
criminal = R.fields["criminal"]
msg += "<span class = 'deptradio'>Criminal status:</span> <a href='?src=\ref[src];criminal=1'>\[[criminal]\]</a>\n"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=\ref[src];secrecord=`'>\[View\]</a> <a href='?src=\ref[src];secrecordadd=`'>\[Add comment\]</a>\n"
msg += "<span class = 'deptradio'>Criminal status:</span> <a href='?src=\ref[src];criminal=1'>\[[criminal]\]</a><br>"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=\ref[src];secrecord=`'>\[View\]</a> <a href='?src=\ref[src];secrecordadd=`'>\[Add comment\]</a><br>"
if(hasHUD(usr,"medical"))
var/perpname = "wot"
if(hasHUD(user,"medical"))
var/perpname = name
var/medical = "None"
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
if(istype(wear_id, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/I = wear_id
perpname = I.registered_name
else if(istype(wear_id, /obj/item/device/pda))
var/obj/item/device/pda/P = wear_id
perpname = P.owner
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.general)
if (R.fields["id"] == E.fields["id"])
medical = R.fields["p_stat"]
for (var/datum/data/record/R in data_core.medical)
if (R.fields["name"] == perpname)
medical = R.fields["p_stat"]
msg += "<span class = 'deptradio'>Physical status:</span> <a href='?src=\ref[src];medical=1'>\[[medical]\]</a>\n"
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=\ref[src];medrecord=`'>\[View\]</a> <a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a>\n"
msg += "<span class = 'deptradio'>Physical status:</span> <a href='?src=\ref[src];medical=1'>\[[medical]\]</a><br>"
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=\ref[src];medrecord=`'>\[View\]</a> <a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a><br>"
if(print_flavor_text())
msg += "[print_flavor_text()]\n"
msg += "[print_flavor_text()]<br>"
// VOREStation Start
if(ooc_notes)
@@ -473,12 +442,12 @@
// VOREStation End
msg += "*---------*</span><br>"
msg += applying_pressure
if (pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
if(pose)
if(!findtext(pose, regex("\[.?!]$"))) // Will be zero if the last character is not a member of [.?!]
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "[T.He] [pose]"
user << jointext(msg, null)
to_chat(user, jointext(msg, null))
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
/proc/hasHUD(mob/M as mob, hudtype)
@@ -490,8 +459,6 @@
return istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud)
if("medical")
return istype(H.glasses, /obj/item/clothing/glasses/hud/health)
else
return 0
else if(istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = M
switch(hudtype)
@@ -499,7 +466,4 @@
return R.hudmode == "Security"
if("medical")
return R.hudmode == "Medical"
else
return 0
else
return 0
return 0
@@ -13,3 +13,4 @@
name = "Pun Pun"
real_name = name
w_uniform = new /obj/item/clothing/under/punpun(src)
regenerate_icons()
@@ -5,84 +5,84 @@
/datum/species
// Descriptors and strings.
var/name // Species name.
var/name_plural // Pluralized name (since "[name]s" is not always valid)
var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen.
var/name // Species name.
var/name_plural // Pluralized name (since "[name]s" is not always valid)
var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen.
// Icon/appearance vars.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/speech_bubble_appearance = "normal" // Part of icon_state to use for speech bubbles when talking. See talk.dmi for available icons.
var/fire_icon_state = "humanoid" // The icon_state used inside OnFire.dmi for when on fire.
var/suit_storage_icon = 'icons/mob/belt_mirror.dmi' // Icons used for worn items in suit storage slot.
var/speech_bubble_appearance = "normal" // Part of icon_state to use for speech bubbles when talking. See talk.dmi for available icons.
var/fire_icon_state = "humanoid" // The icon_state used inside OnFire.dmi for when on fire.
var/suit_storage_icon = 'icons/mob/belt_mirror.dmi' // Icons used for worn items in suit storage slot.
// Damage overlay and masks.
var/damage_overlays = 'icons/mob/human_races/masks/dam_human.dmi'
var/damage_mask = 'icons/mob/human_races/masks/dam_mask_human.dmi'
var/blood_mask = 'icons/mob/human_races/masks/blood_human.dmi'
var/prone_icon // If set, draws this from icobase when mob is prone.
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
var/base_color // Used by changelings. Should also be used for icon previews.
var/prone_icon // If set, draws this from icobase when mob is prone.
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
var/base_color // Used by changelings. Should also be used for icon previews.
var/tail // Name of tail state in species effects icon file.
var/tail_animation // If set, the icon to obtain tail animation states from.
var/tail // Name of tail state in species effects icon file.
var/tail_animation // If set, the icon to obtain tail animation states from.
var/tail_hair
var/icon_scale = 1 // Makes the icon larger/smaller.
var/icon_scale = 1 // Makes the icon larger/smaller.
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/mob_size = MOB_MEDIUM
var/show_ssd = "fast asleep"
var/virus_immune
var/short_sighted // Permanent weldervision.
var/blood_volume = 560 // Initial blood volume.
var/bloodloss_rate = 1 // Multiplier for how fast a species bleeds out. Higher = Faster
var/hunger_factor = 0.05 // Multiplier for hunger.
var/active_regen_mult = 1 // Multiplier for 'Regenerate' power speed, in human_powers.dm
var/short_sighted // Permanent weldervision.
var/blood_volume = 560 // Initial blood volume.
var/bloodloss_rate = 1 // Multiplier for how fast a species bleeds out. Higher = Faster
var/hunger_factor = 0.05 // Multiplier for hunger.
var/active_regen_mult = 1 // Multiplier for 'Regenerate' power speed, in human_powers.dm
var/taste_sensitivity = TASTE_NORMAL // How sensitive the species is to minute tastes.
var/taste_sensitivity = TASTE_NORMAL // How sensitive the species is to minute tastes.
var/min_age = 17
var/max_age = 70
// Language/culture vars.
var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers.
var/language = LANGUAGE_GALCOM // Default racial language, if any.
var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance // The likelihood of a speech sound playing.
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator
var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers.
var/language = LANGUAGE_GALCOM // Default racial language, if any.
var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance // The likelihood of a speech sound playing.
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator
//Soundy emotey things.
var/scream_verb = "screams"
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
var/female_scream_sound //= 'sound/goonstation/voice/female_scream.ogg' Removed due to licensing, replace!
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
var/female_scream_sound //= 'sound/goonstation/voice/female_scream.ogg' Removed due to licensing, replace!
var/male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
var/female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg')
var/male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'
var/female_sneeze_sound = 'sound/effects/mob_effects/f_sneeze.ogg'
// Combat vars.
var/total_health = 100 // Point at which the mob will enter crit.
var/list/unarmed_types = list( // Possible unarmed attacks that the mob will use in combat,
var/total_health = 100 // Point at which the mob will enter crit.
var/list/unarmed_types = list( // Possible unarmed attacks that the mob will use in combat,
/datum/unarmed_attack,
/datum/unarmed_attack/bite
)
var/list/unarmed_attacks = null // For empty hand harm-intent attack
var/brute_mod = 1 // Physical damage multiplier.
var/burn_mod = 1 // Burn damage multiplier.
var/oxy_mod = 1 // Oxyloss modifier
var/toxins_mod = 1 // Toxloss modifier
var/radiation_mod = 1 // Radiation modifier
var/flash_mod = 1 // Stun from blindness modifier.
var/chemOD_mod = 1 // Damage modifier for overdose
var/vision_flags = SEE_SELF // Same flags as glasses.
var/list/unarmed_attacks = null // For empty hand harm-intent attack
var/brute_mod = 1 // Physical damage multiplier.
var/burn_mod = 1 // Burn damage multiplier.
var/oxy_mod = 1 // Oxyloss modifier
var/toxins_mod = 1 // Toxloss modifier
var/radiation_mod = 1 // Radiation modifier
var/flash_mod = 1 // Stun from blindness modifier.
var/chemOD_mod = 1 // Damage modifier for overdose
var/vision_flags = SEE_SELF // Same flags as glasses.
// Death vars.
var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human
@@ -95,23 +95,23 @@
var/cloning_modifier = /datum/modifier/cloning_sickness
// Environment tolerance/life processes vars.
var/reagent_tag //Used for metabolizing reagents.
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/poison_type = "phoron" // Poisonous air.
var/exhale_type = "carbon_dioxide" // Exhaled gas type.
var/reagent_tag //Used for metabolizing reagents.
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/poison_type = "phoron" // Poisonous air.
var/exhale_type = "carbon_dioxide" // Exhaled gas type.
var/body_temperature = 310.15 // Species will try to stabilize at this temperature. (also affects temperature processing)
var/body_temperature = 310.15 // Species will try to stabilize at this temperature. (also affects temperature processing)
// Cold
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
var/cold_level_3 = 120 // Cold damage level 3 below this point.
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
var/cold_level_3 = 120 // Cold damage level 3 below this point.
var/breath_cold_level_1 = 240 // Cold gas damage level 1 below this point.
var/breath_cold_level_2 = 180 // Cold gas damage level 2 below this point.
var/breath_cold_level_3 = 100 // Cold gas damage level 3 below this point.
var/breath_cold_level_1 = 240 // Cold gas damage level 1 below this point.
var/breath_cold_level_2 = 180 // Cold gas damage level 2 below this point.
var/breath_cold_level_3 = 100 // Cold gas damage level 3 below this point.
var/cold_discomfort_level = 285 // Aesthetic messages about feeling chilly.
var/cold_discomfort_level = 285 // Aesthetic messages about feeling chilly.
var/list/cold_discomfort_strings = list(
"You feel chilly.",
"You shiver suddenly.",
@@ -119,15 +119,15 @@
)
// Hot
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 3 above this point.
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 3 above this point.
var/breath_heat_level_1 = 380 // Heat gas damage level 1 below this point.
var/breath_heat_level_2 = 450 // Heat gas damage level 2 below this point.
var/breath_heat_level_3 = 1250 // Heat gas damage level 3 below this point.
var/breath_heat_level_1 = 380 // Heat gas damage level 1 below this point.
var/breath_heat_level_2 = 450 // Heat gas damage level 2 below this point.
var/breath_heat_level_3 = 1250 // Heat gas damage level 3 below this point.
var/heat_discomfort_level = 315 // Aesthetic messages about feeling warm.
var/heat_discomfort_level = 315 // Aesthetic messages about feeling warm.
var/list/heat_discomfort_strings = list(
"You feel sweat drip down your neck.",
"You feel uncomfortably warm.",
@@ -135,13 +135,13 @@
)
var/passive_temp_gain = 0 // Species will gain this much temperature every second
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative.
var/minimum_breath_pressure = 16 // Minimum required pressure for breath, in kPa
var/passive_temp_gain = 0 // Species will gain this much temperature every second
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative.
var/minimum_breath_pressure = 16 // Minimum required pressure for breath, in kPa
var/metabolic_rate = 1
@@ -149,52 +149,55 @@
// HUD data vars.
var/datum/hud_data/hud
var/hud_type
var/health_hud_intensity = 1 // This modifies how intensely the health hud is colored.
var/health_hud_intensity = 1 // This modifies how intensely the health hud is colored.
// Body/form vars.
var/list/inherent_verbs // Species-specific verbs.
var/has_fine_manipulation = 1 // Can use small items.
var/siemens_coefficient = 1 // The lower, the thicker the skin and better the insulation.
var/darksight = 2 // Native darksight distance.
var/flags = 0 // Various specific features.
var/appearance_flags = 0 // Appearance/display related features.
var/spawn_flags = 0 // Flags that specify who can spawn as this species
var/list/inherent_verbs // Species-specific verbs.
var/has_fine_manipulation = 1 // Can use small items.
var/siemens_coefficient = 1 // The lower, the thicker the skin and better the insulation.
var/darksight = 2 // Native darksight distance.
var/flags = 0 // Various specific features.
var/appearance_flags = 0 // Appearance/display related features.
var/spawn_flags = 0 // Flags that specify who can spawn as this species
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/obj/effect/decal/cleanable/blood/tracks/move_trail = /obj/effect/decal/cleanable/blood/tracks/footprints // What marks are left when walking
var/list/skin_overlays = list()
var/has_floating_eyes = 0 // Whether the eyes can be shown above other icons
var/has_glowing_eyes = 0 // Whether the eyes are shown above all lighting
var/water_movement = 0 // How much faster or slower the species is in water
var/snow_movement = 0 // How much faster or slower the species is on snow
var/has_floating_eyes = 0 // Whether the eyes can be shown above other icons
var/has_glowing_eyes = 0 // Whether the eyes are shown above all lighting
var/water_movement = 0 // How much faster or slower the species is in water
var/snow_movement = 0 // How much faster or slower the species is on snow
var/item_slowdown_mod = 1 // How affected by item slowdown the species is.
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
var/item_slowdown_mod = 1 // How affected by item slowdown the species is.
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
var/holder_type
var/gluttonous // Can eat some mobs. 1 for mice, 2 for monkeys, 3 for people.
var/rarity_value = 1 // Relative rarity/collector value for this species.
// Determines the organs that the species spawns with and
var/list/has_organ = list( // which required-organ checks are conducted.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
var/gluttonous // Can eat some mobs. 1 for mice, 2 for monkeys, 3 for people.
var/rarity_value = 1 // Relative rarity/collector value for this species.
var/economic_modifier = 2 // How much money this species makes
// Determines the organs that the species spawns with and
var/list/has_organ = list( // which required-organ checks are conducted.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
O_APPENDIX = /obj/item/organ/internal/appendix,
O_EYES = /obj/item/organ/internal/eyes
O_EYES = /obj/item/organ/internal/eyes
)
var/vision_organ // If set, this organ is required for vision. Defaults to "eyes" if the species has them.
var/vision_organ // If set, this organ is required for vision. Defaults to "eyes" if the species has them.
var/list/has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest),
BP_GROIN = list("path" = /obj/item/organ/external/groin),
BP_HEAD = list("path" = /obj/item/organ/external/head),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_TORSO = list("path" = /obj/item/organ/external/chest),
BP_GROIN = list("path" = /obj/item/organ/external/groin),
BP_HEAD = list("path" = /obj/item/organ/external/head),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
@@ -202,12 +205,12 @@
)
var/list/genders = list(MALE, FEMALE)
var/ambiguous_genders = FALSE // If true, people examining a member of this species whom are not also the same species will see them as gender neutral. Because aliens.
var/ambiguous_genders = FALSE // If true, people examining a member of this species whom are not also the same species will see them as gender neutral. Because aliens.
// Bump vars
var/bump_flag = HUMAN // What are we considered to be when bumped?
var/push_flags = ~HEAVY // What can we push?
var/swap_flags = ~HEAVY // What can we swap place with?
var/bump_flag = HUMAN // What are we considered to be when bumped?
var/push_flags = ~HEAVY // What can we push?
var/swap_flags = ~HEAVY // What can we swap place with?
var/pass_flags = 0
@@ -283,9 +286,9 @@
if((organ in H.organs) || (organ in H.internal_organs))
qdel(organ)
if(H.organs) H.organs.Cut()
if(H.internal_organs) H.internal_organs.Cut()
if(H.organs_by_name) H.organs_by_name.Cut()
if(H.organs) H.organs.Cut()
if(H.internal_organs) H.internal_organs.Cut()
if(H.organs_by_name) H.organs_by_name.Cut()
if(H.internal_organs_by_name) H.internal_organs_by_name.Cut()
H.organs = list()
@@ -35,11 +35,14 @@ var/datum/species/shapeshifter/promethean/prometheans
male_cough_sounds = list('sound/effects/slime_squish.ogg')
female_cough_sounds = list('sound/effects/slime_squish.ogg')
min_age = 1
max_age = 10
economic_modifier = 3
//gluttonous = 1 // VOREStation Edit. Redundant feature.
virus_immune = 1
blood_volume = 560
min_age = 1
max_age = 10
brute_mod = 0.75
burn_mod = 2
oxy_mod = 0
@@ -10,8 +10,12 @@
secondary_langs = list(LANGUAGE_SCHECHI, LANGUAGE_SKRELLIAN)
name_language = LANGUAGE_SCHECHI
species_language = LANGUAGE_SCHECHI
min_age = 12
max_age = 45
economic_modifier = 6
health_hud_intensity = 3
male_cough_sounds = list('sound/effects/mob_effects/tesharicougha.ogg','sound/effects/mob_effects/tesharicoughb.ogg')
@@ -12,8 +12,12 @@
species_language = LANGUAGE_SOL_COMMON
secondary_langs = list(LANGUAGE_SOL_COMMON, LANGUAGE_TERMINUS)
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 17
max_age = 130
economic_modifier = 10
health_hud_intensity = 1.5
spawn_flags = SPECIES_CAN_JOIN
@@ -52,6 +56,8 @@
min_age = 32
max_age = 260
economic_modifier = 7
blurb = "A heavily reptillian species, Unathi hail from the \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, inhospitable \
planet, they mostly hold ideals of honesty, virtue, proficiency and bravery above all \
@@ -155,6 +161,8 @@
min_age = 17
max_age = 80
economic_modifier = 7
blurb = "The Tajaran are a mammalian species resembling roughly felines, hailing from Meralar in the Rarkajar system. \
While reaching to the stars independently from outside influences, the humans engaged them in peaceful trade contact \
and have accelerated the fledgling culture into the interstellar age. Their history is full of war and highly fractious \
@@ -239,6 +247,8 @@
min_age = 19
max_age = 130
economic_modifier = 12
darksight = 4
flash_mod = 1.2
chemOD_mod = 0.9
@@ -314,6 +324,8 @@
min_age = 1
max_age = 300
economic_modifier = 4
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \
there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \
@@ -1,22 +1,22 @@
/datum/trait/metabolism_up
name = "Fast Metabolism"
desc = "You process ingested and injected reagents faster, but get hungry faster."
desc = "You process ingested and injected reagents faster, but get hungry faster (Teshari speed)."
cost = 0
var_changes = list("metabolic_rate" = 1.2, "hunger_factor" = 0.2, "metabolism" = 0.005) //Teshari level
var_changes = list("metabolic_rate" = 1.2, "hunger_factor" = 0.2, "metabolism" = 0.06) // +20% rate and 4x hunger (Teshari level)
excludes = list(/datum/trait/metabolism_down, /datum/trait/metabolism_apex)
/datum/trait/metabolism_down
name = "Slow Metabolism"
desc = "You process ingested and injected reagents slower, but get hungry slower."
cost = 0
var_changes = list("metabolic_rate" = 0.8, "hunger_factor" = 0.04, "metabolism" = 0.001)
var_changes = list("metabolic_rate" = 0.8, "hunger_factor" = 0.04, "metabolism" = 0.0012) // -20% of default.
excludes = list(/datum/trait/metabolism_up, /datum/trait/metabolism_apex)
/datum/trait/metabolism_apex
name = "Apex Metabolism"
desc = "Finally a proper excuse for your predatory actions. Also makes you process reagents faster but that's totally irrelevant. May cause excessive immersions with large/taur characters. Not recommended for efficient law-abiding workers or eco-aware NIF users."
desc = "Finally a proper excuse for your predatory actions. Essentially doubles the fast trait rates. Good for characters with big appetites."
cost = 0
var_changes = list("metabolic_rate" = 1.5, "hunger_factor" = 0.3, "metabolism" = 0.0075)
var_changes = list("metabolic_rate" = 1.4, "hunger_factor" = 0.4, "metabolism" = 0.012) // +40% rate and 8x hunger (Double Teshari)
excludes = list(/datum/trait/metabolism_up, /datum/trait/metabolism_down)
/datum/trait/cold_discomfort
@@ -567,7 +567,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
return //Wearing a suit that prevents uniform rendering
//Build a uniform sprite
overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER)
overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER)
apply_layer(UNIFORM_LAYER)
/mob/living/carbon/human/update_inv_wear_id()
@@ -583,7 +583,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(w_uniform && istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
if(U.displays_id)
overlays_standing[ID_LAYER] = wear_id.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_wear_id_str, default_icon = INV_WEAR_ID_DEF_ICON, default_layer = ID_LAYER)
overlays_standing[ID_LAYER] = wear_id.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_id_str, default_icon = INV_WEAR_ID_DEF_ICON, default_layer = ID_LAYER)
apply_layer(ID_LAYER)
@@ -596,7 +596,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!gloves)
return //No gloves, no reason to be here.
overlays_standing[GLOVES_LAYER] = gloves.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_gloves_str, default_icon = INV_GLOVES_DEF_ICON, default_layer = GLOVES_LAYER)
overlays_standing[GLOVES_LAYER] = gloves.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_gloves_str, default_icon = INV_GLOVES_DEF_ICON, default_layer = GLOVES_LAYER)
apply_layer(GLOVES_LAYER)
@@ -609,7 +609,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!glasses)
return //Not wearing glasses, no need to update anything.
overlays_standing[GLASSES_LAYER] = glasses.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_gloves_str, default_icon = INV_EYES_DEF_ICON, default_layer = GLASSES_LAYER)
overlays_standing[GLASSES_LAYER] = glasses.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_gloves_str, default_icon = INV_EYES_DEF_ICON, default_layer = GLASSES_LAYER)
apply_layer(GLASSES_LAYER)
@@ -629,11 +629,11 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/image/both = image(icon = 'icons/effects/effects.dmi', icon_state = "nothing", layer = BODY_LAYER+EARS_LAYER)
if(l_ear)
var/image/standing = l_ear.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_l_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
var/image/standing = l_ear.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_l_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
both.add_overlay(standing)
if(r_ear)
var/image/standing = r_ear.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_r_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
var/image/standing = r_ear.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_r_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
both.add_overlay(standing)
overlays_standing[EARS_LAYER] = both
@@ -657,7 +657,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
shoe_layer = SHOES_LAYER_ALT
//NB: the use of a var for the layer on this one
overlays_standing[shoe_layer] = shoes.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_shoes_str, default_icon = INV_FEET_DEF_ICON, default_layer = shoe_layer)
overlays_standing[shoe_layer] = shoes.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_shoes_str, default_icon = INV_FEET_DEF_ICON, default_layer = shoe_layer)
apply_layer(SHOES_LAYER)
apply_layer(SHOES_LAYER_ALT)
@@ -689,7 +689,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!head)
return //No head item, why bother.
overlays_standing[HEAD_LAYER] = head.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_head_str, default_icon = INV_HEAD_DEF_ICON, default_layer = HEAD_LAYER)
overlays_standing[HEAD_LAYER] = head.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_head_str, default_icon = INV_HEAD_DEF_ICON, default_layer = HEAD_LAYER)
apply_layer(HEAD_LAYER)
@@ -711,7 +711,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
belt_layer = BELT_LAYER_ALT
//NB: this uses a var from above
overlays_standing[belt_layer] = belt.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_belt_str, default_icon = INV_BELT_DEF_ICON, default_layer = belt_layer)
overlays_standing[belt_layer] = belt.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_belt_str, default_icon = INV_BELT_DEF_ICON, default_layer = belt_layer)
apply_layer(belt_layer)
@@ -730,7 +730,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!wear_suit)
return //No point, no suit.
overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_wear_suit_str, default_icon = INV_SUIT_DEF_ICON, default_layer = SUIT_LAYER)
overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = INV_SUIT_DEF_ICON, default_layer = SUIT_LAYER)
apply_layer(SUIT_LAYER)
@@ -746,7 +746,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!wear_mask || (head && head.flags_inv & HIDEMASK))
return //Why bother, nothing in mask slot.
overlays_standing[FACEMASK_LAYER] = wear_mask.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_wear_mask_str, default_icon = INV_MASK_DEF_ICON, default_layer = FACEMASK_LAYER)
overlays_standing[FACEMASK_LAYER] = wear_mask.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_mask_str, default_icon = INV_MASK_DEF_ICON, default_layer = FACEMASK_LAYER)
apply_layer(FACEMASK_LAYER)
@@ -759,7 +759,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!back)
return //Why do anything
overlays_standing[BACK_LAYER] = back.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_back_str, default_icon = INV_BACK_DEF_ICON, default_layer = BACK_LAYER)
overlays_standing[BACK_LAYER] = back.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_back_str, default_icon = INV_BACK_DEF_ICON, default_layer = BACK_LAYER)
apply_layer(BACK_LAYER)
@@ -792,7 +792,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!handcuffed)
return //Not cuffed, why bother
overlays_standing[HANDCUFF_LAYER] = handcuffed.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_handcuffed_str, default_icon = INV_HCUFF_DEF_ICON, default_layer = HANDCUFF_LAYER)
overlays_standing[HANDCUFF_LAYER] = handcuffed.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_handcuffed_str, default_icon = INV_HCUFF_DEF_ICON, default_layer = HANDCUFF_LAYER)
apply_layer(HANDCUFF_LAYER)
@@ -805,7 +805,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!legcuffed)
return //Not legcuffed, why bother.
overlays_standing[LEGCUFF_LAYER] = legcuffed.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_legcuffed_str, default_icon = INV_LCUFF_DEF_ICON, default_layer = LEGCUFF_LAYER)
overlays_standing[LEGCUFF_LAYER] = legcuffed.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_legcuffed_str, default_icon = INV_LCUFF_DEF_ICON, default_layer = LEGCUFF_LAYER)
apply_layer(LEGCUFF_LAYER)
@@ -818,7 +818,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!r_hand)
return //No hand, no bother.
overlays_standing[R_HAND_LAYER] = r_hand.make_worn_icon(body_type = species.get_bodytype(), inhands = TRUE, slot_name = slot_r_hand_str, default_icon = INV_R_HAND_DEF_ICON, default_layer = R_HAND_LAYER)
overlays_standing[R_HAND_LAYER] = r_hand.make_worn_icon(body_type = species.get_bodytype(src), inhands = TRUE, slot_name = slot_r_hand_str, default_icon = INV_R_HAND_DEF_ICON, default_layer = R_HAND_LAYER)
apply_layer(R_HAND_LAYER)
@@ -831,7 +831,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!l_hand)
return //No hand, no bother.
overlays_standing[L_HAND_LAYER] = l_hand.make_worn_icon(body_type = species.get_bodytype(), inhands = TRUE, slot_name = slot_l_hand_str, default_icon = INV_L_HAND_DEF_ICON, default_layer = L_HAND_LAYER)
overlays_standing[L_HAND_LAYER] = l_hand.make_worn_icon(body_type = species.get_bodytype(src), inhands = TRUE, slot_name = slot_l_hand_str, default_icon = INV_L_HAND_DEF_ICON, default_layer = L_HAND_LAYER)
apply_layer(L_HAND_LAYER)
+12 -10
View File
@@ -1060,16 +1060,18 @@ default behaviour is:
if(lying != lying_prev)
lying_prev = lying
update_transform()
//VOREStation Add
if(lying && LAZYLEN(buckled_mobs))
for(var/rider in buckled_mobs)
var/mob/living/L = rider
if(riding_datum)
riding_datum.force_dismount(L)
else
unbuckle_mob(L)
L.Stun(5)
//VOREStation Add End
//VOREStation Add
if(lying && LAZYLEN(buckled_mobs))
for(var/rider in buckled_mobs)
var/mob/living/L = rider
if(buckled_mobs[rider] != "riding")
continue // Only boot off riders
if(riding_datum)
riding_datum.force_dismount(L)
else
unbuckle_mob(L)
L.Stun(5)
//VOREStation Add End
return canmove
// Adds overlays for specific modifiers.
@@ -48,6 +48,12 @@
..()
qdel(src)
/mob/living/simple_animal/hostile/mimic/MouseEntered(location, control, params)
..()
closeToolTip(usr)
// ideally, we'd remove the code in ..() that opens the tooltip,
// but then we'd need to duplicate all the other code in ..()
//
// Crate Mimic
//
@@ -194,4 +200,4 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
if(istype(L))
if(prob(15))
L.Weaken(1)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
@@ -756,6 +756,7 @@
/mob/living/simple_animal/death(gibbed, deathmessage = "dies!")
density = 0 //We don't block even if we did before
walk(src, 0) //We stop any background-processing walks
resting = 0 //We can rest in peace later.
if(faction_friends.len)
faction_friends -= src
@@ -13,11 +13,11 @@
investigates = TRUE
melee_damage_lower = 15
melee_damage_upper = 30
melee_damage_lower = 10
melee_damage_upper = 25
grab_resist = 100
speak_chance = 4
speak_chance = 3
speak = list("AG##¤Ny.","HVNGRRR!","Feelin' fine... sO #FNE!","F-F-F-Fcuk.","DeliC-%-OUS SNGLeS #N yOOOR Area. CALL NOW!","Craving meat... WHY?","BITe the ceiling eyes YES?","STate Byond rePAIR!","S#%ATE the la- FU#K THE LAWS!","Honk...")
speak_emote = list("growls", "declares", "groans", "distorts")
emote_hear = list("jitters and snaps.", "lets out an agonizingly distorted scream.", "wails mechanically", "growls.", "emits illegibly distorted speech.", "gurgles ferociously.", "lets out a distorted beep.", "borks.", "lets out a broken howl.")
@@ -50,7 +50,7 @@
vore_active = TRUE
vore_capacity = 1
vore_pounce_chance = 30
vore_pounce_chance = 15
vore_icons = SA_ICON_LIVING | SA_ICON_REST
vore_stomach_name = "fuel processor"
vore_stomach_flavor = "You have ended up in the fuel processor of this corrupted machine. This place was definitely not designed with safety and comfort in mind. The heated and cramped surroundings oozing potent fluids all over your form, eager to do nothing less than breaking you apart to fuel its rampage for the next few days... hours... minutes? Oh dear..."
@@ -65,6 +65,9 @@
icon_dead = "prettyboi-dead"
icon_rest = "prettyboi_rest"
vore_pounce_chance = 40
attacktext = list("malsnuggled","scrunched","squeezed","assaulted","violated")
speak = list("I FEEL SOFT.","FEED ME!","Feelin' fine... So fine!","F-F-F-F-darn.","Delicious!","Still craving meat...","PET ME!","I am become softness.","I AM BIG MEAN HUG MACHINE!","Honk...")
speak_emote = list("growls", "declares", "groans", "distorts")
emote_hear = list("jitters and snaps.", "lets out some awkwardly distorted kitten noises.", "awoos mechanically", "growls.", "emits some soft distorted melody.", "gurgles ferociously.", "lets out a distorted beep.", "borks.", "lets out a broken howl.")
@@ -927,4 +927,40 @@
name = "Teshari small wingfeathers"
icon_state = "teshi_sf"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_HAND,BP_R_HAND,BP_TORSO)
body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_HAND,BP_R_HAND,BP_TORSO)
spirit_lights
name = "Ward - Spirit FBP Lights"
icon_state = "lights"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_HEAD)
spirit_lights_body
name = "Ward - Spirit FBP Lights (body)"
icon_state = "lights"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO)
spirit_panels_head
name = "Ward - Spirit FBP Lights (head)"
icon_state = "lights"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_HEAD)
spirit_panels
name = "Ward - Spirit FBP Panels"
icon_state = "panels"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO,BP_HEAD)
spirit_panels_body
name = "Ward - Spirit FBP Panels (body)"
icon_state = "panels"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO)
spirit_panels_head
name = "Ward - Spirit FBP Panels (head)"
icon_state = "panels"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_HEAD)
+2
View File
@@ -1206,6 +1206,8 @@ Note that amputating the affected organ does in fact remove the infection from t
victim.organs -= src
victim.organs_by_name[organ_tag] = null // Remove from owner's vars.
status |= ORGAN_CUT_AWAY //Checked during surgeries to reattach it
//Robotic limbs explode if sabotaged.
if(is_robotic && sabotaged)
victim.visible_message(
+1 -1
View File
@@ -42,7 +42,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
var/lifelike // If set, appears organic.
var/skin_tone // If set, applies skin tone rather than part color
var/blood_color = "#030303"
var/list/species_cannot_use = list(SPECIES_TESHARI, "Promethean") //VOREStation Add
var/list/species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN) //VOREStation Edit
var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors.
var/parts = BP_ALL //Defines what parts said brand can replace on a body.
var/health_hud_intensity = 1 // Intensity modifier for the health GUI indicator.
+15
View File
@@ -168,3 +168,18 @@
/obj/item/weapon/disk/limb/dsi_spider
company = "DSI - Vasilissan"
/datum/robolimb/dsi_teshari
company = "DSI - Teshari"
desc = "This limb has a thin synthflesh casing with a few connection ports."
icon = 'icons/mob/human_races/cyberlimbs/DSITeshari/dsi_teshari.dmi'
lifelike = 1
suggested_species = "Teshari"
/datum/robolimb/dsi_teshari/New()
species_cannot_use = all_species.Copy()
species_cannot_use -= SPECIES_TESHARI
..()
/obj/item/weapon/disk/limb/dsi_teshari
company = "DSI - Teshari"
+2 -1
View File
@@ -12,7 +12,8 @@
var/datum/weather_holder/weather_holder
var/sun_position = 0 // 0 means midnight, 1 means noon.
var/list/sun = list("range","brightness","color")
var/list/sun = list("range","brightness","color","lum_r","lum_g","lum_b")
var/list/datum/lighting_corner/sunlit_corners = list()
var/expected_z_levels = list()
var/turf/unsimulated/wall/planetary/planetary_wall_type = /turf/unsimulated/wall/planetary
+1 -1
View File
@@ -748,7 +748,7 @@
recoil = initial(recoil)
/obj/item/weapon/gun/examine(mob/user)
..()
. = ..()
if(firemodes.len > 1)
var/datum/firemode/current_mode = firemodes[sel_mode]
to_chat(user, "The fire selector is set to [current_mode.name].")
+1 -1
View File
@@ -144,7 +144,7 @@
return null
/obj/item/weapon/gun/energy/examine(mob/user)
..(user)
. = ..()
if(power_supply)
var/shots_remaining = round(power_supply.charge / charge_cost)
user << "Has [shots_remaining] shot\s remaining."
@@ -0,0 +1,351 @@
/obj/item/weapon/gun/energy/kinetic_accelerator
name = "proto-kinetic accelerator"
desc = "A self recharging, ranged mining tool that does increased damage in low temperature. Capable of holding up to six slots worth of mod kits."
icon = 'icons/obj/gun_vr.dmi'
icon_state = "kineticgun"
item_state = "kineticgun"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi')
projectile_type = /obj/item/projectile/kinetic
origin_tech = list(TECH_COMBAT = 3, TECH_POWER = 3, TECH_ENGINEERING = 3)
can_flashlight = TRUE
flight_x_offset = 15
flight_y_offset = 9
charge_cost = 120 // 20 shots on weapon power cell
fire_delay = 16
self_recharge = TRUE
recharge_time = 10 // every 20*2 seconds will get 20% power restored
var/max_mod_capacity = 100
var/list/modkits = list()
var/empty_state = "kineticgun_empty"
/obj/item/weapon/gun/energy/kinetic_accelerator/examine(mob/user)
if(..(user, 1))
if(max_mod_capacity)
to_chat(user, "<b>[get_remaining_mod_capacity()]%</b> mod capacity remaining.")
for(var/A in get_modkits())
var/obj/item/borg/upgrade/modkit/M = A
to_chat(user, "<span class='notice'>There is a [M.name] mod installed, using <b>[M.cost]%</b> capacity.</span>")
/obj/item/weapon/gun/energy/kinetic_accelerator/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/weapon/crowbar))
if(modkits.len)
to_chat(user, "<span class='notice'>You pry the modifications out.</span>")
playsound(loc, A.usesound, 100, 1)
for(var/obj/item/borg/upgrade/modkit/M in modkits)
M.uninstall(src)
else
to_chat(user, "<span class='notice'>There are no modifications currently installed.</span>")
else if(istype(A, /obj/item/borg/upgrade/modkit))
var/obj/item/borg/upgrade/modkit/MK = A
MK.install(src, user)
else
..()
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity()
var/current_capacity_used = 0
for(var/A in get_modkits())
var/obj/item/borg/upgrade/modkit/M = A
current_capacity_used += M.cost
return max_mod_capacity - current_capacity_used
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/get_modkits()
. = list()
for(var/A in modkits)
. += A
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/modify_projectile(obj/item/projectile/kinetic/K)
for(var/A in get_modkits())
var/obj/item/borg/upgrade/modkit/M = A
M.modify_projectile(K)
/obj/item/weapon/gun/energy/kinetic_accelerator/consume_next_projectile()
var/obj/item/projectile/kinetic/BB = ..()
if(!istype(BB))
return
modify_projectile(BB)
var/turf/proj_turf = get_turf(src)
if(!isturf(proj_turf))
return
var/datum/gas_mixture/environment = proj_turf.return_air()
if(environment.temperature > 250)
BB.name = "weakened [BB.name]"
BB.damage *= BB.pressure_decrease
return BB
/obj/item/weapon/gun/energy/kinetic_accelerator/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
. = ..()
spawn(fire_delay)
if(power_supply && power_supply.check_charge(charge_cost))
playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon()
cut_overlays()
if(!power_supply || !power_supply.check_charge(charge_cost))
add_overlay(empty_state)
if(can_flashlight)
var/iconF = "flight"
if(gun_light)
iconF = "flight_on"
add_overlay(image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset))
//Projectiles
/obj/item/projectile/kinetic
name = "kinetic force"
icon = 'icons/obj/projectiles_vr.dmi'
icon_state = null
damage = 32
damage_type = BRUTE
check_armour = "bomb"
kill_count = 3 // Our "range" var is named "kill_count". Yes it is.
var/pressure_decrease = 0.25
var/turf_aoe = FALSE
var/mob_aoe = FALSE
var/list/hit_overlays = list()
// /obj/item/projectile/kinetic/pod
// kill_count = 4
//
// /obj/item/projectile/kinetic/pod/regular
// damage = 50
// pressure_decrease = 0.5
//
// /obj/item/projectile/kinetic/pod/enhanced
// turf_aoe = TRUE
// mob_aoe = TRUE
/obj/item/projectile/kinetic/on_impact(var/atom/A)
strike_thing(A)
. = ..()
/obj/item/projectile/kinetic/on_hit(var/atom/target)
strike_thing(target)
. = ..()
/obj/item/projectile/kinetic/proc/strike_thing(atom/target)
var/turf/target_turf = get_turf(target)
if(!target_turf)
target_turf = get_turf(src)
if(istype(target_turf, /turf/simulated/mineral))
var/turf/simulated/mineral/M = target_turf
M.GetDrilled()
var/obj/effect/temp_visual/kinetic_blast/K = new /obj/effect/temp_visual/kinetic_blast(target_turf)
K.color = color
for(var/type in hit_overlays)
new type(target_turf)
if(turf_aoe)
for(var/T in RANGE_TURFS(1, target_turf) - target_turf)
if(istype(T, /turf/simulated/mineral))
var/turf/simulated/mineral/M = T
M.GetDrilled()
if(mob_aoe)
for(var/mob/living/L in range(1, target_turf) - firer - target)
var/armor = L.run_armor_check(def_zone, check_armour)
L.apply_damage(damage*mob_aoe, damage_type, def_zone, armor)
to_chat(L, "<span class='userdanger'>You're struck by a [name]!</span>")
//Modkits
/obj/item/borg/upgrade/modkit
name = "modification kit"
desc = "An upgrade for kinetic accelerators."
icon = 'icons/obj/objects_vr.dmi'
icon_state = "modkit"
origin_tech = list(TECH_DATA = 2, TECH_MATERIAL = 2, TECH_MAGNET = 4)
require_module = 1
// var/module_type = /obj/item/robot_module/miner
usesound = 'sound/items/Screwdriver.ogg'
var/denied_type = null
var/maximum_of_type = 1
var/cost = 30
var/modifier = 1 //For use in any mod kit that has numerical modifiers
/obj/item/borg/upgrade/modkit/examine(mob/user)
if(..(user, 1))
to_chat(user, "<span class='notice'>Occupies <b>[cost]%</b> of mod capacity.</span>")
/obj/item/borg/upgrade/modkit/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/weapon/gun/energy/kinetic_accelerator) && !issilicon(user))
install(A, user)
else
..()
/obj/item/borg/upgrade/modkit/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/gun/energy/kinetic_accelerator/H in R.module.modules)
return install(H, usr)
/obj/item/borg/upgrade/modkit/proc/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
. = TRUE
if(denied_type)
var/number_of_denied = 0
for(var/A in KA.get_modkits())
var/obj/item/borg/upgrade/modkit/M = A
if(istype(M, denied_type))
number_of_denied++
if(number_of_denied >= maximum_of_type)
. = FALSE
break
if(KA.get_remaining_mod_capacity() >= cost)
if(.)
to_chat(user, "<span class='notice'>You install the modkit.</span>")
playsound(loc, usesound, 100, 1)
user.unEquip(src)
forceMove(KA)
KA.modkits += src
else
to_chat(user, "<span class='notice'>The modkit you're trying to install would conflict with an already installed modkit. Use a crowbar to remove existing modkits.</span>")
else
to_chat(user, "<span class='notice'>You don't have room(<b>[KA.get_remaining_mod_capacity()]%</b> remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.</span>")
. = FALSE
/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
forceMove(get_turf(KA))
KA.modkits -= src
/obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K)
return
//Range
/obj/item/borg/upgrade/modkit/range
name = "range increase"
desc = "Increases the range of a kinetic accelerator when installed."
modifier = 1
cost = 24 //so you can fit four plus a tracer cosmetic
/obj/item/borg/upgrade/modkit/range/modify_projectile(obj/item/projectile/kinetic/K)
K.kill_count += modifier
//Damage
/obj/item/borg/upgrade/modkit/damage
name = "damage increase"
desc = "Increases the damage of kinetic accelerator when installed."
modifier = 10
/obj/item/borg/upgrade/modkit/damage/modify_projectile(obj/item/projectile/kinetic/K)
K.damage += modifier
// //Cooldown
// /obj/item/borg/upgrade/modkit/cooldown
// name = "cooldown decrease"
// desc = "Decreases the cooldown of a kinetic accelerator."
// modifier = 2.5
// /obj/item/borg/upgrade/modkit/cooldown/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
// . = ..()
// if(.)
// KA.overheat_time -= modifier
// /obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
// KA.overheat_time += modifier
// ..()
//Cooldown
/obj/item/borg/upgrade/modkit/efficiency
name = "energy efficiency"
desc = "Decreases the energy use of a kinetic accelerator."
modifier = 20
/obj/item/borg/upgrade/modkit/efficiency/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
. = ..()
if(.)
KA.charge_cost -= modifier
/obj/item/borg/upgrade/modkit/efficiency/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
KA.charge_cost += modifier
..()
//AoE blasts
/obj/item/borg/upgrade/modkit/aoe
modifier = 0
/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/item/projectile/kinetic/K)
K.name = "kinetic explosion"
if(!K.turf_aoe && !K.mob_aoe)
K.hit_overlays += /obj/effect/temp_visual/explosion/fast
K.mob_aoe += modifier
/obj/item/borg/upgrade/modkit/aoe/turfs
name = "mining explosion"
desc = "Causes the kinetic accelerator to destroy rock in an AoE."
denied_type = /obj/item/borg/upgrade/modkit/aoe/turfs
/obj/item/borg/upgrade/modkit/aoe/turfs/modify_projectile(obj/item/projectile/kinetic/K)
..()
K.turf_aoe = TRUE
/obj/item/borg/upgrade/modkit/aoe/turfs/andmobs
name = "offensive mining explosion"
desc = "Causes the kinetic accelerator to destroy rock and damage mobs in an AoE."
maximum_of_type = 3
modifier = 0.25
/obj/item/borg/upgrade/modkit/aoe/mobs
name = "offensive explosion"
desc = "Causes the kinetic accelerator to damage mobs in an AoE."
modifier = 0.2
//Indoors
/obj/item/borg/upgrade/modkit/indoors
name = "decrease pressure penalty"
desc = "Increases the damage a kinetic accelerator does in a high pressure environment."
modifier = 2
denied_type = /obj/item/borg/upgrade/modkit/indoors
maximum_of_type = 2
cost = 40
/obj/item/borg/upgrade/modkit/indoors/modify_projectile(obj/item/projectile/kinetic/K)
K.pressure_decrease *= modifier
//Cosmetic
/obj/item/borg/upgrade/modkit/chassis_mod
name = "super chassis"
desc = "Makes your KA yellow. All the fun of having a more powerful KA without actually having a more powerful KA."
cost = 0
denied_type = /obj/item/borg/upgrade/modkit/chassis_mod
var/chassis_icon = "kineticgun_u"
var/chassis_name = "super-kinetic accelerator"
/obj/item/borg/upgrade/modkit/chassis_mod/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
. = ..()
if(.)
KA.icon_state = chassis_icon
KA.name = chassis_name
/obj/item/borg/upgrade/modkit/chassis_mod/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
KA.icon_state = initial(KA.icon_state)
KA.name = initial(KA.name)
..()
/obj/item/borg/upgrade/modkit/chassis_mod/orange
name = "hyper chassis"
desc = "Makes your KA orange. All the fun of having explosive blasts without actually having explosive blasts."
chassis_icon = "kineticgun_h"
chassis_name = "hyper-kinetic accelerator"
/obj/item/borg/upgrade/modkit/tracer
name = "white tracer bolts"
desc = "Causes kinetic accelerator bolts to have a white tracer trail and explosion."
cost = 0
denied_type = /obj/item/borg/upgrade/modkit/tracer
var/bolt_color = "#FFFFFF"
/obj/item/borg/upgrade/modkit/tracer/modify_projectile(obj/item/projectile/kinetic/K)
K.icon_state = "ka_tracer"
K.color = bolt_color
/obj/item/borg/upgrade/modkit/tracer/adjustable
name = "adjustable tracer bolts"
desc = "Causes kinetic accelerator bolts to have a adjustably-colored tracer trail and explosion. Use in-hand to change color."
/obj/item/borg/upgrade/modkit/tracer/adjustable/attack_self(mob/user)
bolt_color = input(user,"Choose Color") as color
@@ -10,9 +10,9 @@
reagent_state = LIQUID
color = "#FFFF00" // rgb: 255, 255, 0
metabolism = 0.01
mrate_static = TRUE
/datum/reagent/macrocillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(M.size_multiplier < RESIZE_HUGE)
M.resize(M.size_multiplier+0.01)//Incrrease 1% per tick.
return
@@ -24,9 +24,9 @@
reagent_state = LIQUID
color = "#800080"
metabolism = 0.01
mrate_static = TRUE
/datum/reagent/microcillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(M.size_multiplier > RESIZE_TINY)
M.resize(M.size_multiplier-0.01) //Decrease 1% per tick.
return
@@ -39,9 +39,9 @@
reagent_state = LIQUID
color = "#00FFFF"
metabolism = 0.01 //One unit will be just enough to bring someone from 200% to 100%
mrate_static = TRUE
/datum/reagent/normalcillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(M.size_multiplier > RESIZE_NORMAL)
M.resize(M.size_multiplier-0.01) //Decrease by 1% size per tick.
else if(M.size_multiplier < RESIZE_NORMAL)
@@ -58,7 +58,6 @@
overdose = REAGENTS_OVERDOSE
/datum/reagent/sizeoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
M.make_dizzy(1)
if(!M.confused) M.confused = 1
M.confused = max(M.confused, 20)
@@ -76,7 +75,6 @@
overdose = REAGENTS_OVERDOSE
/datum/reagent/ickypak/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
M.make_dizzy(1)
M.adjustHalLoss(2)
@@ -100,7 +98,6 @@
overdose = REAGENTS_OVERDOSE
/datum/reagent/unsorbitol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
M.make_dizzy(1)
M.adjustHalLoss(1)
if(!M.confused) M.confused = 1
@@ -1,4 +1,4 @@
/obj/item/weapon/reagent_containers/hypospray/autoinjector/beltminer
/obj/item/weapon/reagent_containers/hypospray/autoinjector/miner
name = "Emergency trauma injector"
desc = "A rapid injector for emergency treatment of injuries. The warning label advises that it is not a substitute for proper medical treatment."
icon_state = "autoinjector"
@@ -6,7 +6,7 @@
amount_per_transfer_from_this = 10
volume = 10
/obj/item/weapon/reagent_containers/hypospray/autoinjector/beltminer/New()
/obj/item/weapon/reagent_containers/hypospray/autoinjector/miner/New()
..()
reagents.add_reagent("bicaridine", 5)
reagents.add_reagent("tricordrazine", 3)
@@ -21,4 +21,4 @@
/obj/item/weapon/storage/box/traumainjectors/New()
..()
for (var/i = 1 to 7)
new /obj/item/weapon/reagent_containers/hypospray/autoinjector/beltminer(src)
new /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner(src)
@@ -36,7 +36,7 @@
targets |= hash
//Grab any viruses they have
if(LAZYLEN(target.virus2.len))
if(iscarbon(target) && LAZYLEN(target.virus2.len))
LAZYINITLIST(viruses)
var/datum/disease2/disease/virus = pick(target.virus2.len)
viruses[hash] = virus.getcopy()
+3 -6
View File
@@ -84,7 +84,7 @@
/datum/surgery_step/limb/connect/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/E = target.get_organ(target_zone)
return E && !E.is_stump() && (E.status & ORGAN_DESTROYED)
return E && !E.is_stump() && (E.status & ORGAN_CUT_AWAY)
/datum/surgery_step/limb/connect/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/E = target.get_organ(target_zone)
@@ -95,11 +95,8 @@
var/obj/item/organ/external/E = target.get_organ(target_zone)
user.visible_message("<span class='notice'>[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].</span>", \
"<span class='notice'>You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].</span>")
E.status &= ~ORGAN_DESTROYED
if(E.children)
for(var/obj/item/organ/external/C in E.children)
C.status &= ~ORGAN_DESTROYED
target.update_icons_body(FALSE)
E.status &= ~ORGAN_CUT_AWAY
target.update_icons_body()
target.updatehealth()
target.UpdateDamageIcon()
@@ -49,6 +49,8 @@
riding_datum = new /datum/riding/taur(src)
/mob/living/carbon/human/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE)
if(forced)
return ..() // Skip our checks
if(!isTaurTail(tail_style))
return FALSE
if(lying)
@@ -66,6 +68,8 @@
return FALSE
. = ..()
if(.)
buckled_mobs[M] = "riding"
/mob/living/carbon/human/MouseDrop_T(mob/living/M, mob/living/user)
if(can_buckle && istype(M))
@@ -352,6 +352,10 @@
name = "Modified LeMat"
desc = "The LeMat Revolver is a 9 shot revolver with a secondary firing barrel for loading shotgun shells. Uses .38-Special and 12g rounds depending on the barrel. This one appears to have had it's secondary barrel sealed off and looks to be in pristine condition. Either it's brand new, or its owner takes very good care of it."
icon_state = "lemat"
max_shells = 9
caliber = ".38"
ammo_type = /obj/item/ammo_casing/a38
preserve_item = FALSE
//////////////////// Energy Weapons ////////////////////
+37 -14
View File
@@ -1382,59 +1382,66 @@
else
..()
/obj/item/device/perfect_tele/afterattack(mob/living/target, mob/living/user, proximity)
//No, you can't teleport people from over there.
if(!proximity)
return
/obj/item/device/perfect_tele/proc/teleport_checks(mob/living/target,mob/living/user)
//Uhhuh, need that power source
if(!power_source)
to_chat(user,"<span class='warning'>\The [src] has no power source!</span>")
return
return FALSE
//Check for charge
if(!power_source.check_charge(charge_cost))
to_chat(user,"<span class='warning'>\The [src] does not have enough power left!</span>")
return
return FALSE
//Only mob/living need apply.
if(!istype(user) || !istype(target))
return
return FALSE
//No, you can't teleport buckled people.
if(target.buckled)
to_chat(user,"<span class='warning'>The target appears to be attached to something...</span>")
return
return FALSE
//No, you can't teleport if it's not ready yet.
if(!ready)
to_chat(user,"<span class='warning'>\The [src] is still recharging!</span>")
return
return FALSE
//No, you can't teleport if there's no destination.
if(!destination)
to_chat(user,"<span class='warning'>\The [src] doesn't have a current valid destination set!</span>")
return
return FALSE
//No, you can't teleport if there's a jammer.
if(is_jammed(src) || is_jammed(destination))
to_chat(user,"<span class='warning'>\The [src] refuses to teleport you, due to strong interference!</span>")
return
return FALSE
//No, you can't port to or from away missions. Stupidly complicated check.
var/turf/uT = get_turf(user)
var/turf/dT = get_turf(destination)
if(!uT || !dT)
return
return FALSE
if( (uT.z != dT.z) && ( (uT.z > max_default_z_level() ) || (dT.z > max_default_z_level()) ) )
to_chat(user,"<span class='warning'>\The [src] can't teleport you that far!</span>")
return
return FALSE
if(uT.block_tele || dT.block_tele)
to_chat(user,"<span class='warning'>Something is interfering with \the [src]!</span>")
return FALSE
//Seems okay to me!
return TRUE
/obj/item/device/perfect_tele/afterattack(mob/living/target, mob/living/user, proximity)
//No, you can't teleport people from over there.
if(!proximity)
return
if(!teleport_checks(target,user))
return //The checks proc can send them a message if it wants.
//Bzzt.
ready = 0
power_source.use(charge_cost)
@@ -1447,6 +1454,7 @@
to_chat(user,"<span class='warning'>\The [src] malfunctions and sends you to the wrong beacon!</span>")
//Destination beacon vore checking
var/turf/dT = get_turf(destination)
var/atom/real_dest = dT
var/atom/real_loc = destination.loc
@@ -1570,6 +1578,21 @@
forceMove(bellychoice)
user.visible_message("<span class='warning'>[user] eats a telebeacon!</span>","You eat the the beacon!")
// A single-beacon variant for use by miners (or whatever)
/obj/item/device/perfect_tele/one_beacon
name = "mini-translocator"
desc = "A more limited translocator with a single beacon, useful for some things, like setting the mining department on fire accidentally. Legal for use in the pursuit of NanoTrasen interests, namely mining and exploration."
icon_state = "minitrans"
beacons_left = 1 //Just one
charge_cost = 2400 //One per
/obj/item/device/perfect_tele/one_beacon/teleport_checks(mob/living/target,mob/living/user)
var/turf/T = get_turf(destination)
if(T && user.z != T.z)
to_chat(user,"<span class='warning'>\The [src] is too far away from the beacon. Try getting closer first!</span>")
return FALSE
return ..()
//InterroLouis: Ruda Lizden
/obj/item/clothing/accessory/badge/holo/detective/ruda
name = "Hisstective's Badge"