Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into 9/6/2015_baymerge

Conflicts:
	.travis.yml
	code/game/gamemodes/cult/cult.dm
	code/game/gamemodes/heist/heist.dm
	code/game/gamemodes/ninja/ninja.dm
	code/game/gamemodes/nuclear/nuclear.dm
	code/game/gamemodes/traitor/traitor.dm
	code/game/gamemodes/wizard/wizard.dm
	code/game/jobs/job/civilian.dm
	code/game/jobs/job/medical.dm
	code/game/jobs/job/security.dm
	code/game/objects/structures/lattice.dm
	code/global.dm
	code/modules/projectiles/ammunition/boxes.dm
	code/modules/reagents/Chemistry-Recipes.dm
	config/example/config.txt
	polaris.dme
This commit is contained in:
Neerti
2015-09-06 18:26:06 -04:00
377 changed files with 17701 additions and 16938 deletions
+53 -13
View File
@@ -1067,30 +1067,27 @@ proc/admin_notice(var/message, var/rights)
out += "<hr>"
if(ticker.mode.antag_tag)
out += "<b>Core antag id:</b> <a href='?src=\ref[ticker.mode];debug_antag=[ticker.mode.antag_tag]'>[ticker.mode.antag_tag]</a>.</br>"
if(ticker.mode.antag_tags && ticker.mode.antag_tags.len)
out += "<b>Core antag templates:</b></br>"
for(var/antag_tag in ticker.mode.antag_tags)
out += "<a href='?src=\ref[ticker.mode];debug_antag=[antag_tag]'>[antag_tag]</a>.</br>"
if(ticker.mode.round_autoantag)
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.get_antag_prob()]% spawn chance)"
if(ticker.mode.antag_scaling_coeff)
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b>."
if(ticker.mode.antag_scaling_coeff > 0)
out += " (scaling with <a href='?src=\ref[ticker.mode];set=antag_scaling'>[ticker.mode.antag_scaling_coeff]</a>)"
else
out += " (not currently scaling, <a href='?src=\ref[ticker.mode];set=antag_scaling'>set a coefficient</a>)"
out += "<br/>"
else
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>disabled</a></b>.<br/>"
out += "<b>All antag ids:</b>"
if(ticker.mode.antag_templates && ticker.mode.antag_templates.len).
var/playercount = ticker.mode.num_players()
for(var/datum/antagonist/antag in ticker.mode.antag_templates)
var/cur_max_antags
if(ticker.mode.antag_tag && antag.id == ticker.mode.antag_tag)
cur_max_antags = antag.max_antags_round
else
cur_max_antags = antag.max_antags
if(ticker.mode.antag_scaling_coeff)
cur_max_antags = Clamp((playercount/ticker.mode.antag_scaling_coeff), 1, cur_max_antags)
antag.update_current_antag_max()
out += " <a href='?src=\ref[ticker.mode];debug_antag=[antag.id]'>[antag.id]</a>"
out += " ([antag.get_antag_count()]/[cur_max_antags]) "
out += " ([antag.get_antag_count()]/[antag.cur_max]) "
out += " <a href='?src=\ref[ticker.mode];remove_antag_type=[antag.id]'>\[-\]</a><br/>"
else
out += " None."
@@ -1272,3 +1269,46 @@ proc/admin_notice(var/message, var/rights)
tomob.ckey = frommob.ckey
qdel(frommob)
return 1
/datum/admins/proc/force_antag_latespawn()
set category = "Admin"
set name = "Force Template Spawn"
set desc = "Force an antagonist template to spawn."
if (!istype(src,/datum/admins))
src = usr.client.holder
if (!istype(src,/datum/admins))
usr << "Error: you are not an admin!"
return
if(!ticker || !ticker.mode)
usr << "Mode has not started."
return
var/antag_type = input("Choose a template.","Force Latespawn") as null|anything in all_antag_types
if(!antag_type || !all_antag_types[antag_type])
usr << "Aborting."
return
var/datum/antagonist/antag = all_antag_types[antag_type]
message_admins("[key_name(usr)] attempting to force latespawn with template [antag.id].")
antag.attempt_late_spawn()
/datum/admins/proc/force_mode_latespawn()
set category = "Admin"
set name = "Force Mode Spawn"
set desc = "Force autotraitor to proc."
if (!istype(src,/datum/admins))
src = usr.client.holder
if (!istype(src,/datum/admins))
usr << "Error: you are not an admin!"
return
if(!ticker || !ticker.mode)
usr << "Mode has not started."
return
message_admins("[key_name(usr)] attempting to force mode latespawn.")
ticker.mode.next_spawn = 0
ticker.mode.try_latespawn()
+7 -2
View File
@@ -16,6 +16,8 @@ var/list/admin_verbs_admin = list(
/client/proc/invisimin, /*allows our mob to go invisible/visible*/
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage
/datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/
/datum/admins/proc/force_mode_latespawn, /*Force the mode to try a latespawn proc*/
/datum/admins/proc/force_antag_latespawn, /*Force a specific template to try a latespawn proc*/
/datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/
/datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/
/datum/admins/proc/announce, /*priority announce something to all clients.*/
@@ -105,7 +107,7 @@ var/list/admin_verbs_fun = list(
/client/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/everyone_random,
/client/proc/everyone_random,
/client/proc/cinematic,
/datum/admins/proc/toggle_aliens,
/datum/admins/proc/toggle_space_ninja,
@@ -114,8 +116,11 @@ var/list/admin_verbs_fun = list(
/client/proc/make_sound,
/client/proc/toggle_random_events,
/client/proc/editappear,
/client/proc/roll_dices
/client/proc/roll_dices,
/datum/admins/proc/call_supply_drop,
/datum/admins/proc/call_drop_pod
)
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_fruit,
/datum/admins/proc/spawn_custom_item,
+2 -2
View File
@@ -7,7 +7,7 @@
msg = sanitize(msg)
if(!msg) return
log_admin("[key_name(src)] : [msg]")
log_admin("ADMIN: [key_name(src)] : [msg]")
if(check_rights(R_ADMIN,0))
for(var/client/C in admins)
@@ -29,7 +29,7 @@
if (!msg)
return
var/sender_name = src.key
var/sender_name = key_name(usr, 1)
if(check_rights(R_ADMIN, 0))
sender_name = "<span class='admin'>[sender_name]</span>"
for(var/client/C in admins)
+3 -3
View File
@@ -64,7 +64,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procname) return
if(targetselected)
if(!target)
usr << "<span class='danger'>Your target no longer exists.</span>"
@@ -624,9 +624,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_to_slot_or_del(new /obj/item/clothing/under/det(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_trench(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/head/det(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store)
+4 -4
View File
@@ -3,8 +3,8 @@
desc = "Used to remotely activate devices."
icon_state = "signaller"
item_state = "signaler"
origin_tech = list(TECH_MAGNET = 1)
matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, "waste" = 100)
origin_tech = list(TECH_MAGNET = 1)
matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, "waste" = 100)
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
secured = 1
@@ -79,8 +79,8 @@
if (href_list["freq"])
var/new_frequency = (frequency + text2num(href_list["freq"]))
if(new_frequency < 1200 || new_frequency > 1600)
new_frequency = sanitize_frequency(new_frequency)
if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
if(href_list["code"])
+1 -1
View File
@@ -74,7 +74,7 @@
W.access = list()
if(corpseidjob)
W.assignment = corpseidjob
W.set_owner_info(M)
M.set_id_info(W)
M.equip_to_slot_or_del(W, slot_wear_id)
qdel(src)
+40 -5
View File
@@ -18,7 +18,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"ninja" = "true", // 10
"raider" = IS_MODE_COMPILED("heist"), // 11
"diona" = 1, // 12
"mutineer" = IS_MODE_COMPILED("mutiny"), // 13
"loyalist" = IS_MODE_COMPILED("revolution"), // 13
"pAI candidate" = 1, // -- TLE // 14
)
@@ -76,6 +76,7 @@ datum/preferences
var/species = "Human" //Species datum to use.
var/species_preview //Used for the species selection window.
var/list/alternate_languages = list() //Secondary language(s)
var/list/language_prefixes = list() //Kanguage prefix keys
var/list/gear //Custom/fluff item loadout.
//Some faction information.
@@ -401,8 +402,11 @@ datum/preferences
dat += "- <a href='byond://?src=\ref[user];preference=language;add=1'>add</a> ([S.num_alternate_languages - alternate_languages.len] remaining)<br>"
else
dat += "- [species] cannot choose secondary languages.<br>"
dat += "<br><br>"
dat += "<b>Language Keys</b><br>"
dat += " [english_list(language_prefixes, and_text = " ", comma_text = " ")] <a href='byond://?src=\ref[user];preference=language_prefix'>Change</a><br>"
dat += "<br><br>"
var/list/undies = gender == MALE ? underwear_m : underwear_f
dat += "Underwear: <a href ='?_src_=prefs;preference=underwear;task=input'><b>[get_key_by_value(undies,underwear)]</b></a><br>"
@@ -1175,6 +1179,26 @@ datum/preferences
if(new_lang)
alternate_languages |= new_lang
else if(href_list["preference"] == "language_prefix")
var/char
var/keys[0]
do
char = input("Enter a single special character.\nYou may re-select the same characters.\nThe following characters are already in use by radio: ; : .\nThe following characters are already in use by special say commands: ! *", "Enter Character - [3 - keys.len] remaining") as null|text
if(char)
if(length(char) > 1)
alert("Only single characters allowed.", "Error", "Ok")
else if(char in list(";", ":", "."))
alert("Radio character. Rejected.", "Error", "Ok")
else if(char in list("!","*"))
alert("Say character. Rejected.", "Error", "Ok")
else if(contains_az09(char))
alert("Non-special character. Rejected.", "Error", "Ok")
else
keys.Add(char)
while(char && keys.len < 3)
if(keys.len == 3)
language_prefixes = keys
switch(href_list["task"])
if("change")
if(href_list["preference"] == "species")
@@ -1303,7 +1327,8 @@ datum/preferences
b_type = new_b_type
if("hair")
if(species == "Human" || species == "Unathi" || species == "Tajara" || species == "Skrell")
var/datum/species/S = all_species[species]
if(S && (S.appearance_flags & HAS_HAIR_COLOR))
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null
if(new_hair)
r_hair = hex2num(copytext(new_hair, 2, 4))
@@ -1383,7 +1408,8 @@ datum/preferences
s_tone = 35 - max(min( round(new_s_tone), 220),1)
if("skin")
if(species == "Unathi" || species == "Tajara" || species == "Skrell")
var/datum/species/S = all_species[species]
if(S && (S.appearance_flags & HAS_SKIN_COLOR))
var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(r_skin, g_skin, b_skin)) as color|null
if(new_skin)
r_skin = hex2num(copytext(new_skin, 2, 4))
@@ -1465,7 +1491,16 @@ datum/preferences
rlimb_data[second_limb] = null
if("Prothesis")
var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in chargen_robolimbs
var/tmp_species = species ? species : "Human"
var/list/usable_manufacturers = list()
for(var/company in chargen_robolimbs)
var/datum/robolimb/M = chargen_robolimbs[company]
if(tmp_species in M.species_cannot_use)
continue
usable_manufacturers[company] = M
if(!usable_manufacturers.len)
return
var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in usable_manufacturers
if(!choice)
return
rlimb_data[limb] = choice
+38 -1
View File
@@ -596,8 +596,45 @@ var/global/list/gear_datums = list()
slot = slot_w_uniform
allowed_roles = list("Security Officer","Head of Security","Warden")
// Attachments
/datum/gear/resomi_grey
display_name = "Resomi uniform, grey"
path = /obj/item/clothing/under/resomi
cost = 1
slot = slot_w_uniform
/datum/gear/resomi_rainbow
display_name = "Resomi uniform, rainbow"
path = /obj/item/clothing/under/resomi/rainbow
cost = 1
slot = slot_w_uniform
/datum/gear/resomi_white
display_name = "Resomi uniform, white"
path = /obj/item/clothing/under/resomi/white
cost = 1
slot = slot_w_uniform
/datum/gear/resomi_eng
display_name = "Resomi uniform, Engineering"
path = /obj/item/clothing/under/resomi/yellow
cost = 1
slot = slot_w_uniform
allowed_roles = list("Chief Engineer","Station Engineer","Atmospherics Technician")
/datum/gear/resomi_sec
display_name = "Resomi uniform, Security"
path = /obj/item/clothing/under/resomi/red
cost = 1
slot = slot_w_uniform
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/resomi_med
display_name = "Resomi uniform, Medical"
path = /obj/item/clothing/under/resomi/medical
cost = 1
slot = slot_w_uniform
// Attachments
/datum/gear/armband_cargo
display_name = "armband, cargo"
path = /obj/item/clothing/accessory/armband/cargo
@@ -110,8 +110,11 @@
S["spawnpoint"] >> spawnpoint
S["language"] >> alternate_languages
S["language_prefixes"] >> language_prefixes
if(isnull(alternate_languages))
alternate_languages = list()
if(isnull(language_prefixes) || !language_prefixes.len)
language_prefixes = config.language_prefixes.Copy()
if(!islist(alternate_languages))
if(client)
// Warn them that we (probably) just broke their languages
@@ -287,6 +290,7 @@
S["age"] << age
S["species"] << species
S["language"] << alternate_languages
S["language_prefixes"] << language_prefixes
S["hair_red"] << r_hair
S["hair_green"] << g_hair
S["hair_blue"] << b_hair
+49 -11
View File
@@ -95,6 +95,7 @@
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
@@ -176,7 +177,10 @@ 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')
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))
@@ -197,8 +201,11 @@ BLIND // can't see anything
body_parts_covered = HANDS
slot_flags = SLOT_GLOVES
attack_verb = list("challenged")
species_restricted = list("exclude","Unathi","Tajara")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/gloves.dmi')
species_restricted = list("exclude","Unathi","Tajara", "Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/gloves.dmi',
"Resomi" = 'icons/mob/species/resomi/gloves.dmi',
)
/obj/item/clothing/gloves/update_clothing_icon()
if (ismob(src.loc))
@@ -253,6 +260,11 @@ BLIND // can't see anything
var/brightness_on
var/on = 0
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Resomi" = 'icons/mob/species/resomi/head.dmi'
)
/obj/item/clothing/head/attack_self(mob/user)
if(brightness_on)
if(!isturf(user.loc))
@@ -312,14 +324,26 @@ BLIND // can't see anything
/obj/item/clothing/head/update_icon(var/mob/user)
overlays.Cut()
var/mob/living/carbon/human/H
if(istype(user,/mob/living/carbon/human))
H = user
if(on)
// Generate object icon.
if(!light_overlay_cache["[light_overlay]_icon"])
light_overlay_cache["[light_overlay]_icon"] = image("icon" = 'icons/obj/light_overlays.dmi', "icon_state" = "[light_overlay]")
if(!light_overlay_cache["[light_overlay]"])
light_overlay_cache["[light_overlay]"] = image("icon" = 'icons/mob/light_overlays.dmi', "icon_state" = "[light_overlay]")
overlays |= light_overlay_cache["[light_overlay]_icon"]
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
// Generate and cache the on-mob icon, which is used in update_inv_head().
var/cache_key = "[light_overlay][H ? "_[H.species.get_bodytype()]" : ""]"
if(!light_overlay_cache[cache_key])
var/use_icon = 'icons/mob/light_overlays.dmi'
if(H && sprite_sheets[H.species.get_bodytype()])
use_icon = sprite_sheets[H.species.get_bodytype()]
light_overlay_cache[cache_key] = image("icon" = use_icon, "icon_state" = "[light_overlay]")
if(H)
H.update_inv_head()
/obj/item/clothing/head/update_clothing_icon()
@@ -335,7 +359,10 @@ BLIND // can't see anything
body_parts_covered = HEAD
slot_flags = SLOT_MASK
body_parts_covered = FACE|EYES
sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi')
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/masks.dmi',
"Resomi" = 'icons/mob/species/resomi/masks.dmi',
)
var/voicechange = 0
var/list/say_messages
@@ -364,8 +391,11 @@ BLIND // can't see anything
slowdown = SHOES_SLOWDOWN
force = 2
var/overshoes = 0
species_restricted = list("exclude","Unathi","Tajara")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/shoes.dmi')
species_restricted = list("exclude","Unathi","Tajara","Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/shoes.dmi',
"Resomi" = 'icons/mob/species/resomi/shoes.dmi',
)
/obj/item/clothing/shoes/proc/handle_movement(var/turf/walking, var/running)
return
@@ -389,6 +419,11 @@ BLIND // can't see anything
siemens_coefficient = 0.9
w_class = 3
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi',
"Resomi" = 'icons/mob/species/resomi/suit.dmi'
)
/obj/item/clothing/suit/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
@@ -418,7 +453,10 @@ BLIND // can't see anything
var/list/accessories = list()
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')
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/uniform.dmi',
"Resomi" = 'icons/mob/species/resomi/uniform.dmi'
)
//convenience var for defining the icon state for the overlay used when the clothing is worn.
//Also used by rolling/unrolling.
+4 -1
View File
@@ -9,7 +9,10 @@
name = "ultra rare hat"
desc = "an ultra rare hat. It commands a certain respect."
icon_state = "petehat"
sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi')
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Resomi" = 'icons/mob/species/resomi/head.dmi'
)
/obj/item/clothing/head/collectable/slime
name = "collectable slime cap!"
+1 -1
View File
@@ -59,7 +59,7 @@
icon_state = "swathelm"
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi'
)
armor = list(melee = 62, bullet = 50, laser = 50,energy = 35, bomb = 10, bio = 2, rad = 0)
-5
View File
@@ -8,11 +8,6 @@
w_class = 2
gas_transfer_coefficient = 0.10
permeability_coefficient = 0.50
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/masks.dmi'
)
var/hanging = 0
/obj/item/clothing/mask/breath/proc/adjust_mask(mob/user)
+2 -2
View File
@@ -44,7 +44,7 @@
shoes = null
return 0
H.drop_from_inventory(shoes) //Remove the old shoes so you can put on the magboots.
shoes.loc = src
shoes.forceMove(src)
if(!..())
if(shoes) //Put the old shoes back on if the check fails.
@@ -63,7 +63,7 @@
var/mob/living/carbon/human/H = wearer
if(shoes)
if(!H.equip_to_slot_if_possible(shoes, slot_shoes))
shoes.loc = get_turf(src)
shoes.forceMove(get_turf(src))
src.shoes = null
wearer = null
+1 -3
View File
@@ -40,14 +40,12 @@
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = list("Vox")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
/obj/item/clothing/head/helmet/space/vox
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.6
item_flags = STOPPRESSUREDAMAGE
species_restricted = list("Vox")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi')
/obj/item/clothing/head/helmet/space/vox/pressure
name = "alien helmet"
@@ -122,7 +120,7 @@
siemens_coefficient = 0
permeability_coefficient = 0.05
species_restricted = list("Vox")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/gloves.dmi')
/obj/item/clothing/shoes/magboots/vox
desc = "A pair of heavy, jagged armoured foot pieces, seemingly suitable for a velociraptor."
@@ -23,7 +23,7 @@
usr << "Your module is not installed in a hardsuit."
return
module.holder.ui_interact(usr)
module.holder.ui_interact(usr, nano_state = contained_state)
/obj/item/rig_module/ai_container
@@ -46,9 +46,23 @@
var/obj/item/ai_card // Reference to the MMI, posibrain, intellicard or pAI card previously holding the AI.
var/obj/item/ai_verbs/verb_holder
/mob
var/get_rig_stats = 0
/obj/item/rig_module/ai_container/process()
if(integrated_ai && loc)
integrated_ai.SetupStat(loc.get_rig())
if(integrated_ai)
var/obj/item/weapon/rig/rig = get_rig()
if(rig && rig.ai_override_enabled)
integrated_ai.get_rig_stats = 1
else
integrated_ai.get_rig_stats = 0
/mob/living/Stat()
. = ..()
if(. && get_rig_stats)
var/obj/item/weapon/rig/rig = get_rig()
if(rig)
SetupStat(rig)
/obj/item/rig_module/ai_container/proc/update_verb_holder()
if(!verb_holder)
@@ -158,7 +172,10 @@
if(integrated_ai)
integrated_ai.ghostize()
qdel(integrated_ai)
if(ai_card) qdel(ai_card)
integrated_ai = null
if(ai_card)
qdel(ai_card)
ai_card = null
else if(user)
user.put_in_hands(ai_card)
else
@@ -168,7 +185,6 @@
update_verb_holder()
/obj/item/rig_module/ai_container/proc/integrate_ai(var/obj/item/ai,var/mob/user)
if(!ai) return
// The ONLY THING all the different AI systems have in common is that they all store the mob inside an item.
@@ -227,21 +227,21 @@
return 0
/mob/living/carbon/human/Stat()
..()
. = ..()
if(istype(back,/obj/item/weapon/rig))
if(. && istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/R = back
SetupStat(R)
/mob/proc/SetupStat(var/obj/item/weapon/rig/R)
if(src == usr && R && !R.canremove && R.installed_modules.len && statpanel("Hardsuit Modules"))
if(R && !R.canremove && R.installed_modules.len && statpanel("Hardsuit Modules"))
var/cell_status = R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "ERROR"
statpanel("Hardsuit Modules", "Suit charge", cell_status)
stat("Suit charge", cell_status)
for(var/obj/item/rig_module/module in R.installed_modules)
{
for(var/stat_rig_module/SRM in module.stat_modules)
if(SRM.CanUse())
statpanel("Hardsuit Modules",SRM.module.interface_name,SRM)
stat(SRM.module.interface_name,SRM)
}
/stat_rig_module
@@ -95,7 +95,7 @@
playsound(T, "sparks", 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
/obj/item/rig_module/teleporter/engage(atom/target)
/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai)
if(!..()) return 0
+155 -35
View File
@@ -27,6 +27,8 @@
var/interface_path = "hardsuit.tmpl"
var/ai_interface_path = "hardsuit.tmpl"
var/interface_title = "Hardsuit Controller"
var/wearer_move_delay //Used for AI moving.
var/ai_controlled_move_delay = 10
// Keeps track of what this rig should spawn with.
var/suit_type = "hardsuit"
@@ -179,8 +181,8 @@
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
piece.icon_state = "[initial(icon_state)]"
if(airtight)
piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT)
if(airtight)
piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT)
update_icon(1)
/obj/item/weapon/rig/proc/toggle_seals(var/mob/living/carbon/human/M,var/instant)
@@ -268,9 +270,9 @@
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
piece.icon_state = "[initial(icon_state)][!seal_target ? "" : "_sealed"]"
canremove = !seal_target
canremove = !seal_target
if(airtight)
update_component_sealed()
update_component_sealed()
update_icon(1)
return 0
@@ -289,9 +291,9 @@
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(canremove)
piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT)
else
else
piece.item_flags |= (STOPPRESSUREDAMAGE|AIRTIGHT)
update_icon(1)
update_icon(1)
/obj/item/weapon/rig/process()
@@ -302,7 +304,7 @@
if(istype(piece.loc, /mob/living))
M = piece.loc
M.drop_from_inventory(piece)
piece.loc = src
piece.forceMove(src)
if(!istype(wearer) || loc != wearer || wearer.back != src || canremove || !cell || cell.charge <= 0)
if(!cell || cell.charge <= 0)
@@ -324,6 +326,8 @@
else
if(offline)
offline = 0
if(istype(wearer) && !wearer.wearing_rig)
wearer.wearing_rig = src
chest.slowdown = initial(slowdown)
if(offline)
@@ -381,8 +385,7 @@
cell.use(cost*10)
return 1
/obj/item/weapon/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/item/weapon/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/nano_state = inventory_state)
if(!user)
return
@@ -452,7 +455,7 @@
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, data["ai"] ? contained_state : inventory_state)
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, state = nano_state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
@@ -541,12 +544,10 @@
return 0
/obj/item/weapon/rig/proc/notify_ai(var/message)
if(!message || !installed_modules || !installed_modules.len)
return
for(var/obj/item/rig_module/module in installed_modules)
for(var/mob/living/silicon/ai/ai in module.contents)
if(ai && ai.client && !ai.stat)
ai << "[message]"
for(var/obj/item/rig_module/ai_container/module in installed_modules)
if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat)
module.integrated_ai << "[message]"
. = 1
/obj/item/weapon/rig/equipped(mob/living/carbon/human/M)
..()
@@ -557,12 +558,13 @@
if(M && M.back == src)
M.back = null
M.drop_from_inventory(src)
src.loc = get_turf(src)
src.forceMove(get_turf(src))
return
if(istype(M) && M.back == src)
M.visible_message("<font color='blue'><b>[M] struggles into \the [src].</b></font>", "<font color='blue'><b>You struggle into \the [src].</b></font>")
wearer = M
wearer.wearing_rig = src
update_icon()
/obj/item/weapon/rig/proc/toggle_piece(var/piece, var/mob/living/carbon/human/H, var/deploy_mode)
@@ -613,22 +615,21 @@
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.</b></font>"
use_obj.canremove = 1
holder.drop_from_inventory(use_obj)
use_obj.loc = get_turf(src)
use_obj.forceMove(get_turf(src))
use_obj.dropped()
use_obj.canremove = 0
use_obj.loc = src
use_obj.forceMove(src)
else if (deploy_mode != ONLY_RETRACT)
if(check_slot)
if(check_slot != use_obj)
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
if(check_slot && check_slot == use_obj)
return
use_obj.forceMove(H)
if(!H.equip_to_slot_if_possible(use_obj, equip_to, 0, 1))
use_obj.forceMove(src)
if(check_slot)
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
else
use_obj.loc = H
if(!H.equip_to_slot_if_possible(use_obj, equip_to, 0))
use_obj.loc = src
else
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</b></span>"
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</b></span>"
if(piece == "helmet" && helmet)
helmet.update_light(H)
@@ -674,6 +675,7 @@
..()
for(var/piece in list("helmet","gauntlets","chest","boots"))
toggle_piece(piece, user, ONLY_RETRACT)
wearer.wearing_rig = null
wearer = null
//Todo
@@ -755,15 +757,130 @@
return 1
return 0
/*/obj/item/weapon/rig/proc/forced_move(dir)
if(locked_down)
return 0
if(!control_overridden)
return
if(!wearer || wearer.back != src)
return 0
wearer.Move(null,dir)*/
/obj/item/weapon/rig/proc/ai_can_move_suit(var/mob/user, var/check_user_module = 0, var/check_for_ai = 0)
if(check_for_ai)
if(!(locate(/obj/item/rig_module/ai_container) in contents))
return 0
var/found_ai
for(var/obj/item/rig_module/ai_container/module in contents)
if(module.damage >= 2)
continue
if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat)
found_ai = 1
break
if(!found_ai)
return 0
if(check_user_module)
if(!user || !user.loc || !user.loc.loc)
return 0
var/obj/item/rig_module/ai_container/module = user.loc.loc
if(!istype(module) || module.damage >= 2)
user << "<span class='warning'>Your host module is unable to interface with the suit.</span>"
return 0
if(offline || !cell || !cell.charge || locked_down)
if(user) user << "<span class='warning'>Your host rig is unpowered and unresponsive.</span>"
return 0
if(!wearer || wearer.back != src)
if(user) user << "<span class='warning'>Your host rig is not being worn.</span>"
return 0
if(!wearer.stat && !control_overridden && !ai_override_enabled)
if(user) user << "<span class='warning'>You are locked out of the suit servo controller.</span>"
return 0
return 1
/obj/item/weapon/rig/proc/force_rest(var/mob/user)
if(!ai_can_move_suit(user, check_user_module = 1))
return
wearer.lay_down()
user << "<span class='notice'>\The [wearer] is now [wearer.resting ? "resting" : "getting up"].</span>"
/obj/item/weapon/rig/proc/forced_move(var/direction, var/mob/user)
// Why is all this shit in client/Move()? Who knows?
if(world.time < wearer_move_delay)
return
if(!wearer || !wearer.loc || !ai_can_move_suit(user, check_user_module = 1))
return
//This is sota the goto stop mobs from moving var
if(wearer.transforming || !wearer.canmove)
return
if(locate(/obj/effect/stop/, wearer.loc))
for(var/obj/effect/stop/S in wearer.loc)
if(S.victim == wearer)
return
if(!wearer.lastarea)
wearer.lastarea = get_area(wearer.loc)
if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0))
if(!wearer.Process_Spacemove(0))
return 0
if(malfunctioning)
direction = pick(cardinal)
// Inside an object, tell it we moved.
if(isobj(wearer.loc) || ismob(wearer.loc))
var/atom/O = wearer.loc
return O.relaymove(wearer, direction)
if(isturf(wearer.loc))
if(wearer.restrained())//Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(wearer, 1))
if(M.pulling == wearer)
if(!M.restrained() && M.stat == 0 && M.canmove && wearer.Adjacent(M))
user << "<span class='notice'>Your host is restrained! They can't move!</span>"
return 0
else
M.stop_pulling()
if(wearer.pinned.len)
src << "<span class='notice'>Your host is pinned to a wall by [wearer.pinned[1]]</span>!"
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
if(config.Tickcomp)
tickcomp = ((1/(world.tick_lag))*1.3) - 1.3
wearer_move_delay += tickcomp
if(istype(wearer.buckled, /obj/vehicle))
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
wearer_move_delay = world.time + tickcomp
return wearer.buckled.relaymove(wearer, direction)
if(istype(wearer.machine, /obj/machinery))
if(wearer.machine.relaymove(wearer, direction))
return
if(wearer.pulledby || wearer.buckled) // Wheelchair driving!
if(istype(wearer.loc, /turf/space))
return // No wheelchair driving in space
if(istype(wearer.pulledby, /obj/structure/bed/chair/wheelchair))
return wearer.pulledby.relaymove(wearer, direction)
else if(istype(wearer.buckled, /obj/structure/bed/chair/wheelchair))
if(ishuman(wearer.buckled))
var/obj/item/organ/external/l_hand = wearer.get_organ("l_hand")
var/obj/item/organ/external/r_hand = wearer.get_organ("r_hand")
if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED)))
return // No hands to drive your chair? Tough luck!
wearer_move_delay += 2
return wearer.buckled.relaymove(wearer,direction)
cell.use(200) //Arbitrary, TODO
wearer.Move(get_step(get_turf(wearer),direction),direction)
// This returns the rig if you are contained inside one, but not if you are wearing it
/atom/proc/get_rig()
if(loc)
return loc.get_rig()
@@ -772,6 +889,9 @@
/obj/item/weapon/rig/get_rig()
return src
/mob/living/carbon/human/get_rig()
return back
#undef ONLY_DEPLOY
#undef ONLY_RETRACT
#undef SEAL_DELAY
@@ -10,7 +10,11 @@
heat_protection = HEAD|FACE|EYES
cold_protection = HEAD|FACE|EYES
brightness_on = 4
sprite_sheets = list("Tajara" = 'icons/mob/species/tajaran/helmet.dmi',"Skrell" = 'icons/mob/species/skrell/helmet.dmi',"Unathi" = 'icons/mob/species/unathi/helmet.dmi')
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi'
)
species_restricted = null
/obj/item/clothing/gloves/rig
@@ -44,7 +48,10 @@
breach_threshold = 38
resilience = 0.2
can_breach = 1
sprite_sheets = list("Tajara" = 'icons/mob/species/tajaran/suit.dmi',"Unathi" = 'icons/mob/species/unathi/suit.dmi')
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
"Unathi" = 'icons/mob/species/unathi/suit.dmi'
)
supporting_limbs = list()
var/obj/item/weapon/material/hatchet/tacknife
@@ -19,7 +19,7 @@
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("Human", "Skrell", "Tajara", "Unathi")
species_restricted = list("exclude","Diona", "Xenomorph")
var/obj/machinery/camera/camera
var/list/camera_networks
@@ -64,7 +64,7 @@
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("Human", "Skrell", "Tajara", "Unathi")
species_restricted = list("exclude","Diona", "Xenomorph")
var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit.
+10 -10
View File
@@ -112,7 +112,7 @@
if(istype(H))
if(helmet && H.head == helmet)
H.drop_from_inventory(helmet)
helmet.loc = src
helmet.forceMove(src)
if(boots)
boots.canremove = 1
@@ -120,11 +120,11 @@
if(istype(H))
if(boots && H.shoes == boots)
H.drop_from_inventory(boots)
boots.loc = src
boots.forceMove(src)
if(tank)
tank.canremove = 1
tank.loc = src
tank.forceMove(src)
/obj/item/clothing/suit/space/void/verb/toggle_helmet()
@@ -148,7 +148,7 @@
H << "<span class='notice'>You retract your suit helmet.</span>"
helmet.canremove = 1
H.drop_from_inventory(helmet)
helmet.loc = src
helmet.forceMove(src)
else
if(H.head)
H << "<span class='danger'>You cannot deploy your helmet while wearing \the [H.head].</span>"
@@ -197,15 +197,15 @@
if(choice == tank) //No, a switch doesn't work here. Sorry. ~Techhead
user << "You pop \the [tank] out of \the [src]'s storage compartment."
tank.loc = get_turf(src)
tank.forceMove(get_turf(src))
src.tank = null
else if(choice == helmet)
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
helmet.loc = get_turf(src)
helmet.forceMove(get_turf(src))
src.helmet = null
else if(choice == boots)
user << "You detatch \the [boots] from \the [src]'s boot mounts."
boots.loc = get_turf(src)
boots.forceMove(get_turf(src))
src.boots = null
else
user << "\The [src] does not have anything installed."
@@ -216,7 +216,7 @@
else
user << "You attach \the [W] to \the [src]'s helmet mount."
user.drop_item()
W.loc = src
W.forceMove(src)
src.helmet = W
return
else if(istype(W,/obj/item/clothing/shoes/magboots))
@@ -225,7 +225,7 @@
else
user << "You attach \the [W] to \the [src]'s boot mounts."
user.drop_item()
W.loc = src
W.forceMove(src)
boots = W
return
else if(istype(W,/obj/item/weapon/tank))
@@ -236,7 +236,7 @@
else
user << "You insert \the [W] into \the [src]'s storage compartment."
user.drop_item()
W.loc = src
W.forceMove(src)
tank = W
return
+41 -3
View File
@@ -63,6 +63,26 @@
armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0
/obj/item/clothing/suit/armor/laserproof/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
var/reflectchance = 40 - round(damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
if(P.starting && prob(reflectchance))
visible_message("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
// Find a turf near or on the original location to bounce to
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(user)
// redirect the projectile
P.redirect(new_x, new_y, curloc, user)
return PROJECTILE_CONTINUE // complete projectile permutation
/obj/item/clothing/suit/armor/swat
name = "swat suit"
desc = "A heavily armored suit that protects against moderate damage. Used in special operations."
@@ -113,9 +133,27 @@
slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/suit/armor/reactive/IsShield()
if(active)
return 1
/obj/item/clothing/suit/armor/reactive/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(prob(50))
user.visible_message("<span class='danger'>The reactive teleport system flings [user] clear of the attack!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(6, user))
if(istype(T,/turf/space)) continue
if(T.density) continue
if(T.x>world.maxx-6 || T.x<6) continue
if(T.y>world.maxy-6 || T.y<6) continue
turfs += T
if(!turfs.len) turfs += pick(/turf in orange(6))
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, user.loc)
spark_system.start()
playsound(user.loc, "sparks", 50, 1)
user.loc = picked
return PROJECTILE_FORCE_MISS
return 0
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user as mob)
+6 -12
View File
@@ -11,7 +11,7 @@
blood_overlay_type = "armor"
body_parts_covered = 0
allowed = list (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/fertilizer,/obj/item/weapon/material/minihoe)
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
//Captain
/obj/item/clothing/suit/captunic
name = "captain's parade tunic"
@@ -20,7 +20,6 @@
item_state = "captunic"
body_parts_covered = UPPER_TORSO|ARMS
flags_inv = HIDEJUMPSUIT
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
/obj/item/clothing/suit/captunic/capjacket
name = "captain's uniform jacket"
@@ -37,7 +36,6 @@
icon_state = "chaplain_hoodie"
item_state = "chaplain_hoodie"
body_parts_covered = UPPER_TORSO|ARMS
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
//Chaplain
/obj/item/clothing/suit/nun
@@ -47,7 +45,6 @@
item_state = "nun"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDESHOES|HIDEJUMPSUIT
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
//Chef
/obj/item/clothing/suit/chef
@@ -59,7 +56,6 @@
permeability_coefficient = 0.50
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list (/obj/item/weapon/material/knife)
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
//Chef
/obj/item/clothing/suit/chef/classic
@@ -93,18 +89,18 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
//Detective
/obj/item/clothing/suit/storage/det_suit
name = "coat"
desc = "An 18th-century multi-purpose trenchcoat. Someone who wears this means serious business."
/obj/item/clothing/suit/storage/det_trench
name = "brown trenchcoat"
desc = "A rugged canvas trenchcoat, designed and created by TX Fabrication Corp. The coat is externally impact resistant - perfect for your next act of autodefenestration!"
icon_state = "detective"
item_state = "det_suit"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/flame/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder)
armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
/obj/item/clothing/suit/storage/det_suit/black
/obj/item/clothing/suit/storage/det_trench/grey
name = "grey trenchcoat"
icon_state = "detective2"
//Forensics
@@ -138,8 +134,6 @@
/obj/item/clothing/mask/gas, /obj/item/taperoll/engineering)
body_parts_covered = UPPER_TORSO
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
//Lawyer
/obj/item/clothing/suit/storage/toggle/lawyer/bluejacket
name = "Blue Suit Jacket"
-1
View File
@@ -9,7 +9,6 @@
body_parts_covered = UPPER_TORSO|ARMS
allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper)
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0)
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
/obj/item/clothing/suit/storage/toggle/labcoat/red
name = "red labcoat"
+25 -21
View File
@@ -74,35 +74,38 @@
* Detective
*/
/obj/item/clothing/under/det
name = "hard-worn suit"
desc = "Someone who wears this means business."
name = "detective's suit"
desc = "A rumpled white dress shirt paired with well-worn grey slacks, complete with a blue striped tie and a faux-gold tie clip."
icon_state = "detective"
item_state = "det"
worn_state = "detective"
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.9
/obj/item/clothing/under/det/black
icon_state = "detective2"
worn_state = "detective2"
item_state = "sl_suit"
/obj/item/clothing/under/det/slob
icon_state = "polsuit"
worn_state = "polsuit"
/obj/item/clothing/under/det/slob/verb/rollup()
set name = "Roll suit sleeves"
/obj/item/clothing/under/det/verb/rollup()
set name = "Roll Suit Sleeves"
set category = "Object"
set src in usr
worn_state = worn_state == "polsuit" ? "polsuit_rolled" : "polsuit"
if (ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform(1)
var/unrolled = item_state_slots[slot_w_uniform_str] == initial(worn_state)
item_state_slots[slot_w_uniform_str] = unrolled ? "[worn_state]_r" : initial(worn_state)
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform(1)
H << "<span class='notice'>You roll the sleeves of your shirt [unrolled ? "up" : "down"]</span>"
/obj/item/clothing/head/det_hat
name = "hat"
desc = "Someone who wears this will look very smart."
/obj/item/clothing/under/det/grey
icon_state = "detective2"
worn_state = "detective2"
desc = "A serious-looking tan dress shirt paired with freshly-pressed black slacks, complete with a red striped tie."
/obj/item/clothing/under/det/black
icon_state = "detective3"
worn_state = "detective3"
item_state = "sl_suit"
desc = "An immaculate white dress shirt, paired with a pair of dark grey dress pants, a red tie, and a charcoal vest."
/obj/item/clothing/head/det
name = "fedora"
desc = "A brown fedora - either the cornerstone of a detective's style or a poor attempt at looking cool, depending on the person wearing it."
icon_state = "detective"
item_state_slots = list(
slot_l_hand_str = "det_hat",
@@ -113,8 +116,9 @@
siemens_coefficient = 0.9
body_parts_covered = 0
/obj/item/clothing/head/det_hat/black
/obj/item/clothing/head/det/grey
icon_state = "detective2"
desc = "A grey fedora - either the cornerstone of a detective's style or a poor attempt at looking cool, depending on the person wearing it."
/*
@@ -0,0 +1,32 @@
/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"
+1 -1
View File
@@ -160,7 +160,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 30, list(ASSIGNMENT_ENGINEER = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)),
)
+8 -2
View File
@@ -252,8 +252,14 @@
New()
item_color = "red"
/obj/item/weapon/holo/esword/IsShield()
if(active)
/obj/item/weapon/holo/esword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(active && default_parry_check(user, attacker, damage_source) && prob(50))
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, user.loc)
spark_system.start()
playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1)
return 1
return 0
+1 -1
View File
@@ -126,7 +126,7 @@
/obj/machinery/portable_atmospherics/hydroponics/AltClick()
if(mechanical && !usr.stat && !usr.lying && Adjacent(usr))
close_lid(usr)
return
return 1
return ..()
/obj/machinery/portable_atmospherics/hydroponics/attack_ghost(var/mob/dead/observer/user)
@@ -198,6 +198,12 @@
if(grown_seed.get_trait(TRAIT_TELEPORTING))
dat += "<br>The fruit is temporal/spatially unstable."
if(grown_seed.get_trait(TRAIT_EXUDE_GASSES))
dat += "<br>It will release gas into the environment."
if(grown_seed.get_trait(TRAIT_CONSUME_GASSES))
dat += "<br>It will remove gas from the environment."
if(dat)
last_data = dat
dat += "<br><br>\[<a href='?src=\ref[src];print=1'>print report</a>\]"
+9 -6
View File
@@ -46,7 +46,7 @@
/obj/item/stack/material/proc/update_strings()
// Update from material datum.
singular_name = material.sheet_singular_name
if(amount>1)
name = "[material.use_name] [material.sheet_plural_name]"
desc = "A stack of [material.use_name] [material.sheet_plural_name]."
@@ -196,12 +196,15 @@
default_type = "rglass"
/obj/item/stack/material/glass/phoronglass
name = "phoron glass"
singular_name = "phoron glass sheet"
name = "borosilicate glass"
desc = "This sheet is special platinum-glass alloy designed to withstand large temperatures"
singular_name = "borosilicate glass sheet"
icon_state = "sheet-phoronglass"
default_type = "phglass"
default_type = "borosilicate glass"
/obj/item/stack/material/glass/phoronrglass
name = "reinforced phoron glass"
name = "reinforced borosilicate glass"
desc = "This sheet is special platinum-glass alloy designed to withstand large temperatures. It is reinforced with few rods."
singular_name = "reinforced borosilicate glass sheet"
icon_state = "sheet-phoronrglass"
default_type = "rphglass"
default_type = "reinforced borosilicate glass"
+29 -8
View File
@@ -326,6 +326,20 @@ var/list/name_to_material
icon_reinf = "reinf_over"
icon_colour = "#666666"
/material/diona
name = "biomass"
icon_colour = null
stack_type = null
integrity = 600
icon_base = "diona"
icon_reinf = "noreinf"
/material/diona/place_dismantled_product()
return
/material/diona/place_dismantled_girder(var/turf/target)
spawn_diona_nymph(target)
/material/steel/holographic
name = "holo" + DEFAULT_WALL_MATERIAL
display_name = DEFAULT_WALL_MATERIAL
@@ -346,6 +360,14 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 2)
composite_material = list(DEFAULT_WALL_MATERIAL = 3750, "platinum" = 3750) //todo
/material/plasteel/titanium
name = "titanium"
stack_type = null
icon_base = "metal"
door_icon_base = "metal"
icon_colour = "#D1E6E3"
icon_reinf = "reinf_metal"
/material/glass
name = "glass"
stack_type = /obj/item/stack/material/glass
@@ -454,23 +476,22 @@ var/list/name_to_material
rod_product = null
/material/glass/phoron
name = "phglass"
display_name = "phoron glass"
name = "borosilicate glass"
display_name = "borosilicate glass"
stack_type = /obj/item/stack/material/glass/phoronglass
flags = MATERIAL_BRITTLE
ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE+300
integrity = 200 // idk why but phoron windows are strong, so.
integrity = 100
icon_colour = "#FC2BC5"
stack_origin_tech = list(TECH_MATERIAL = 3, TECH_PHORON = 2)
stack_origin_tech = list(TECH_MATERIAL = 4)
created_window = /obj/structure/window/phoronbasic
wire_product = null
rod_product = /obj/item/stack/material/glass/phoronrglass
/material/glass/phoron/reinforced
name = "rphglass"
display_name = "reinforced phoron glass"
name = "reinforced borosilicate glass"
display_name = "reinforced borosilicate glass"
stack_type = /obj/item/stack/material/glass/phoronrglass
stack_origin_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 2)
stack_origin_tech = list(TECH_MATERIAL = 5)
composite_material = list() //todo
created_window = /obj/structure/window/phoronreinforced
hardness = 40
+9 -1
View File
@@ -24,4 +24,12 @@
"carbon" = 1,
"hematite" = 1
)
product = /obj/item/stack/material/steel
product = /obj/item/stack/material/steel
/datum/alloy/borosilicate
metaltag = "borosilicate glass"
requires = list(
"platinum" = 1,
"sand" = 2
)
product = /obj/item/stack/material/glass/phoronglass
+9 -6
View File
@@ -74,7 +74,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
mind = body.mind //we don't transfer the mind but we keep a reference to it.
if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position
loc = T
forceMove(T)
if(!name) //To prevent nameless ghosts
name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
@@ -293,7 +293,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
usr << "No area available."
usr.loc = pick(L)
usr.forceMove(pick(L))
following = null
/mob/dead/observer/verb/follow(input in getmobs())
@@ -320,7 +320,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
following = target
src << "<span class='notice'>Now following [target]</span>"
if(ismob(target))
loc = get_turf(target)
forceMove(get_turf(target))
var/mob/M = target
M.following_mobs += src
else
@@ -331,7 +331,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
break
// To stop the ghost flickering.
if(loc != T)
loc = T
forceMove(T)
sleep(15)
/mob/proc/update_following()
@@ -341,7 +341,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
following_mobs -= M
else
if(M.loc != .)
M.loc = .
M.forceMove(.)
/mob
var/list/following_mobs = list()
@@ -392,7 +392,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/turf/T = get_turf(M) //Turf of the destination mob
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
src.loc = T
forceMove(T)
following = null
else
src << "This mob is not located in the game world."
@@ -657,6 +657,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/canface()
return 1
/mob/dead/observer/proc/can_admin_interact()
return check_rights(R_ADMIN, 0, src)
/mob/dead/observer/verb/toggle_ghostsee()
set name = "Toggle Ghost Vision"
set desc = "Toggles your ability to see things only ghosts can see, like other ghosts"
@@ -40,7 +40,7 @@
cultnet.updateVisibility(src)
/datum/antagonist/add_antagonist(var/datum/mind/player)
..()
. = ..()
if(src == cult)
cultnet.updateVisibility(player.current, 0)
+48 -2
View File
@@ -1,10 +1,17 @@
var/list/holder_mob_icon_cache = list()
//Helper object for picking dionaea (and other creatures) up.
/obj/item/weapon/holder
name = "holder"
desc = "You shouldn't ever see this."
icon = 'icons/obj/objects.dmi'
slot_flags = SLOT_HEAD
sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi')
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Resomi" = 'icons/mob/species/resomi/head.dmi'
)
origin_tech = null
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_holder.dmi',
@@ -57,7 +64,7 @@
slot_flags = SLOT_HEAD | SLOT_OCLOTHING
/obj/item/weapon/holder/drone
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5)
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 5)
/obj/item/weapon/holder/mouse
w_class = 1
@@ -86,3 +93,42 @@
grabber.status_flags |= PASSEMOTES
H.sync(src)
return H
/obj/item/weapon/holder/human
icon = 'icons/mob/holder_complex.dmi'
var/list/generate_for_slots = list(slot_l_hand_str, slot_r_hand_str, slot_back_str)
slot_flags = SLOT_BACK
/obj/item/weapon/holder/human/sync(var/mob/living/M)
// Generate appropriate on-mob icons.
var/mob/living/carbon/human/owner = M
if(istype(owner) && owner.species)
var/skin_colour = rgb(owner.r_skin, owner.g_skin, owner.b_skin)
var/hair_colour = rgb(owner.r_hair, owner.g_hair, owner.b_hair)
var/eye_colour = rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)
var/species_name = lowertext(owner.species.get_bodytype())
for(var/cache_entry in generate_for_slots)
var/cache_key = "[owner.species]-[cache_entry]-[skin_colour]-[hair_colour]"
if(!holder_mob_icon_cache[cache_key])
// Generate individual icons.
var/icon/mob_icon = icon(icon, "[species_name]_holder_[cache_entry]_base")
mob_icon.Blend(skin_colour, ICON_ADD)
var/icon/hair_icon = icon(icon, "[species_name]_holder_[cache_entry]_hair")
hair_icon.Blend(hair_colour, ICON_ADD)
var/icon/eyes_icon = icon(icon, "[species_name]_holder_[cache_entry]_eyes")
eyes_icon.Blend(eye_colour, ICON_ADD)
// Blend them together.
mob_icon.Blend(eyes_icon, ICON_OVERLAY)
mob_icon.Blend(hair_icon, ICON_OVERLAY)
// Add to the cache.
holder_mob_icon_cache[cache_key] = mob_icon
item_icons[cache_entry] = holder_mob_icon_cache[cache_key]
// Handle the rest of sync().
..(M)
+7 -3
View File
@@ -216,11 +216,9 @@ var/list/slot_equipment_priority = list( \
update_inv_wear_mask(0)
return
//This differs from remove_from_mob() in that it checks if the item can be unequipped first.
/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress.
/mob/proc/canUnEquip(obj/item/I)
if(!I) //If there's nothing to drop, the drop is automatically successful.
return 1
var/slot
for(var/s in slot_back to slot_tie) //kind of worries me
if(get_equipped_item(s) == I)
@@ -230,6 +228,12 @@ var/list/slot_equipment_priority = list( \
if(slot && !I.mob_can_unequip(src, slot))
return 0
return 1
//This differs from remove_from_mob() in that it checks if the item can be unequipped first.
/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress.
if(!(force || canUnEquip(I)))
return
drop_from_inventory(I)
return 1
+22 -9
View File
@@ -101,15 +101,17 @@
log_say("[key_name(speaker)] : ([name]) [message]")
if(!speaker_mask) speaker_mask = speaker.name
for(var/mob/player in player_list)
player.hear_broadcast(src, speaker, speaker_mask, format_message(message, get_spoken_verb(message)))
message = format_message(message, get_spoken_verb(message))
/mob/proc/hear_broadcast(var/datum/language/language, var/speaker, var/message)
for(var/mob/player in player_list)
player.hear_broadcast(src, speaker, speaker_mask, message)
/mob/proc/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
if((language in languages) && language.check_special_condition(src))
var/msg = "<i><span class='game say'>[language.name], <span class='name'>[speaker]</span> [message]</span></i>"
var/msg = "<i><span class='game say'>[language.name], <span class='name'>[speaker_name]</span> [message]</span></i>"
src << msg
/mob/new_player/hear_broadcast()
/mob/new_player/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
return
/mob/dead/observer/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
@@ -153,9 +155,20 @@
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak(datum/language/speaking)
return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages)
/mob/proc/get_language_prefix()
if(client && client.prefs.language_prefixes && client.prefs.language_prefixes.len)
return client.prefs.language_prefixes[1]
return config.language_prefixes[1]
/mob/proc/is_language_prefix(var/prefix)
if(client && client.prefs.language_prefixes && client.prefs.language_prefixes.len)
return prefix in client.prefs.language_prefixes
return prefix in config.language_prefixes
//TBD
/mob/verb/check_languages()
set name = "Check Known Languages"
@@ -166,7 +179,7 @@
for(var/datum/language/L in languages)
if(!(L.flags & NONGLOBAL))
dat += "<b>[L.name] (:[L.key])</b><br/>[L.desc]<br/><br/>"
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
return
@@ -180,9 +193,9 @@
for(var/datum/language/L in languages)
if(!(L.flags & NONGLOBAL))
if(L == default_language)
dat += "<b>[L.name] (:[L.key])</b> - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/>[L.desc]<br/><br/>"
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b> - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/>[L.desc]<br/><br/>"
else
dat += "<b>[L.name] (:[L.key])</b> - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a><br/>[L.desc]<br/><br/>"
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b> - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
+1 -1
View File
@@ -7,7 +7,7 @@
key = "6"
/datum/language/skrell/monkey
name = "Neara"
name = "Neaera"
desc = "Squik squik squik."
key = "8"
+2 -2
View File
@@ -90,7 +90,7 @@
ask_verb = "intones"
exclaim_verb = "chants"
colour = "cult"
key = "n"
key = "f"
flags = RESTRICTED
space_chance = 100
syllables = list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri", \
@@ -108,5 +108,5 @@
ask_verb = "intones"
exclaim_verb = "chants"
colour = "cult"
key = "m"
key = "y"
flags = RESTRICTED | HIVEMIND
+15 -3
View File
@@ -107,11 +107,23 @@
space_chance = 10
/datum/language/machine/get_random_name()
var/new_name
if(prob(70))
name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
new_name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
else
name = pick(ai_names)
return name
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
syllables = list("caw","caw","caw","caw","ka")
//Syllable Lists
/*
+1 -1
View File
@@ -336,7 +336,7 @@
path = list()
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
if(!M || !istype(M) || M.stat)
if(!M || !istype(M) || M.stat || src == M)
return 0
if(emagged)
+7 -4
View File
@@ -25,10 +25,6 @@
w_class = 3
origin_tech = list(TECH_BIO = 3)
var/list/construction_cost = list(DEFAULT_WALL_MATERIAL=1000,"glass"=500)
var/construction_time = 75
//these vars are so the mecha fabricator doesn't shit itself anymore. --NEO
req_access = list(access_robotics)
//Revised. Brainmob is now contained directly within object of transfer. MMI in this case.
@@ -122,6 +118,13 @@
locked = 1
return
/obj/item/device/mmi/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/weapon/rig/rig = src.get_rig()
if(rig)
rig.forced_move(direction, user)
/obj/item/device/mmi/Destroy()
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
@@ -49,12 +49,12 @@
return 1
return ..()
/mob/living/carbon/brain/update_canmove()
if(in_contents_of(/obj/mecha))
if(in_contents_of(/obj/mecha) || istype(loc, /obj/item/device/mmi))
canmove = 1
use_me = 1 //If it can move, let it emote
else canmove = 0
use_me = 1
else
canmove = 0
return canmove
/mob/living/carbon/brain/binarycheck()
@@ -6,8 +6,6 @@
w_class = 3
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2, TECH_DATA = 4)
construction_cost = list(DEFAULT_WALL_MATERIAL=500,"glass"=500,"silver"=200,"gold"=200,"phoron"=100,"diamond"=10)
construction_time = 75
var/searching = 0
var/askDelay = 10 * 60 * 1
req_access = list(access_robotics)
+3 -1
View File
@@ -136,8 +136,10 @@
return shock_damage
/mob/proc/swap_hand()
return
/mob/living/carbon/proc/swap_hand()
/mob/living/carbon/swap_hand()
var/obj/item/item_in_hand = src.get_active_hand()
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
if(istype(item_in_hand,/obj/item/weapon/material/twohanded))
@@ -95,6 +95,8 @@
g_hair = green
b_hair = blue
force_update_limbs()
update_body()
update_hair()
return 1
@@ -61,11 +61,13 @@
if(!gibbed && species.death_sound)
playsound(loc, species.death_sound, 80, 1, 1)
if(ticker && ticker.mode)
sql_report_death(src)
ticker.mode.check_win()
if(wearing_rig)
wearing_rig.notify_ai("<span class='danger'>Warning: user death event. Mobility control passed to integrated intelligence system.</span>")
return ..(gibbed,species.death_message)
/mob/living/carbon/human/proc/ChangeToHusk()
@@ -266,7 +266,11 @@
else
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] a robot [temp.name]. It has[temp.get_wounds_desc()]!</span>\n"
else if(temp.wounds.len > 0 || temp.open)
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] [temp.get_wounds_desc()] on [T.his] [temp.name].</span><br>"
if(temp.is_stump() && temp.parent_organ && organs_by_name[temp.parent_organ])
var/obj/item/organ/external/parent = organs_by_name[temp.parent_organ]
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] has [temp.get_wounds_desc()] on [T.His] [parent.name].</span><br>"
else
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] has [temp.get_wounds_desc()] on [T.His] [temp.name].</span><br>"
if(temp.status & ORGAN_BLEEDING)
is_bleeding["[temp.name]"] = "<span class='danger'>[T.His] [temp.name] is bleeding!</span><br>"
else
+30 -4
View File
@@ -7,6 +7,7 @@
var/list/hud_list[10]
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
/mob/living/carbon/human/New(var/new_loc, var/new_species = null)
@@ -207,7 +208,7 @@
/mob/living/carbon/human/show_inv(mob/user as mob)
if(user.incapacitated())
if(user.incapacitated() || !user.Adjacent(src))
return
var/obj/item/clothing/under/suit = null
@@ -1092,18 +1093,21 @@
else
dna.species = new_species
// No more invisible screaming wheelchairs because of set_species() typos.
if(!all_species[new_species])
new_species = "Human"
if(species)
if(species.name && species.name == new_species)
return
if(species.language)
remove_language(species.language)
if(species.default_language)
remove_language(species.default_language)
// Clear out their species abilities.
species.remove_inherent_verbs(src)
holder_type = null
species = all_species[new_species]
@@ -1123,6 +1127,11 @@
g_skin = 0
b_skin = 0
if(species.holder_type)
holder_type = species.holder_type
icon_state = lowertext(species.name)
species.create_organs(src)
species.handle_post_spawn(src)
@@ -1370,6 +1379,23 @@
handle_regular_hud_updates()
/mob/living/carbon/human/Check_Shoegrip()
if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.item_flags & NOSLIP)) //magboots + dense_object = no floating
if(shoes && (shoes.item_flags & NOSLIP) && istype(shoes, /obj/item/clothing/shoes/magboots)) //magboots + dense_object = no floating
return 1
return 0
/mob/living/carbon/human/can_stand_overridden()
if(wearing_rig && wearing_rig.ai_can_move_suit(check_for_ai = 1))
// Actually missing a leg will screw you up. Everything else can be compensated for.
for(var/limbcheck in list("l_leg","r_leg"))
var/obj/item/organ/affecting = get_organ(limbcheck)
if(!affecting)
return 0
return 1
return 0
/mob/living/carbon/human/MouseDrop(var/atom/over_object)
var/mob/living/carbon/human/H = over_object
if(holder_type && a_intent == "help" && istype(H) && H.a_intent == "help" && !issmall(H) && Adjacent(H))
get_scooped(H)
return
return ..()
@@ -19,8 +19,7 @@
// Should this all be in Touch()?
if(istype(H))
if((H != src) && check_shields(0, H.name))
visible_message("\red <B>[H] attempted to touch [src]!</B>")
if(H != src && check_shields(0, null, H, H.zone_sel.selecting, H.name))
H.do_attack_animation(src)
return 0
@@ -32,7 +32,6 @@
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.take_damage(amount)
sponge.damage = min(max(sponge.damage, 0),(maxHealth*2))
brainloss = sponge.damage
else
brainloss = 200
@@ -86,9 +85,7 @@
/mob/living/carbon/human/adjustBruteLoss(var/amount)
if(species && species.brute_mod)
amount = amount*species.brute_mod
amount = amount*species.brute_mod
if(amount > 0)
take_overall_damage(amount, 0)
else
@@ -96,9 +93,7 @@
BITSET(hud_updateflag, HEALTH_HUD)
/mob/living/carbon/human/adjustFireLoss(var/amount)
if(species && species.burn_mod)
amount = amount*species.burn_mod
amount = amount*species.burn_mod
if(amount > 0)
take_overall_damage(0, amount)
else
@@ -106,9 +101,7 @@
BITSET(hud_updateflag, HEALTH_HUD)
/mob/living/carbon/human/proc/adjustBruteLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
if(species && species.brute_mod)
amount = amount*species.brute_mod
amount = amount*species.brute_mod
if (organ_name in organs_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -121,9 +114,7 @@
BITSET(hud_updateflag, HEALTH_HUD)
/mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
if(species && species.burn_mod)
amount = amount*species.burn_mod
amount = amount*species.burn_mod
if (organ_name in organs_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -145,6 +136,9 @@
/mob/living/carbon/human/Paralyse(amount)
if(HULK in mutations) return
// Notify our AI if they can now control the suit.
if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second.
wearing_rig.notify_ai("<span class='danger'>Warning: user consciousness failure. Mobility control passed to integrated intelligence system.</span>")
..()
/mob/living/carbon/human/getCloneLoss()
@@ -203,7 +197,8 @@
if(species.flags & NO_BREATHE)
oxyloss = 0
else
..()
amount = amount*species.oxy_mod
..(amount)
/mob/living/carbon/human/setOxyLoss(var/amount)
if(species.flags & NO_BREATHE)
@@ -220,7 +215,8 @@
if(species.flags & NO_POISON)
toxloss = 0
else
..()
amount = amount*species.toxins_mod
..(amount)
/mob/living/carbon/human/setToxLoss(var/amount)
if(species.flags & NO_POISON)
@@ -386,14 +382,12 @@ This function restores all organs.
switch(damagetype)
if(BRUTE)
damageoverlaytemp = 20
if(species && species.brute_mod)
damage = damage*species.brute_mod
damage = damage*species.brute_mod
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
UpdateDamageIcon()
if(BURN)
damageoverlaytemp = 20
if(species && species.burn_mod)
damage = damage*species.burn_mod
damage = damage*species.burn_mod
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
UpdateDamageIcon()
@@ -16,30 +16,14 @@ emp_act
var/obj/item/organ/external/organ = get_organ()
//Shields
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2, def_zone)
return 2
//Laserproof armour
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof))
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 40 - round(P.damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
if(prob(reflectchance))
visible_message("\red <B>\The [P] gets reflected by \the [src]'s [wear_suit.name]!</B>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.redirect(new_x, new_y, curloc, src)
return PROJECTILE_CONTINUE // complete projectile permutation
//Shields
var/shield_check = check_shields(P.damage, P, null, def_zone, "the [P.name]")
if(shield_check)
if(shield_check < 0)
return shield_check
else
P.on_hit(src, 2, def_zone)
return 2
//Shrapnel
if(P.can_embed())
@@ -148,33 +132,11 @@ emp_act
return gear
return null
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack")
if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3)
var/obj/item/weapon/I = l_hand
if(I.IsShield() && (prob(50 - round(damage / 3))))
visible_message("\red <B>[src] blocks [attack_text] with the [l_hand.name]!</B>")
return 1
if(r_hand && istype(r_hand, /obj/item/weapon))
var/obj/item/weapon/I = r_hand
if(I.IsShield() && (prob(50 - round(damage / 3))))
visible_message("\red <B>[src] blocks [attack_text] with the [r_hand.name]!</B>")
return 1
if(wear_suit && istype(wear_suit, /obj/item/))
var/obj/item/I = wear_suit
if(I.IsShield() && (prob(35)))
visible_message("\red <B>The reactive teleport system flings [src] clear of [attack_text]!</B>")
var/list/turfs = new/list()
for(var/turf/T in orange(6))
if(istype(T,/turf/space)) continue
if(T.density) continue
if(T.x>world.maxx-6 || T.x<6) continue
if(T.y>world.maxy-6 || T.y<6) continue
turfs += T
if(!turfs.len) turfs += pick(/turf in orange(6))
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
src.loc = picked
return 1
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/atom/damage_source = null, var/mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
for(var/obj/item/shield in list(l_hand, r_hand, wear_suit))
if(!shield) continue
. = shield.handle_shield(src, damage, damage_source, attacker, def_zone, attack_text)
if(.) return
return 0
/mob/living/carbon/human/emp_act(severity)
@@ -206,7 +168,7 @@ emp_act
if(user.a_intent == "disarm") effective_force = round(I.force/2)
var/hit_area = affecting.name
if((user != src) && check_shields(effective_force, "the [I.name]"))
if((user != src) && check_shields(effective_force, I, user, target_zone, "the [I.name]"))
return 0
if(istype(I,/obj/item/weapon/card/emag))
@@ -329,15 +291,19 @@ emp_act
miss_chance = max(15*(distance-2), 0)
zone = get_zone_with_miss_chance(zone, src, miss_chance, ranged_attack=1)
if(zone && O.thrower != src)
var/shield_check = check_shields(throw_damage, O, thrower, zone, "[O]")
if(shield_check == PROJECTILE_FORCE_MISS)
zone = null
else if(shield_check)
return
if(!zone)
visible_message("\blue \The [O] misses [src] narrowly!")
visible_message("<span class='notice'>\The [O] misses [src] narrowly!</span>")
return
O.throwing = 0 //it hit, so stop moving
if ((O.thrower != src) && check_shields(throw_damage, "[O]"))
return
var/obj/item/organ/external/affecting = get_organ(zone)
var/hit_area = affecting.name
@@ -31,8 +31,8 @@
/mob/living/carbon/human/farwa/New(var/new_loc)
..(new_loc, "Farwa")
/mob/living/carbon/human/neara/New(var/new_loc)
..(new_loc, "Neara")
/mob/living/carbon/human/neaera/New(var/new_loc)
..(new_loc, "Neaera")
/mob/living/carbon/human/stok/New(var/new_loc)
..(new_loc, "Stok")
+26 -18
View File
@@ -52,6 +52,10 @@
// update the current life tick, can be used to e.g. only do something every 4 ticks
life_tick++
// This is not an ideal place for this but it will do for now.
if(wearing_rig && wearing_rig.offline)
wearing_rig = null
in_stasis = istype(loc, /obj/structure/closet/body_bag/cryobag) && loc:opened == 0
if(in_stasis) loc:used++
@@ -276,7 +280,7 @@
Weaken(3)
if(!lying)
emote("collapse")
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.name == "Human") //apes go bald
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == "Human") //apes go bald
if((h_style != "Bald" || f_style != "Shaved" ))
src << "<span class='warning'>Your hair falls out.</span>"
h_style = "Bald"
@@ -294,6 +298,7 @@
emote("gasp")
if(damage)
damage *= species.radiation_mod
adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT)
updatehealth()
if(organs.len)
@@ -964,10 +969,10 @@
stat = UNCONSCIOUS
animate_tail_reset()
adjustHalLoss(-3)
if(paralysis)
AdjustParalysis(-1)
else if(sleeping)
speech_problem_flag = 1
handle_dreams()
@@ -1214,7 +1219,7 @@
seer = 0
else
sight = species.vision_flags
sight = species.get_vision_flags(src)
see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
var/tmp/glasses_processed = 0
@@ -1233,8 +1238,8 @@
see_in_dark = 8
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(!glasses_processed && (species.vision_flags > 0))
sight |= species.vision_flags
if(!glasses_processed && (species.get_vision_flags(src) > 0))
sight |= species.get_vision_flags(src)
if(!seer && !glasses_processed)
see_invisible = SEE_INVISIBLE_LIVING
@@ -1340,19 +1345,22 @@
if(config.welder_vision)
var/found_welder
if(istype(glasses, /obj/item/clothing/glasses/welding))
var/obj/item/clothing/glasses/welding/O = glasses
if(!O.up)
found_welder = 1
if(!found_welder && istype(head, /obj/item/clothing/head/welding))
var/obj/item/clothing/head/welding/O = head
if(!O.up)
found_welder = 1
if(!found_welder && istype(back, /obj/item/weapon/rig))
var/obj/item/weapon/rig/O = back
if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES))
if((O.offline && O.offline_vision_restriction == 1) || (!O.offline && O.vision_restriction == 1))
if(species.short_sighted)
found_welder = 1
else
if(istype(glasses, /obj/item/clothing/glasses/welding))
var/obj/item/clothing/glasses/welding/O = glasses
if(!O.up)
found_welder = 1
if(!found_welder && istype(head, /obj/item/clothing/head/welding))
var/obj/item/clothing/head/welding/O = head
if(!O.up)
found_welder = 1
if(!found_welder && istype(back, /obj/item/weapon/rig))
var/obj/item/weapon/rig/O = back
if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES))
if((O.offline && O.offline_vision_restriction == 1) || (!O.offline && O.vision_restriction == 1))
found_welder = 1
if(found_welder)
client.screen |= global_hud.darkMask
+5 -4
View File
@@ -162,10 +162,11 @@
/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
switch(message_mode)
if("intercom")
for(var/obj/item/device/radio/intercom/I in view(1))
I.talk_into(src, message, verb, speaking)
I.add_fingerprint(src)
used_radios += I
if(!src.restrained())
for(var/obj/item/device/radio/intercom/I in view(1))
I.talk_into(src, message, null, verb, speaking)
I.add_fingerprint(src)
used_radios += I
if("headset")
if(l_ear && istype(l_ear,/obj/item/device/radio))
var/obj/item/device/radio/R = l_ear
@@ -25,11 +25,13 @@
var/base_color // Used by changelings. Should also be used for icon previes..
var/tail // Name of tail state in species effects icon file.
var/tail_animation // If set, the icon to obtain tail animation states from.
var/tail_hair
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/is_small
var/show_ssd = "fast asleep"
var/virus_immune
var/short_sighted
// Language/culture vars.
var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
@@ -46,8 +48,12 @@
/datum/unarmed_attack/bite
)
var/list/unarmed_attacks = null // For empty hand harm-intent attack
var/brute_mod = 1 // Physical damage multiplier.
var/burn_mod = 1 // Burn damage multiplier.
var/brute_mod = 1 // Physical damage multiplier.
var/burn_mod = 1 // Burn damage multiplier.
var/oxy_mod = 1 // Oxyloss modifier
var/toxins_mod = 1 // Toxloss modifier
var/radiation_mod = 1 // Radiation modifier
var/flash_mod = 1 // Stun from blindness modifier.
var/vision_flags = SEE_SELF // Same flags as glasses.
// Death vars.
@@ -108,6 +114,7 @@
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
var/holder_type
var/gluttonous // Can eat some mobs. 1 for mice, 2 for monkeys, 3 for people.
var/rarity_value = 1 // Relative rarity/collector value for this species.
// Determines the organs that the species spawns with and
@@ -305,3 +312,6 @@
// Called in life() when the mob has no client.
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
return
/datum/species/proc/get_vision_flags(var/mob/living/carbon/human/H)
return vision_flags
@@ -69,4 +69,15 @@
/datum/unarmed_attack/slime_glomp/apply_effects()
//Todo, maybe have a chance of causing an electrical shock?
return
return
/datum/unarmed_attack/stomp/weak
attack_verb = list("jumped on")
/datum/unarmed_attack/stomp/weak/get_unarmed_damage()
return damage
/datum/unarmed_attack/stomp/weak/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/obj/item/organ/external/affecting = target.get_organ(zone)
user.visible_message("<span class='warning'>[user] jumped up and down on \the [target]'s [affecting.name]!</span>")
playsound(user.loc, attack_sound, 25, 1, -1)
@@ -0,0 +1,57 @@
/datum/species/human/gravworlder
name = "grav-adapted Human"
name_plural = "grav-adapted Humans"
blurb = "Heavier and stronger than a baseline human, gravity-adapted people have \
thick radiation-resistant skin with a high lead content, denser bones, and recessed \
eyes beneath a prominent brow in order to shield them from the glare of a dangerously \
bright, alien sun. This comes at the cost of mobility, flexibility, and increased \
oxygen requirements to support their robust metabolism."
icobase = 'icons/mob/human_races/subspecies/r_gravworlder.dmi'
flash_mod = 0.9
oxy_mod = 1.1
radiation_mod = 0.5
brute_mod = 0.85
slowdown = 1
/datum/species/human/spacer
name = "space-adapted Human"
name_plural = "space-adapted Humans"
blurb = "Lithe and frail, these sickly folk were engineered for work in environments that \
lack both light and atmosphere. As such, they're quite resistant to asphyxiation as well as \
toxins, but they suffer from weakened bone structure and a marked vulnerability to bright lights."
icobase = 'icons/mob/human_races/subspecies/r_spacer.dmi'
oxy_mod = 0.8
toxins_mod = 0.9
flash_mod = 1.2
brute_mod = 1.1
burn_mod = 1.1
/datum/species/human/vatgrown
name = "vat-grown Human"
name_plural = "vat-grown Humans"
blurb = "With cloning on the forefront of human scientific advancement, cheap mass production \
of bodies is a very real and rather ethically grey industry. Vat-grown humans tend to be paler than \
baseline, with no appendix and fewer inherited genetic disabilities, but a weakened metabolism."
icobase = 'icons/mob/human_races/subspecies/r_vatgrown.dmi'
toxins_mod = 1.1
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
)
/*
// These guys are going to need full resprites of all the suits/etc so I'm going to
// define them and commit the sprites, but leave the clothing for another day.
/datum/species/human/chimpanzee
name = "uplifted Chimpanzee"
name_plural = "uplifted Chimpanzees"
blurb = "Ook ook."
icobase = 'icons/mob/human_races/subspecies/r_upliftedchimp.dmi'
*/
@@ -63,14 +63,14 @@
tail = "farwatail"
/datum/species/monkey/skrell
name = "Neara"
name_plural = "Neara"
name = "Neaera"
name_plural = "Neaera"
icobase = 'icons/mob/human_races/monkeys/r_neara.dmi'
deform = 'icons/mob/human_races/monkeys/r_neara.dmi'
icobase = 'icons/mob/human_races/monkeys/r_neaera.dmi'
deform = 'icons/mob/human_races/monkeys/r_neaera.dmi'
greater_form = "Skrell"
default_language = "Neara"
default_language = "Neaera"
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
reagent_tag = IS_SKRELL
@@ -0,0 +1,113 @@
/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")
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
is_small = 1
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
@@ -12,7 +12,10 @@
secondary_langs = list("Sol Common")
spawn_flags = CAN_JOIN
appearance_flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
/datum/species/human/get_bodytype()
return "Human"
/datum/species/unathi
name = "Unathi"
@@ -45,7 +48,7 @@
heat_level_3 = 1100 //Default 1000
spawn_flags = CAN_JOIN | IS_WHITELISTED
appearance_flags = HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
@@ -103,7 +106,7 @@
primitive_form = "Farwa"
spawn_flags = CAN_JOIN | IS_WHITELISTED
appearance_flags = HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#AFA59E"
base_color = "#333333"
@@ -126,7 +129,7 @@
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
eyes = "skrell_eyes_s"
primitive_form = "Neara"
primitive_form = "Neaera"
unarmed_types = list(/datum/unarmed_attack/punch)
blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \
the royals' or 'Light of the Crown'.<br/><br/>Skrell are a highly advanced and logical race who live under the rule \
@@ -137,7 +140,7 @@
secondary_langs = list("Skrellian")
spawn_flags = CAN_JOIN | IS_WHITELISTED
appearance_flags = HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
@@ -3,7 +3,7 @@
if(!slot_to_strip || !istype(user))
return
if(user.incapacitated())
if(user.incapacitated() || !user.Adjacent(src))
user << browse(null, text("window=mob[src.name]"))
return
@@ -208,7 +208,7 @@ var/global/list/damage_icon_parts = list()
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]"
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
@@ -271,8 +271,13 @@ var/global/list/damage_icon_parts = list()
icon_key += "[part.species.race_key]"
icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]"
icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]"
if(part.s_col)
if(part.s_col && part.s_col.len >= 3)
icon_key += "[rgb(part.s_col[1],part.s_col[2],part.s_col[3])]"
if(part.body_hair && part.h_col && part.h_col.len >= 3)
icon_key += "[rgb(part.h_col[1],part.h_col[2],part.h_col[3])]"
else
icon_key += "#000000"
icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]"
var/icon/base_icon
@@ -517,7 +522,14 @@ var/global/list/damage_icon_parts = list()
if(wear_id)
wear_id.screen_loc = ui_id //TODO
if(w_uniform && w_uniform:displays_id)
overlays_standing[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
var/image/standing
if(wear_id.icon_override)
standing = image("icon" = wear_id.icon_override, "icon_state" = "[icon_state]")
else if(wear_id.sprite_sheets && wear_id.sprite_sheets[species.get_bodytype()])
standing = image("icon" = wear_id.sprite_sheets[species.get_bodytype()], "icon_state" = "[icon_state]")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
overlays_standing[ID_LAYER] = standing
else
overlays_standing[ID_LAYER] = null
else
@@ -682,8 +694,9 @@ var/global/list/damage_icon_parts = list()
if(istype(head,/obj/item/clothing/head))
var/obj/item/clothing/head/hat = head
if(hat.on && light_overlay_cache["[hat.light_overlay]"])
standing.overlays |= light_overlay_cache["[hat.light_overlay]"]
var/cache_key = "[hat.light_overlay]_[species.get_bodytype()]"
if(hat.on && light_overlay_cache[cache_key])
standing.overlays |= light_overlay_cache[cache_key]
overlays_standing[HEAD_LAYER] = standing
@@ -834,14 +847,32 @@ var/global/list/damage_icon_parts = list()
drop_r_hand()
drop_l_hand()
stop_pulling() //TODO: should be handled elsewhere
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
var/image/standing
if(handcuffed.icon_override)
standing = image("icon" = handcuffed.icon_override, "icon_state" = "handcuff1")
else if(handcuffed.sprite_sheets && handcuffed.sprite_sheets[species.get_bodytype()])
standing = image("icon" = handcuffed.sprite_sheets[species.get_bodytype()], "icon_state" = "handcuff1")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
overlays_standing[HANDCUFF_LAYER] = standing
else
overlays_standing[HANDCUFF_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
if(legcuffed)
overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
var/image/standing
if(legcuffed.icon_override)
standing = image("icon" = legcuffed.icon_override, "icon_state" = "legcuff1")
else if(legcuffed.sprite_sheets && legcuffed.sprite_sheets[species.get_bodytype()])
standing = image("icon" = legcuffed.sprite_sheets[species.get_bodytype()], "icon_state" = "legcuff1")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
overlays_standing[LEGCUFF_LAYER] = standing
if(src.m_intent != "walk")
src.m_intent = "walk"
if(src.hud_used && src.hud_used.move_intent)
@@ -927,15 +958,17 @@ var/global/list/damage_icon_parts = list()
update_icons()
/mob/living/carbon/human/proc/get_tail_icon()
var/icon_key = "[species.race_key][r_skin][g_skin][b_skin]"
var/icon_key = "[species.race_key][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]"
var/icon/tail_icon = tail_icon_cache[icon_key]
if(!tail_icon)
//generate a new one
tail_icon = new/icon(icon = (species.tail_animation? species.tail_animation : 'icons/effects/species.dmi'))
tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
// The following will not work with animated tails.
if(species.tail_hair)
var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.tail]_[species.tail_hair]")
hair_icon.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
tail_icon.Blend(hair_icon, ICON_OVERLAY)
tail_icon_cache[icon_key] = tail_icon
return tail_icon
+1
View File
@@ -24,6 +24,7 @@
adjustCloneLoss(damage/(blocked+1))
if(HALLOSS)
adjustHalLoss(damage/(blocked+1))
flash_weak_pain()
updatehealth()
return 1
+30 -11
View File
@@ -575,12 +575,14 @@ default behaviour is:
if(can_resist())
setClickCooldown(20)
process_resist()
resist_grab()
if(!weakened && !restrained())
process_resist()
/mob/living/proc/can_resist()
//need to allow !canmove, or otherwise neck grabs can't be resisted
//so just check weakened instead.
if(stat || weakened)
//similar thing with weakened and pinning
if(stat)
return 0
if(!canClick())
return 0
@@ -592,10 +594,6 @@ default behaviour is:
escape_inventory(src.loc)
return
//resisting grabs (as if it helps anyone...)
if (!restrained())
resist_grab()
//unbuckling yourself
if(buckled)
spawn() escape_buckle()
@@ -657,7 +655,27 @@ default behaviour is:
set category = "IC"
resting = !resting
src << "\blue You are now [resting ? "resting" : "getting up"]"
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"].</span>"
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(istype(carried_item, /obj/item/weapon/implant))
return 1
if(istype(carried_item, /obj/item/clothing/mask/facehugger))
return 1
return 0
/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in internal_organs)
return 1
return ..()
/mob/living/carbon/human/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in organs)
return 1
return ..()
/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item)
return carried_item != held_item
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
if(stat)
@@ -721,9 +739,10 @@ default behaviour is:
if(!ignore_items)
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
src << "\red You can't be carrying items or have items equipped when vent crawling!"
return
if(is_allowed_vent_crawl_item(carried_item))
continue
src << "<span class='warning'>You can't be carrying items or have items equipped when vent crawling!</span>"
return
if(isslime(src))
var/mob/living/carbon/slime/S = src
@@ -50,7 +50,6 @@
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone)
flash_weak_pain()
//Being hit while using a cloaking device
var/obj/item/weapon/cloaking_device/C = locate((/obj/item/weapon/cloaking_device) in src)
+41 -41
View File
@@ -1,49 +1,49 @@
var/list/department_radio_keys = list(
":r" = "right ear", "#r" = "right ear", ".r" = "right ear",
":l" = "left ear", "#l" = "left ear", ".l" = "left ear",
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
":h" = "department", "#h" = "department", ".h" = "department",
":+" = "special", "#+" = "special", ".+" = "special", //activate radio-specific special functions
":c" = "Command", "#c" = "Command", ".c" = "Command",
":n" = "Science", "#n" = "Science", ".n" = "Science",
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
":e" = "Engineering", "#e" = "Engineering", ".e" = "Engineering",
":s" = "Security", "#s" = "Security", ".s" = "Security",
":w" = "whisper", "#w" = "whisper", ".w" = "whisper",
":t" = "Mercenary", "#t" = "Mercenary", ".t" = "Mercenary",
":u" = "Supply", "#u" = "Supply", ".u" = "Supply",
":v" = "Service", "#v" = "Service", ".v" = "Service",
":p" = "AI Private", "#p" = "AI Private", ".p" = "AI Private",
":r" = "right ear", ".r" = "right ear",
":l" = "left ear", ".l" = "left ear",
":i" = "intercom", ".i" = "intercom",
":h" = "department", ".h" = "department",
":+" = "special", ".+" = "special", //activate radio-specific special functions
":c" = "Command", ".c" = "Command",
":n" = "Science", ".n" = "Science",
":m" = "Medical", ".m" = "Medical",
":e" = "Engineering", ".e" = "Engineering",
":s" = "Security", ".s" = "Security",
":w" = "whisper", ".w" = "whisper",
":t" = "Mercenary", ".t" = "Mercenary",
":u" = "Supply", ".u" = "Supply",
":v" = "Service", ".v" = "Service",
":p" = "AI Private", ".p" = "AI Private",
":R" = "right ear", "#R" = "right ear", ".R" = "right ear",
":L" = "left ear", "#L" = "left ear", ".L" = "left ear",
":I" = "intercom", "#I" = "intercom", ".I" = "intercom",
":H" = "department", "#H" = "department", ".H" = "department",
":C" = "Command", "#C" = "Command", ".C" = "Command",
":N" = "Science", "#N" = "Science", ".N" = "Science",
":M" = "Medical", "#M" = "Medical", ".M" = "Medical",
":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering",
":S" = "Security", "#S" = "Security", ".S" = "Security",
":W" = "whisper", "#W" = "whisper", ".W" = "whisper",
":T" = "Mercenary", "#T" = "Mercenary", ".T" = "Mercenary",
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
":V" = "Service", "#V" = "Service", ".V" = "Service",
":P" = "AI Private", "#P" = "AI Private", ".P" = "AI Private",
":R" = "right ear", ".R" = "right ear",
":L" = "left ear", ".L" = "left ear",
":I" = "intercom", ".I" = "intercom",
":H" = "department", ".H" = "department",
":C" = "Command", ".C" = "Command",
":N" = "Science", ".N" = "Science",
":M" = "Medical", ".M" = "Medical",
":E" = "Engineering", ".E" = "Engineering",
":S" = "Security", ".S" = "Security",
":W" = "whisper", ".W" = "whisper",
":T" = "Mercenary", ".T" = "Mercenary",
":U" = "Supply", ".U" = "Supply",
":V" = "Service", ".V" = "Service",
":P" = "AI Private", ".P" = "AI Private",
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
":ê" = "right ear", "#ê" = "right ear", ".ê" = "right ear",
":ä" = "left ear", "#ä" = "left ear", ".ä" = "left ear",
":ø" = "intercom", "#ø" = "intercom", ".ø" = "intercom",
":ð" = "department", "#ð" = "department", ".ð" = "department",
":ñ" = "Command", "#ñ" = "Command", ".ñ" = "Command",
":ò" = "Science", "#ò" = "Science", ".ò" = "Science",
":ü" = "Medical", "#ü" = "Medical", ".ü" = "Medical",
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
":û" = "Security", "#û" = "Security", ".û" = "Security",
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
":å" = "Mercenary", "#å" = "Mercenary", ".å" = "Mercenary",
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
":ê" = "right ear", ".ê" = "right ear",
":ä" = "left ear", ".ä" = "left ear",
":ø" = "intercom", ".ø" = "intercom",
":ð" = "department", ".ð" = "department",
":ñ" = "Command", ".ñ" = "Command",
":ò" = "Science", ".ò" = "Science",
":ü" = "Medical", ".ü" = "Medical",
":ó" = "Engineering", ".ó" = "Engineering",
":û" = "Security", ".û" = "Security",
":ö" = "whisper", ".ö" = "whisper",
":å" = "Mercenary", ".å" = "Mercenary",
":é" = "Supply", ".é" = "Supply",
)
+12 -2
View File
@@ -81,7 +81,7 @@ var/list/ai_verbs_default = list(
var/datum/ai_icon/selected_sprite // The selected icon set
var/custom_sprite = 0 // Whether the selected icon is custom
var/carded
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
@@ -368,7 +368,7 @@ var/list/ai_verbs_default = list(
if(emergency_message_cooldown)
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>"
return
var/input = input(usr, "Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")
var/input = sanitize(input(usr, "Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", ""))
if(!input)
return
Centcomm_announce(input, usr)
@@ -689,5 +689,15 @@ var/list/ai_verbs_default = list(
icon_state = selected_sprite.alive_icon
set_light(1, 1, selected_sprite.alive_light)
// Pass lying down or getting up to our pet human, if we're in a rig.
/mob/living/silicon/ai/lay_down()
set name = "Rest"
set category = "IC"
resting = 0
var/obj/item/weapon/rig/rig = src.get_rig()
if(rig)
rig.force_rest(src)
#undef AI_CHECK_WIRELESS
#undef AI_CHECK_RADIO
+7 -6
View File
@@ -72,8 +72,6 @@
var/current_pda_messaging = null
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
canmove = 0
src.loc = paicard
card = paicard
sradio = new(src)
@@ -276,8 +274,6 @@
var/obj/item/device/pda/holder = card.loc
holder.pai = null
canmove = 1
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = src
src.forceMove(get_turf(card))
@@ -339,12 +335,16 @@
set name = "Rest"
set category = "IC"
// Pass lying down or getting up to our pet human, if we're in a rig.
if(istype(src.loc,/obj/item/device/paicard))
resting = 0
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.force_rest(src)
else
resting = !resting
icon_state = resting ? "[chassis]_rest" : "[chassis]"
src << "\blue You are now [resting ? "resting" : "getting up"]"
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>"
canmove = !resting
@@ -393,7 +393,8 @@
card.loc = get_turf(card)
src.forceMove(card)
card.forceMove(card.loc)
canmove = 0
canmove = 1
resting = 0
icon_state = "[chassis]"
/mob/living/silicon/pai/start_pulling(var/atom/movable/AM)
@@ -510,7 +510,7 @@
else if(href_list["freq"])
var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"]))
if(new_frequency < 1200 || new_frequency > 1600)
if(new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ)
new_frequency = sanitize_frequency(new_frequency)
P.sradio.set_frequency(new_frequency)
return 1
@@ -217,8 +217,6 @@
/obj/item/robot_parts/robot_component
icon = 'icons/obj/robot_component.dmi'
icon_state = "working"
construction_time = 200
construction_cost = list(DEFAULT_WALL_MATERIAL=5000)
var/brute = 0
var/burn = 0
var/icon_state_broken = "broken"
@@ -87,6 +87,9 @@
/obj/item/weapon/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item
/obj/item/weapon/gripper/no_use/attack_self(mob/user as mob)
return
/obj/item/weapon/gripper/no_use/loader //This is used to disallow building with metal.
name = "sheet loader"
desc = "A specialized loading device, designed to pick up and insert sheets of materials inside machines."
@@ -101,9 +104,6 @@
return wrapped.attack_self(user)
return ..()
/obj/item/weapon/gripper/no_use/attack_self(mob/user as mob)
return
/obj/item/weapon/gripper/verb/drop_item()
set name = "Drop Item"
@@ -130,6 +130,8 @@
force_holder = wrapped.force
wrapped.force = 0.0
wrapped.attack(M,user)
if(deleted(wrapped))
wrapped = null
return 1
return 0
@@ -5,4 +5,6 @@
winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")
return
// Forces synths to select an icon relevant to their module
if(!icon_selected)
choose_icon(icon_selection_tries, module_sprites)
+28 -57
View File
@@ -24,8 +24,10 @@
//Icon stuff
var/icontype //Persistent icontype tracking allows for cleaner icon updates
var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
var/icontype //Persistent icontype tracking allows for cleaner icon updates
var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
var/icon_selected = 1 //If icon selection has been completed yet
var/icon_selection_tries = 0//Remaining attempts to select icon before a selection is forced
//Hud stuff
@@ -89,21 +91,6 @@
/mob/living/silicon/robot/proc/robot_checklaws
)
/mob/living/silicon/robot/syndicate
lawupdate = 0
scrambledcodes = 1
icon_state = "securityrobot"
modtype = "Security"
lawchannel = "State"
/mob/living/silicon/robot/syndicate/New()
if(!cell)
cell = new /obj/item/weapon/cell(src)
cell.maxcharge = 25000
cell.charge = 25000
..()
/mob/living/silicon/robot/New(loc,var/unfinished = 0)
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
@@ -178,17 +165,6 @@
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
/mob/living/silicon/robot/syndicate/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
laws = new /datum/ai_laws/syndicate_override
new /obj/item/weapon/robot_module/syndicate(src)
radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
radio.recalculateChannels()
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/SetName(pickedName as text)
custom_name = pickedName
updatename()
@@ -241,10 +217,15 @@
..()
/mob/living/silicon/robot/proc/set_module_sprites(var/list/new_sprites)
module_sprites = new_sprites
module_sprites = new_sprites.Copy()
//Custom_sprite check and entry
if (custom_sprite == 1)
module_sprites["Custom"] = "[src.ckey]-[modtype]"
icontype = "Custom"
else
icontype = module_sprites[1]
icon_state = module_sprites[icontype]
updateicon()
return module_sprites
/mob/living/silicon/robot/proc/pick_module()
@@ -255,7 +236,7 @@
if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately.
src << "\red Crisis mode active. Combat module available."
modules+="Combat"
modtype = input("Please, select a module!", "Robot", null, null) in modules
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
if(module)
return
@@ -268,8 +249,6 @@
hands.icon_state = lowertext(modtype)
feedback_inc("cyborg_[lowertext(modtype)]",1)
updatename()
set_module_sprites(module.sprites)
choose_icon(module_sprites.len + 1, module_sprites)
notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
/mob/living/silicon/robot/proc/updatename(var/prefix as text)
@@ -688,7 +667,7 @@
/mob/living/silicon/robot/updateicon()
overlays.Cut()
if(stat == 0)
if(stat == CONSCIOUS)
overlays += "eyes-[module_sprites[icontype]]"
if(opened)
@@ -916,38 +895,30 @@
return
/mob/living/silicon/robot/proc/choose_icon(var/triesleft, var/list/module_sprites)
if(triesleft<1 || !module_sprites.len)
return
else
triesleft--
if (custom_sprite == 1)
icontype = "Custom"
triesleft = 0
else if(module_sprites.len == 1)
icontype = module_sprites[1]
else
icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chances." : "This is your last try."]", "Robot", null, null) in module_sprites
if(icontype)
icon_state = module_sprites[icontype]
else
if(!module_sprites.len)
src << "Something is badly wrong with the sprite selection. Harass a coder."
icon_state = module_sprites[1]
return
icon_selected = 0
src.icon_selection_tries = triesleft
if(module_sprites.len == 1 || !client)
if(!(icontype in module_sprites))
icontype = module_sprites[1]
else
icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot", icontype, null) in module_sprites
icon_state = module_sprites[icontype]
updateicon()
if (triesleft >= 1)
if (module_sprites.len > 1 && triesleft >= 1 && client)
icon_selection_tries--
var/choice = input("Look at your icon - is this what you want?") in list("Yes","No")
if(choice=="No")
choose_icon(triesleft, module_sprites)
choose_icon(icon_selection_tries, module_sprites)
return
else
triesleft = 0
return
else
src << "Your icon has been set. You now require a module reset to change it."
icon_selected = 1
icon_selection_tries = 0
src << "Your icon has been set. You now require a module reset to change it."
/mob/living/silicon/robot/proc/sensor_mode() //Medical/Security HUD controller for borgs
set name = "Set Sensor Augmentation"
@@ -105,13 +105,6 @@
desc = "A circuit grafted onto the bottom of an ID card. It is used to transmit access codes into other robot chassis, \
allowing you to lock and unlock other robots' panels."
/obj/item/weapon/card/id/robot/attack_self() //override so borgs can't flash their IDs.
return
/obj/item/weapon/card/id/robot/read()
usr << "The ID card does not appear to have any writing on it."
return
//A harvest item for serviceborgs.
/obj/item/weapon/robot_harvester
name = "auto harvester"
@@ -49,9 +49,13 @@ var/global/list/robot_modules = list(
if(R.radio)
R.radio.recalculateChannels()
/obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
R.module = null
R.set_module_sprites(sprites)
R.choose_icon(R.module_sprites.len + 1, R.module_sprites)
for(var/obj/item/I in modules)
I.canremove = 0
/obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
remove_camera_networks(R)
remove_languages(R)
remove_subsystems(R)
@@ -59,16 +63,17 @@ var/global/list/robot_modules = list(
if(R.radio)
R.radio.recalculateChannels()
qdel(src)
R.choose_icon(0, R.set_module_sprites(list("Default" = "robot")))
/obj/item/weapon/robot_module/Destroy()
qdel(modules)
qdel(synths)
for(var/module in modules)
qdel(module)
for(var/synth in synths)
qdel(synths)
modules.Cut()
synths.Cut()
qdel(emag)
qdel(jetpack)
modules = null
synths = null
emag = null
jetpack = null
return ..()
@@ -144,7 +149,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/standard/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/melee/baton/loaded(src)
src.modules += new /obj/item/weapon/extinguisher(src)
@@ -152,7 +156,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.emag = new /obj/item/weapon/melee/energy/sword(src)
return
..()
/obj/item/weapon/robot_module/medical
name = "medical robot module"
@@ -172,7 +176,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/medical/surgeon/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
@@ -204,7 +207,7 @@ var/global/list/robot_modules = list(
src.modules += N
src.modules += B
return
..()
/obj/item/weapon/robot_module/medical/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
if(src.emag)
@@ -224,7 +227,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/medical/crisis/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
@@ -258,7 +260,7 @@ var/global/list/robot_modules = list(
src.modules += B
src.modules += S
return
..()
/obj/item/weapon/robot_module/medical/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
@@ -294,7 +296,6 @@ var/global/list/robot_modules = list(
no_slip = 1
/obj/item/weapon/robot_module/engineering/construction/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/extinguisher(src)
@@ -328,8 +329,9 @@ var/global/list/robot_modules = list(
RG.synths = list(metal, glass)
src.modules += RG
/obj/item/weapon/robot_module/engineering/general/New()
..()
/obj/item/weapon/robot_module/engineering/general/New()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/extinguisher(src)
@@ -382,7 +384,7 @@ var/global/list/robot_modules = list(
RG.synths = list(metal, glass)
src.modules += RG
return
..()
/obj/item/weapon/robot_module/security
name = "security robot module"
@@ -403,7 +405,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/security/general/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/hud/sec(src)
src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
@@ -411,7 +412,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src)
src.modules += new /obj/item/taperoll/police(src)
src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src)
return
..()
/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/device/flash/F = locate() in src.modules
@@ -442,7 +443,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/janitor/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/soap/nanotrasen(src)
src.modules += new /obj/item/weapon/storage/bag/trash(src)
@@ -451,7 +451,7 @@ var/global/list/robot_modules = list(
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("lube", 250)
src.emag.name = "Lube spray"
return
..()
/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/device/lightreplacer/LR = locate() in src.modules
@@ -485,7 +485,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/clerical/butler/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/gripper/service(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src)
@@ -507,14 +506,14 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
src.emag.reagents = R
R.my_atom = src.emag
R.add_reagent("beer2", 50)
src.emag.name = "Mickey Finn's Special Brew"
return
..()
/obj/item/weapon/robot_module/clerical/general
name = "clerical robot module"
@@ -528,13 +527,13 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/clerical/general/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/pen/robopen(src)
src.modules += new /obj/item/weapon/form_printer(src)
src.modules += new /obj/item/weapon/gripper/paperwork(src)
src.modules += new /obj/item/weapon/hand_labeler(src)
src.emag = new /obj/item/weapon/stamp/denied(src)
..()
/obj/item/weapon/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
@@ -556,7 +555,6 @@ var/global/list/robot_modules = list(
supported_upgrades = list(/obj/item/borg/upgrade/jetpack)
/obj/item/weapon/robot_module/miner/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/wrench(src)
@@ -568,7 +566,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/mining_scanner(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
return
..()
/obj/item/weapon/robot_module/research
name = "research module"
@@ -579,7 +577,6 @@ var/global/list/robot_modules = list(
)
/obj/item/weapon/robot_module/research/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/portable_destructive_analyzer(src)
src.modules += new /obj/item/weapon/gripper/research(src)
@@ -605,7 +602,7 @@ var/global/list/robot_modules = list(
N.synths = list(nanite)
src.modules += N
return
..()
/obj/item/weapon/robot_module/syndicate
name = "illegal robot module"
@@ -617,9 +614,12 @@ var/global/list/robot_modules = list(
LANGUAGE_SKRELLIAN = 0,
LANGUAGE_GUTTER = 1
)
sprites = list(
"Dread" = "securityrobot",
)
var/id
/obj/item/weapon/robot_module/syndicate/New(var/mob/living/silicon/robot/R)
..()
loc = R
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
@@ -628,14 +628,21 @@ var/global/list/robot_modules = list(
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
return
id = R.idcard
src.modules += id
..()
/obj/item/weapon/robot_module/syndicate/Destroy()
src.modules -= id
id = null
return ..()
/obj/item/weapon/robot_module/security/combat
name = "combat robot module"
sprites = list("Combat Android" = "droid-combat")
/obj/item/weapon/robot_module/combat/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src)
@@ -643,7 +650,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/mounted(src)
return
..()
/obj/item/weapon/robot_module/drone
name = "drone module"
@@ -651,7 +658,6 @@ var/global/list/robot_modules = list(
networks = list(NETWORK_ENGINEERING)
/obj/item/weapon/robot_module/drone/New()
..()
src.modules += new /obj/item/weapon/weldingtool(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
@@ -718,14 +724,16 @@ var/global/list/robot_modules = list(
P.synths = list(plastic)
src.modules += P
..()
/obj/item/weapon/robot_module/drone/construction
name = "construction drone module"
channels = list("Engineering" = 1)
languages = list()
/obj/item/weapon/robot_module/drone/construction/New()
..()
src.modules += new /obj/item/weapon/rcd/borg(src)
..()
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/device/lightreplacer/LR = locate() in src.modules
@@ -0,0 +1,28 @@
/mob/living/silicon/robot/syndicate
lawupdate = 0
scrambledcodes = 1
icon_state = "securityrobot"
modtype = "Security"
lawchannel = "State"
idcard_type = /obj/item/weapon/card/id/syndicate
/mob/living/silicon/robot/syndicate/New()
if(!cell)
cell = new /obj/item/weapon/cell(src)
cell.maxcharge = 25000
cell.charge = 25000
..()
/mob/living/silicon/robot/syndicate/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
laws = new /datum/ai_laws/syndicate_override
overlays.Cut()
init_id()
new /obj/item/weapon/robot_module/syndicate(src)
radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
radio.recalculateChannels()
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
@@ -23,6 +23,10 @@
var/next_alarm_notice
var/list/datum/alarm/queued_alarms = new()
var/list/access_rights
var/obj/item/weapon/card/id/idcard
var/idcard_type = /obj/item/weapon/card/id/synthetic
#define SEC_HUD 1 //Security HUD mode
#define MED_HUD 2 //Medical HUD mode
@@ -30,6 +34,7 @@
silicon_mob_list |= src
..()
add_language("Galactic Common")
init_id()
init_subsystems()
/mob/living/silicon/Destroy()
@@ -38,6 +43,12 @@
AH.unregister(src)
..()
/mob/living/silicon/proc/init_id()
if(idcard)
return
idcard = new idcard_type(src)
set_id_info(idcard)
/mob/living/silicon/proc/SetName(pickedName as text)
real_name = pickedName
name = real_name
@@ -34,6 +34,11 @@
/mob/living/simple_animal/borer/roundstart
roundstart = 1
/mob/living/simple_animal/borer/Login()
..()
if(mind)
borers.add_antagonist(mind)
/mob/living/simple_animal/borer/New()
..()
@@ -150,11 +155,7 @@
if(!host) return
if(host.mind)
//If they're not a proper traitor, reset their antag status.
if(host.mind.special_role == "Borer Thrall")
host << "<span class ='danger'>You are no longer an antagonist.</span>"
borers.hosts -= host.mind
host.mind.special_role = null
borers.remove_antagonist(host.mind)
src.loc = get_turf(host)
@@ -109,15 +109,9 @@
//Update their traitor status.
if(host.mind)
if(!host.mind.special_role)
borers.hosts |= host.mind
host.mind.special_role = "Borer Thrall"
host << "<span class='danger'>A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine.</span>"
host << "<span class = 'danger'>You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head.</span>"
show_generic_antag_text(host.mind)
borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/I = H.internal_organs_by_name["brain"]
if(!I) // No brain organ, so the borer moves in and replaces it permanently.
+42 -30
View File
@@ -649,7 +649,7 @@
/mob/Stat()
..()
. = (client && client.inactivity < 1200)
. = (is_client_active(10 MINUTES))
if(.)
if(statpanel("Status") && ticker && ticker.current_state != GAME_STATE_PREGAME)
@@ -692,40 +692,52 @@
if(transforming) return 0
return 1
// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
/mob/proc/can_stand_overridden()
return 0
/mob/proc/cannot_stand()
return incapacitated() || restrained() || resting || sleeping || (status_flags & FAKEDEATH)
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
pixel_y = V.mob_offset_y - 5
else
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled)
anchored = 1
canmove = 0
if(istype(buckled))
if(buckled.buckle_lying != -1)
lying = buckled.buckle_lying
if(buckled.buckle_movable)
anchored = 0
canmove = 1
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
if(!resting && cannot_stand() && can_stand_overridden())
lying = 0
canmove = 1
else
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(cannot_stand())
lying = 1
canmove = 0
pixel_y = V.mob_offset_y - 5
else
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled)
anchored = 1
canmove = 0
if(istype(buckled))
if(buckled.buckle_lying != -1)
lying = buckled.buckle_lying
if(buckled.buckle_movable)
anchored = 0
canmove = 1
else if(cannot_stand())
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
lying = 0
canmove = 1
if(lying)
density = 0
+52 -187
View File
@@ -1,6 +1,13 @@
#define UPGRADE_COOLDOWN 40
#define UPGRADE_KILL_TIMER 100
///Process_Grab()
///Called by client/Move()
///Checks to see if you are grabbing anything and if moving will affect your grab.
/client/proc/Process_Grab()
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
G.reset_kill_state() //no wandering across the station/asteroid while choking someone
/obj/item/weapon/grab
name = "grab"
icon = 'icons/mob/screen1.dmi'
@@ -69,7 +76,6 @@
else
hud.screen_loc = ui_lhand
/obj/item/weapon/grab/process()
if(gcDestroyed) // GC is trying to delete us, we'll kill our processing so we can cleanly GC
return PROCESS_KILL
@@ -116,23 +122,9 @@
affecting.drop_l_hand()
affecting.drop_r_hand()
var/hit_zone = assailant.zone_sel.selecting
var/announce = 0
if(hit_zone != last_hit_zone)
announce = 1
last_hit_zone = hit_zone
if(ishuman(affecting))
switch(hit_zone)
if("mouth")
if(announce)
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s mouth!</span>")
if(affecting:silent < 3)
affecting:silent = 3
if("eyes")
if(announce)
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s eyes!</span>")
if(affecting:eye_blind < 3)
affecting:eye_blind = 3
if(iscarbon(affecting))
handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting)
if(force_down)
if(affecting.loc != assailant.loc)
force_down = 0
@@ -153,6 +145,21 @@
adjust_position()
/obj/item/weapon/grab/proc/handle_eye_mouth_covering(mob/living/carbon/target, mob/user, var/target_zone)
var/announce = (target_zone != last_hit_zone) //only display messages when switching between different target zones
last_hit_zone = target_zone
switch(target_zone)
if("mouth")
if(announce)
user.visible_message("<span class='warning'>\The [user] covers [target]'s mouth!</span>")
if(target.silent < 3)
target.silent = 3
if("eyes")
if(announce)
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s eyes!</span>")
if(affecting.eye_blind < 3)
affecting.eye_blind = 3
/obj/item/weapon/grab/attack_self()
return s_click(hud)
@@ -202,8 +209,6 @@
if(EAST)
animate(affecting, pixel_x =-shift, pixel_y = 0, 5, 1, LINEAR_EASING)
/obj/item/weapon/grab/proc/s_click(obj/screen/S)
if(!affecting)
return
@@ -226,11 +231,8 @@
assailant.visible_message("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
else
assailant.visible_message("<span class='warning'>[assailant] pins [affecting] down to the ground (now hands)!</span>")
force_down = 1
affecting.Weaken(3)
step_to(assailant, affecting)
assailant.set_dir(EAST) //face the victim
affecting.set_dir(SOUTH) //face up
apply_pinning(affecting, assailant)
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
hud.icon_state = "reinforce1"
@@ -264,7 +266,6 @@
affecting.set_dir(WEST)
adjust_position()
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
/obj/item/weapon/grab/proc/confirm()
if(!assailant || !affecting)
@@ -278,17 +279,18 @@
return 1
/obj/item/weapon/grab/attack(mob/M, mob/living/user)
if(!affecting)
return
if(world.time < (last_action + 20))
return
last_action = world.time
reset_kill_state() //using special grab moves will interrupt choking them
//clicking on the victim while grabbing them
if(M == affecting)
if(ishuman(M))
last_action = world.time
if(ishuman(affecting))
var/hit_zone = assailant.zone_sel.selecting
flick(hud.icon_state, hud)
switch(assailant.a_intent)
@@ -297,174 +299,37 @@
assailant << "<span class='warning'>You are no longer pinning [affecting] to the ground.</span>"
force_down = 0
return
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/E = H.get_organ(hit_zone)
if(E && !(E.status & ORGAN_DESTROYED))
assailant.visible_message("<span class='notice'>[assailant] starts inspecting [affecting]'s [E.name] carefully.</span>")
if(do_mob(assailant,H, 10))
if(E.wounds.len)
assailant << "<span class='warning'>You find [E.get_wounds_desc()]</span>"
else
assailant << "<span class='notice'>You find no visible wounds.</span>"
else
assailant << "<span class='notice'>You must stand still to inspect [E] for wounds.</span>"
assailant << "<span class='notice'>Checking bones now...</span>"
if(do_mob(assailant, H, 20))
if(E.status & ORGAN_BROKEN)
assailant << "<span class='warning'>The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!</span>"
H.custom_pain("Your [E.name] hurts where it's poked.")
else
assailant << "<span class='notice'>The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine.</span>"
else
assailant << "<span class='notice'>You must stand still to feel [E] for fractures.</span>"
assailant << "<span class='notice'>Checking skin now...</span>"
if(do_mob(assailant, H, 10))
var/bad = 0
if(H.getToxLoss() >= 40)
assailant << "<span class='warning'>[H] has an unhealthy skin discoloration.</span>"
bad = 1
if(H.getOxyLoss() >= 20)
assailant << "<span class='warning'>[H]'s skin is unusaly pale.</span>"
bad = 1
if(E.status & ORGAN_DEAD)
assailant << "<span class='warning'>[E] is decaying!</span>"
bad = 1
if(!bad)
assailant << "<span class='notice'>[H]'s skin is normal.</span>"
else
assailant << "<span class='notice'>You must stand still to check [H]'s skin for abnormalities.</span>"
else
assailant << "<span class='notice'>[H] is missing that bodypart.</span>"
inspect_organ(affecting, assailant, hit_zone)
if(I_GRAB)
if(state < GRAB_AGGRESSIVE)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
var/obj/item/organ/external/organ = affecting:get_organ(check_zone(hit_zone))
if(!organ || organ.dislocated == -1)
return
assailant.visible_message("<span class='danger'>[assailant] [pick("bent", "twisted")] [affecting]'s [organ.name] into a jointlock!</span>")
var/armor = affecting:run_armor_check(affecting, "melee")
if(armor < 2)
affecting << "<span class='danger'>You feel extreme pain!</span>"
affecting.adjustHalLoss(Clamp(0, 40-affecting.halloss, 40)) //up to 40 halloss
return
jointlock(affecting, assailant, hit_zone)
if(I_HURT)
if(hit_zone == "eyes")
var/mob/living/carbon/human/H = affecting
var/datum/unarmed_attack/attack = H.get_unarmed_attack(src, hit_zone)
if(!attack)
return
if(state < GRAB_NECK)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
for(var/slot in list(slot_wear_mask, slot_head, slot_glasses))
var/obj/item/protection = affecting.get_equipped_item(slot)
if(istype(protection) && (protection.body_parts_covered & EYES))
assailant << "<span class='danger'>You're going to need to remove the eye covering first.</span>"
return
if(!affecting.has_eyes())
assailant << "<span class='danger'>You cannot locate any eyes on [affecting]!</span>"
return
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [affecting.name]'s eyes using grab ([affecting.ckey])</font>")
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had eyes attacked by [assailant.name]'s grab ([assailant.ckey])</font>")
msg_admin_attack("[key_name(assailant)] attacked [key_name(affecting)]'s eyes using a grab action.")
attack.handle_eye_attack(assailant, affecting)
else if(hit_zone != "head")
if(state < GRAB_NECK)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
if(affecting:grab_joint(assailant))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
attack_eye(affecting, assailant)
else if(hit_zone == "head")
headbut(affecting, assailant)
else
if(affecting.lying)
return
assailant.visible_message("<span class='danger'>[assailant] thrusts \his head into [affecting]'s skull!</span>")
var/damage = 20
var/obj/item/clothing/hat = assailant.head
if(istype(hat))
damage += hat.force * 10
var/armor = affecting:run_armor_check(affecting, "melee")
affecting.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", armor)
assailant.apply_damage(10*rand(90, 110)/100, BRUTE, "head", assailant:run_armor_check("head", "melee"))
if(!armor && prob(damage))
affecting.apply_effect(20, PARALYZE)
affecting.visible_message("<span class='danger'>[affecting] has been knocked unconscious!</span>")
playsound(assailant.loc, "swing_hit", 25, 1, -1)
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Headbutted [affecting.name] ([affecting.ckey])</font>")
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Headbutted by [assailant.name] ([assailant.ckey])</font>")
msg_admin_attack("[key_name(assailant)] has headbutted [key_name(affecting)]")
assailant.drop_from_inventory(src)
src.loc = null
qdel(src)
return
dislocate(affecting, assailant, hit_zone)
if(I_DISARM)
if(state < GRAB_AGGRESSIVE)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
assailant << "<span class='warning'>You start forcing [affecting] to the ground.</span>"
if(!force_down)
if(do_after(assailant, 20) && affecting)
assailant.visible_message("<span class='danger'>[assailant] is forcing [affecting] to the ground!</span>")
force_down = 1
affecting.Weaken(3)
affecting.lying = 1
step_to(assailant, affecting)
assailant.set_dir(EAST) //face the victim
affecting.set_dir(SOUTH) //face up
return
else
assailant << "<span class='warning'>You are already pinning [affecting] to the ground.</span>"
return
pin_down(affecting, assailant)
//clicking on yourself while grabbing them
if(M == assailant && state >= GRAB_AGGRESSIVE)
var/can_eat
if((FAT in user.mutations) && issmall(affecting))
can_eat = 1
else
var/mob/living/carbon/human/H = user
if(istype(H) && H.species.gluttonous)
// Small animals (mice, lizards).
if(affecting.small)
can_eat = 2
else
if(H.species.gluttonous == 2)
// Diona nymphs, alien larvae.
if(iscarbon(affecting) && !ishuman(affecting))
can_eat = 2
// Monkeys.
else if(issmall(affecting))
can_eat = 1
else if(H.species.gluttonous == 3)
// Full-sized humans.
if(ishuman(affecting) && !issmall(affecting))
can_eat = 1
// Literally everything else.
else
can_eat = 2
if(can_eat)
var/mob/living/carbon/attacker = user
user.visible_message("<span class='danger'>[user] is attempting to devour [affecting]!</span>")
if(can_eat == 2)
if(!do_mob(user, affecting)||!do_after(user, 30)) return
else
if(!do_mob(user, affecting)||!do_after(user, 100)) return
user.visible_message("<span class='danger'>[user] devours [affecting]!</span>")
affecting.loc = user
attacker.stomach_contents.Add(affecting)
qdel(src)
devour(affecting, assailant)
/obj/item/weapon/grab/dropped()
loc = null
if(!destroying)
qdel(src)
/obj/item/weapon/grab/proc/reset_kill_state()
if(state == GRAB_KILL)
assailant.visible_message("<span class='warning'>[assailant] lost \his tight grip on [affecting]'s neck!</span>")
hud.icon_state = "kill"
state = GRAB_NECK
/obj/item/weapon/grab
var/destroying = 0
+165
View File
@@ -0,0 +1,165 @@
/obj/item/weapon/grab/proc/inspect_organ(mob/living/carbon/human/H, mob/user, var/target_zone)
var/obj/item/organ/external/E = H.get_organ(target_zone)
if(!E || (E.status & ORGAN_DESTROYED))
user << "<span class='notice'>[H] is missing that bodypart.</span>"
return
user.visible_message("<span class='notice'>[user] starts inspecting [affecting]'s [E.name] carefully.</span>")
if(!do_mob(user,H, 10))
user << "<span class='notice'>You must stand still to inspect [E] for wounds.</span>"
else if(E.wounds.len)
user << "<span class='warning'>You find [E.get_wounds_desc()]</span>"
else
user << "<span class='notice'>You find no visible wounds.</span>"
user << "<span class='notice'>Checking bones now...</span>"
if(!do_mob(user, H, 20))
user << "<span class='notice'>You must stand still to feel [E] for fractures.</span>"
else if(E.status & ORGAN_BROKEN)
user << "<span class='warning'>The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!</span>"
H.custom_pain("Your [E.name] hurts where it's poked.")
else
user << "<span class='notice'>The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine.</span>"
user << "<span class='notice'>Checking skin now...</span>"
if(!do_mob(user, H, 10))
user << "<span class='notice'>You must stand still to check [H]'s skin for abnormalities.</span>"
else
var/bad = 0
if(H.getToxLoss() >= 40)
user << "<span class='warning'>[H] has an unhealthy skin discoloration.</span>"
bad = 1
if(H.getOxyLoss() >= 20)
user << "<span class='warning'>[H]'s skin is unusaly pale.</span>"
bad = 1
if(E.status & ORGAN_DEAD)
user << "<span class='warning'>[E] is decaying!</span>"
bad = 1
if(!bad)
user << "<span class='notice'>[H]'s skin is normal.</span>"
/obj/item/weapon/grab/proc/jointlock(mob/living/carbon/human/target, mob/attacker, var/target_zone)
if(state < GRAB_AGGRESSIVE)
attacker << "<span class='warning'>You require a better grab to do this.</span>"
return
var/obj/item/organ/external/organ = target.get_organ(check_zone(target_zone))
if(!organ || organ.dislocated == -1)
return
attacker.visible_message("<span class='danger'>[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!</span>")
var/armor = target.run_armor_check(target, "melee")
if(armor < 2)
target << "<span class='danger'>You feel extreme pain!</span>"
affecting.adjustHalLoss(Clamp(0, 60-affecting.halloss, 30)) //up to 60 halloss
/obj/item/weapon/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
if(!istype(attacker))
return
var/datum/unarmed_attack/attack = attacker.get_unarmed_attack(target, "eyes")
if(!attack)
return
if(state < GRAB_NECK)
attacker << "<span class='warning'>You require a better grab to do this.</span>"
return
for(var/obj/item/protection in list(target.head, target.wear_mask, target.glasses))
if(protection && (protection.body_parts_covered & EYES))
attacker << "<span class='danger'>You're going to need to remove the eye covering first.</span>"
return
if(!target.has_eyes())
attacker << "<span class='danger'>You cannot locate any eyes on [target]!</span>"
return
attacker.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [target.name]'s eyes using grab ([target.ckey])</font>")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had eyes attacked by [attacker.name]'s grab ([attacker.ckey])</font>")
msg_admin_attack("[key_name(attacker)] attacked [key_name(target)]'s eyes using a grab action.")
attack.handle_eye_attack(attacker, target)
/obj/item/weapon/grab/proc/headbut(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
if(!istype(attacker))
return
if(target.lying)
return
attacker.visible_message("<span class='danger'>[attacker] thrusts \his head into [target]'s skull!</span>")
var/damage = 20
var/obj/item/clothing/hat = attacker.head
if(istype(hat))
damage += hat.force * 10
var/armor = target.run_armor_check("head", "melee")
target.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", armor)
attacker.apply_damage(10*rand(90, 110)/100, BRUTE, "head", attacker.run_armor_check("head", "melee"))
if(!armor && prob(damage))
target.apply_effect(20, PARALYZE)
target.visible_message("<span class='danger'>[target] has been knocked unconscious!</span>")
playsound(attacker.loc, "swing_hit", 25, 1, -1)
attacker.attack_log += text("\[[time_stamp()]\] <font color='red'>Headbutted [target.name] ([target.ckey])</font>")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Headbutted by [attacker.name] ([attacker.ckey])</font>")
msg_admin_attack("[key_name(attacker)] has headbutted [key_name(target)]")
attacker.drop_from_inventory(src)
src.loc = null
qdel(src)
return
/obj/item/weapon/grab/proc/dislocate(mob/living/carbon/human/target, mob/living/attacker, var/target_zone)
if(state < GRAB_NECK)
attacker << "<span class='warning'>You require a better grab to do this.</span>"
return
if(target.grab_joint(attacker, target_zone))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
/obj/item/weapon/grab/proc/pin_down(mob/target, mob/attacker)
if(state < GRAB_AGGRESSIVE)
attacker << "<span class='warning'>You require a better grab to do this.</span>"
return
if(force_down)
attacker << "<span class='warning'>You are already pinning [target] to the ground.</span>"
attacker.visible_message("<span class='danger'>[attacker] starts forcing [target] to the ground!</span>")
if(do_after(attacker, 20) && target)
last_action = world.time
attacker.visible_message("<span class='danger'>[attacker] forces [target] to the ground!</span>")
apply_pinning(target, attacker)
/obj/item/weapon/grab/proc/apply_pinning(mob/target, mob/attacker)
force_down = 1
target.Weaken(3)
target.lying = 1
step_to(attacker, target)
attacker.set_dir(EAST) //face the victim
target.set_dir(SOUTH) //face up
/obj/item/weapon/grab/proc/devour(mob/target, mob/user)
var/can_eat
if((FAT in user.mutations) && issmall(target))
can_eat = 1
else
var/mob/living/carbon/human/H = user
if(istype(H) && H.species.gluttonous)
if(H.species.gluttonous == 2)
can_eat = 2
else if(!ishuman(target) && !issmall(target) && (target.small || iscarbon(target)))
can_eat = 1
if(can_eat)
var/mob/living/carbon/attacker = user
user.visible_message("<span class='danger'>[user] is attempting to devour [target]!</span>")
if(can_eat == 2)
if(!do_mob(user, target)||!do_after(user, 30)) return
else
if(!do_mob(user, target)||!do_after(user, 100)) return
user.visible_message("<span class='danger'>[user] devours [target]!</span>")
target.loc = user
attacker.stomach_contents.Add(target)
qdel(src)
+1 -1
View File
@@ -632,7 +632,7 @@ proc/is_blind(A)
return SAFE_PERP
//Agent cards lower threatlevel.
var/obj/item/weapon/card/id/id = GetIdCard(src)
var/obj/item/weapon/card/id/id = GetIdCard()
if(id && istype(id, /obj/item/weapon/card/id/syndicate))
threatcount -= 2
// A proper CentCom id is hard currency.
-12
View File
@@ -233,7 +233,6 @@
if(Process_Grab()) return
if(!mob.canmove)
return
@@ -246,7 +245,6 @@
if((istype(mob.loc, /turf/space)) || (mob.lastarea.has_gravity == 0))
if(!mob.Process_Spacemove(0)) return 0
if(isobj(mob.loc) || ismob(mob.loc))//Inside an object, tell it we moved
var/atom/O = mob.loc
return O.relaymove(mob, direct)
@@ -371,16 +369,6 @@
return Move(n, direct)
///Process_Grab()
///Called by client/Move()
///Checks to see if you are grabbing anything and if moving will affect your grab.
/client/proc/Process_Grab()
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone
mob.visible_message("<span class='warning'>[mob] lost \his tight grip on [G.affecting]'s neck!</span>")
G.hud.icon_state = "kill"
G.state = GRAB_NECK
///Process_Incorpmove
///Called by client/Move()
///Allows mobs to run though walls
@@ -57,6 +57,21 @@
name = "Short Hair" // try to capatilize the names please~
icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you
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"
@@ -367,6 +382,10 @@
name = "Joestar"
icon_state = "hair_joestar"
volaju
name = "Volaju"
icon_state = "hair_volaju"
bald
name = "Bald"
icon_state = "bald"
@@ -526,6 +545,10 @@
name = "Adam Jensen Beard"
icon_state = "facial_jensen"
volaju
name = "Volaju"
icon_state = "facial_volaju"
dwarf
name = "Dwarf Beard"
icon_state = "facial_dwarf"
+4 -3
View File
@@ -147,11 +147,12 @@
//parses the language code (e.g. :j) from text, such as that supplied to say.
//returns the language object only if the code corresponds to a language that src can speak, otherwise null.
/mob/proc/parse_language(var/message)
if(length(message) >= 1 && copytext(message,1,2) == "!")
var/prefix = copytext(message,1,2)
if(length(message) >= 1 && prefix == "!")
return all_languages["Noise"]
if(length(message) >= 2)
var/language_prefix = lowertext(copytext(message, 1 ,3))
if(length(message) >= 2 && is_language_prefix(prefix))
var/language_prefix = lowertext(copytext(message, 2 ,3))
var/datum/language/L = language_keys[language_prefix]
if (can_speak(L))
return L
-2
View File
@@ -98,8 +98,6 @@
loc_landmark = sloc
O.loc = loc_landmark.loc
for (var/obj/item/device/radio/intercom/comm in O.loc)
comm.ai += O
O.on_mob_init()
+16
View File
@@ -0,0 +1,16 @@
/obj/effect/landmark/map_data
name = "Unknown"
desc = "An unknown location."
invisibility = 101
var/height = 1 ///< The number of Z-Levels in the map.
var/turf/edge_type ///< What the map edge should be formed with. (null = world.turf)
// FOR THE LOVE OF GOD USE THESE. DO NOT FUCKING SPAGHETTIFY THIS.
// Use the Has*() functions if you ONLY need to check.
// If you need to do something, use Get*().
HasAbove(var/z)
HasBelow(var/z)
// These give either the turf or null.
GetAbove(var/atom/atom)
GetBelow(var/atom/atom)
+35
View File
@@ -0,0 +1,35 @@
// If you add a more comprehensive system, just untick this file.
// WARNING: Only works for up to 17 z-levels!
var/z_levels = 0 // Each bit represents a connection between adjacent levels. So the first bit means levels 1 and 2 are connected.
// If the height is more than 1, we mark all contained levels as connected.
/obj/effect/landmark/map_data/New()
ASSERT(height <= z)
// Due to the offsets of how connections are stored v.s. how z-levels are indexed, some magic number silliness happened.
for(var/i = (z - height) to (z - 2))
z_levels |= (1 << i)
qdel(src)
// The storage of connections between adjacent levels means some bitwise magic is needed.
proc/HasAbove(var/z)
if(z >= world.maxz || z > 16 || z < 1)
return 0
return z_levels & (1 << (z - 1))
proc/HasBelow(var/z)
if(z > world.maxz || z > 17 || z < 2)
return 0
return z_levels & (1 << (z - 2))
// Thankfully, no bitwise magic is needed here.
proc/GetAbove(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasAbove(turf.z) ? get_step(turf, UP) : null
proc/GetBelow(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasBelow(turf.z) ? get_step(turf, DOWN) : null
+10
View File
@@ -0,0 +1,10 @@
proc/HasAbove(var/z)
return 0
proc/HasBelow(var/z)
return 0
// These give either the turf or null.
proc/GetAbove(var/turf/turf)
return null
proc/GetBelow(var/turf/turf)
return null
+51
View File
@@ -0,0 +1,51 @@
/obj/item/weapon/tank/jetpack/verb/moveup()
set name = "Move Upwards"
set category = "Object"
. = 1
if(!allow_thrust(0.01, usr))
usr << "<span class='warning'>\The [src] is disabled.</span>"
return
var/turf/above = GetAbove(src)
if(!istype(above))
usr << "<span class='notice'>There is nothing of interest in this direction.</span>"
return
if(!istype(above, /turf/space) && !istype(above, /turf/simulated/open))
usr << "<span class='warning'>You bump against \the [above].</span>"
return
for(var/atom/A in above)
if(A.density)
usr << "<span class='warning'>\The [A] blocks you.</span>"
return
usr.Move(above)
usr << "<span class='notice'>You move upwards.</span>"
/obj/item/weapon/tank/jetpack/verb/movedown()
set name = "Move Downwards"
set category = "Object"
. = 1
if(!allow_thrust(0.01, usr))
usr << "<span class='warning'>\The [src] is disabled.</span>"
return
var/turf/below = GetBelow(src)
if(!istype(below))
usr << "<span class='notice'>There is nothing of interest in this direction.</span>"
return
if(below.density)
usr << "<span class='warning'>You bump against \the [below].</span>"
return
for(var/atom/A in below)
if(A.density)
usr << "<span class='warning'>\The [A] blocks you.</span>"
return
usr.Move(below)
usr << "<span class='notice'>You move downwards.</span>"
+227
View File
@@ -0,0 +1,227 @@
////////////////////////////
// parent class for pipes //
////////////////////////////
obj/machinery/atmospherics/pipe/zpipe
icon = 'icons/obj/structures.dmi'
icon_state = "up"
name = "upwards pipe"
desc = "A pipe segment to connect upwards."
volume = 70
dir = SOUTH
initialize_directions = SOUTH
var/obj/machinery/atmospherics/node1 //connection on the same Z
var/obj/machinery/atmospherics/node2 //connection on the other Z
var/minimum_temperature_difference = 300
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
var/maximum_pressure = 70*ONE_ATMOSPHERE
var/fatigue_pressure = 55*ONE_ATMOSPHERE
alert_pressure = 55*ONE_ATMOSPHERE
level = 1
obj/machinery/atmospherics/pipe/zpipe/New()
..()
switch(dir)
if(SOUTH)
initialize_directions = SOUTH
if(NORTH)
initialize_directions = NORTH
if(WEST)
initialize_directions = WEST
if(EAST)
initialize_directions = EAST
if(NORTHEAST)
initialize_directions = NORTH
if(NORTHWEST)
initialize_directions = WEST
if(SOUTHEAST)
initialize_directions = EAST
if(SOUTHWEST)
initialize_directions = SOUTH
/obj/machinery/atmospherics/pipe/zpipe/hide(var/i)
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
obj/machinery/atmospherics/pipe/up/process()
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
. = PROCESS_KILL
obj/machinery/atmospherics/pipe/zpipe/check_pressure(pressure)
var/datum/gas_mixture/environment = loc.return_air()
var/pressure_difference = pressure - environment.return_pressure()
if(pressure_difference > maximum_pressure)
burst()
else if(pressure_difference > fatigue_pressure)
//TODO: leak to turf, doing pfshhhhh
if(prob(5))
burst()
else return 1
obj/machinery/atmospherics/pipe/zpipe/proc/burst()
src.visible_message("<span class='warning'>\The [src] bursts!</span>");
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
var/datum/effect/effect/system/smoke_spread/smoke = new
smoke.set_up(1,0, src.loc, 0)
smoke.start()
qdel(src) // NOT qdel.
obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir()
if(dir==3)
set_dir(1)
else if(dir==12)
set_dir(4)
obj/machinery/atmospherics/pipe/zpipe/Destroy()
if(node1)
node1.disconnect(src)
if(node2)
node2.disconnect(src)
..()
obj/machinery/atmospherics/pipe/zpipe/pipeline_expansion()
return list(node1, node2)
obj/machinery/atmospherics/pipe/zpipe/update_icon()
return
obj/machinery/atmospherics/pipe/zpipe/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/atmospherics/pipe))
qdel(parent)
node2 = null
return null
/////////////////////////
// the elusive up pipe //
/////////////////////////
obj/machinery/atmospherics/pipe/zpipe/up
icon = 'icons/obj/structures.dmi'
icon_state = "up"
name = "upwards pipe"
desc = "A pipe segment to connect upwards."
obj/machinery/atmospherics/pipe/zpipe/up/initialize()
normalize_dir()
var/node1_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
var/turf/above = GetAbove(src)
if(above)
for(var/obj/machinery/atmospherics/target in above)
if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/down))
if (check_connect_types(target,src))
node2 = target
break
var/turf/T = src.loc // hide if turf is not intact
hide(!T.is_plating())
///////////////////////
// and the down pipe //
///////////////////////
obj/machinery/atmospherics/pipe/zpipe/down
icon = 'icons/obj/structures.dmi'
icon_state = "down"
name = "downwards pipe"
desc = "A pipe segment to connect downwards."
obj/machinery/atmospherics/pipe/zpipe/down/initialize()
normalize_dir()
var/node1_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
var/turf/below = GetBelow(src)
if(below)
for(var/obj/machinery/atmospherics/target in below)
if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/up))
if (check_connect_types(target,src))
node2 = target
break
var/turf/T = src.loc // hide if turf is not intact
hide(!T.is_plating())
///////////////////////
// supply/scrubbers //
///////////////////////
obj/machinery/atmospherics/pipe/zpipe/up/scrubbers
icon_state = "up-scrubbers"
name = "upwards scrubbers pipe"
desc = "A scrubbers pipe segment to connect upwards."
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
obj/machinery/atmospherics/pipe/zpipe/up/supply
icon_state = "up-supply"
name = "upwards supply pipe"
desc = "A supply pipe segment to connect upwards."
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
obj/machinery/atmospherics/pipe/zpipe/down/scrubbers
icon_state = "down-scrubbers"
name = "downwards scrubbers pipe"
desc = "A scrubbers pipe segment to connect downwards."
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
obj/machinery/atmospherics/pipe/zpipe/down/supply
icon_state = "down-supply"
name = "downwards supply pipe"
desc = "A supply pipe segment to connect downwards."
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
+86
View File
@@ -0,0 +1,86 @@
//////////////////////////////
//Contents: Ladders, Stairs.//
//////////////////////////////
/obj/structure/ladder
name = "ladder"
desc = "A ladder. You can climb it up and down."
icon_state = "ladderdown"
icon = 'icons/obj/structures.dmi'
density = 0
opacity = 0
anchored = 1
var/obj/structure/ladder/target
initialize()
// the upper will connect to the lower
if(icon_state == "ladderup")
return
for(var/obj/structure/ladder/L in GetBelow(src))
if(L.icon_state == "ladderup")
target = L
L.target = src
return
Destroy()
if(target && icon_state == "ladderdown")
qdel(target)
return ..()
attackby(obj/item/C as obj, mob/user as mob)
. = ..()
attack_hand(user)
return
attack_hand(var/mob/M)
if(!target || !istype(target.loc, /turf))
M << "<span class='notice'>\The [src] is incomplete and can't be climbed.</span>"
return
var/turf/T = target.loc
for(var/atom/A in T)
if(A.density)
M << "<span class='notice'>\A [A] is blocking \the [src].</span>"
return
M.visible_message("<span class='notice'>\A [M] climbs [icon_state == "ladderup" ? "up" : "down"] \a [src]!</span>",
"You climb [icon_state == "ladderup" ? "up" : "down"] \the [src]!",
"You hear the grunting and clanging of a metal ladder being used.")
M.Move(T)
CanPass(obj/mover, turf/source, height, airflow)
return airflow || !density
/obj/structure/stairs
name = "Stairs"
desc = "Stairs. You walk up and down them."
icon_state = "rampbottom"
icon = 'icons/obj/structures.dmi'
density = 0
opacity = 0
anchored = 1
var/obj/structure/stairs/connected
New()
..()
var/turf/above = GetAbove(src)
if(istype(above, /turf/space))
above.ChangeTurf(/turf/simulated/open)
initialize()
var/updown = icon_state == "rampbottom" ? UP : DOWN
var/turf/T = get_step(src, dir | updown)
connected = locate() in T
ASSERT(connected)
Uncross(var/atom/movable/M)
if(connected && M.dir == dir)
M.loc = connected.loc
return 1
CanPass(obj/mover, turf/source, height, airflow)
return airflow || !density
+111
View File
@@ -0,0 +1,111 @@
/turf/simulated/open
name = "open space"
icon = 'icons/turf/space.dmi'
icon_state = "black"
alpha = 16
layer = 0
density = 0
pathweight = 100000 //Seriously, don't try and path over this one numbnuts
var/turf/below
var/list/underlay_references
var/global/overlay_map = list()
/turf/simulated/open/New()
. = ..()
ASSERT(HasBelow(z))
below = GetBelow(src)
/turf/simulated/open/Entered(var/atom/movable/mover)
// only fall down in defined areas (read: areas with artificial gravitiy)
if(!istype(below)) //make sure that there is actually something below
below = GetBelow(src)
if(!below)
return
// No gravity in space, apparently.
var/area/area = get_area(src)
if(area.name == "Space")
return
// Prevent pipes from falling into the void... if there is a pipe to support it.
if(istype(mover, /obj/item/pipe) && \
(locate(/obj/structure/disposalpipe/up) in below) || \
locate(/obj/machinery/atmospherics/pipe/zpipe/up in below))
return
// See if something prevents us from falling.
var/soft = 0
for(var/atom/A in below)
if(A.density)
if(!istype(A, /obj/structure/window))
return
else
var/obj/structure/window/W = A
if(W.is_fulltile())
return
// Dont break here, since we still need to be sure that it isnt blocked
if(istype(A, /obj/structure/stairs))
soft = 1
// We've made sure we can move, now.
mover.Move(below)
if(!soft)
if(!istype(mover, /mob))
if(istype(below, /turf/simulated/open))
below.visible_message("\The [mover] falls from the deck above through \the [below]!", "You hear a whoosh of displaced air.")
else
below.visible_message("\The [mover] falls from the deck above and slams into \the [below]!", "You hear something slam into the deck.")
else
var/mob/M = mover
if(istype(below, /turf/simulated/open))
below.visible_message("\The [mover] falls from the deck above through \the [below]!", "You hear a soft whoosh.[M.stat ? "" : ".. and some screaming."]")
else
M.visible_message("\The [mover] falls from the deck above and slams into \the [below]!", "You land on \the [below].", "You hear a soft whoosh and a crunch")
// Handle people getting hurt, it's funny!
if (istype(mover, /mob/living/carbon/human))
var/mob/living/carbon/human/H = mover
var/damage = 5
H.apply_damage(rand(0, damage), BRUTE, "head")
H.apply_damage(rand(0, damage), BRUTE, "chest")
H.apply_damage(rand(0, damage), BRUTE, "l_leg")
H.apply_damage(rand(0, damage), BRUTE, "r_leg")
H.apply_damage(rand(0, damage), BRUTE, "l_arm")
H.apply_damage(rand(0, damage), BRUTE, "r_arm")
H.weakened = max(H.weakened,2)
H.updatehealth()
// override to make sure nothing is hidden
/turf/simulated/open/levelupdate()
for(var/obj/O in src)
O.hide(0)
// Straight copy from space.
/turf/simulated/open/attackby(obj/item/C as obj, mob/user as mob)
if (istype(C, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = C
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ReplaceWithLattice()
return
if (istype(C, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = C
if (S.get_amount() < 1)
return
qdel(L)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
S.use(1)
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
return
+1 -1
View File
@@ -14,7 +14,7 @@
/mob/proc/shared_nano_interaction()
if (src.stat || !client)
return STATUS_CLOSE // no updates, close the interface
else if (restrained() || lying || stat || stunned || weakened)
else if (incapacitated())
return STATUS_UPDATE // update only (orange visibility)
return STATUS_INTERACTIVE
+1 -16
View File
@@ -10,7 +10,7 @@
return STATUS_CLOSE // By default no mob can do anything with NanoUI
/mob/dead/observer/default_can_use_topic()
if(check_rights(R_ADMIN, 0, src))
if(can_admin_interact())
return STATUS_INTERACTIVE // Admins are more equal
return STATUS_UPDATE // Ghosts can view updates
@@ -30,21 +30,6 @@
return STATUS_INTERACTIVE // interactive (green visibility)
return STATUS_DISABLED // no updates, completely disabled (red visibility)
/mob/living/silicon/robot/syndicate/default_can_use_topic(var/src_object)
. = ..()
if(. != STATUS_INTERACTIVE)
return
if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level
return STATUS_INTERACTIVE
if(istype(get_area(src), /area/syndicate_station)) // If elsewhere, they can interact with everything on the syndicate shuttle
return STATUS_INTERACTIVE
if(istype(src_object, /obj/machinery)) // Otherwise they can only interact with emagged machinery
var/obj/machinery/Machine = src_object
if(Machine.emagged)
return STATUS_INTERACTIVE
return STATUS_UPDATE
/mob/living/silicon/ai/default_can_use_topic(var/src_object)
. = shared_nano_interaction()
if(. != STATUS_INTERACTIVE)
@@ -152,6 +152,8 @@
generate_data()
/datum/nano_module/appearance_changer/proc/generate_data()
if(!owner)
return
if(!valid_species.len)
valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist)
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)

Some files were not shown because too many files have changed in this diff Show More