Merge remote-tracking branch 'polaris/master' into pl-chemistry

This commit is contained in:
GinjaNinja32
2015-12-22 02:55:31 +00:00
160 changed files with 20420 additions and 20049 deletions

View File

@@ -1342,3 +1342,19 @@ proc/admin_notice(var/message, var/rights)
message_admins(msg)
else
usr << "You do not have access to this command."
/datum/admins/proc/paralyze_mob(mob/living/H as mob)
set category = "Admin"
set name = "Toggle Paralyze"
set desc = "Paralyzes a player. Or unparalyses them."
var/msg
if(check_rights(R_ADMIN|R_MOD))
if (H.paralysis == 0)
H.paralysis = 8000
msg = "[key_name(usr)] has paralyzed [key_name(H)]."
else
H.paralysis = 0
msg = "[key_name(usr)] has unparalyzed [key_name(H)]."
message_admins(msg)

View File

@@ -94,7 +94,8 @@ var/list/admin_verbs_admin = list(
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
/client/proc/change_security_level,
/client/proc/view_chemical_reaction_logs,
/client/proc/makePAI
/client/proc/makePAI,
/datum/admins/proc/paralyze_mob
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
@@ -303,7 +304,8 @@ var/list/admin_verbs_mod = list(
/datum/admins/proc/show_player_panel,
/client/proc/check_antagonists,
/client/proc/jobbans,
/client/proc/cmd_admin_subtle_message /*send an message to somebody as a 'voice in their head'*/
/client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/
/datum/admins/proc/paralyze_mob
)
var/list/admin_verbs_mentor = list(

View File

@@ -54,7 +54,7 @@
update_icon()
/obj/effect/blob/proc/expand(var/turf/T)
if(istype(T, /turf/unsimulated/) || istype(T, /turf/space))
if(istype(T, /turf/unsimulated/) || istype(T, /turf/space) || (istype(T, /turf/simulated/mineral) && T.density))
return
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/SW = T

View File

@@ -45,8 +45,8 @@
if(href_list["flavor_text"])
switch(href_list["flavor_text"])
if("open")
else if("general")
var/msg = sanitize(input(usr,"Give a general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(pref.flavor_texts[href_list["task"]])) as message, extra = 0)
if("general")
var/msg = sanitize(input(usr,"Give a general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(pref.flavor_texts[href_list["flavor_text"]])) as message, extra = 0)
if(CanUseTopic(user))
pref.flavor_texts[href_list["flavor_text"]] = msg
else
@@ -59,7 +59,7 @@
else if(href_list["flavour_text_robot"])
switch(href_list["flavour_text_robot"])
if("open")
else if("Default")
if("Default")
var/msg = sanitize(input(usr,"Set the default flavour text for your robot. It will be used for any module without individual setting.","Flavour Text",html_decode(pref.flavour_texts_robot["Default"])) as message, extra = 0)
if(CanUseTopic(user))
pref.flavour_texts_robot[href_list["flavour_text_robot"]] = msg

View File

@@ -0,0 +1,26 @@
/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 ..()

View File

@@ -89,6 +89,9 @@
var/available_in_days = job.available_in_days(user.client)
. += "<del>[rank]</del></td><td> \[IN [(available_in_days)] DAYS]</td></tr>"
continue
if(job.minimum_character_age && user.client && (user.client.prefs.age < job.minimum_character_age))
. += "<del>[rank]</del></td><td> \[MINIMUM CHARACTER AGE: [job.minimum_character_age]]</td></tr>"
continue
if((pref.job_civilian_low & ASSISTANT) && (rank != "Assistant"))
. += "<font color=orange>[rank]</font></td><td></td></tr>"
continue

View File

@@ -108,6 +108,9 @@ datum/preferences
// OOC Metadata:
var/metadata = ""
// Communicator identity data
var/communicator_visibility = 0
var/client/client = null
var/datum/category_collection/player_setup_collection/player_setup

File diff suppressed because it is too large Load Diff

View File

@@ -38,7 +38,6 @@
icons.Add(usr.gun_setting_icon)
icons.Add(usr.item_use_icon)
icons.Add(usr.gun_move_icon)
icons.Add(usr.gun_run_icon)
icons.Add(usr.radio_use_icon)
var/icon/ic = all_ui_styles[UI_style_new]

View File

@@ -101,7 +101,6 @@
w_class = 1.0
throwforce = 2
slot_flags = SLOT_EARS
sprite_sheets = list("Resomi" = 'icons/mob/species/resomi/ears.dmi')
/obj/item/clothing/ears/attack_hand(mob/user as mob)
if (!user) return
@@ -209,10 +208,6 @@ BLIND // can't see anything
var/vision_flags = 0
var/darkness_view = 0//Base human is 2
var/see_invisible = -1
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi',
"Resomi" = 'icons/mob/species/resomi/eyes.dmi',
)
/obj/item/clothing/glasses/update_clothing_icon()
if (ismob(src.loc))
@@ -235,8 +230,7 @@ BLIND // can't see anything
attack_verb = list("challenged")
species_restricted = list("exclude","Unathi","Tajara", "Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/gloves.dmi',
"Resomi" = 'icons/mob/species/resomi/gloves.dmi',
"Vox" = 'icons/mob/species/vox/gloves.dmi'
)
/obj/item/clothing/gloves/update_clothing_icon()
@@ -293,8 +287,7 @@ BLIND // can't see anything
var/on = 0
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Resomi" = 'icons/mob/species/resomi/head.dmi'
"Vox" = 'icons/mob/species/vox/head.dmi'
)
/obj/item/clothing/head/attack_self(mob/user)
@@ -392,8 +385,7 @@ BLIND // can't see anything
slot_flags = SLOT_MASK
body_parts_covered = FACE|EYES
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/masks.dmi',
"Resomi" = 'icons/mob/species/resomi/masks.dmi',
"Vox" = 'icons/mob/species/vox/masks.dmi'
)
var/voicechange = 0
@@ -428,8 +420,7 @@ BLIND // can't see anything
var/overshoes = 0
species_restricted = list("exclude","Unathi","Tajara","Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/shoes.dmi',
"Resomi" = 'icons/mob/species/resomi/shoes.dmi',
"Vox" = 'icons/mob/species/vox/shoes.dmi'
)
/obj/item/clothing/shoes/proc/draw_knife()
@@ -503,8 +494,7 @@ BLIND // can't see anything
w_class = 3
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi',
"Resomi" = 'icons/mob/species/resomi/suit.dmi'
"Vox" = 'icons/mob/species/vox/suit.dmi'
)
/obj/item/clothing/suit/update_clothing_icon()
@@ -537,8 +527,7 @@ BLIND // can't see anything
var/displays_id = 1
var/rolled_down = -1 //0 = unrolled, 1 = rolled, -1 = cannot be toggled
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/uniform.dmi',
"Resomi" = 'icons/mob/species/resomi/uniform.dmi'
"Vox" = 'icons/mob/species/vox/uniform.dmi'
)
//convenience var for defining the icon state for the overlay used when the clothing is worn.

View File

@@ -28,8 +28,56 @@
icon_state = "skrell_cloth_female"
item_state = "skrell_cloth_female"
/obj/item/clothing/ears/skrell/cloth_female/black
name = "skrell headtail cloth"
desc = "A cloth shawl worn by female skrell draped around their head tails."
icon_state = "skrell_cloth_black_female"
item_state = "skrell_cloth_black_female"
/obj/item/clothing/ears/skrell/cloth_female/blue
name = "skrell headtail cloth"
desc = "A cloth shawl worn by female skrell draped around their head tails."
icon_state = "skrell_cloth_blue_female"
item_state = "skrell_cloth_blue_female"
/obj/item/clothing/ears/skrell/cloth_female/green
name = "skrell headtail cloth"
desc = "A cloth shawl worn by female skrell draped around their head tails."
icon_state = "skrell_cloth_green_female"
item_state = "skrell_cloth_green_female"
/obj/item/clothing/ears/skrell/cloth_female/pink
name = "skrell headtail cloth"
desc = "A cloth shawl worn by female skrell draped around their head tails."
icon_state = "skrell_cloth_pink_female"
item_state = "skrell_cloth_pink_female"
/obj/item/clothing/ears/skrell/cloth_male
name = "skrell headtail cloth"
desc = "A cloth band worn by male skrell around their head tails."
icon_state = "skrell_cloth_male"
item_state = "skrell_cloth_male"
item_state = "skrell_cloth_male"
/obj/item/clothing/ears/skrell/cloth_male/black
name = "skrell headtail cloth"
desc = "A cloth band worn by male skrell around their head tails."
icon_state = "skrell_cloth_black_male"
item_state = "skrell_cloth_black_male"
/obj/item/clothing/ears/skrell/cloth_male/blue
name = "skrell headtail cloth"
desc = "A cloth band worn by male skrell around their head tails."
icon_state = "skrell_cloth_blue_male"
item_state = "skrell_cloth_blue_male"
/obj/item/clothing/ears/skrell/cloth_male/green
name = "skrell headtail cloth"
desc = "A cloth band worn by male skrell around their head tails."
icon_state = "skrell_cloth_green_male"
item_state = "skrell_cloth_green_male"
/obj/item/clothing/ears/skrell/cloth_male/pink
name = "skrell headtail cloth"
desc = "A cloth band worn by male skrell around their head tails."
icon_state = "skrell_cloth_pink_male"
item_state = "skrell_cloth_pink_male"

View File

@@ -19,7 +19,6 @@
/obj/item/clothing/glasses/hud/health/prescription
name = "Prescription Health Scanner HUD"
desc = "A medical HUD integrated with a set of prescription glasses"
icon_state = "healthhud"
prescription = 1
icon_state = "healthhudpresc"
item_state = "healthhudpresc"
@@ -37,7 +36,6 @@
/obj/item/clothing/glasses/hud/security/prescription
name = "Prescription Security HUD"
desc = "A security HUD integrated with a set of prescription glasses"
icon_state = "securityhud"
prescription = 1
icon_state = "sechudpresc"
item_state = "sechudpresc"

View File

@@ -10,8 +10,7 @@
desc = "an ultra rare hat. It commands a certain respect."
icon_state = "petehat"
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Resomi" = 'icons/mob/species/resomi/head.dmi'
"Vox" = 'icons/mob/species/vox/head.dmi'
)
/obj/item/clothing/head/collectable/slime

View File

@@ -204,6 +204,13 @@
//end bs12 hats
/obj/item/clothing/head/cowboy_hat
name = "cowboy hat"
desc = "For those that have spurs that go jingle jangle jingle."
icon_state = "cowboyhat"
item_state = "cowboy_hat"
body_parts_covered = 0
/obj/item/clothing/head/witchwig
name = "witch costume wig"
desc = "Eeeee~heheheheheheh!"

View File

@@ -5,7 +5,7 @@
* Ushanka
* Pumpkin head
* Kitty ears
*
* Holiday hats
*/
/*
@@ -153,3 +153,15 @@
icon_state = "richard"
body_parts_covered = HEAD|FACE
flags_inv = BLOCKHAIR
/obj/item/clothing/head/santa
name = "santa hat"
desc = "It's a festive christmas hat, in red!"
icon_state = "santahatnorm"
body_parts_covered = 0
/obj/item/clothing/head/santa/green
name = "green santa hat"
desc = "It's a festive christmas hat, in green!"
icon_state = "santahatgreen"
body_parts_covered = 0

View File

@@ -851,7 +851,6 @@
return 0
// AIs are a bit slower than regular and ignore move intent.
wearer.last_move_intent = world.time + ai_controlled_move_delay
wearer_move_delay = world.time + ai_controlled_move_delay
var/tickcomp = 0

View File

@@ -355,17 +355,17 @@
icon_state = "puffervest"
item_state = "puffervest"
/obj/item/clothing/suit/jacket/miljacket
/obj/item/clothing/suit/storage/miljacket
name = "military jacket"
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable."
icon_state = "militaryjacket"
item_state = "militaryjacket"
icon_state = "militaryjacket_nobadge"
item_state = "militaryjacket_nobadge"
/obj/item/clothing/suit/jacket/miljacket2
/obj/item/clothing/suit/storage/miljacket/alt
name = "military jacket"
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable."
icon_state = "militaryjacket2"
item_state = "militaryjacket2"
icon_state = "militaryjacket_badge"
item_state = "militaryjacket_badge"
/obj/item/clothing/suit/storage/toggle/bomber
name = "bomber jacket"
@@ -478,6 +478,29 @@
icon_open = "yellow_hoodie_open"
icon_closed = "yellow_hoodie"
/obj/item/clothing/suit/storage/toggle/hoodie/cti
name = "CTI hoodie"
desc = "A warm, black sweatshirt. It bears the letters <20>CTI<54> on the back, a lettering to the prestigious university in Tau Ceti, Ceti Technical Institute. There is a blue supernova embroidered on the front, the emblem of CTI."
icon_state = "cti_hoodie"
item_state = "cti_hoodie"
icon_open = "cti_hoodie_open"
icon_closed = "cti_hoodie"
/obj/item/clothing/suit/storage/toggle/hoodie/mu
name = "mars university hoodie"
desc = "A warm, gray sweatshirt. It bears the letters <20>MU<4D> on the front, a lettering to the well-known public college, Mars University."
icon_state = "mu_hoodie"
item_state = "mu_hoodie"
icon_open = "mu_hoodie_open"
icon_closed = "mu_hoodie"
/obj/item/clothing/suit/storage/toggle/hoodie/nt
name = "NT hoodie"
desc = "A warm, blue sweatshirt. It proudly bears the silver NanoTrasen insignia lettering on the back. The edges are trimmed with silver."
icon_state = "nt_hoodie"
item_state = "nt_hoodie"
icon_open = "nt_hoodie_open"
icon_closed = "nt_hoodie"
// FUN!
@@ -557,12 +580,12 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/captain
name = "captain's winter coat"
icon_state = "coatcaptain"
armor = list(melee = 25, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0)
armor = list(melee = 20, bullet = 15, laser = 20, energy = 10, bomb = 15, bio = 0, rad = 0)
/obj/item/clothing/suit/storage/hooded/wintercoat/security
name = "security winter coat"
icon_state = "coatsecurity"
armor = list(melee = 25, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0)
armor = list(melee = 25, bullet = 20, laser = 20, energy = 15, bomb = 20, bio = 0, rad = 0)
/obj/item/clothing/suit/storage/hooded/wintercoat/medical
name = "medical winter coat"

View File

@@ -98,7 +98,7 @@
icon_state = icon_badge
usr << "You reveal \the [src]'s badge."
else
usr << "\The [src] does not have a vest badge."
usr << "\The [src] does not have a badge."
return
update_clothing_icon()

View File

@@ -5,8 +5,8 @@
slot = "utility"
var/obj/item/holstered = null
/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob)
if(holstered)
/obj/item/clothing/accessory/holster/proc/holster(var/obj/item/I, var/mob/living/user)
if(holstered && istype(user))
user << "<span class='warning'>There is already \a [holstered] holstered here!</span>"
return
@@ -14,6 +14,8 @@
user << "<span class='warning'>[I] won't fit in [src]!</span>"
return
if(istype(user))
user.stop_aiming(no_message=1)
holstered = I
user.drop_from_inventory(holstered)
holstered.loc = src

View File

@@ -566,3 +566,38 @@
icon_state = "blue_blazer"
item_state = "blue_blazer"
worn_state = "blue_blazer"
/obj/item/clothing/under/croptop
name = "crop top"
desc = "A shirt that has had the top cropped. This one is NT sponsored."
icon_state = "croptop"
item_state = "gy_suit"
worn_state = "croptop"
/obj/item/clothing/under/croptop/red
name = "red crop top"
desc = "A red shirt that has had the top cropped."
icon_state = "croptop_red"
item_state = "r_suit"
worn_state = "croptop_red"
/obj/item/clothing/under/croptop/grey
name = "grey crop top"
desc = "A grey shirt that has had the top cropped."
icon_state = "croptop_grey"
item_state = "gy_suit"
worn_state = "croptop_grey"
/obj/item/clothing/under/cuttop
name = "grey cut top"
desc = "A grey shirt that has had the top cut low."
icon_state = "cuttop"
item_state = "gy_suit"
worn_state = "cuttop"
/obj/item/clothing/under/cuttop/red
name = "red cut top"
desc = "A red shirt that has had the top cut low."
icon_state = "cuttop_red"
item_state = "r_suit"
worn_state = "cuttop_red"

View File

@@ -28,3 +28,59 @@
name = "grey athletic shorts"
icon_state = "greyshorts"
worn_state = "greyshorts"
/obj/item/clothing/under/shorts/jeans
name = "jeans shorts"
desc = "Some jeans! Just in short form!"
icon_state = "jeans_shorts"
worn_state = "jeans_shorts"
/obj/item/clothing/under/shorts/jeans/female
icon_state = "jeans_shorts_f"
worn_state = "jeans_shorts_f"
/obj/item/clothing/under/shorts/jeans/classic
name = "classic jeans shorts"
icon_state = "jeansclassic_shorts"
worn_state = "jeansclassic_shorts"
/obj/item/clothing/under/shorts/jeans/classic/female
icon_state = "jeansclassic_shorts_f"
worn_state = "jeansclassic_shorts_f"
/obj/item/clothing/under/shorts/jeans/mustang
name = "mustang jeans shorts"
icon_state = "jeansmustang_shorts"
worn_state = "jeansmustang_shorts"
/obj/item/clothing/under/shorts/jeans/mustang/female
icon_state = "jeansmustang_shorts_f"
worn_state = "jeansmustang_shorts_f"
/obj/item/clothing/under/shorts/jeans/youngfolks
name = "young folks jeans shorts"
icon_state = "jeansyoungfolks_shorts"
worn_state = "jeansyoungfolks_shorts"
/obj/item/clothing/under/shorts/jeans/youngfolks/female
icon_state = "jeansyoungfolks_shorts_f"
worn_state = "jeansyoungfolks_shorts_f"
/obj/item/clothing/under/shorts/jeans/black
name = "black jeans shorts"
icon_state = "black_shorts"
worn_state = "black_shorts"
/obj/item/clothing/under/shorts/jeans/black/female
icon_state = "black_shorts_f"
worn_state = "black_shorts_f"
/obj/item/clothing/under/shorts/khaki
name = "khaki shorts"
desc = "For that island getaway. It's five o'clock somewhere, right?"
icon_state = "khaki_shorts"
worn_state = "khaki_shorts"
/obj/item/clothing/under/shorts/khaki/female
icon_state = "khaki_shorts_f"
worn_state = "khaki_shorts_f"

View File

@@ -1,32 +0,0 @@
/obj/item/clothing/under/resomi
name = "small grey smock"
desc = "It looks fitted to nonhuman proportions."
icon = 'icons/obj/clothing/species/resomi/uniform.dmi'
icon_state = "resomi_grey"
worn_state = "resomi_grey"
species_restricted = list("Resomi")
/obj/item/clothing/under/resomi/white
name = "small white smock"
icon_state = "resomi_white"
worn_state = "resomi_white"
/obj/item/clothing/under/resomi/red
name = "small Security smock"
icon_state = "resomi_red"
worn_state = "resomi_red"
/obj/item/clothing/under/resomi/yellow
name = "small Engineering smock"
icon_state = "resomi_yellow"
worn_state = "resomi_yellow"
/obj/item/clothing/under/resomi/medical
name = "small Medical uniform"
icon_state = "resomi_medical"
worn_state = "resomi_medical"
/obj/item/clothing/under/resomi/rainbow
name = "small rainbow smock"
icon_state = "resomi_rainbow"
worn_state = "resomi_rainbow"

View File

@@ -18,3 +18,5 @@
/datum/event/communications_blackout/start()
for(var/obj/machinery/telecomms/T in telecomms_list)
T.emp_act(1)
for(var/obj/machinery/exonet_node/N in machines)
N.emp_act(1)

View File

@@ -2,6 +2,7 @@
endWhen = 36000
var/last_spam_time = 0
var/obj/machinery/message_server/useMS
var/obj/machinery/exonet_node/node
/datum/event/pda_spam/setup()
last_spam_time = world.time
@@ -19,6 +20,11 @@
//if there's no spam managed to get to receiver for five minutes, give up
kill()
return
if(!node)
node = get_exonet_node()
if(!node || !node.on || !node.allow_external_PDAs)
return
if(!useMS || !useMS.active)
useMS = null

View File

@@ -0,0 +1,22 @@
/obj/item/device/communicator
description_info = "This device allows someone to speak to another player sourced from the observer pool, as well as other communicators linked to it. \
To use the device, use it in your hand, and it will open an interface with various buttons. Near the bottom will be a list of devices currently available \
for you to call, both from communications on the station, and communicators very far away (observers). To call someone, send a communications request to \
someone and hope they respond, or receive one yourself and respond to them. Hanging up is also simple, and is handled in the 'Manage Connections' tab."
description_fluff = "As a concept, a device that allows long-distance communication has existed for over five hundred years. A device that can accomplish \
that while in space, across star systems, and that the consumer can afford and use without training, is much more recent, and is thanks to the backbone \
that is the Exonet.<br>\
<br>\
The Exonet is the predominant interstellar telecom system, servicing trillions of devices across a large portion of human-controlled space. \
It is distributed by a massive network of telecommunication satellites, some privately owned and others owned by the systems<6D> local governments, \
that utilize FTL technologies to bounce data between satellites at speeds that would not be possible at sub-light technology. This communicator \
uses a protocol called Exonet Protocol Version 2, generally shortened to EPv2.<br>\
<br>\
EPv2 is the most common communications protocol in the Exonet, and was specifically designed for it. It was designed to facilitate communication \
between any device in a star system, and have the ability to forward interstellar requests at the root node of that system<65>s Exonet. \
It is also built to cope with the reality that the numerous nodes in a system will likely have frequent outages. The protocol allows for \
up to 18,446,744,073,709,551,616 unique addresses, one of which is assigned to this device."
description_antag = "Electromagnetic pulses will cause the device to disconnect all linked communicators. Turning off the Exonet node at the Telecomms \
satellite will also accomplish this, but for all communicators on and near the station. This may be needed to allow for a quiet kill or capture."

View File

@@ -0,0 +1,36 @@
//This is not strictly a telecomms machine but conceptually it is.
/obj/machinery/exonet_node
description_info = "This machine is needed for several machines back at the colony to interact with systems beyond this region of space, such as \
communicators, external PDA messages, and even newscaster units, which host their content externally. You can fiddle with the device with \
just your hands, due to the integrated monitor and keyboard. Synthetic units can interface with it as well, just like most other machines."
description_fluff = "This is one of many nodes that make up the Exonet, which services trillions of devices across space. This particular node \
is referred to as a terminal node, servicing the Northern Star.<br>\
<br>\
In the beginning of humanity's ascend into space, the Exonet didn't exist. Instead, the Exonet is the evolution to a network called the Interplanetary \
Internet (sometimes referred to as the InterPlaNet), which was conceived and developed due to the limitations of the terrestrial Internet, mainly because \
the IP protocol was unsuitable for long range communications in space, due to the massive delays associated with lightspeed being unable to overcome \
the massive distances between planets in a timely manner. It was a store-and-forward network of smaller internets, distributed between various nodes, \
and was designed to be error, fault, and delay tolerant. The first nodes were put into space around the time when colonization had begun, to service humanity<74>s \
close holdings, such as Luna and Mars.<br>\
<br>\
By 2104, the Interplanetary Internet had coverage within most of Sol, but the network of networks were limited by the speed of light, and due \
to orbital mechanics, the delay for a request to be processed could vary. As an example, a direct message from Mars to Earth could take anywhere \
between three to twenty two minutes to get to Earth, and then the same amount of time to return to Mars. Coverage was also spotty due to the \
nature of operating at such vast distances.<br>\
<br>\
Fortunately, a method for traveling faster than light was discovered, which could allow data to be transmitted beyond the speed of light, \
and thus overcome the limitations of the Interplanetary Internet. One by one, each of the nodes were upgraded to utilize cutting edge \
(at the time) FTL technologies to rapidly increase response time.<br>\
<br>\
Once humanity had send colonists out beyond Sol, to other star systems such as Sirius and Alpha Centauri, they required their own interplanetary \
internet, so a new protocol had to be created, and another hardware upgrade for the separate interplanetary internets. The end result allowed \
communications between Sol and the various exosolar systems, and was dubbed the Exonet. It remains the most common way for consumers to engage \
in long range communications across planets and star systems. Generally, each system has their own Exonet, which is connected to all the other \
Exonets at the root node(s), and is typically arranged in a tree structure. The root node(s) are generally government-owned and are very secure \
and resilient to failure.<br>\
<br>\
This node is privately owned and maintained by Nanotrasen, and allows the colonists of the Northern Star to have access to the Exonet."
description_antag = "An EMP will disable this device for a short period of time. A longer downage can be achieved by turning it off, or rigging \
the APC it uses to turn off remotely, such as with a signaler in the right wire."

View File

@@ -74,12 +74,8 @@
return
//Drill through the flooring, if any.
if(istype(get_turf(src), /turf/simulated/floor/asteroid))
var/turf/simulated/floor/asteroid/T = get_turf(src)
if(!T.dug)
T.gets_dug()
else if(istype(get_turf(src), /turf/simulated/floor))
var/turf/simulated/floor/T = get_turf(src)
if(istype(get_turf(src), /turf/simulated))
var/turf/simulated/T = get_turf(src)
T.ex_act(2.0)
//Dig out the tasty ores.

View File

@@ -235,7 +235,7 @@
var/obj/item/stack/flag/F = locate() in get_turf(src)
var/turf/T = get_turf(src)
if(!T || !istype(T,/turf/simulated/floor/asteroid))
if(!T || !istype(T,/turf/simulated/mineral))
user << "The flag won't stand up in this terrain."
return

View File

@@ -1,3 +1,5 @@
var/list/mining_overlay_cache = list()
/**********************Mineral deposits**************************/
/turf/unsimulated/mineral
name = "impassable rock"
@@ -5,7 +7,7 @@
icon_state = "rock-dark"
/turf/simulated/mineral //wall piece
name = "Rock"
name = "rock"
icon = 'icons/turf/walls.dmi'
icon_state = "rock"
oxygen = 0
@@ -14,11 +16,13 @@
density = 1
blocks_air = 1
temperature = T0C
var/mined_turf = /turf/simulated/floor/asteroid
var/ore/mineral
var/sand_dug
var/mined_ore = 0
var/last_act = 0
var/emitter_blasts_taken = 0 // EMITTER MINING! Muhehe.
var/overlay_detail
var/datum/geosample/geologic_data
var/excavation_level = 0
@@ -28,26 +32,121 @@
var/excav_overlay = ""
var/obj/item/weapon/last_find
var/datum/artifact_find/artifact_find
var/ignore_mapgen
has_resources = 1
/turf/simulated/mineral/New()
spawn(0)
MineralSpread()
spawn(2)
updateMineralOverlays(1)
/turf/simulated/mineral/ignore_mapgen
ignore_mapgen = 1
/turf/simulated/mineral/proc/updateMineralOverlays(var/update_neighbors)
var/list/step_overlays = list("s" = NORTH, "n" = SOUTH, "w" = EAST, "e" = WEST)
for(var/direction in step_overlays)
var/turf/turf_to_check = get_step(src,step_overlays[direction])
if(update_neighbors && istype(turf_to_check,/turf/simulated/floor/asteroid))
var/turf/simulated/floor/asteroid/T = turf_to_check
T.updateMineralOverlays()
else if(istype(turf_to_check,/turf/space) || istype(turf_to_check,/turf/simulated/floor))
turf_to_check.overlays += image('icons/turf/walls.dmi', "rock_side_[direction]")
/turf/simulated/mineral/floor
name = "sand"
icon = 'icons/turf/flooring/asteroid.dmi'
icon_state = "asteroid"
density = 0
opacity = 0
blocks_air = 0
/turf/simulated/mineral/floor/ignore_mapgen
ignore_mapgen = 1
/turf/simulated/mineral/proc/make_floor()
if(!density && !opacity)
return
density = 0
opacity = 0
blocks_air = 0
update_general()
/turf/simulated/mineral/proc/make_wall()
if(density && opacity)
return
density = 1
opacity = 1
blocks_air = 1
update_general()
/turf/simulated/mineral/proc/update_general()
update_icon(1)
if(ticker && ticker.current_state == GAME_STATE_PLAYING)
reconsider_lights()
if(air_master)
air_master.mark_for_update(src)
/turf/simulated/mineral/Entered(atom/movable/M as mob|obj)
. = ..()
if(istype(M,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = M
if(R.module)
for(var/obj/item/weapon/storage/bag/ore/O in list(R.module_state_1, R.module_state_2, R.module_state_3))
attackby(O, R)
return
/turf/simulated/mineral/initialize()
if(prob(20))
overlay_detail = "asteroid[rand(0,9)]"
if(density)
spawn(0)
MineralSpread()
update_icon(1)
/turf/simulated/mineral/update_icon(var/update_neighbors)
overlays.Cut()
if(density)
if(mineral)
name = "[mineral.display_name] deposit"
else
name = "rock"
icon = 'icons/turf/walls.dmi'
icon_state = "rock"
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(istype(T) && !T.density)
var/place_dir = turn(direction, 180)
if(!mining_overlay_cache["rock_side_[place_dir]"])
mining_overlay_cache["rock_side_[place_dir]"] = image('icons/turf/walls.dmi', "rock_side", dir = place_dir)
T.overlays += mining_overlay_cache["rock_side_[place_dir]"]
else
name = "sand"
icon = 'icons/turf/flooring/asteroid.dmi'
icon_state = "asteroid"
if(sand_dug)
if(!mining_overlay_cache["dug_overlay"])
mining_overlay_cache["dug_overlay"] = image('icons/turf/flooring/asteroid.dmi', "dug_overlay")
overlays += mining_overlay_cache["dug_overlay"]
for(var/direction in cardinal)
if(istype(get_step(src, direction), /turf/space))
if(!mining_overlay_cache["asteroid_edge_[direction]"])
mining_overlay_cache["asteroid_edge_[direction]"] = image('icons/turf/flooring/asteroid.dmi', "asteroid_edges", dir = direction)
overlays += mining_overlay_cache["asteroid_edge_[direction]"]
else
var/turf/simulated/mineral/M = get_step(src, direction)
if(istype(M) && M.density)
if(!mining_overlay_cache["rock_side_[direction]"])
mining_overlay_cache["rock_side_[direction]"] = image('icons/turf/walls.dmi', "rock_side", dir = direction)
overlays += mining_overlay_cache["rock_side_[direction]"]
if(overlay_detail)
if(!mining_overlay_cache["decal_[overlay_detail]"])
mining_overlay_cache["decal_[overlay_detail]"] = image(icon = 'icons/turf/flooring/decals.dmi', icon_state = overlay_detail)
overlays += mining_overlay_cache["decal_[overlay_detail]"]
if(update_neighbors)
for(var/direction in alldirs)
if(istype(get_step(src, direction), /turf/simulated/mineral))
var/turf/simulated/mineral/M = get_step(src, direction)
M.update_icon()
/turf/simulated/mineral/ex_act(severity)
switch(severity)
if(2.0)
if (prob(70))
@@ -62,13 +161,17 @@
// Emitter blasts
if(istype(Proj, /obj/item/projectile/beam/emitter))
emitter_blasts_taken++
if(emitter_blasts_taken > 2) // 3 blasts per tile
mined_ore = 1
GetDrilled()
/turf/simulated/mineral/Bumped(AM)
. = ..()
if(!density)
return .
if(istype(AM,/mob/living/carbon/human))
var/mob/living/carbon/human/H = AM
if((istype(H.l_hand,/obj/item/weapon/pickaxe)) && (!H.hand))
@@ -91,7 +194,7 @@
for(var/trydir in cardinal)
if(prob(mineral.spread_chance))
var/turf/simulated/mineral/target_turf = get_step(src, trydir)
if(istype(target_turf) && !target_turf.mineral)
if(istype(target_turf) && target_turf.density && !target_turf.mineral)
target_turf.mineral = mineral
target_turf.UpdateMineral()
target_turf.MineralSpread()
@@ -99,143 +202,213 @@
/turf/simulated/mineral/proc/UpdateMineral()
clear_ore_effects()
if(!mineral)
name = "\improper Rock"
icon_state = "rock"
return
name = "\improper [mineral.display_name] deposit"
new /obj/effect/mineral(src, mineral)
if(mineral)
new /obj/effect/mineral(src, mineral)
update_icon()
//Not even going to touch this pile of spaghetti
/turf/simulated/mineral/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
usr << "\red You don't have the dexterity to do this!"
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
return
if (istype(W, /obj/item/device/core_sampler))
geologic_data.UpdateNearbyArtifactInfo(src)
var/obj/item/device/core_sampler/C = W
C.sample_item(src, user)
return
if(!density)
if (istype(W, /obj/item/device/depth_scanner))
var/obj/item/device/depth_scanner/C = W
C.scan_atom(user, src)
return
var/list/usable_tools = list(
/obj/item/weapon/shovel,
/obj/item/weapon/pickaxe/diamonddrill,
/obj/item/weapon/pickaxe/drill,
/obj/item/weapon/pickaxe/borgdrill
)
if (istype(W, /obj/item/device/measuring_tape))
var/obj/item/device/measuring_tape/P = W
user.visible_message("\blue[user] extends [P] towards [src].","\blue You extend [P] towards [src].")
if(do_after(user,25))
user << "\blue \icon[P] [src] has been excavated to a depth of [2*excavation_level]cm."
return
var/valid_tool
for(var/valid_type in usable_tools)
if(istype(W,valid_type))
valid_tool = 1
break
if (istype(W, /obj/item/weapon/pickaxe))
var/turf/T = user.loc
if (!( istype(T, /turf) ))
return
var/obj/item/weapon/pickaxe/P = W
if(last_act + P.digspeed > world.time)//prevents message spam
return
last_act = world.time
playsound(user, P.drill_sound, 20, 1)
//handle any archaeological finds we might uncover
var/fail_message
if(finds && finds.len)
var/datum/find/F = finds[1]
if(excavation_level + P.excavation_amount > F.excavation_required)
//Chance to destroy / extract any finds here
fail_message = ". <b>[pick("There is a crunching noise","[W] collides with some different rock","Part of the rock face crumbles away","Something breaks under [W]")]</b>"
user << "\red You start [P.drill_verb][fail_message ? fail_message : ""]."
if(fail_message && prob(90))
if(prob(25))
excavate_find(5, finds[1])
else if(prob(50))
finds.Remove(finds[1])
if(prob(50))
artifact_debris()
if(do_after(user,P.digspeed))
user << "\blue You finish [P.drill_verb] the rock."
if(finds && finds.len)
var/datum/find/F = finds[1]
if(round(excavation_level + P.excavation_amount) == F.excavation_required)
//Chance to extract any items here perfectly, otherwise just pull them out along with the rock surrounding them
if(excavation_level + P.excavation_amount > F.excavation_required)
//if you can get slightly over, perfect extraction
excavate_find(100, F)
else
excavate_find(80, F)
else if(excavation_level + P.excavation_amount > F.excavation_required - F.clearance_range)
//just pull the surrounding rock out
excavate_find(0, F)
if( excavation_level + P.excavation_amount >= 100 )
//if players have been excavating this turf, leave some rocky debris behind
var/obj/structure/boulder/B
if(artifact_find)
if( excavation_level > 0 || prob(15) )
//boulder with an artifact inside
B = new(src)
if(artifact_find)
B.artifact_find = artifact_find
else
artifact_debris(1)
else if(prob(15))
//empty boulder
B = new(src)
if(B)
GetDrilled(0)
else
GetDrilled(1)
if(valid_tool)
if (sand_dug)
user << "<span class='warning'>This area has already been dug.</span>"
return
excavation_level += P.excavation_amount
var/turf/T = user.loc
if (!(istype(T)))
return
//archaeo overlays
if(!archaeo_overlay && finds && finds.len)
var/datum/find/F = finds[1]
if(F.excavation_required <= excavation_level + F.view_range)
archaeo_overlay = "overlay_archaeo[rand(1,3)]"
overlays += archaeo_overlay
user << "<span class='notice'>You start digging.</span>"
playsound(user.loc, 'sound/effects/rustle1.ogg', 50, 1)
//there's got to be a better way to do this
var/update_excav_overlay = 0
if(excavation_level >= 75)
if(excavation_level - P.excavation_amount < 75)
update_excav_overlay = 1
else if(excavation_level >= 50)
if(excavation_level - P.excavation_amount < 50)
update_excav_overlay = 1
else if(excavation_level >= 25)
if(excavation_level - P.excavation_amount < 25)
update_excav_overlay = 1
if(!do_after(user,40)) return
//update overlays displaying excavation level
if( !(excav_overlay && excavation_level > 0) || update_excav_overlay )
var/excav_quadrant = round(excavation_level / 25) + 1
excav_overlay = "overlay_excv[excav_quadrant]_[rand(1,3)]"
overlays += excav_overlay
user << "<span class='notice'>You dug a hole.</span>"
GetDrilled()
else if(istype(W,/obj/item/weapon/storage/bag/ore))
var/obj/item/weapon/storage/bag/ore/S = W
if(S.collection_mode)
for(var/obj/item/weapon/ore/O in contents)
O.attackby(W,user)
return
else if(istype(W,/obj/item/weapon/storage/bag/fossils))
var/obj/item/weapon/storage/bag/fossils/S = W
if(S.collection_mode)
for(var/obj/item/weapon/fossil/F in contents)
F.attackby(W,user)
return
else if(istype(W, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = W
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
new /obj/structure/lattice(get_turf(src))
else if(istype(W, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = W
if (S.get_amount() < 1)
return
qdel(L)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ChangeTurf(/turf/simulated/floor)
S.use(1)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
return
//drop some rocks
next_rock += P.excavation_amount * 10
while(next_rock > 100)
next_rock -= 100
var/obj/item/weapon/ore/O = new(src)
geologic_data.UpdateNearbyArtifactInfo(src)
O.geologic_data = geologic_data
else
return attack_hand(user)
if (istype(W, /obj/item/device/core_sampler))
geologic_data.UpdateNearbyArtifactInfo(src)
var/obj/item/device/core_sampler/C = W
C.sample_item(src, user)
return
if (istype(W, /obj/item/device/depth_scanner))
var/obj/item/device/depth_scanner/C = W
C.scan_atom(user, src)
return
if (istype(W, /obj/item/device/measuring_tape))
var/obj/item/device/measuring_tape/P = W
user.visible_message("<span class='notice'>\The [user] extends \a [P] towards \the [src].</span>","<span class='notice'>You extend \the [P] towards \the [src].</span>")
if(do_after(user,25))
user << "<span class='notice'>\icon[P] [src] has been excavated to a depth of [2*excavation_level]cm.</span>"
return
if (istype(W, /obj/item/weapon/pickaxe))
var/turf/T = user.loc
if (!( istype(T, /turf) ))
return
var/obj/item/weapon/pickaxe/P = W
if(last_act + P.digspeed > world.time)//prevents message spam
return
last_act = world.time
playsound(user, P.drill_sound, 20, 1)
//handle any archaeological finds we might uncover
var/fail_message
if(finds && finds.len)
var/datum/find/F = finds[1]
if(excavation_level + P.excavation_amount > F.excavation_required)
//Chance to destroy / extract any finds here
fail_message = ". <b>[pick("There is a crunching noise","[W] collides with some different rock","Part of the rock face crumbles away","Something breaks under [W]")]</b>"
user << "<span class='notice'>You start [P.drill_verb][fail_message ? fail_message : ""].</span>"
if(fail_message && prob(90))
if(prob(25))
excavate_find(5, finds[1])
else if(prob(50))
finds.Remove(finds[1])
if(prob(50))
artifact_debris()
if(do_after(user,P.digspeed))
user << "<span class='notice'>You finish [P.drill_verb] \the [src].</span>"
if(finds && finds.len)
var/datum/find/F = finds[1]
if(round(excavation_level + P.excavation_amount) == F.excavation_required)
//Chance to extract any items here perfectly, otherwise just pull them out along with the rock surrounding them
if(excavation_level + P.excavation_amount > F.excavation_required)
//if you can get slightly over, perfect extraction
excavate_find(100, F)
else
excavate_find(80, F)
else if(excavation_level + P.excavation_amount > F.excavation_required - F.clearance_range)
//just pull the surrounding rock out
excavate_find(0, F)
if( excavation_level + P.excavation_amount >= 100 )
//if players have been excavating this turf, leave some rocky debris behind
var/obj/structure/boulder/B
if(artifact_find)
if( excavation_level > 0 || prob(15) )
//boulder with an artifact inside
B = new(src)
if(artifact_find)
B.artifact_find = artifact_find
else
artifact_debris(1)
else if(prob(15))
//empty boulder
B = new(src)
if(B)
GetDrilled(0)
else
GetDrilled(1)
return
excavation_level += P.excavation_amount
//archaeo overlays
if(!archaeo_overlay && finds && finds.len)
var/datum/find/F = finds[1]
if(F.excavation_required <= excavation_level + F.view_range)
archaeo_overlay = "overlay_archaeo[rand(1,3)]"
overlays += archaeo_overlay
//there's got to be a better way to do this
var/update_excav_overlay = 0
if(excavation_level >= 75)
if(excavation_level - P.excavation_amount < 75)
update_excav_overlay = 1
else if(excavation_level >= 50)
if(excavation_level - P.excavation_amount < 50)
update_excav_overlay = 1
else if(excavation_level >= 25)
if(excavation_level - P.excavation_amount < 25)
update_excav_overlay = 1
//update overlays displaying excavation level
if( !(excav_overlay && excavation_level > 0) || update_excav_overlay )
var/excav_quadrant = round(excavation_level / 25) + 1
excav_overlay = "overlay_excv[excav_quadrant]_[rand(1,3)]"
overlays += excav_overlay
//drop some rocks
next_rock += P.excavation_amount * 10
while(next_rock > 100)
next_rock -= 100
var/obj/item/weapon/ore/O = new(src)
geologic_data.UpdateNearbyArtifactInfo(src)
O.geologic_data = geologic_data
return
return attack_hand(user)
/turf/simulated/mineral/proc/clear_ore_effects()
for(var/obj/effect/mineral/M in contents)
@@ -244,7 +417,6 @@
/turf/simulated/mineral/proc/DropMineral()
if(!mineral)
return
clear_ore_effects()
var/obj/item/weapon/ore/O = new mineral.ore (src)
if(istype(O))
@@ -253,7 +425,15 @@
return O
/turf/simulated/mineral/proc/GetDrilled(var/artifact_fail = 0)
//var/destroyed = 0 //used for breaking strange rocks
if(!density)
if(!sand_dug)
sand_dug = 1
for(var/i=0;i<(rand(3)+2);i++)
new/obj/item/weapon/ore/glass(src)
update_icon()
return
if (mineral && mineral.result_amount)
//if the turf has already been excavated, some of it's ore has been removed
@@ -267,7 +447,7 @@
if(prob(50))
pain = 1
for(var/mob/living/M in range(src, 200))
M << "<font color='red'><b>[pick("A high pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fading away!</b></font>"
M << "<span class='danger'>[pick("A high-pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fading away!</span>"
if(pain)
flick("pain",M.pain)
if(prob(50))
@@ -278,25 +458,8 @@
M.Stun(5)
M.apply_effect(25, IRRADIATE)
var/list/step_overlays = list("n" = NORTH, "s" = SOUTH, "e" = EAST, "w" = WEST)
//Add some rubble, you did just clear out a big chunk of rock.
var/turf/simulated/floor/asteroid/N = ChangeTurf(mined_turf)
// Kill and update the space overlays around us.
for(var/direction in step_overlays)
var/turf/space/T = get_step(src, step_overlays[direction])
if(istype(T))
T.overlays.Cut()
for(var/next_direction in step_overlays)
if(istype(get_step(T, step_overlays[next_direction]),/turf/simulated/mineral))
T.overlays += image('icons/turf/walls.dmi', "rock_side_[next_direction]")
if(istype(N))
N.overlay_detail = "asteroid[rand(0,9)]"
N.updateMineralOverlays(1)
make_floor()
update_icon(1)
/turf/simulated/mineral/proc/excavate_find(var/prob_clean = 0, var/datum/find/F)
//with skill and luck, players can cleanly extract finds
@@ -311,7 +474,7 @@
//some find types delete the /obj/item/weapon/archaeological_find and replace it with something else, this handles when that happens
//yuck
var/display_name = "something"
var/display_name = "Something"
if(!X)
X = last_find
if(X)
@@ -322,12 +485,11 @@
var/obj/effect/suspension_field/S = locate() in src
if(!S || S.field_type != get_responsive_reagent(F.find_type))
if(X)
visible_message("\red<b>[pick("[display_name] crumbles away into dust","[display_name] breaks apart")].</b>")
visible_message("<span class='danger'>\The [pick("[display_name] crumbles away into dust","[display_name] breaks apart")].</span>")
qdel(X)
finds.Remove(F)
/turf/simulated/mineral/proc/artifact_debris(var/severity = 0)
//cael's patented random limited drop componentized loot system!
//sky's patented not-fucking-retarded overhaul!
@@ -336,219 +498,34 @@
for(var/j in 1 to rand(1, 3 + max(min(severity, 1), 0) * 2))
switch(rand(1,7))
if(1)
var/obj/item/stack/rods/R = new(src)
R.amount = rand(5,25)
new /obj/item/stack/rods(src, rand(5,25))
if(2)
var/obj/item/stack/material/plasteel/R = new(src)
R.amount = rand(5,25)
new /obj/item/stack/material/plasteel(src, rand(5,25))
if(3)
var/obj/item/stack/material/steel/R = new(src)
R.amount = rand(5,25)
new /obj/item/stack/material/steel(src, rand(5,25))
if(4)
var/obj/item/stack/material/plasteel/R = new(src)
R.amount = rand(5,25)
new /obj/item/stack/material/plasteel(src, rand(5,25))
if(5)
var/quantity = rand(1,3)
for(var/i=0, i<quantity, i++)
for(var/i=1 to rand(1,3))
new /obj/item/weapon/material/shard(src)
if(6)
var/quantity = rand(1,3)
for(var/i=0, i<quantity, i++)
for(var/i=1 to rand(1,3))
new /obj/item/weapon/material/shard/phoron(src)
if(7)
var/obj/item/stack/material/uranium/R = new(src)
R.amount = rand(5,25)
new /obj/item/stack/material/uranium(src, rand(5,25))
/turf/simulated/mineral/random
name = "Mineral deposit"
var/mineralSpawnChanceList = list("Uranium" = 5, "Platinum" = 5, "Iron" = 35, "Coal" = 35, "Diamond" = 1, "Gold" = 5, "Silver" = 5, "Phoron" = 10)
var/mineralChance = 100 //10 //means 10% chance of this plot changing to a mineral deposit
/turf/simulated/mineral/random/New()
if (prob(mineralChance) && !mineral)
var/mineral_name = pickweight(mineralSpawnChanceList) //temp mineral name
mineral_name = lowertext(mineral_name)
if (mineral_name && (mineral_name in ore_data))
mineral = ore_data[mineral_name]
UpdateMineral()
. = ..()
/turf/simulated/mineral/random/high_chance
mineralChance = 100 //25
mineralSpawnChanceList = list("Uranium" = 10, "Platinum" = 10, "Iron" = 20, "Coal" = 20, "Diamond" = 2, "Gold" = 10, "Silver" = 10, "Phoron" = 20)
/**********************Asteroid**************************/
// Setting icon/icon_state initially will use these values when the turf is built on/replaced.
// This means you can put grass on the asteroid etc.
/turf/simulated/floor/asteroid
name = "sand"
icon = 'icons/turf/flooring/asteroid.dmi'
icon_state = "asteroid"
base_name = "sand"
base_desc = "Gritty and unpleasant."
base_icon = 'icons/turf/flooring/asteroid.dmi'
base_icon_state = "asteroid"
initial_flooring = null
oxygen = 0
nitrogen = 0
temperature = TCMB
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
var/overlay_detail
has_resources = 1
/turf/simulated/floor/asteroid/New()
if(prob(20))
overlay_detail = "asteroid[rand(0,9)]"
/turf/simulated/floor/asteroid/ex_act(severity)
switch(severity)
if(3.0)
return
if(2.0)
if (prob(70))
gets_dug()
if(1.0)
gets_dug()
return
/turf/simulated/floor/asteroid/is_plating()
return 0
/turf/simulated/floor/asteroid/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(!W || !user)
return 0
var/list/usable_tools = list(
/obj/item/weapon/shovel,
/obj/item/weapon/pickaxe/diamonddrill,
/obj/item/weapon/pickaxe/drill,
/obj/item/weapon/pickaxe/borgdrill
)
var/valid_tool
for(var/valid_type in usable_tools)
if(istype(W,valid_type))
valid_tool = 1
break
if(valid_tool)
if (dug)
user << "\red This area has already been dug"
return
var/turf/T = user.loc
if (!(istype(T)))
return
user << "\red You start digging."
playsound(user.loc, 'sound/effects/rustle1.ogg', 50, 1)
if(!do_after(user,40)) return
user << "\blue You dug a hole."
gets_dug()
else if(istype(W,/obj/item/weapon/storage/bag/ore))
var/obj/item/weapon/storage/bag/ore/S = W
if(S.collection_mode)
for(var/obj/item/weapon/ore/O in contents)
O.attackby(W,user)
return
else if(istype(W,/obj/item/weapon/storage/bag/fossils))
var/obj/item/weapon/storage/bag/fossils/S = W
if(S.collection_mode)
for(var/obj/item/weapon/fossil/F in contents)
F.attackby(W,user)
return
else if(istype(W, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = W
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
new /obj/structure/lattice(get_turf(src))
/turf/simulated/mineral/proc/make_ore(var/rare_ore)
if(mineral)
return
else if(istype(W, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = W
if (S.get_amount() < 1)
return
qdel(L)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ChangeTurf(/turf/simulated/floor/airless)
S.use(1)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
return
var/mineral_name
if(rare_ore)
mineral_name = pickweight(list("uranium" = 10, "platinum" = 10, "iron" = 20, "coal" = 20, "diamond" = 2, "gold" = 10, "silver" = 10, "phoron" = 20))
else
..(W,user)
return
mineral_name = pickweight(list("uranium" = 5, "platinum" = 5, "iron" = 35, "coal" = 35, "diamond" = 1, "gold" = 5, "silver" = 5, "phoron" = 10))
/turf/simulated/floor/asteroid/proc/gets_dug()
if(dug)
return
for(var/i=0;i<(rand(3)+2);i++)
new/obj/item/weapon/ore/glass(src)
dug = 1
icon_state = "asteroid_dug"
return
/turf/simulated/floor/asteroid/proc/updateMineralOverlays(var/update_neighbors)
overlays.Cut()
var/list/step_overlays = list("n" = NORTH, "s" = SOUTH, "e" = EAST, "w" = WEST)
for(var/direction in step_overlays)
if(istype(get_step(src, step_overlays[direction]), /turf/space))
overlays += image('icons/turf/floors.dmi', "asteroid_edge_[direction]")
if(istype(get_step(src, step_overlays[direction]), /turf/simulated/mineral))
overlays += image('icons/turf/walls.dmi', "rock_side_[direction]")
//todo cache
if(overlay_detail) overlays |= image(icon = 'icons/turf/flooring/decals.dmi', icon_state = overlay_detail)
if(update_neighbors)
var/list/all_step_directions = list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,SOUTHWEST,WEST,NORTHWEST)
for(var/direction in all_step_directions)
var/turf/simulated/floor/asteroid/A
if(istype(get_step(src, direction), /turf/simulated/floor/asteroid))
A = get_step(src, direction)
A.updateMineralOverlays()
/turf/simulated/floor/asteroid/Entered(atom/movable/M as mob|obj)
..()
if(istype(M,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = M
if(R.module)
if(istype(R.module_state_1,/obj/item/weapon/storage/bag/ore))
attackby(R.module_state_1,R)
else if(istype(R.module_state_2,/obj/item/weapon/storage/bag/ore))
attackby(R.module_state_2,R)
else if(istype(R.module_state_3,/obj/item/weapon/storage/bag/ore))
attackby(R.module_state_3,R)
else
return
if(mineral_name && (mineral_name in ore_data))
mineral = ore_data[mineral_name]
UpdateMineral()
update_icon()

View File

@@ -8,8 +8,7 @@ var/list/holder_mob_icon_cache = list()
slot_flags = SLOT_HEAD | SLOT_HOLSTER
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Resomi" = 'icons/mob/species/resomi/head.dmi'
"Vox" = 'icons/mob/species/vox/head.dmi'
)
origin_tech = null

View File

@@ -165,6 +165,7 @@ var/list/slot_equipment_priority = list( \
// Removes an item from inventory and places it in the target atom.
// If canremove or other conditions need to be checked then use unEquip instead.
/mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
if(W)
if(!Target)
Target = loc

View File

@@ -114,25 +114,6 @@
new_name = pick(ai_names)
return new_name
/datum/language/resomi
name = "Resomi"
desc = "A trilling language spoken by the diminutive Resomi."
speech_verb = "chirps"
ask_verb = "chirrups"
exclaim_verb = "trills"
colour = "alien"
key = "v"
flags = WHITELISTED
space_chance = 50
syllables = list(
"ca", "ra", "ma", "sa", "na", "ta", "la", "sha", "scha", "a", "a",
"ce", "re", "me", "se", "ne", "te", "le", "she", "sche", "e", "e",
"ci", "ri", "mi", "si", "ni", "ti", "li", "shi", "schi", "i", "i"
)
/datum/language/resomi/get_random_name(gender)
return ..(gender, 1, 4, 1.5)
//Syllable Lists
/*
This list really long, mainly because I can't make up my mind about which mandarin syllables should be removed,

View File

@@ -49,6 +49,8 @@
if(shock_stage >= 10) tally += 3
if(aiming && aiming.aiming_at) tally += 5 // Iron sights make you slower, it's a well-known fact.
if(FAT in src.mutations)
tally += 1.5
if (bodytemperature < 283.222)

View File

@@ -375,7 +375,7 @@
safe_pressure_min *= 1.25
var/safe_exhaled_max = 10
var/safe_toxins_max = 0.005
var/safe_toxins_max = 0.2
var/SA_para_min = 1
var/SA_sleep_min = 5
var/inhaled_gas_used = 0

View File

@@ -1,114 +0,0 @@
/datum/species/resomi
name = "Resomi"
name_plural = "Resomii"
blurb = "A race of feathered raptors who developed on a cold world, almost \
outside of the Goldilocks zone. Extremely fragile, they developed hunting skills \
that emphasized taking out their prey without themselves getting hit. They are an \
advanced post-scarcity culture on good terms with Skrellian and Human interests."
num_alternate_languages = 2
secondary_langs = list("Resomi")
name_language = "Resomi"
blood_color = "#D514F7"
flesh_color = "#5F7BB0"
base_color = "#001144"
tail = "resomitail"
tail_hair = "feathers"
icobase = 'icons/mob/human_races/r_resomi.dmi'
deform = 'icons/mob/human_races/r_resomi.dmi'
damage_overlays = 'icons/mob/human_races/masks/dam_resomi.dmi'
damage_mask = 'icons/mob/human_races/masks/dam_mask_resomi.dmi'
blood_mask = 'icons/mob/human_races/masks/blood_resomi.dmi'
eyes = "eyes_resomi"
slowdown = -1
total_health = 50
brute_mod = 1.35
burn_mod = 1.35
mob_size = MOB_SMALL
holder_type = /obj/item/weapon/holder/human
short_sighted = 1
gluttonous = 1
spawn_flags = CAN_JOIN | IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR
bump_flag = MONKEY
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN
cold_level_1 = 180
cold_level_2 = 130
cold_level_3 = 70
heat_level_1 = 320
heat_level_2 = 370
heat_level_3 = 600
heat_discomfort_level = 292
heat_discomfort_strings = list(
"Your feathers prickle in the heat.",
"You feel uncomfortably warm.",
)
cold_discomfort_level = 180
has_limbs = list(
"chest" = list("path" = /obj/item/organ/external/chest),
"groin" = list("path" = /obj/item/organ/external/groin),
"head" = list("path" = /obj/item/organ/external/head),
"l_arm" = list("path" = /obj/item/organ/external/arm),
"r_arm" = list("path" = /obj/item/organ/external/arm/right),
"l_leg" = list("path" = /obj/item/organ/external/leg),
"r_leg" = list("path" = /obj/item/organ/external/leg/right),
"l_hand" = list("path" = /obj/item/organ/external/hand/resomi),
"r_hand" = list("path" = /obj/item/organ/external/hand/right/resomi),
"l_foot" = list("path" = /obj/item/organ/external/foot/resomi),
"r_foot" = list("path" = /obj/item/organ/external/foot/right/resomi)
)
has_organ = list(
"heart" = /obj/item/organ/heart,
"lungs" = /obj/item/organ/lungs,
"liver" = /obj/item/organ/liver,
"kidneys" = /obj/item/organ/kidneys,
"brain" = /obj/item/organ/brain,
"eyes" = /obj/item/organ/eyes
)
unarmed_types = list(
/datum/unarmed_attack/bite/sharp,
/datum/unarmed_attack/claws,
/datum/unarmed_attack/stomp/weak
)
var/shock_cap = 30
var/hallucination_cap = 25
// I'm... so... ronrery, so ronery...
/datum/species/resomi/handle_environment_special(var/mob/living/carbon/human/H)
// If they're dead or unconcious they're a bit beyond this kind of thing.
if(H.stat)
return
// No point processing if we're already stressing the hell out.
if(H.hallucination >= hallucination_cap && H.shock_stage >= shock_cap)
return
// Check for company.
for(var/mob/living/M in viewers(H))
if(M == H || M.stat == DEAD || M.invisibility > H.see_invisible)
continue
if(M.faction == "neutral" || M.faction == H.faction)
return
// No company? Suffer :(
if(H.shock_stage < shock_cap)
H.shock_stage += 1
if(H.shock_stage >= shock_cap && H.hallucination < hallucination_cap)
H.hallucination += 2.5
/datum/species/resomi/get_vision_flags(var/mob/living/carbon/human/H)
if(!(H.sdisabilities & DEAF) && !H.ear_deaf)
return SEE_SELF|SEE_MOBS
else
return SEE_SELF

View File

@@ -429,17 +429,6 @@ var/global/list/damage_icon_parts = list()
overlays_standing[MUTATIONS_LAYER] = null
if(update_icons) update_icons()
//Call when target overlay should be added/removed
/mob/living/carbon/human/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
qdel(target_locked)
if (!targeted_by)
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
/* --------------------------------------- */
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
@@ -502,6 +491,7 @@ var/global/list/damage_icon_parts = list()
//need to append _s to the icon state for legacy compatibility
var/image/standing = image(icon = under_icon, icon_state = "[under_state]_s")
standing.color = w_uniform.color
//apply blood overlay
if(w_uniform.blood_DNA)
@@ -562,6 +552,7 @@ var/global/list/damage_icon_parts = list()
bloodsies.color = gloves.blood_color
standing.overlays += bloodsies
gloves.screen_loc = ui_gloves
standing.color = gloves.color
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
@@ -637,6 +628,7 @@ var/global/list/damage_icon_parts = list()
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
standing.color = shoes.color
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
@@ -702,6 +694,7 @@ var/global/list/damage_icon_parts = list()
if(hat.on && light_overlay_cache[cache_key])
standing.overlays |= light_overlay_cache[cache_key]
standing.color = head.color
overlays_standing[HEAD_LAYER] = standing
else
@@ -736,6 +729,8 @@ var/global/list/damage_icon_parts = list()
if(!i_state) i_state = i.icon_state
standing.overlays += image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[i_state]")
standing.color = belt.color
overlays_standing[belt_layer] = standing
else
overlays_standing[BELT_LAYER] = null
@@ -759,6 +754,7 @@ var/global/list/damage_icon_parts = list()
t_icon = wear_suit.item_icons[slot_wear_suit_str]
standing = image("icon" = t_icon, "icon_state" = "[wear_suit.icon_state]")
standing.color = wear_suit.color
if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) )
drop_from_inventory(handcuffed)
@@ -800,6 +796,7 @@ var/global/list/damage_icon_parts = list()
standing = image("icon" = wear_mask.sprite_sheets[species.get_bodytype()], "icon_state" = "[wear_mask.icon_state]")
else
standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]")
standing.color = wear_mask.color
if( !istype(wear_mask, /obj/item/clothing/mask/smokable/cigarette) && wear_mask.blood_DNA )
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood")
@@ -839,8 +836,12 @@ var/global/list/damage_icon_parts = list()
else
overlay_state = back.icon_state
//apply color
var/image/standing = image(icon = overlay_icon, icon_state = overlay_state)
standing.color = back.color
//create the image
overlays_standing[BACK_LAYER] = image(icon = overlay_icon, icon_state = overlay_state)
overlays_standing[BACK_LAYER] = standing
else
overlays_standing[BACK_LAYER] = null
@@ -919,7 +920,11 @@ var/global/list/damage_icon_parts = list()
else
t_icon = INV_R_HAND_DEF_ICON
overlays_standing[R_HAND_LAYER] = image(icon = t_icon, icon_state = t_state)
//apply color
var/image/standing = image(icon = t_icon, icon_state = t_state)
standing.color = r_hand.color
overlays_standing[R_HAND_LAYER] = standing
if (handcuffed) drop_r_hand() //this should be moved out of icon code
else
@@ -951,7 +956,11 @@ var/global/list/damage_icon_parts = list()
else
t_icon = INV_L_HAND_DEF_ICON
overlays_standing[L_HAND_LAYER] = image(icon = t_icon, icon_state = t_state)
//apply color
var/image/standing = image(icon = t_icon, icon_state = t_state)
standing.color = l_hand.color
overlays_standing[L_HAND_LAYER] = standing
if (handcuffed) drop_l_hand() //This probably should not be here
else

View File

@@ -703,14 +703,6 @@
icon_state = module_sprites[icontype]
return
//Call when target overlay should be added/removed
/mob/living/silicon/robot/update_targeted()
if(!targeted_by && target_locked)
qdel(target_locked)
updateicon()
if (targeted_by && target_locked)
overlays += target_locked
/mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock)
src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]"

View File

@@ -16,9 +16,9 @@
maxHealth = 20
health = 20
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
harm_intent_damage = 10
melee_damage_lower = 3
melee_damage_upper = 3
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'

View File

@@ -6,14 +6,15 @@
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
health = 80
maxHealth = 80
melee_damage_lower = 25
melee_damage_upper = 50
health = 40
maxHealth = 40
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "chomped"
attack_sound = 'sound/weapons/bite.ogg'
faction = "creature"
speed = 4
speed = 8
harm_intent_damage = 10
/mob/living/simple_animal/hostile/creature/cult
faction = "cult"

View File

@@ -9,13 +9,13 @@
response_help = "passes through"
response_disarm = "shoves"
response_harm = "hits"
speed = -1
maxHealth = 80
health = 80
speed = 8
maxHealth = 50
health = 50
harm_intent_damage = 10
melee_damage_lower = 15
melee_damage_upper = 15
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "gripped"
attack_sound = 'sound/hallucinations/growl1.ogg'
@@ -50,6 +50,7 @@
/mob/living/simple_animal/hostile/faithless/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return

View File

@@ -365,14 +365,6 @@
return (0)
return 1
//Call when target overlay should be added/removed
/mob/living/simple_animal/update_targeted()
if(!targeted_by && target_locked)
qdel(target_locked)
overlays = null
if (targeted_by && target_locked)
overlays += target_locked
/mob/living/simple_animal/say(var/message)
var/verb = "says"
if(speak_emote.len)

View File

@@ -1,13 +1,11 @@
//A very, very simple mob that exists inside other objects to talk and has zero influence on the world.
/mob/living/voice
name = "unknown"
name = "unknown person"
desc = "How are you examining me?"
// default_language = "Galactic Common"
see_invisible = SEE_INVISIBLE_LIVING
var/obj/item/device/communicator/comm = null
emote_type = 2 //This lets them emote through containers. The communicator has a image feed of the person calling them so...
var/stable_connection = 0 //If set to zero, makes the mob effectively deaf, mute, and blind, due to interferance.
/mob/living/voice/New(loc)
add_language("Galactic Common")
@@ -20,11 +18,15 @@
comm = loc
..()
// Proc: transfer_identity()
// Parameters: 1 (speaker - the mob (usually an observer) to copy information from)
// Description: Copies the mob's icons, overlays, TOD, gender, currently loaded character slot, and languages, to src.
/mob/living/voice/proc/transfer_identity(mob/speaker)
if(ismob(speaker))
icon = speaker.icon
icon_state = speaker.icon_state
overlays = speaker.overlays
timeofdeath = speaker.timeofdeath
alpha = 127 //Maybe we'll have hologram calls later.
if(speaker.client && speaker.client.prefs)
@@ -36,6 +38,9 @@
for(var/language in p.alternate_languages)
add_language(language)
// Proc: Login()
// Parameters: None
// Description: Adds a static overlay to the client's screen.
/mob/living/voice/Login()
var/obj/screen/static_effect = new() //Since what the player sees is essentially a video feed, from a vast distance away, the view isn't going to be perfect.
static_effect.screen_loc = ui_entire_screen
@@ -44,10 +49,23 @@
static_effect.mouse_opacity = 0 //So the static doesn't get in the way of clicking.
client.screen.Add(static_effect)
// Proc: Destroy()
// Parameters: None
// Description: Removes reference to the communicator, so it can qdel() successfully.
/mob/living/voice/Destroy()
comm = null
..()
// Proc: ghostize()
// Parameters: None
// Description: Sets a timeofdeath variable, to fix the free respawn bug.
/mob/living/voice/ghostize()
timeofdeath = world.time
. = ..()
// Verb: hang_up()
// Parameters: None
// Description: Disconnects the voice mob from the communicator.
/mob/living/voice/verb/hang_up()
set name = "Hang Up"
set category = "Communicator"
@@ -55,40 +73,53 @@
set src = usr
if(comm)
comm.close_connection(src, "[src] hung up")
comm.close_connection(user = src, target = src, reason = "[src] hung up")
else
src << "You appear to not be inside a communicator. This is a bug and you should report it."
// Verb: change_name()
// Parameters: None
// Description: Allows the voice mob to change their name, assuming it is valid.
/mob/living/voice/verb/change_name()
set name = "Change Name"
set category = "Communicator"
set desc = "Changes your name."
set src = usr
var/new_name = sanitizeSafe(input(src, "Who would you like to be now?", "Communicator", src.client.prefs.real_name) as text, MAX_NAME_LEN)
if(new_name)
if(comm)
comm.visible_message("<span class='notice'>\icon[comm] [src.name] has left, and now you see [new_name].</span>")
//Do a bit of logging in-case anyone tries to impersonate other characters for whatever reason.
var/msg = "[src.client.key] ([src]) has changed their communicator identity's name to [new_name]."
message_admins(msg)
log_game(msg)
src.name = new_name
else
src << "<span class='warning'>Invalid name. Rejected.</span>"
// Proc: Life()
// Parameters: None
// Description: Checks the active variable on the Exonet node, and kills the mob if it goes down or stops existing.
/mob/living/voice/Life()
if(comm && comm.server && !comm.server.active)
comm.close_connection(src,"Connection to telecommunications array timed out")
if(comm)
if(!comm.node || !comm.node.on || !comm.node.allow_external_communicators)
comm.close_connection(user = src, target = src, reason = "Connection to telecommunications array timed out")
..()
// Proc: say()
// Parameters: 4 (generic say() arguments)
// Description: Adds a speech bubble to the communicator device, then calls ..() to do the real work.
/mob/living/voice/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
// world << "say() was called. Arguments: ([message], [speaking], [verb], [alt_name])."
if(!stable_connection)
return 0
//Speech bubbles.
if(comm)
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
var/image/speech_bubble = image('icons/mob/talk.dmi',comm,"h[speech_bubble_test]")
spawn(30)
qdel(speech_bubble)
for(var/mob/M in hearers(world.view,comm)) //simplifed since it's just a speech bubble
for(var/mob/M in hearers(comm)) //simplifed since it's just a speech bubble
M << speech_bubble
src << speech_bubble
..(message, speaking, verb, alt_name) //mob/living/say() can do the actual talking.
/*
/mob/verb/test_voice_mob()
set name = "Make Voice Mob"
set category = "Debug"
set desc = "For testing only!"
set src = usr
var/turf/T = get_turf(src)
var/obj/item/device/communicator/comm = new(T)
comm.open_connection(src, src)
*/
..(message, speaking, verb, alt_name) //mob/living/say() can do the actual talking.

View File

@@ -39,7 +39,6 @@
pain = null
item_use_icon = null
gun_move_icon = null
gun_run_icon = null
gun_setting_icon = null
spell_masters = null
zone_sel = null
@@ -765,8 +764,8 @@
if(lying)
density = 0
drop_l_hand()
drop_r_hand()
if(l_hand) unEquip(l_hand)
if(r_hand) unEquip(r_hand)
else
density = initial(density)

View File

@@ -265,7 +265,7 @@
return 0
move_delay = world.time//set move delay
mob.last_move_intent = world.time + 10
switch(mob.m_intent)
if("run")
if(mob.drowsyness > 0)

View File

@@ -375,9 +375,11 @@
else // Crew transfer initiated
dat += "<font color='red'>The station is currently undergoing crew transfer procedures.</font><br>"
dat += "Choose from the following open positions:<br>"
dat += "Choose from the following open/valid positions:<br>"
for(var/datum/job/job in job_master.occupations)
if(job && IsJobAvailable(job.title))
if(job.minimum_character_age && (client.prefs.age < job.minimum_character_age))
continue
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10)

View File

@@ -61,21 +61,6 @@
name = "Short Hair 2"
icon_state = "hair_shorthair3"
resomi
name = "Resomi Plumage"
icon_state = "resomi_default"
species_allowed = list("Resomi")
resomi_ears
name = "Resomi Ears"
icon_state = "resomi_ears"
species_allowed = list("Resomi")
resomi_excited
name = "Resomi Spiky"
icon_state = "resomi_spiky"
species_allowed = list("Resomi")
cut
name = "Cut Hair"
icon_state = "hair_c"
@@ -152,6 +137,10 @@
name = "Side Ponytail"
icon_state = "hair_stail"
sideponytail4 //Not happy about this... but it's for the save files.
name = "Side Ponytail 2"
icon_state = "hair_ponytailf"
sideponytail2
name = "One Shoulder"
icon_state = "hair_oneshoulder"
@@ -160,6 +149,10 @@
name = "Tress Shoulder"
icon_state = "hair_tressshoulder"
wisp
name = "Wisp"
icon_state = "hair_wisp"
parted
name = "Parted"
icon_state = "hair_parted"

View File

@@ -15,7 +15,7 @@ var/global/datum/robolimb/basic_robolimb
var/desc = "A generic unbranded robotic prosthesis." // Seen when examining a limb.
var/icon = 'icons/mob/human_races/robotic.dmi' // Icon base to draw from.
var/unavailable_at_chargen // If set, not available at chargen.
var/list/species_cannot_use = list("Resomi")
var/list/species_cannot_use = list()
/datum/robolimb/bishop
company = "Bishop Cybernetics"

View File

@@ -1,8 +0,0 @@
/obj/item/organ/external/foot/resomi
body_hair = "feathers"
/obj/item/organ/external/foot/right/resomi
body_hair = "feathers"
/obj/item/organ/external/hand/resomi
body_hair = "feathers"
/obj/item/organ/external/hand/right/resomi
body_hair = "feathers"

View File

@@ -107,7 +107,7 @@
if(process_projectile(P, user, user, pick("l_foot", "r_foot")))
handle_post_fire(user, user)
user.visible_message(
"<span class='danger'>[user] shoots \himself in the foot with \the [src]!</span>",
"<span class='danger'>\The [user] shoots \himself in the foot with \the [src]!</span>",
"<span class='danger'>You shoot yourself in the foot with \the [src]!</span>"
)
M.drop_item()
@@ -123,17 +123,17 @@
/obj/item/weapon/gun/afterattack(atom/A, mob/living/user, adjacent, params)
if(adjacent) return //A is adjacent, is the user, or is on the user's person
//decide whether to aim or shoot normally
var/aiming = 0
if(user && user.client && !(A in aim_targets))
if(user.client.gun_mode)
aiming = PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at.
if(!user.aiming)
user.aiming = new(user)
if (!aiming)
if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on
user << "\red You refrain from firing your [src] as your intent is set to help."
else
Fire(A,user,params) //Otherwise, fire normally.
if(user && user.client && user.aiming && user.aiming.active && user.aiming.aiming_at != A)
PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at.
return
if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on
user << "<span class='warning'>You refrain from firing your [src] as your intent is set to help.</span>"
else
Fire(A,user,params) //Otherwise, fire normally.
/obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone)
if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot)

View File

@@ -28,11 +28,12 @@
/obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun()
set name = "Name Gun"
set category = "Object"
set desc = "Rename your gun. If you're the detective."
set desc = "Rename your gun. If you're Security."
var/mob/M = usr
if(!M.mind) return 0
if(!M.mind.assigned_role == "Detective")
var/job = M.mind.assigned_role
if(job != "Detective" && job != "Security Officer" && job != "Warden" && job != "Head of Security")
M << "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>"
return 0
@@ -44,9 +45,9 @@
return 1
/obj/item/weapon/gun/projectile/colt/detective/verb/reskin_gun()
set name = "Reskin gun"
set name = "Resprite gun"
set category = "Object"
set desc = "Click to reskin your gun."
set desc = "Click to choose a sprite for your gun."
var/mob/M = usr
var/list/options = list()
@@ -57,11 +58,11 @@
options["H&K VP"] = "VP78"
options["P08 Luger"] = "p08"
options["P08 Luger, Brown"] = "p08b"
var/choice = input(M,"What do you want to skin the gun to?","Reskin Gun") in options
var/choice = input(M,"What do you want the gun's sprite to be?","Resprite Gun") in options
if(src && choice && !M.stat && in_range(M,src))
icon_state = options[choice]
unique_reskin = options[choice]
M << "Your gun is now skinned as [choice]. Say hello to your new friend."
M << "Your gun is now sprited as [choice]. Say hello to your new friend."
return 1
/obj/item/weapon/gun/projectile/sec

View File

@@ -1,407 +0,0 @@
/obj/item/weapon/gun/verb/toggle_firerate()
set name = "Toggle Continue Aiming"
set category = "Object"
keep_aim = !keep_aim
if (keep_aim)
loc << "You will now continue firing when your target moves."
else
loc << "You will now only fire once, then lower your aim, when your target moves."
/obj/item/weapon/gun/verb/lower_aim()
set name = "Lower Aim"
set category = "Object"
if(aim_targets)
stop_aim()
usr.visible_message("<span class='notice'> \The [usr] lowers \the [src]...</span>")
//Removing the lock and the buttons.
/obj/item/weapon/gun/dropped(mob/user as mob)
stop_aim()
if(user && user.client)
user.client.remove_gun_icons()
return ..()
/obj/item/weapon/gun/equipped(var/mob/user, var/slot)
if (slot != slot_l_hand && slot != slot_r_hand)
stop_aim()
if (user.client)
user.client.remove_gun_icons()
return ..()
//Removes lock from all targets
/obj/item/weapon/gun/proc/stop_aim()
if(aim_targets)
for(var/mob/living/M in aim_targets)
if(M)
M.NotTargeted(src) //Untargeting people.
aim_targets = null
//Compute how to fire.....
//Return 1 if a target was found, 0 otherwise.
/obj/item/weapon/gun/proc/PreFire(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, params)
//Lets not spam it.
if(lock_time > world.time - 2) return
user.set_dir(get_cardinal_dir(src, A))
if(isliving(A) && !(A in aim_targets))
Aim(A) //Clicked a mob, aim at them
return 1
//Didn't click someone, check if there is anyone along that guntrace
var/mob/living/M = GunTrace(usr.x,usr.y,A.x,A.y,usr.z,usr) //Find dat mob.
if(isliving(M) && (M in view(user)) && !(M in aim_targets))
Aim(M) //Aha! Aim at them!
return 1
return 0
//Aiming at the target mob.
/obj/item/weapon/gun/proc/Aim(var/mob/living/M)
if(!aim_targets || !(M in aim_targets))
admin_attack_log(usr, M, "Pointed a [src] at [M]", "Had a [src] aimed at them, by [usr]", "aims a gun ([src]) (MODE: [src.mode_name]) at")
lock_time = world.time
if(aim_targets && !multi_aim) //If they're targeting someone and they have a non multi_aim weapon.
for(var/mob/living/L in aim_targets)
if(L)
L.NotTargeted(src)
aim_targets = null
usr.visible_message("<span class='danger'><b>[usr] turns \the [src] on [M]!</b></span>")
else
usr.visible_message("<span class='danger'><b>[usr] aims \a [src] at [M]!</b></span>")
M.Targeted(src)
//HE MOVED, SHOOT HIM!
/obj/item/weapon/gun/proc/TargetActed(var/mob/living/T)
var/mob/living/M = loc
if(M == T) return
if(!istype(M)) return
if(src != M.get_active_hand())
stop_aim()
return
//reflex firing is disabled when help intent is set
if (M.a_intent == I_HELP)
M << "<span class='danger'>You refrain from firing your [src] as your intent is set to help.</span>"
return
M.last_move_intent = world.time
var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
if(firing_check > 0)
if(firing_check == 1)
Fire(T,usr, reflex = 1)
else if(!told_cant_shoot)
M << "<span class='danger'>They can't be hit from here!</span>"
told_cant_shoot = 1
spawn(30)
told_cant_shoot = 0
usr.set_dir(get_cardinal_dir(src, T))
if (!keep_aim) // If keep_aim is set to lower aim after one shot, untarget the target
T.NotTargeted(src)
//Yay, math!
#define SIGN(X) ((X<0)?-1:1)
/proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16)
//bluh << "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z]."
var/turf/T
var/mob/living/M
if(X1==X2)
if(Y1==Y2) return 0 //Light cannot be blocked on same tile
else
var/s = SIGN(Y2-Y1)
Y1+=s
while(1)
T = locate(X1,Y1,Z)
if(!T) return 0
M = locate() in T
if(M) return M
M = locate() in orange(1,T)-exc_obj
if(M) return M
Y1+=s
else
var
m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
signX = SIGN(X2-X1)
signY = SIGN(Y2-Y1)
if(X1<X2) b+=m
while(1)
var/xvert = round(m*X1+b-Y1)
if(xvert) Y1+=signY //Line exits tile vertically
else X1+=signX //Line exits tile horizontally
T = locate(X1,Y1,Z)
if(!T) return 0
M = locate() in T
if(M) return M
M = locate() in orange(1,T)-exc_obj
if(M) return M
return 0
//Targeting management procs
/mob/var
list/targeted_by
target_time = -100
last_move_intent = -100
last_target_click = -5
target_locked = null
last_target_radio = -5;
/mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
if(!I.aim_targets)
I.aim_targets = list(src)
else if(I.multi_aim && I.aim_targets.len < 5) //multi_aim weapon, they can hold down a room.
I.aim_targets += src
else if(I.aim_targets.len >= 5)
if(ismob(I.loc))
I.loc << "You can only target 5 people at once!"
return
else
return
for(var/mob/living/K in viewers(usr))
K << 'sound/weapons/TargetOn.ogg'
if(!targeted_by) targeted_by = list()
targeted_by += I
I.lock_time = world.time + 20 //Target has 2 second to realize they're targeted and stop (or target the opponent).
src << "((<span class='danger'><b>Your character is being targeted. They have 2 seconds to stop any click or move actions.</b></span> While targeted, they may \
drag and drop items in or into the map, speak, and click on interface buttons. Clicking on the map objects (floors and walls are fine), their items \
(other than a weapon to de-target), moving, or talking into a radio will result in being fired upon. <span class='danger'>The aggressor may also fire manually, \
so try not to get on their bad side.</span>))"
if(targeted_by.len == 1)
spawn(0)
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locking")
overlays += target_locked
spawn(0)
sleep(20)
if(target_locked)
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locked")
update_targeted()
//Adding the buttons to the controller person
var/mob/living/T = I.loc
if(T)
if(T.client)
T.client.add_gun_icons()
else
I.lower_aim()
return
if(iscarbon(src) && m_intent == "run" && T.client.target_can_move == 1 && T.client.target_can_run == 0)
src << "<span class='danger'>Your move intent is now set to walk, as your targeter permits it.</span>" //Self explanitory.
set_m_intent("walk")
//Processing the aiming. Should be probably in separate object with process() but lasy.
while(targeted_by && T.client)
if(last_move_intent > I.lock_time + 10 && !T.client.target_can_move) //If target moved when not allowed to
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
else if(last_move_intent > I.lock_time + 10 && !T.client.target_can_run && m_intent == "run") //If the target ran while targeted
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
if(last_target_click > I.lock_time + 10 && !T.client.target_can_click) //If the target clicked the map to pick something up/shoot/etc
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
if(last_target_radio > I.lock_time + 10 && !T.client.target_can_radio)
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
sleep(1)
/mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I)
if(!I.silenced)
for(var/mob/living/M in viewers(src))
M << 'sound/weapons/TargetOff.ogg'
targeted_by -= I
I.aim_targets.Remove(src) //De-target them
if(!I.aim_targets.len)
I.aim_targets = null
var/mob/living/T = I.loc //Remove the targeting icons
if(T && ismob(T) && !I.aim_targets && T.client)
T.client.remove_gun_icons()
if(!targeted_by.len)
qdel(target_locked) //Remove the overlay
targeted_by.Cut()
spawn(1) update_targeted()
/mob/living/Move()
. = ..()
for(var/obj/item/weapon/gun/G in targeted_by) //Handle moving out of the gunner's view.
var/mob/living/M = G.loc
if(!(M in view(src)))
NotTargeted(G)
for(var/obj/item/weapon/gun/G in src) //Handle the gunner loosing sight of their target/s
if(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(M && !(M in view(src)))
M.NotTargeted(G)
//If you move out of range, it isn't going to still stay locked on you any more.
/client/var
target_can_move = 0
target_can_run = 0
target_can_click = 0
target_can_radio = 0
gun_mode = 0
//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
/client/proc/add_gun_icons()
if(!usr) return 1 // This can runtime if someone manages to throw a gun out of their hand before the proc is called.
screen += usr.item_use_icon
screen += usr.gun_move_icon
screen += usr.radio_use_icon
if (target_can_move)
screen += usr.gun_run_icon
/client/proc/remove_gun_icons()
if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG
screen -= usr.item_use_icon
screen -= usr.gun_move_icon
screen -= usr.radio_use_icon
if (target_can_move)
screen -= usr.gun_run_icon
/client/verb/ToggleGunMode()
set name = "Toggle Gun Mode"
set hidden = 1
gun_mode = !gun_mode
if(gun_mode)
usr << "You will now take people captive."
else
usr << "You will now shoot where you target."
for(var/obj/item/weapon/gun/G in usr)
G.stop_aim()
remove_gun_icons()
if(usr.gun_setting_icon)
usr.gun_setting_icon.icon_state = "gun[gun_mode]"
/client/verb/AllowTargetMove()
set hidden=1
//Changing client's permissions
target_can_move = !target_can_move
if(target_can_move)
usr << "Target may now walk."
//usr.gun_run_icon = new /obj/screen/gun/run(null) //adding icon for running permission
screen += usr.gun_run_icon
else
usr << "Target may no longer move."
target_can_run = 0
qdel(usr.gun_run_icon) //no need for icon for running permission
//Updating walking permission button
if(usr.gun_move_icon)
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in usr)
G.lock_time = world.time + 5
if(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(target_can_move)
M << "Your character may now <b>walk</b> at the discretion of their targeter."
if(!target_can_run)
M << "<span class='danger'>Your move intent is now set to walk, as your targeter permits it.</span>"
M.set_m_intent("walk")
else
M << "<span class='danger'><b>Your character will now be shot if they move.</b></span>"
/mob/living/proc/set_m_intent(var/intent)
if (intent != "walk" && intent != "run")
return 0
m_intent = intent
if(hud_used)
if (hud_used.move_intent)
hud_used.move_intent.icon_state = intent == "walk" ? "walking" : "running"
client/verb/AllowTargetRun()
set hidden=1
//Changing client's permissions
target_can_run = !target_can_run
if(target_can_run)
usr << "Target may now run."
else
usr << "Target may no longer run."
//Updating running permission button
if(usr.gun_run_icon)
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(target_can_run)
M << "Your character may now <b>run</b> at the discretion of their targeter."
else
M << "<span class='danger'><b>Your character will now be shot if they run.</b></span>"
/client/verb/AllowTargetClick()
set hidden=1
//Changing client's permissions
target_can_click = !target_can_click
if(target_can_click)
usr << "Target may now use items."
else
usr << "Target may no longer use items."
if(usr.item_use_icon)
usr.item_use_icon.icon_state = "no_item[target_can_click]"
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(target_can_click)
M << "Your character may now <b>use items</b> at the discretion of their targeter."
else
M << "<span class='danger'><b>Your character will now be shot if they use items.</b></span>"
/client/verb/AllowTargetRadio()
set hidden=1
target_can_radio = !target_can_radio
if(target_can_radio)
usr << "Target may now use radio."
else
usr << "Target may no longer use radio."
if(usr.radio_use_icon)
usr.radio_use_icon.icon_state = "no_radio[target_can_radio]"
usr.radio_use_icon.name = "[target_can_radio ? "Disallow" : "Allow"] Radio Use"
//Handling change for all the guns on client
for(var/obj/item/weapon/gun/G in src)
G.lock_time = world.time + 5
if(G.aim_targets)
for(var/mob/living/M in G.aim_targets)
if(target_can_radio)
M << "Your character may now <b>use the radio</b> at the discretion of their targeter."
else
M << "<span class='danger'><b>Your character will now be shot if they use the radio.</b></span>"

View File

@@ -0,0 +1,12 @@
//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
/client/proc/add_gun_icons()
if(!usr) return 1 // This can runtime if someone manages to throw a gun out of their hand before the proc is called.
screen |= usr.item_use_icon
screen |= usr.gun_move_icon
screen |= usr.radio_use_icon
/client/proc/remove_gun_icons()
if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG
screen -= usr.item_use_icon
screen -= usr.gun_move_icon
screen -= usr.radio_use_icon

View File

@@ -0,0 +1,21 @@
//Removing the lock and the buttons.
/obj/item/weapon/gun/dropped(var/mob/living/user)
if(istype(user))
user.stop_aiming(src)
return ..()
/obj/item/weapon/gun/equipped(var/mob/living/user, var/slot)
if(istype(user) && (slot != slot_l_hand && slot != slot_r_hand))
user.stop_aiming(src)
return ..()
//Compute how to fire.....
//Return 1 if a target was found, 0 otherwise.
/obj/item/weapon/gun/proc/PreFire(var/atom/A, var/mob/living/user, var/params)
if(!user.aiming)
user.aiming = new(user)
user.face_atom(A)
if(ismob(A) && user.aiming)
user.aiming.aim_at(A, src)
return 1
return 0

View File

@@ -0,0 +1,52 @@
/mob/living/var/obj/aiming_overlay/aiming
/mob/living/var/list/aimed = list()
/mob/living/proc/stop_aiming(var/obj/item/thing, var/no_message = 0)
if(!aiming)
aiming = new(src)
if(thing && aiming.aiming_with != thing)
return
aiming.cancel_aiming(no_message)
/mob/living/death(gibbed,deathmessage="seizes up and falls limp...")
if(..())
stop_aiming(no_message=1)
/mob/living/update_canmove()
..()
if(lying)
stop_aiming(no_message=1)
/mob/living/Weaken(amount)
stop_aiming(no_message=1)
..()
/mob/living/Destroy()
if(aiming)
qdel(aiming)
aiming = null
aimed.Cut()
return ..()
/turf/Enter(var/mob/living/mover)
. = ..()
if(istype(mover))
if(mover.aiming && mover.aiming.aiming_at)
mover.aiming.update_aiming()
if(mover.aimed.len)
mover.trigger_aiming(TARGET_CAN_MOVE)
/mob/living/forceMove(var/atom/destination)
. = ..()
if(aiming && aiming.aiming_at)
aiming.update_aiming()
if(aimed.len)
trigger_aiming(TARGET_CAN_MOVE)
/mob/living/proc/set_m_intent(var/intent)
if (intent != "walk" && intent != "run")
return 0
m_intent = intent
if(hud_used)
if (hud_used.move_intent)
hud_used.move_intent.icon_state = intent == "walk" ? "walking" : "running"

View File

@@ -0,0 +1,215 @@
/obj/aiming_overlay
name = ""
desc = "Stick 'em up!"
icon = 'icons/effects/Targeted.dmi'
icon_state = "locking"
anchored = 1
density = 0
opacity = 0
layer = FLY_LAYER
simulated = 0
mouse_opacity = 0
var/mob/living/aiming_at // Who are we currently targeting, if anyone?
var/obj/item/aiming_with // What are we targeting with?
var/mob/owner // Who do we belong to?
var/locked = 0 // Have we locked on?
var/lock_time = 0 // When -will- we lock on?
var/active = 0 // Is our owner intending to take hostages?
var/target_permissions = 0 // Permission bitflags.
/obj/aiming_overlay/New(var/newowner)
..()
owner = newowner
loc = null
verbs.Cut()
/obj/aiming_overlay/proc/toggle_permission(var/perm)
if(target_permissions & perm)
target_permissions &= ~perm
else
target_permissions |= perm
// Update HUD icons.
if(owner.gun_move_icon)
if(!(target_permissions & TARGET_CAN_MOVE))
owner.gun_move_icon.icon_state = "no_walk0"
owner.gun_move_icon.name = "Allow Movement"
else
owner.gun_move_icon.icon_state = "no_walk1"
owner.gun_move_icon.name = "Disallow Movement"
if(owner.item_use_icon)
if(!(target_permissions & TARGET_CAN_CLICK))
owner.item_use_icon.icon_state = "no_item0"
owner.item_use_icon.name = "Allow Item Use"
else
owner.item_use_icon.icon_state = "no_item1"
owner.item_use_icon.name = "Disallow Item Use"
if(owner.radio_use_icon)
if(!(target_permissions & TARGET_CAN_RADIO))
owner.radio_use_icon.icon_state = "no_radio0"
owner.radio_use_icon.name = "Allow Radio Use"
else
owner.radio_use_icon.icon_state = "no_radio1"
owner.radio_use_icon.name = "Disallow Radio Use"
var/message = "no longer permitted to "
var/use_span = "warning"
if(target_permissions & perm)
message = "now permitted to "
use_span = "notice"
switch(perm)
if(TARGET_CAN_MOVE)
message += "move"
if(TARGET_CAN_CLICK)
message += "use items"
if(TARGET_CAN_RADIO)
message += "use a radio"
else
return
owner << "<span class='[use_span]'>[aiming_at ? "\The [aiming_at] is" : "Your targets are"] [message].</span>"
if(aiming_at)
aiming_at << "<span class='[use_span]'>You are [message].</span>"
/obj/aiming_overlay/process()
if(!owner)
qdel(src)
return
..()
update_aiming()
/obj/aiming_overlay/Destroy()
if(aiming_at)
aiming_at.aimed -= src
aiming_at = null
owner = null
aiming_with = null
processing_objects -= src
return ..()
obj/aiming_overlay/proc/update_aiming_deferred()
set waitfor = 0
sleep(0)
update_aiming()
/obj/aiming_overlay/proc/update_aiming()
if(!owner)
qdel(src)
return
if(!aiming_at)
cancel_aiming()
return
if(!locked && lock_time >= world.time)
locked = 1
update_icon()
var/cancel_aim = 1
if(!(aiming_with in owner) || (owner.l_hand != aiming_with && owner.r_hand != aiming_with))
owner << "<span class='warning'>You must keep hold of your weapon!</span>"
else if(!aiming_at || !istype(aiming_at.loc, /turf))
owner << "<span class='warning'>You have lost sight of your target!</span>"
else if(owner.incapacitated() || owner.lying || owner.restrained())
owner << "<span class='warning'>You must be conscious and standing to keep track of your target!</span>"
else if(aiming_at.alpha == 0 || (aiming_at.invisibility > owner.see_invisible))
owner << "<span class='warning'>Your target has become invisible!</span>"
else if(get_dist(get_turf(owner), get_turf(aiming_at)) > 7) // !(owner in viewers(aiming_at, 7))
owner << "<span class='warning'>Your target is too far away to track!</span>"
else
cancel_aim = 0
forceMove(get_turf(aiming_at))
if(cancel_aim)
cancel_aiming()
return
if(!owner.incapacitated() && owner.client)
spawn(0)
owner.set_dir(get_dir(get_turf(owner), get_turf(src)))
/obj/aiming_overlay/proc/aim_at(var/mob/target, var/obj/thing)
if(!owner)
return
if(owner.incapacitated())
owner << "<span class='warning'>You cannot aim a gun in your current state.</span>"
return
if(owner.lying)
owner << "<span class='warning'>You cannot aim a gun while prone.</span>"
return
if(owner.restrained())
owner << "<span class='warning'>You cannot aim a gun while handcuffed.</span>"
return
if(aiming_at)
if(aiming_at == target)
return
aiming_at.aimed -= src
owner.visible_message("<span class='danger'>\The [owner] turns \the [thing] on \the [target]!</span>")
else
owner.visible_message("<span class='danger'>\The [owner] aims \the [thing] at \the [target]!</span>")
if(owner.client)
owner.client.add_gun_icons()
target << "<span class='danger'>You now have a gun pointed at you. No sudden moves!</span>"
aiming_with = thing
aiming_at = target
if(istype(aiming_with, /obj/item/weapon/gun))
playsound(get_turf(owner), 'sound/weapons/TargetOn.ogg', 50,1)
forceMove(get_turf(target))
processing_objects |= src
aiming_at.aimed |= src
toggle_active(1)
locked = 0
update_icon()
lock_time = world.time + 35
/obj/aiming_overlay/update_icon()
if(locked)
icon_state = "locked"
else
icon_state = "locking"
/obj/aiming_overlay/proc/toggle_active(var/force_state = null)
if(!isnull(force_state))
if(active == force_state)
return
active = force_state
else
active = !active
if(!active)
cancel_aiming()
if(owner.client)
if(active)
owner << "<span class='notice'>You will now aim rather than fire.</span>"
owner.client.add_gun_icons()
else
owner << "<span class='notice'>You will no longer aim rather than fire.</span>"
owner.client.remove_gun_icons()
/obj/aiming_overlay/proc/cancel_aiming(var/no_message = 0)
if(!aiming_with || !aiming_at)
return
if(istype(aiming_with, /obj/item/weapon/gun))
playsound(get_turf(owner), 'sound/weapons/TargetOff.ogg', 50,1)
if(!no_message)
owner.visible_message("<span class='notice'>\The [owner] lowers \the [aiming_with].</span>")
aiming_with = null
aiming_at.aimed -= src
aiming_at = null
loc = null
processing_objects -= src

View File

@@ -0,0 +1,29 @@
/mob/living/proc/trigger_aiming(var/trigger_type)
if(!aimed.len)
return
for(var/obj/aiming_overlay/AO in aimed)
if(AO.aiming_at == src)
AO.update_aiming()
if(AO.aiming_at == src)
AO.trigger(trigger_type)
AO.update_aiming_deferred()
/obj/aiming_overlay/proc/trigger(var/perm)
if(!owner || !aiming_with || !aiming_at || !locked)
return
if(perm && (target_permissions & perm))
return
if(!owner.canClick())
return
owner.setClickCooldown(5) // Spam prevention, essentially.
if(owner.a_intent == I_HELP)
owner << "<span class='warning'>You refrain from firing \the [aiming_with] as your intent is set to help.</span>"
return
owner.visible_message("<span class='danger'>\The [owner] pulls the trigger reflexively!</span>")
var/obj/item/weapon/gun/G = aiming_with
if(istype(G))
G.Fire(aiming_at, owner)
/mob/living/ClickOn(var/atom/A, var/params)
. = ..()
trigger_aiming(TARGET_CAN_CLICK)

View File

@@ -1,23 +1,10 @@
/datum/random_map/automata/cave_system
iterations = 5
descriptor = "moon caves"
wall_type = /turf/simulated/mineral
floor_type = /turf/simulated/floor/asteroid
target_turf_type = /turf/unsimulated/mask
var/mineral_sparse = /turf/simulated/mineral/random
var/mineral_rich = /turf/simulated/mineral/random/high_chance
var/list/ore_turfs = list()
/datum/random_map/automata/cave_system/get_appropriate_path(var/value)
switch(value)
if(DOOR_CHAR)
return mineral_sparse
if(EMPTY_CHAR)
return mineral_rich
if(FLOOR_CHAR)
return floor_type
if(WALL_CHAR)
return wall_type
return
/datum/random_map/automata/cave_system/get_map_char(var/value)
switch(value)
@@ -50,3 +37,20 @@
map[check_cell] = EMPTY_CHAR // Rare mineral block.
ore_count--
return 1
/datum/random_map/automata/cave_system/apply_to_turf(var/x,var/y)
var/current_cell = get_map_cell(x,y)
if(!current_cell)
return 0
var/turf/simulated/mineral/T = locate((origin_x-1)+x,(origin_y-1)+y,origin_z)
if(istype(T) && !T.ignore_mapgen)
if(map[current_cell] == FLOOR_CHAR)
T.make_floor()
else
T.make_wall()
if(map[current_cell] == DOOR_CHAR)
T.make_ore()
else if(map[current_cell] == EMPTY_CHAR)
T.make_ore(1)
get_additional_spawns(map[current_cell],T,get_spawn_dir(x, y))
return T

View File

@@ -45,7 +45,7 @@ var/global/list/datum/supply_drop_loot/supply_drop
/datum/supply_drop_loot/ballistics/New()
..()
contents = list(
/obj/item/weapon/gun/projectile/sec,
/obj/item/weapon/gun/projectile/colt/detective,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/gun/projectile/automatic/wt550,
@@ -57,7 +57,7 @@ var/global/list/datum/supply_drop_loot/supply_drop
/datum/supply_drop_loot/ballistics/New()
..()
contents = list(
/obj/item/weapon/gun/projectile/sec,
/obj/item/weapon/gun/projectile/colt/detective,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/gun/projectile/automatic/wt550,

View File

@@ -344,7 +344,7 @@
scannable = 1
/datum/reagent/hyronalin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.apply_effect(max(M.radiation - 30 * removed, 0), IRRADIATE, check_protection = 0)
M.radiation = max(M.radiation - 30 * removed, 0)
/datum/reagent/arithrazine
name = "Arithrazine"
@@ -357,7 +357,7 @@
scannable = 1
/datum/reagent/arithrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.apply_effect(max(M.radiation - 70 * removed, 0), IRRADIATE, check_protection = 0)
M.radiation = max(M.radiation - 70 * removed, 0)
M.adjustToxLoss(-10 * removed)
if(prob(60))
M.take_organ_damage(4 * removed, 0)

View File

@@ -116,7 +116,7 @@
if (GM.client)
GM.client.perspective = EYE_PERSPECTIVE
GM.client.eye = src
GM.loc = src
GM.forceMove(src)
for (var/mob/C in viewers(src))
C.show_message("\red [GM.name] has been placed in the [src] by [user].", 3)
qdel(G)
@@ -132,7 +132,7 @@
user.drop_item()
if(I)
I.loc = src
I.forceMove(src)
user << "You place \the [I] into the [src]."
for(var/mob/M in viewers(src))
@@ -177,7 +177,8 @@
if (target.client)
target.client.perspective = EYE_PERSPECTIVE
target.client.eye = src
target.loc = src
target.forceMove(src)
for (var/mob/C in viewers(src))
if(C == user)
@@ -201,7 +202,7 @@
if (user.client)
user.client.eye = user.client.mob
user.client.perspective = MOB_PERSPECTIVE
user.loc = src.loc
user.forceMove(src.loc)
update()
return
@@ -310,7 +311,7 @@
// eject the contents of the disposal unit
/obj/machinery/disposal/proc/eject()
for(var/atom/movable/AM in src)
AM.loc = src.loc
AM.forceMove(src.loc)
AM.pipe_eject(0)
update()
@@ -443,7 +444,7 @@
for(var/atom/movable/AM in H)
target = get_offset_target_turf(src.loc, rand(5)-rand(5), rand(5)-rand(5))
AM.loc = src.loc
AM.forceMove(src.loc)
AM.pipe_eject(0)
if(!istype(AM,/mob/living/silicon/robot/drone)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z
spawn(1)
@@ -459,7 +460,7 @@
if(istype(I, /obj/item/projectile))
return
if(prob(75))
I.loc = src
I.forceMove(src)
for(var/mob/M in viewers(src))
M.show_message("\The [I] lands in \the [src].", 3)
else
@@ -508,7 +509,7 @@
// now everything inside the disposal gets put into the holder
// note AM since can contain mobs or objs
for(var/atom/movable/AM in D)
AM.loc = src
AM.forceMove(src)
if(istype(AM, /obj/structure/bigDelivery) && !hasmob)
var/obj/structure/bigDelivery/T = AM
src.destinationTag = T.sortTag
@@ -528,7 +529,7 @@
D.expel(src) // no trunk connected, so expel immediately
return
loc = D.trunk
forceMove(D.trunk)
active = 1
set_dir(DOWN)
spawn(1)
@@ -585,7 +586,7 @@
// used when a a holder meets a stuck holder
proc/merge(var/obj/structure/disposalholder/other)
for(var/atom/movable/AM in other)
AM.loc = src // move everything in other holder to this one
AM.forceMove(src) // move everything in other holder to this one
if(ismob(AM))
var/mob/M = AM
if(M.client) // if a client mob, update eye to follow this holder
@@ -671,7 +672,7 @@
// this is unlikely, but just dump out everything into the turf in case
for(var/atom/movable/AM in H)
AM.loc = T
AM.forceMove(T)
AM.pipe_eject(0)
qdel(H)
..()
@@ -702,9 +703,9 @@
if(H2 && !H2.active)
H.merge(H2)
H.loc = P
H.forceMove(P)
else // if wasn't a pipe, then set loc to turf
H.loc = T
H.forceMove(T)
return null
return P
@@ -746,6 +747,7 @@
H.active = 0
H.loc = src
return
if(!T.is_plating() && istype(T,/turf/simulated/floor)) //intact floor, pop the tile
var/turf/simulated/floor/F = T
F.break_tile()
@@ -760,7 +762,7 @@
playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0)
if(H)
for(var/atom/movable/AM in H)
AM.loc = T
AM.forceMove(T)
AM.pipe_eject(direction)
spawn(1)
if(AM)
@@ -775,7 +777,7 @@
for(var/atom/movable/AM in H)
target = get_offset_target_turf(T, rand(5)-rand(5), rand(5)-rand(5))
AM.loc = T
AM.forceMove(T)
AM.pipe_eject(0)
spawn(1)
if(AM)
@@ -808,7 +810,7 @@
// this is unlikely, but just dump out everything into the turf in case
for(var/atom/movable/AM in H)
AM.loc = T
AM.forceMove(T)
AM.pipe_eject(0)
qdel(H)
return
@@ -929,7 +931,7 @@
// this is unlikely, but just dump out everything into the turf in case
for(var/atom/movable/AM in H)
AM.loc = T
AM.forceMove(T)
AM.pipe_eject(0)
qdel(H)
..()
@@ -990,7 +992,7 @@
if(nextdir == 12)
T = GetAbove(src)
if(!T)
H.loc = loc
H.forceMove(loc)
return
else
for(var/obj/structure/disposalpipe/down/F in T)
@@ -1006,9 +1008,9 @@
if(H2 && !H2.active)
H.merge(H2)
H.loc = P
H.forceMove(P)
else // if wasn't a pipe, then set loc to turf
H.loc = T
H.forceMove(T)
return null
return P
@@ -1040,7 +1042,7 @@
if(nextdir == 11)
T = GetBelow(src)
if(!T)
H.loc = src.loc
H.forceMove(src.loc)
return
else
for(var/obj/structure/disposalpipe/up/F in T)
@@ -1056,9 +1058,9 @@
if(H2 && !H2.active)
H.merge(H2)
H.loc = P
H.forceMove(P)
else // if wasn't a pipe, then set loc to turf
H.loc = T
H.forceMove(T)
return null
return P
@@ -1249,9 +1251,9 @@
if(H2 && !H2.active)
H.merge(H2)
H.loc = P
H.forceMove(P)
else // if wasn't a pipe, then set loc to turf
H.loc = T
H.forceMove(T)
return null
return P
@@ -1439,7 +1441,7 @@
if(H)
for(var/atom/movable/AM in H)
AM.loc = src.loc
AM.forceMove(src.loc)
AM.pipe_eject(dir)
if(!istype(AM,/mob/living/silicon/robot/drone)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z
spawn(5)

View File

@@ -1215,6 +1215,13 @@ CIRCUITS BELOW
build_path = /obj/item/weapon/circuitboard/telecomms/receiver
sort_string = "PAAAG"
/datum/design/circuit/tcom/exonet_node
name = "exonet node"
id = "tcom-exonet_node"
req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4)
build_path = /obj/item/weapon/circuitboard/telecomms/exonet_node
sort_string = "PAAAH"
/datum/design/circuit/shield
req_tech = list(TECH_BLUESPACE = 4, TECH_PHORON = 3)
materials = list("glass" = 2000, "gold" = 1000)