mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 11:38:12 +01:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
@@ -401,8 +401,10 @@ var/list/admin_verbs_mentor = list(
|
||||
var/mob/body = mob
|
||||
var/mob/dead/observer/ghost = body.ghostize(1)
|
||||
ghost.admin_ghosted = 1
|
||||
if(body && !body.key)
|
||||
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus
|
||||
if(body)
|
||||
body.aghosted = ghost
|
||||
if(!body.key)
|
||||
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus
|
||||
feedback_add_details("admin_verb","O") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
icon = 'icons/misc/buildmode.dmi'
|
||||
var/obj/effect/bmode/buildholder/master = null
|
||||
|
||||
/obj/effect/bmode/Destroy()
|
||||
if(master && master.cl)
|
||||
master.cl.screen -= src
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/bmode/builddir
|
||||
icon_state = "build"
|
||||
screen_loc = "NORTH,WEST"
|
||||
@@ -117,6 +123,19 @@
|
||||
var/obj/effect/bmode/buildquit/buildquit = null
|
||||
var/atom/movable/throw_atom = null
|
||||
|
||||
/obj/effect/bmode/buildholder/Destroy()
|
||||
qdel(builddir)
|
||||
builddir = null
|
||||
qdel(buildhelp)
|
||||
buildhelp = null
|
||||
qdel(buildmode)
|
||||
buildmode = null
|
||||
qdel(buildquit)
|
||||
buildquit = null
|
||||
throw_atom = null
|
||||
cl = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/bmode/buildmode
|
||||
icon_state = "buildmode1"
|
||||
screen_loc = "NORTH,WEST+2"
|
||||
|
||||
@@ -218,7 +218,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(!choice)
|
||||
return 0
|
||||
if(!istype(choice, /mob/dead/observer))
|
||||
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
|
||||
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank them out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
|
||||
if(confirm != "Yes")
|
||||
return 0
|
||||
var/obj/item/device/paicard/card = new(T)
|
||||
|
||||
@@ -153,6 +153,13 @@
|
||||
add_admin_verbs()
|
||||
admin_memo_show()
|
||||
|
||||
// Forcibly enable hardware-accelerated graphics, as we need them for the lighting overlays.
|
||||
// (but turn them off first, since sometimes BYOND doesn't turn them on properly otherwise)
|
||||
spawn(5) // And wait a half-second, since it sounds like you can do this too fast.
|
||||
if(src)
|
||||
winset(src, null, "command=\".configure graphics-hwmode off\"")
|
||||
winset(src, null, "command=\".configure graphics-hwmode on\"")
|
||||
|
||||
log_client_to_db()
|
||||
|
||||
send_resources()
|
||||
|
||||
@@ -75,7 +75,7 @@ datum/preferences
|
||||
var/b_eyes = 0 //Eye color
|
||||
var/species = "Human" //Species datum to use.
|
||||
var/species_preview //Used for the species selection window.
|
||||
var/language = "None" //Secondary language
|
||||
var/list/alternate_languages = list() //Secondary language(s)
|
||||
var/list/gear //Custom/fluff item loadout.
|
||||
|
||||
//Some faction information.
|
||||
@@ -132,9 +132,12 @@ datum/preferences
|
||||
var/metadata = ""
|
||||
var/slot_name = ""
|
||||
|
||||
var/client/client = null
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
|
||||
if(istype(C))
|
||||
client = C
|
||||
if(!IsGuestKey(C.key))
|
||||
load_path(C.ckey)
|
||||
if(load_preferences())
|
||||
@@ -307,7 +310,7 @@ datum/preferences
|
||||
dat += "(<a href='?_src_=prefs;preference=all;task=random'>®</A>)"
|
||||
dat += "<br>"
|
||||
dat += "Species: <a href='?src=\ref[user];preference=species;task=change'>[species]</a><br>"
|
||||
dat += "Secondary Language:<br><a href='byond://?src=\ref[user];preference=language;task=input'>[language]</a><br>"
|
||||
|
||||
dat += "Blood Type: <a href='byond://?src=\ref[user];preference=b_type;task=input'>[b_type]</a><br>"
|
||||
dat += "Skin Tone: <a href='?_src_=prefs;preference=s_tone;task=input'>[-s_tone + 35]/220<br></a>"
|
||||
//dat += "Skin pattern: <a href='byond://?src=\ref[user];preference=skin_style;task=input'>Adjust</a><br>"
|
||||
@@ -381,6 +384,25 @@ datum/preferences
|
||||
else
|
||||
dat += "<br><br>"
|
||||
|
||||
|
||||
dat += "<b>Languages</b><br>"
|
||||
var/datum/species/S = all_species[species]
|
||||
if(S.language)
|
||||
dat += "- [S.language]<br>"
|
||||
if(S.default_language && S.default_language != S.language)
|
||||
dat += "- [S.default_language]<br>"
|
||||
if(S.num_alternate_languages)
|
||||
if(alternate_languages.len)
|
||||
for(var/i = 1 to alternate_languages.len)
|
||||
var/lang = alternate_languages[i]
|
||||
dat += "- [lang] - <a href='byond://?src=\ref[user];preference=language;remove=[i]'>remove</a><br>"
|
||||
|
||||
if(alternate_languages.len < S.num_alternate_languages)
|
||||
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>"
|
||||
|
||||
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>"
|
||||
@@ -1126,6 +1148,32 @@ datum/preferences
|
||||
if(gear_name == choice)
|
||||
gear -= gear_name
|
||||
break
|
||||
else if(href_list["preference"] == "language")
|
||||
if(href_list["remove"])
|
||||
var/index = text2num(href_list["remove"])
|
||||
alternate_languages.Cut(index, index+1)
|
||||
if(href_list["add"])
|
||||
var/datum/species/S = all_species[species]
|
||||
if(alternate_languages.len >= S.num_alternate_languages)
|
||||
alert(user, "You have already selected the maximum number of alternate languages for this species!")
|
||||
else
|
||||
var/list/available_languages = S.secondary_langs.Copy()
|
||||
for(var/L in all_languages)
|
||||
var/datum/language/lang = all_languages[L]
|
||||
if(!(lang.flags & RESTRICTED) && (!config.usealienwhitelist || is_alien_whitelisted(user, L) || !(lang.flags & WHITELISTED)))
|
||||
available_languages |= L
|
||||
|
||||
// make sure we don't let them waste slots on the default languages
|
||||
available_languages -= S.language
|
||||
available_languages -= S.default_language
|
||||
available_languages -= alternate_languages
|
||||
|
||||
if(!available_languages.len)
|
||||
alert(user, "There are no additional languages available to select.")
|
||||
else
|
||||
var/new_lang = input("Select an additional language", "Character Generation", null) as null|anything in available_languages
|
||||
if(new_lang)
|
||||
alternate_languages |= new_lang
|
||||
|
||||
switch(href_list["task"])
|
||||
if("change")
|
||||
@@ -1135,6 +1183,7 @@ datum/preferences
|
||||
if(!choice) return
|
||||
species_preview = choice
|
||||
SetSpecies(user)
|
||||
alternate_languages = list() // Reset their alternate languages. Todo: attempt to just fix it instead?
|
||||
|
||||
if("random")
|
||||
switch(href_list["preference"])
|
||||
@@ -1243,29 +1292,6 @@ datum/preferences
|
||||
|
||||
s_tone = 0
|
||||
|
||||
if("language")
|
||||
var/languages_available
|
||||
var/list/new_languages = list("None")
|
||||
var/datum/species/S = all_species[species]
|
||||
|
||||
if(config.usealienwhitelist)
|
||||
for(var/L in all_languages)
|
||||
var/datum/language/lang = all_languages[L]
|
||||
if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))||(S && (L in S.secondary_langs))))
|
||||
new_languages += lang
|
||||
|
||||
languages_available = 1
|
||||
|
||||
if(!(languages_available))
|
||||
alert(user, "There are not currently any available secondary languages.")
|
||||
else
|
||||
for(var/L in all_languages)
|
||||
var/datum/language/lang = all_languages[L]
|
||||
if(!(lang.flags & RESTRICTED))
|
||||
new_languages += lang.name
|
||||
|
||||
language = input("Please select a secondary language", "Character Generation", null) in new_languages
|
||||
|
||||
if("metadata")
|
||||
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
|
||||
if(new_metadata)
|
||||
@@ -1375,7 +1401,7 @@ datum/preferences
|
||||
backbag = backbaglist.Find(new_backbag)
|
||||
|
||||
if("nt_relation")
|
||||
var/new_relation = input(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference") as null|anything in list("Loyal", "Supportive", "Neutral", "Skeptical", "Opposed")
|
||||
var/new_relation = input(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference") as null|anything in COMPANY_ALIGNMENTS
|
||||
if(new_relation)
|
||||
nanotrasen_relation = new_relation
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ var/global/list/gear_datums = list()
|
||||
|
||||
/datum/gear/scanning_goggles
|
||||
display_name = "scanning goggles"
|
||||
path = /obj/item/clothing/glasses/science/scanners
|
||||
path = /obj/item/clothing/glasses/regular/scanners
|
||||
cost = 1
|
||||
slot = slot_glasses
|
||||
|
||||
|
||||
@@ -107,9 +107,30 @@
|
||||
S["gender"] >> gender
|
||||
S["age"] >> age
|
||||
S["species"] >> species
|
||||
S["language"] >> language
|
||||
S["spawnpoint"] >> spawnpoint
|
||||
|
||||
S["language"] >> alternate_languages
|
||||
if(isnull(alternate_languages))
|
||||
alternate_languages = list()
|
||||
if(!islist(alternate_languages))
|
||||
if(client)
|
||||
// Warn them that we (probably) just broke their languages
|
||||
client << "<span class='danger'>Your current character slot's languages list has been updated from an old version, and may not be what you expect.</span>"
|
||||
|
||||
if(alternate_languages in all_languages)
|
||||
alternate_languages = list(alternate_languages)
|
||||
else
|
||||
alternate_languages = list()
|
||||
|
||||
// try to give them their species language
|
||||
var/datum/species/SP = all_species[species]
|
||||
if(SP)
|
||||
alternate_languages |= SP.language
|
||||
alternate_languages |= SP.default_language
|
||||
|
||||
// remove the Galcom that most races have as default_language
|
||||
alternate_languages -= "Galactic Common"
|
||||
|
||||
//colors to be consolidated into hex strings (requires some work with dna code)
|
||||
S["hair_red"] >> r_hair
|
||||
S["hair_green"] >> g_hair
|
||||
@@ -200,7 +221,7 @@
|
||||
if(isnum(undershirt))
|
||||
undershirt = undershirt_t[undershirt_t[undershirt]]
|
||||
|
||||
if(isnull(language)) language = "None"
|
||||
if(isnull(alternate_languages)) alternate_languages = list()
|
||||
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
|
||||
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
|
||||
if(!real_name) real_name = random_name(gender)
|
||||
@@ -265,7 +286,7 @@
|
||||
S["gender"] << gender
|
||||
S["age"] << age
|
||||
S["species"] << species
|
||||
S["language"] << language
|
||||
S["language"] << alternate_languages
|
||||
S["hair_red"] << r_hair
|
||||
S["hair_green"] << g_hair
|
||||
S["hair_blue"] << b_hair
|
||||
@@ -346,4 +367,4 @@
|
||||
|
||||
|
||||
#undef SAVEFILE_VERSION_MAX
|
||||
#undef SAVEFILE_VERSION_MIN
|
||||
#undef SAVEFILE_VERSION_MIN
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
//Set species_restricted list
|
||||
switch(target_species)
|
||||
if("Human", "Skrell") //humanoid bodytypes
|
||||
species_restricted = list("exclude","Unathi","Tajara","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human", "Skrell") //skrell/humans can wear each other's suits
|
||||
else
|
||||
species_restricted = list(target_species)
|
||||
|
||||
@@ -72,9 +72,7 @@
|
||||
//Set species_restricted list
|
||||
switch(target_species)
|
||||
if("Skrell")
|
||||
species_restricted = list("exclude","Unathi","Tajara","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
if("Human")
|
||||
species_restricted = list("exclude","Skrell","Unathi","Tajara","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human", "Skrell") //skrell helmets fit humans too
|
||||
else
|
||||
species_restricted = list(target_species)
|
||||
|
||||
@@ -275,6 +273,41 @@ BLIND // can't see anything
|
||||
update_icon(user)
|
||||
user.update_action_buttons()
|
||||
|
||||
/obj/item/clothing/head/attack_ai(var/mob/user)
|
||||
if(!mob_wear_hat(user))
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/attack_generic(var/mob/user)
|
||||
if(!mob_wear_hat(user))
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/proc/mob_wear_hat(var/mob/user)
|
||||
if(!Adjacent(user))
|
||||
return 0
|
||||
var/success
|
||||
if(istype(user, /mob/living/silicon/robot/drone))
|
||||
var/mob/living/silicon/robot/drone/D = user
|
||||
if(D.hat)
|
||||
success = 2
|
||||
else
|
||||
D.wear_hat(src)
|
||||
success = 1
|
||||
else if(istype(user, /mob/living/carbon/alien/diona))
|
||||
var/mob/living/carbon/alien/diona/D = user
|
||||
if(D.hat)
|
||||
success = 2
|
||||
else
|
||||
D.wear_hat(src)
|
||||
success = 1
|
||||
|
||||
if(!success)
|
||||
return 0
|
||||
else if(success == 2)
|
||||
user << "<span class='warning'>You are already wearing a hat.</span>"
|
||||
else if(success == 1)
|
||||
user << "<span class='notice'>You crawl under \the [src].</span>"
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/head/update_icon(var/mob/user)
|
||||
|
||||
overlays.Cut()
|
||||
@@ -303,6 +336,10 @@ BLIND // can't see anything
|
||||
body_parts_covered = FACE|EYES
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi')
|
||||
|
||||
var/voicechange = 0
|
||||
var/list/say_messages
|
||||
var/list/say_verbs
|
||||
|
||||
/obj/item/clothing/mask/update_clothing_icon()
|
||||
if (ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
@@ -387,6 +424,7 @@ BLIND // can't see anything
|
||||
var/worn_state = null
|
||||
|
||||
/obj/item/clothing/under/New()
|
||||
..()
|
||||
if(worn_state)
|
||||
if(!item_state_slots)
|
||||
item_state_slots = list()
|
||||
@@ -399,6 +437,29 @@ BLIND // can't see anything
|
||||
if((worn_state + "_d_s") in icon_states('icons/mob/uniform.dmi'))
|
||||
rolled_down = 0
|
||||
|
||||
/obj/item/clothing/under/proc/update_rolldown_status()
|
||||
var/mob/living/carbon/human/H
|
||||
if(istype(src.loc, /mob/living/carbon/human))
|
||||
H = src.loc
|
||||
|
||||
var/icon/under_icon
|
||||
if(icon_override)
|
||||
under_icon = icon_override
|
||||
else if(H && sprite_sheets && sprite_sheets[H.species.name])
|
||||
under_icon = sprite_sheets[H.species.name]
|
||||
else if(item_icons && item_icons[slot_w_uniform_str])
|
||||
under_icon = item_icons[slot_w_uniform_str]
|
||||
else
|
||||
under_icon = INV_W_UNIFORM_DEF_ICON
|
||||
|
||||
// The _s is because the icon update procs append it.
|
||||
if(("[worn_state]_d_s") in icon_states(under_icon))
|
||||
if(rolled_down != 1)
|
||||
rolled_down = 0
|
||||
else
|
||||
rolled_down = -1
|
||||
if(H) update_clothing_icon()
|
||||
|
||||
/obj/item/clothing/under/update_clothing_icon()
|
||||
if (ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
@@ -540,7 +601,8 @@ BLIND // can't see anything
|
||||
if(!istype(usr, /mob/living)) return
|
||||
if(usr.stat) return
|
||||
|
||||
if(rolled_down < 0)
|
||||
update_rolldown_status()
|
||||
if(rolled_down == -1)
|
||||
usr << "<span class='notice'>You cannot roll down [src]!</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -61,11 +61,6 @@
|
||||
..()
|
||||
overlay = global_hud.science
|
||||
|
||||
/obj/item/clothing/glasses/science/scanners
|
||||
name = "Scanning Goggles"
|
||||
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
|
||||
icon_state = "uzenwa_sissra_1"
|
||||
|
||||
/obj/item/clothing/glasses/night
|
||||
name = "Night Vision Goggles"
|
||||
desc = "You can totally see in the dark now!"
|
||||
@@ -111,6 +106,11 @@
|
||||
item_state = "glasses"
|
||||
prescription = 1
|
||||
body_parts_covered = 0
|
||||
|
||||
/obj/item/clothing/glasses/regular/scanners
|
||||
name = "Scanning Goggles"
|
||||
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
|
||||
icon_state = "uzenwa_sissra_1"
|
||||
|
||||
/obj/item/clothing/glasses/regular/hipster
|
||||
name = "Prescription Glasses"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
name = "cargo cap"
|
||||
desc = "It's a peaked cap in a tasteless yellow color."
|
||||
icon_state = "cargosoft"
|
||||
flags = HEADCOVERSEYES
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "helmet", //probably a placeholder
|
||||
slot_r_hand_str = "helmet",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat
|
||||
name = "clown wig and mask"
|
||||
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."
|
||||
desc = "A true prankster's facial attire. A clown is incomplete without their wig and mask."
|
||||
icon_state = "clown"
|
||||
item_state = "clown_hat"
|
||||
|
||||
@@ -100,4 +100,4 @@
|
||||
/obj/item/clothing/mask/gas/owl_mask
|
||||
name = "owl mask"
|
||||
desc = "Twoooo!"
|
||||
icon_state = "owl"
|
||||
icon_state = "owl"
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
body_parts_covered = 0
|
||||
w_class = 2
|
||||
gas_transfer_coefficient = 0.90
|
||||
voicechange = 1
|
||||
|
||||
/obj/item/clothing/mask/muzzle/New()
|
||||
..()
|
||||
say_messages = list("Mmfph!", "Mmmf mrrfff!", "Mmmf mnnf!")
|
||||
say_verbs = list("mumbles", "says")
|
||||
|
||||
// Clumsy folks can't take the mask off themselves.
|
||||
/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
|
||||
@@ -99,9 +105,14 @@
|
||||
flags_inv = HIDEFACE
|
||||
body_parts_covered = HEAD|FACE|EYES
|
||||
w_class = 2
|
||||
var/voicechange = 0
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
/obj/item/clothing/mask/horsehead/New()
|
||||
..()
|
||||
// The horse mask doesn't cause voice changes by default, the wizard spell changes the flag as necessary
|
||||
say_messages = list("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
|
||||
say_verbs = list("whinnies", "neighs", "says")
|
||||
|
||||
/obj/item/clothing/mask/ai
|
||||
name = "camera MIU"
|
||||
desc = "Allows for direct mental connection to accessible camera networks."
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
name = "mounted grenade launcher"
|
||||
desc = "A shoulder-mounted micro-explosive dispenser."
|
||||
selectable = 1
|
||||
icon_state = "grenadelauncher"
|
||||
icon_state = "grenade"
|
||||
|
||||
interface_name = "integrated grenade launcher"
|
||||
interface_desc = "Discharges loaded grenades against the wearer's location."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/weapon/rig/unathi
|
||||
name = "NT breacher chassis control module"
|
||||
desc = "A cheap NT knock-off of a Unathi battle-rig. Looks like a fish, moves like a fish, steers like a cow."
|
||||
desc = "A cheap NT knock-off of an Unathi battle-rig. Looks like a fish, moves like a fish, steers like a cow."
|
||||
suit_type = "NT breacher"
|
||||
icon_state = "breacher_rig_cheap"
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 70, bio = 100, rad = 50)
|
||||
@@ -9,12 +9,24 @@
|
||||
offline_slowdown = 10
|
||||
vision_restriction = 1
|
||||
offline_vision_restriction = 2
|
||||
|
||||
chest_type = /obj/item/clothing/suit/space/rig
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/unathi
|
||||
boot_type = /obj/item/clothing/shoes/magboots/rig/unathi
|
||||
|
||||
/obj/item/weapon/rig/unathi/fancy
|
||||
name = "breacher chassis control module"
|
||||
desc = "An authentic Unathi breacher chassis. Huge, bulky and absurdly heavy. It must be like wearing a tank."
|
||||
suit_type = "breacher chassis"
|
||||
icon_state = "breacher_rig"
|
||||
armor = list(melee = 90, bullet = 90, laser = 90, energy = 90, bomb = 90, bio = 100, rad = 80)
|
||||
armor = list(melee = 90, bullet = 90, laser = 90, energy = 90, bomb = 90, bio = 100, rad = 80) //Takes TEN TIMES as much damage to stop someone in a breacher. In exchange, it's slow.
|
||||
vision_restriction = 0
|
||||
slowdown = 4
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/unathi
|
||||
species_restricted = list("Unathi")
|
||||
|
||||
/obj/item/clothing/suit/space/rig/unathi
|
||||
species_restricted = list("Unathi")
|
||||
|
||||
/obj/item/clothing/shoes/magboots/rig/unathi
|
||||
species_restricted = list("Unathi")
|
||||
@@ -18,7 +18,7 @@
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
siemens_coefficient = 0.9
|
||||
species_restricted = list("exclude","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human", "Skrell", "Tajara", "Unathi")
|
||||
|
||||
var/obj/machinery/camera/camera
|
||||
var/list/camera_networks
|
||||
@@ -63,7 +63,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("exclude","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human", "Skrell", "Tajara", "Unathi")
|
||||
|
||||
var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
item_state = "syndie_helm"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
|
||||
siemens_coefficient = 0.6
|
||||
species_restricted = list("exclude","Unathi","Tajara","Skrell","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human")
|
||||
camera_networks = list("NUKE")
|
||||
light_overlay = "helmet_light_green" //todo: species-specific light overlays
|
||||
|
||||
@@ -20,4 +20,4 @@
|
||||
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
|
||||
siemens_coefficient = 0.6
|
||||
species_restricted = list("exclude","Unathi","Tajara","Skrell","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human", "Skrell")
|
||||
@@ -9,7 +9,7 @@
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
//Species-specific stuff.
|
||||
species_restricted = list("exclude","Unathi","Tajara","Skrell","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human")
|
||||
sprite_sheets_refit = list(
|
||||
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
|
||||
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
|
||||
@@ -34,7 +34,7 @@
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
species_restricted = list("exclude","Unathi","Tajara","Diona","Vox", "Xenomorph", "Xenomorph Drone", "Xenomorph Hunter", "Xenomorph Sentinel", "Xenomorph Queen")
|
||||
species_restricted = list("Human", "Skrell")
|
||||
sprite_sheets_refit = list(
|
||||
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
|
||||
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
|
||||
/obj/item/clothing/suit/armor/reactive
|
||||
name = "Reactive Teleport Armor"
|
||||
desc = "Someone seperated our Research Director from his own head!"
|
||||
desc = "Someone separated our Research Director from their own head!"
|
||||
var/active = 0.0
|
||||
icon_state = "reactiveoff"
|
||||
item_state = "reactiveoff"
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
/obj/item/clothing/accessory/medal/conduct
|
||||
name = "distinguished conduct medal"
|
||||
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."
|
||||
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of their crew."
|
||||
|
||||
/obj/item/clothing/accessory/medal/bronze_heart
|
||||
name = "bronze heart medal"
|
||||
|
||||
@@ -49,18 +49,23 @@
|
||||
item.icon = CUSTOM_ITEM_OBJ
|
||||
item.icon_state = item_icon
|
||||
return
|
||||
else
|
||||
else
|
||||
if(inherit_inhands)
|
||||
apply_inherit_inhands(item)
|
||||
else
|
||||
item.item_state_slots = null
|
||||
item.item_icons = null
|
||||
|
||||
|
||||
item.icon = CUSTOM_ITEM_OBJ
|
||||
item.icon_state = item_icon
|
||||
item.item_state = null
|
||||
item.icon_override = CUSTOM_ITEM_MOB
|
||||
|
||||
var/obj/item/clothing/under/U = item
|
||||
if(istype(U))
|
||||
U.worn_state = U.icon_state
|
||||
U.update_rolldown_status()
|
||||
|
||||
// Kits are dumb so this is going to have to be hardcoded/snowflake.
|
||||
if(istype(item, /obj/item/device/kit))
|
||||
var/obj/item/device/kit/K = item
|
||||
@@ -81,9 +86,9 @@
|
||||
/datum/custom_item/proc/apply_inherit_inhands(var/obj/item/item)
|
||||
var/list/new_item_icons = list()
|
||||
var/list/new_item_state_slots = list()
|
||||
|
||||
|
||||
var/list/available_states = icon_states(CUSTOM_ITEM_MOB)
|
||||
|
||||
|
||||
//If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots
|
||||
//Then use icon_override to make every other slot use the custom sprites by default.
|
||||
//This has to be done before we touch any of item's vars
|
||||
@@ -93,7 +98,7 @@
|
||||
if(!("[item_icon]_r" in available_states))
|
||||
new_item_state_slots[slot_r_hand_str] = get_state(item, slot_r_hand_str, "_r")
|
||||
new_item_icons[slot_r_hand_str] = get_icon(item, slot_r_hand_str, 'icons/mob/items/righthand.dmi')
|
||||
|
||||
|
||||
item.item_state_slots = new_item_state_slots
|
||||
item.item_icons = new_item_icons
|
||||
|
||||
|
||||
@@ -14,33 +14,208 @@
|
||||
var/track_blood = 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag
|
||||
name = "damp rag"
|
||||
name = "rag"
|
||||
desc = "For cleaning up messes, you suppose."
|
||||
w_class = 1
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "rag"
|
||||
amount_per_transfer_from_this = 5
|
||||
possible_transfer_amounts = list(5)
|
||||
volume = 5
|
||||
volume = 10
|
||||
can_be_placed_into = null
|
||||
flags = OPENCONTAINER | NOBLUDGEON
|
||||
unacidable = 0
|
||||
|
||||
var/on_fire = 0
|
||||
var/burn_time = 20 //if the rag burns for too long it turns to ashes
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/New()
|
||||
..()
|
||||
update_name()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/Destroy()
|
||||
processing_objects -= src //so we don't continue turning to ash while gc'd
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/attack_self(mob/user as mob)
|
||||
return
|
||||
if(on_fire)
|
||||
user.visible_message("<span class='warning'>\The [user] stamps out [src].</span>", "<span class='warning'>You stamp out [src].</span>")
|
||||
user.unEquip(src)
|
||||
extinguish()
|
||||
else
|
||||
remove_contents(user)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/attackby(obj/item/W, mob/user)
|
||||
if(!on_fire && istype(W, /obj/item/weapon/flame))
|
||||
var/obj/item/weapon/flame/F = W
|
||||
if(F.lit)
|
||||
ignite()
|
||||
if(on_fire)
|
||||
visible_message("<span class='warning'>\The [user] lights [src] with [W].</span>")
|
||||
else
|
||||
user << "<span class='warning'>You manage to singe [src], but fail to light it.</span>"
|
||||
|
||||
. = ..()
|
||||
update_name()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/proc/update_name()
|
||||
if(on_fire)
|
||||
name = "burning [initial(name)]"
|
||||
else if(reagents.total_volume)
|
||||
name = "damp [initial(name)]"
|
||||
else
|
||||
name = "dry [initial(name)]"
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/update_icon()
|
||||
if(on_fire)
|
||||
icon_state = "raglit"
|
||||
else
|
||||
icon_state = "rag"
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/bottle/B = loc
|
||||
if(istype(B))
|
||||
B.update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/proc/remove_contents(mob/user, atom/trans_dest = null)
|
||||
if(!trans_dest && !user.loc)
|
||||
return
|
||||
|
||||
if(reagents.total_volume)
|
||||
var/target_text = trans_dest? "\the [trans_dest]" : "\the [user.loc]"
|
||||
user.visible_message("<span class='danger'>\The [user] begins to wring out [src] over [target_text].</span>", "<span class='notice'>You begin to wring out [src] over [target_text].</span>")
|
||||
|
||||
if(do_after(user, reagents.total_volume*5)) //50 for a fully soaked rag
|
||||
if(trans_dest)
|
||||
reagents.trans_to(trans_dest, reagents.total_volume)
|
||||
else
|
||||
reagents.splash(user.loc, reagents.total_volume)
|
||||
user.visible_message("<span class='danger'>\The [user] wrings out [src] over [target_text].</span>", "<span class='notice'>You finish to wringing out [src].</span>")
|
||||
update_name()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/proc/wipe_down(atom/A, mob/user)
|
||||
if(!reagents.total_volume)
|
||||
user << "<span class='warning'>The [initial(name)] is dry!</span>"
|
||||
else
|
||||
user.visible_message("\The [user] starts to wipe down [A] with [src]!")
|
||||
reagents.splash(A, 1) //get a small amount of liquid on the thing we're wiping.
|
||||
update_name()
|
||||
if(do_after(user,30))
|
||||
user.visible_message("\The [user] finishes wiping off the [A]!")
|
||||
A.clean_blood()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
|
||||
if(ismob(target) && target.reagents && reagents.total_volume)
|
||||
user.visible_message("\red \The [target] has been smothered with \the [src] by \the [user]!", "\red You smother \the [target] with \the [src]!", "You hear some struggling and muffled cries of surprise")
|
||||
reagents.trans_to_mob(target, reagents.total_volume, CHEM_INGEST)
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
if(on_fire)
|
||||
user.visible_message("<span class='danger'>\The [user] hits [target] with [src]!</span>",)
|
||||
user.do_attack_animation(src)
|
||||
M.IgniteMob()
|
||||
else if(reagents.total_volume)
|
||||
if(user.zone_sel.selecting == "mouth")
|
||||
user.do_attack_animation(src)
|
||||
user.visible_message(
|
||||
"<span class='danger'>\The [user] smothers [target] with [src]!</span>",
|
||||
"<span class='warning'>You smother [target] with [src]!</span>",
|
||||
"You hear some struggling and muffled cries of surprise"
|
||||
)
|
||||
|
||||
//it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now
|
||||
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
|
||||
update_name()
|
||||
else
|
||||
wipe_down(target, user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
if(istype(A) && src in user)
|
||||
user.visible_message("[user] starts to wipe down [A] with [src]!")
|
||||
if(do_after(user,30))
|
||||
user.visible_message("[user] finishes wiping off the [A]!")
|
||||
A.clean_blood()
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
if(istype(A, /obj/structure/reagent_dispensers))
|
||||
if(!reagents.get_free_space())
|
||||
user << "<span class='warning'>\The [src] is already soaked.</span>"
|
||||
return
|
||||
|
||||
if(A.reagents && A.reagents.trans_to_obj(src, reagents.maximum_volume))
|
||||
user.visible_message("<span class='notice'>\The [user] soaks [src] using [A].</span>", "<span class='notice'>You soak [src] using [A].</span>")
|
||||
update_name()
|
||||
return
|
||||
|
||||
if(!on_fire && istype(A) && (src in user))
|
||||
if(A.is_open_container())
|
||||
remove_contents(user, A)
|
||||
else if(!ismob(A)) //mobs are handled in attack() - this prevents us from wiping down people while smothering them.
|
||||
wipe_down(A, user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature >= 50 + T0C)
|
||||
ignite()
|
||||
if(exposed_temperature >= 900 + T0C)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
//rag must have a minimum of 2 units welder fuel and at least 80% of the reagents must be welder fuel.
|
||||
//maybe generalize flammable reagents someday
|
||||
/obj/item/weapon/reagent_containers/glass/rag/proc/can_ignite()
|
||||
var/fuel = reagents.get_reagent_amount("fuel")
|
||||
return (fuel >= 2 && fuel >= reagents.total_volume*0.8)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/proc/ignite()
|
||||
if(on_fire)
|
||||
return
|
||||
if(!can_ignite())
|
||||
return
|
||||
|
||||
//also copied from matches
|
||||
if(reagents.get_reagent_amount("phoron")) // the phoron explodes when exposed to fire
|
||||
visible_message("<span class='danger'>\The [src] conflagrates violently!</span>")
|
||||
var/datum/effect/effect/system/reagents_explosion/e = new()
|
||||
e.set_up(round(reagents.get_reagent_amount("phoron") / 2.5, 1), get_turf(src), 0, 0)
|
||||
e.start()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
processing_objects += src
|
||||
set_light(2, null, "#E38F46")
|
||||
on_fire = 1
|
||||
update_name()
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/proc/extinguish()
|
||||
processing_objects -= src
|
||||
set_light(0)
|
||||
on_fire = 0
|
||||
|
||||
//rags sitting around with 1 second of burn time left is dumb.
|
||||
//ensures players always have a few seconds of burn time left when they light their rag
|
||||
if(burn_time <= 5)
|
||||
visible_message("<span class='warning'>\The [src] falls apart!</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
update_name()
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/rag/process()
|
||||
if(!can_ignite())
|
||||
visible_message("<span class='warning'>\The [src] burns out.</span>")
|
||||
extinguish()
|
||||
|
||||
//copied from matches
|
||||
if(isliving(loc))
|
||||
var/mob/living/M = loc
|
||||
M.IgniteMob()
|
||||
var/turf/location = get_turf(src)
|
||||
if(location)
|
||||
location.hotspot_expose(700, 5)
|
||||
|
||||
if(burn_time <= 0)
|
||||
processing_objects -= src
|
||||
new /obj/effect/decal/cleanable/ash(location)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
reagents.remove_reagent("fuel", reagents.maximum_volume/25)
|
||||
update_name()
|
||||
burn_time--
|
||||
|
||||
@@ -42,7 +42,7 @@ var/list/weighted_mundaneevent_locations = list()
|
||||
return null
|
||||
|
||||
/datum/trade_destination/icarus
|
||||
name = "NMV Icarus"
|
||||
name = "NDV Icarus"
|
||||
description = "Corvette assigned to patrol NSS Exodus local space."
|
||||
distance = 0.1
|
||||
willing_to_buy = list()
|
||||
|
||||
@@ -46,6 +46,15 @@
|
||||
|
||||
#define GEAR_EVA 15
|
||||
|
||||
|
||||
/var/list/economic_species_modifier = list(
|
||||
/datum/species/human = 10,
|
||||
/datum/species/skrell = 12,
|
||||
/datum/species/tajaran = 7,
|
||||
/datum/species/unathi = 7,
|
||||
/datum/species/vox = 1
|
||||
)
|
||||
|
||||
//---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel:
|
||||
//Corporation NanoTrasen - Generalised / high tech research and phoron exploitation.
|
||||
//Corporation Vessel Contracting - Ship and station construction, materials research.
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.",
|
||||
"All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.",
|
||||
"[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.",
|
||||
"Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
|
||||
"Jokes about a dead person and the manner of their death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
|
||||
"[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.",
|
||||
"There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.")
|
||||
var/law = pick(laws)
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
/datum/event/rogue_drone/announce()
|
||||
var/msg
|
||||
if(prob(33))
|
||||
msg = "A combat drone wing operating out of the NMV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution."
|
||||
msg = "A combat drone wing operating out of the NDV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution."
|
||||
else if(prob(50))
|
||||
msg = "Contact has been lost with a combat drone wing operating out of the NMV Icarus. If any are sighted in the area, approach with caution."
|
||||
msg = "Contact has been lost with a combat drone wing operating out of the NDV Icarus. If any are sighted in the area, approach with caution."
|
||||
else
|
||||
msg = "Unidentified hackers have targetted a combat drone wing deployed from the NMV Icarus. If any are sighted in the area, approach with caution."
|
||||
msg = "Unidentified hackers have targetted a combat drone wing deployed from the NDV Icarus. If any are sighted in the area, approach with caution."
|
||||
command_announcement.Announce(msg, "Rogue drone alert")
|
||||
|
||||
/datum/event/rogue_drone/end()
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
duration = 10*90
|
||||
|
||||
start(mob/living/carbon/human/H)
|
||||
H.emote("me", 1, "has drool running down from his mouth.")
|
||||
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
|
||||
|
||||
finish(mob/living/carbon/human/H)
|
||||
if(!H.reagents.has_reagent("anti_toxin"))
|
||||
@@ -68,7 +68,7 @@
|
||||
duration = 10*30
|
||||
|
||||
start(mob/living/carbon/human/H)
|
||||
H.emote("me", 1, "has drool running down from his mouth.")
|
||||
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
|
||||
|
||||
finish(mob/living/carbon/human/H)
|
||||
if(!H.reagents.has_reagent("anti_toxin"))
|
||||
@@ -88,4 +88,4 @@ proc/trigger_side_effect(mob/living/carbon/human/H)
|
||||
|
||||
if(!istype(H)) return
|
||||
H.SetWeakened(0)
|
||||
S.finish(H)
|
||||
S.finish(H)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/obj/machinery/computer/HolodeckControl
|
||||
name = "holodeck control console"
|
||||
desc = "A computer used to control a nearby holodeck."
|
||||
icon_state = "holocontrol"
|
||||
icon_keyboard = "tech_key"
|
||||
icon_screen = "holocontrol"
|
||||
|
||||
use_power = 1
|
||||
active_power_usage = 8000 //8kW for the scenery + 500W per holoitem
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
/obj/structure/holostool
|
||||
name = "stool"
|
||||
desc = "Apply butt."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "stool"
|
||||
icon = 'icons/obj/furniture.dmi'
|
||||
icon_state = "stool_padded_preview"
|
||||
anchored = 1.0
|
||||
pressure_resistance = 15
|
||||
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/obj/machinery/beehive
|
||||
name = "beehive"
|
||||
icon = 'icons/obj/beekeeping.dmi'
|
||||
icon_state = "beehive"
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
var/closed = 0
|
||||
var/bee_count = 0 // Percent
|
||||
var/smoked = 0 // Timer
|
||||
var/honeycombs = 0 // Percent
|
||||
var/frames = 0
|
||||
var/maxFrames = 5
|
||||
|
||||
/obj/machinery/beehive/update_icon()
|
||||
overlays.Cut()
|
||||
icon_state = "beehive"
|
||||
if(closed)
|
||||
overlays += "lid"
|
||||
if(frames)
|
||||
overlays += "empty[frames]"
|
||||
if(honeycombs >= 100)
|
||||
overlays += "full[round(honeycombs / 100)]"
|
||||
if(!smoked)
|
||||
switch(bee_count)
|
||||
if(1 to 40)
|
||||
overlays += "bees1"
|
||||
if(41 to 80)
|
||||
overlays += "bees2"
|
||||
if(81 to 100)
|
||||
overlays += "bees3"
|
||||
|
||||
/obj/machinery/beehive/examine(var/mob/user)
|
||||
..()
|
||||
if(!closed)
|
||||
user << "The lid is open."
|
||||
|
||||
/obj/machinery/beehive/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
closed = !closed
|
||||
user.visible_message("<span class='notice'>[user] [closed ? "closes" : "opens"] \the [src].</span>", "<span class='notice'>You [closed ? "close" : "open"] \the [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
else if(istype(I, /obj/item/weapon/wrench))
|
||||
anchored = !anchored
|
||||
user.visible_message("<span class='notice'>[user] [anchored ? "wrenches" : "unwrenches"] \the [src].</span>", "<span class='notice'>You [anchored ? "wrench" : "unwrench"] \the [src].</span>")
|
||||
return
|
||||
else if(istype(I, /obj/item/bee_smoker))
|
||||
if(closed)
|
||||
user << "<span class='notice'>You need to open \the [src] with a crowbar before smoking the bees.</span>"
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] smokes the bees in \the [src].</span>", "<span class='notice'>You smoke the bees in \the [src].</span>")
|
||||
smoked = 30
|
||||
update_icon()
|
||||
return
|
||||
else if(istype(I, /obj/item/honey_frame))
|
||||
if(closed)
|
||||
user << "<span class='notice'>You need to open \the [src] with a crowbar before inserting \the [I].</span>"
|
||||
return
|
||||
if(frames >= maxFrames)
|
||||
user << "<span class='notice'>There is no place for an another frame.</span>"
|
||||
return
|
||||
var/obj/item/honey_frame/H = I
|
||||
if(H.honey)
|
||||
user << "<span class='notice'>\The [I] is full with beeswax and honey, empty it in the extractor first.</span>"
|
||||
return
|
||||
++frames
|
||||
user.visible_message("<span class='notice'>[user] loads \the [I] into \the [src].</span>", "<span class='notice'>You load \the [I] into \the [src].</span>")
|
||||
update_icon()
|
||||
user.drop_from_inventory(I)
|
||||
qdel(I)
|
||||
return
|
||||
else if(istype(I, /obj/item/bee_pack))
|
||||
var/obj/item/bee_pack/B = I
|
||||
if(B.full && bee_count)
|
||||
user << "<span class='notice'>\The [src] already has bees inside.</span>"
|
||||
return
|
||||
if(!B.full && bee_count < 90)
|
||||
user << "<span class='notice'>\The [src] is not ready to split.</span>"
|
||||
return
|
||||
if(!B.full && !smoked)
|
||||
user << "<span class='notice'>Smoke \the [src] first!</span>"
|
||||
return
|
||||
if(closed)
|
||||
user << "<span class='notice'>You need to open \the [src] with a crowbar before moving the bees.</span>"
|
||||
return
|
||||
if(B.full)
|
||||
user.visible_message("<span class='notice'>[user] puts the queen and the bees from \the [I] into \the [src].</span>", "<span class='notice'>You put the queen and the bees from \the [I] into \the [src].</span>")
|
||||
bee_count = 20
|
||||
B.empty()
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] puts bees and larvae from \the [src] into \the [I].</span>", "<span class='notice'>You put puts bees and larvae from \the [src] into \the [I].</span>")
|
||||
bee_count /= 2
|
||||
B.fill()
|
||||
update_icon()
|
||||
return
|
||||
else if(istype(I, /obj/item/device/analyzer/plant_analyzer))
|
||||
user << "<span class='notice'>Scan result of \the [src]...</span>"
|
||||
user << "Beehive is [bee_count ? "[round(bee_count)]% full" : "empty"].[bee_count > 90 ? " Colony is ready to split." : ""]"
|
||||
if(frames)
|
||||
user << "[frames] frames installed, [round(honeycombs / 100)] filled."
|
||||
if(honeycombs < frames * 100)
|
||||
user << "Next frame is [round(honeycombs % 100)]% full."
|
||||
else
|
||||
user << "No frames installed."
|
||||
if(smoked)
|
||||
user << "The hive is smoked."
|
||||
return 1
|
||||
else if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(bee_count)
|
||||
user << "<span class='notice'>You can't dismantle \the [src] with these bees inside.</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start dismantling \the [src]...</span>"
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 30))
|
||||
user.visible_message("<span class='notice'>[user] dismantles \the [src].</span>", "<span class='notice'>You dismantle \the [src].</span>")
|
||||
new /obj/item/beehive_assembly(loc)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/machinery/beehive/attack_hand(var/mob/user)
|
||||
if(!closed)
|
||||
if(honeycombs < 100)
|
||||
user << "<span class='notice'>There are no filled honeycombs.</span>"
|
||||
return
|
||||
if(!smoked && bee_count)
|
||||
user << "<span class='notice'>The bees won't let you take the honeycombs out like this, smoke them first.</span>"
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts taking the honeycombs out of \the [src].</span>", "<span class='notice'>You start taking the honeycombs out of \the [src]...</span>")
|
||||
while(honeycombs >= 100 && do_after(user, 30))
|
||||
new /obj/item/honey_frame/filled(loc)
|
||||
honeycombs -= 100
|
||||
--frames
|
||||
update_icon()
|
||||
if(honeycombs < 100)
|
||||
user << "<span class='notice'>You take all filled honeycombs out.</span>"
|
||||
return
|
||||
|
||||
/obj/machinery/beehive/process()
|
||||
if(closed && !smoked && bee_count)
|
||||
pollinate_flowers()
|
||||
update_icon()
|
||||
smoked = max(0, smoked - 1)
|
||||
if(!smoked && bee_count)
|
||||
bee_count = min(bee_count * 1.005, 100)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/beehive/proc/pollinate_flowers()
|
||||
var/coef = bee_count / 100
|
||||
var/trays = 0
|
||||
for(var/obj/machinery/portable_atmospherics/hydroponics/H in view(7, src))
|
||||
if(H.seed && !H.dead)
|
||||
H.health += 0.05 * coef
|
||||
++trays
|
||||
honeycombs = min(honeycombs + 0.1 * coef * min(trays, 5), frames * 100)
|
||||
|
||||
/obj/machinery/honey_extractor
|
||||
name = "honey extractor"
|
||||
desc = "A machine used to turn honeycombs on the frame into honey and wax."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "centrifuge"
|
||||
|
||||
var/processing = 0
|
||||
var/honey = 0
|
||||
|
||||
/obj/machinery/honey_extractor/attackby(var/obj/item/I, var/mob/user)
|
||||
if(processing)
|
||||
user << "<span class='notice'>\The [src] is currently spinning, wait until it's finished.</span>"
|
||||
return
|
||||
else if(istype(I, /obj/item/honey_frame))
|
||||
var/obj/item/honey_frame/H = I
|
||||
if(!H.honey)
|
||||
user << "<span class='notice'>\The [H] is empty, put it into a beehive.</span>"
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] loads \the [H] into \the [src] and turns it on.</span>", "<span class='notice'>You load \the [H] into \the [src] and turn it on.</span>")
|
||||
processing = H.honey
|
||||
icon_state = "centrifuge_moving"
|
||||
qdel(H)
|
||||
spawn(50)
|
||||
new /obj/item/honey_frame(loc)
|
||||
new /obj/item/stack/wax(loc)
|
||||
honey += processing
|
||||
processing = 0
|
||||
icon_state = "centrifuge"
|
||||
else if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
if(!honey)
|
||||
user << "<span class='notice'>There is no honey in \the [src].</span>"
|
||||
return
|
||||
var/obj/item/weapon/reagent_containers/glass/G = I
|
||||
var/transferred = min(G.reagents.maximum_volume - G.reagents.total_volume, honey)
|
||||
G.reagents.add_reagent("honey", transferred)
|
||||
honey -= transferred
|
||||
user.visible_message("<span class='notice'>[user] collects honey from \the [src] into \the [G].</span>", "<span class='notice'>You collect [transferred] units of honey from \the [src] into \the [G].</span>")
|
||||
return 1
|
||||
|
||||
/obj/item/bee_smoker
|
||||
name = "bee smoker"
|
||||
desc = "A device used to calm down bees before harvesting honey."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "battererburnt"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/honey_frame
|
||||
name = "beehive frame"
|
||||
desc = "A frame for the beehive that the bees will fill with honeycombs."
|
||||
icon = 'icons/obj/beekeeping.dmi'
|
||||
icon_state = "honeyframe"
|
||||
w_class = 2
|
||||
|
||||
var/honey = 0
|
||||
|
||||
/obj/item/honey_frame/filled
|
||||
name = "filled beehive frame"
|
||||
desc = "A frame for the beehive that the bees have filled with honeycombs."
|
||||
honey = 20
|
||||
|
||||
/obj/item/honey_frame/filled/New()
|
||||
..()
|
||||
overlays += "honeycomb"
|
||||
|
||||
/obj/item/beehive_assembly
|
||||
name = "beehive assembly"
|
||||
desc = "Contains everything you need to build a beehive."
|
||||
icon = 'icons/obj/apiary_bees_etc.dmi'
|
||||
icon_state = "apiary"
|
||||
|
||||
/obj/item/beehive_assembly/attack_self(var/mob/user)
|
||||
user << "<span class='notice'>You start assembling \the [src]...</span>"
|
||||
if(do_after(user, 30))
|
||||
user.visible_message("<span class='notice'>[user] constructs a beehive.</span>", "<span class='notice'>You construct a beehive.</span>")
|
||||
new /obj/machinery/beehive(get_turf(user))
|
||||
user.drop_from_inventory(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/stack/wax
|
||||
name = "wax"
|
||||
singular_name = "wax piece"
|
||||
desc = "Soft substance produced by bees. Used to make candles."
|
||||
icon = 'icons/obj/beekeeping.dmi'
|
||||
icon_state = "wax"
|
||||
|
||||
/obj/item/stack/wax/New()
|
||||
..()
|
||||
recipes = wax_recipes
|
||||
|
||||
var/global/list/datum/stack_recipe/wax_recipes = list( \
|
||||
new/datum/stack_recipe("candle", /obj/item/weapon/flame/candle) \
|
||||
)
|
||||
|
||||
/obj/item/bee_pack
|
||||
name = "bee pack"
|
||||
desc = "Contains a queen bee and some worker bees. Everything you'll need to start a hive!"
|
||||
icon = 'icons/obj/beekeeping.dmi'
|
||||
icon_state = "beepack"
|
||||
var/full = 1
|
||||
|
||||
/obj/item/bee_pack/New()
|
||||
..()
|
||||
overlays += "beepack-full"
|
||||
|
||||
/obj/item/bee_pack/proc/empty()
|
||||
full = 0
|
||||
name = "empty bee pack"
|
||||
desc = "A stasis pack for moving bees. It's empty."
|
||||
overlays.Cut()
|
||||
overlays += "beepack-empty"
|
||||
|
||||
/obj/item/bee_pack/proc/fill()
|
||||
full = initial(full)
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
overlays.Cut()
|
||||
overlays += "beepack-full"
|
||||
@@ -690,10 +690,11 @@
|
||||
else
|
||||
product = new /obj/item/weapon/reagent_containers/food/snacks/grown(get_turf(user),name)
|
||||
if(get_trait(TRAIT_PRODUCT_COLOUR))
|
||||
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(istype(product,/obj/item/weapon/reagent_containers/food))
|
||||
var/obj/item/weapon/reagent_containers/food/food = product
|
||||
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(!istype(product, /mob))
|
||||
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(istype(product,/obj/item/weapon/reagent_containers/food))
|
||||
var/obj/item/weapon/reagent_containers/food/food = product
|
||||
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
|
||||
if(mysterious)
|
||||
product.name += "?"
|
||||
|
||||
@@ -532,19 +532,6 @@
|
||||
anchored = !anchored
|
||||
user << "You [anchored ? "wrench" : "unwrench"] \the [src]."
|
||||
|
||||
else if(istype(O, /obj/item/apiary))
|
||||
|
||||
if(seed)
|
||||
user << "<span class='danger'>[src] is already occupied!</span>"
|
||||
else
|
||||
user.drop_item()
|
||||
qdel(O)
|
||||
|
||||
var/obj/machinery/apiary/A = new(src.loc)
|
||||
A.icon = src.icon
|
||||
A.icon_state = src.icon_state
|
||||
A.hydrotray_type = src.type
|
||||
qdel(src)
|
||||
else if(O.force && seed)
|
||||
user.visible_message("<span class='danger'>\The [seed.display_name] has been attacked by [user] with \the [O]!</span>")
|
||||
if(!dead)
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
//http://www.youtube.com/watch?v=-1GadTfGFvU
|
||||
//i could have done these as just an ordinary plant, but fuck it - there would have been too much snowflake code
|
||||
|
||||
/obj/machinery/apiary
|
||||
name = "apiary tray"
|
||||
icon = 'icons/obj/hydroponics_machines.dmi'
|
||||
icon_state = "hydrotray3"
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/nutrilevel = 0
|
||||
var/yieldmod = 1
|
||||
var/mut = 1
|
||||
var/toxic = 0
|
||||
var/dead = 0
|
||||
var/health = -1
|
||||
var/maxhealth = 100
|
||||
var/lastcycle = 0
|
||||
var/cycledelay = 100
|
||||
var/harvestable_honey = 0
|
||||
var/beezeez = 0
|
||||
var/swarming = 0
|
||||
|
||||
var/bees_in_hive = 0
|
||||
var/list/owned_bee_swarms = list()
|
||||
var/hydrotray_type = /obj/machinery/portable_atmospherics/hydroponics
|
||||
|
||||
//overwrite this after it's created if the apiary needs a custom machinery sprite
|
||||
/obj/machinery/apiary/New()
|
||||
..()
|
||||
overlays += image('icons/obj/apiary_bees_etc.dmi', icon_state="apiary")
|
||||
|
||||
/obj/machinery/apiary/bullet_act(var/obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables.
|
||||
if(istype(Proj ,/obj/item/projectile/energy/floramut))
|
||||
mut++
|
||||
else if(istype(Proj ,/obj/item/projectile/energy/florayield))
|
||||
if(!yieldmod)
|
||||
yieldmod += 1
|
||||
//world << "Yield increased by 1, from 0, to a total of [myseed.yield]"
|
||||
else if (prob(1/(yieldmod * yieldmod) *100))//This formula gives you diminishing returns based on yield. 100% with 1 yield, decreasing to 25%, 11%, 6, 4, 2...
|
||||
yieldmod += 1
|
||||
//world << "Yield increased by 1, to a total of [myseed.yield]"
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/apiary/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(istype(O, /obj/item/queen_bee))
|
||||
if(health > 0)
|
||||
user << "\red There is already a queen in there."
|
||||
else
|
||||
health = 10
|
||||
nutrilevel += 10
|
||||
user.drop_item()
|
||||
qdel(O)
|
||||
user << "\blue You carefully insert the queen into [src], she gets busy making a hive."
|
||||
bees_in_hive = 0
|
||||
else if(istype(O, /obj/item/beezeez))
|
||||
beezeez += 100
|
||||
nutrilevel += 10
|
||||
user.drop_item()
|
||||
if(health > 0)
|
||||
user << "\blue You insert [O] into [src]. A relaxed humming appears to pick up."
|
||||
else
|
||||
user << "\blue You insert [O] into [src]. Now it just needs some bees."
|
||||
qdel(O)
|
||||
else if(istype(O, /obj/item/weapon/material/minihoe))
|
||||
if(health > 0)
|
||||
user << "\red <b>You begin to dislodge the apiary from the tray, the bees don't like that.</b>"
|
||||
angry_swarm(user)
|
||||
else
|
||||
user << "\blue You begin to dislodge the dead apiary from the tray."
|
||||
if(do_after(user, 50))
|
||||
new hydrotray_type(src.loc)
|
||||
new /obj/item/apiary(src.loc)
|
||||
user << "\red You dislodge the apiary from the tray."
|
||||
qdel(src)
|
||||
else if(istype(O, /obj/item/weapon/bee_net))
|
||||
var/obj/item/weapon/bee_net/N = O
|
||||
if(N.caught_bees > 0)
|
||||
user << "\blue You empty the bees into the apiary."
|
||||
bees_in_hive += N.caught_bees
|
||||
N.caught_bees = 0
|
||||
else
|
||||
user << "\blue There are no more bees in the net."
|
||||
else if(istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
var/obj/item/weapon/reagent_containers/glass/G = O
|
||||
if(harvestable_honey > 0)
|
||||
if(health > 0)
|
||||
user << "\red You begin to harvest the honey. The bees don't seem to like it."
|
||||
angry_swarm(user)
|
||||
else
|
||||
user << "\blue You begin to harvest the honey."
|
||||
if(do_after(user,50))
|
||||
G.reagents.add_reagent("honey",harvestable_honey)
|
||||
harvestable_honey = 0
|
||||
user << "\blue You successfully harvest the honey."
|
||||
else
|
||||
user << "\blue There is no honey left to harvest."
|
||||
else
|
||||
angry_swarm(user)
|
||||
..()
|
||||
|
||||
/obj/machinery/apiary/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
|
||||
if(istype(mover) && mover.checkpass(PASSTABLE))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/apiary/process()
|
||||
|
||||
if(swarming > 0)
|
||||
swarming -= 1
|
||||
if(swarming <= 0)
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
bees_in_hive += B.strength
|
||||
qdel(B)
|
||||
else if(bees_in_hive < 10)
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
bees_in_hive += B.strength
|
||||
qdel(B)
|
||||
|
||||
if(world.time > (lastcycle + cycledelay))
|
||||
lastcycle = world.time
|
||||
if(health < 0)
|
||||
return
|
||||
|
||||
//magical bee formula
|
||||
if(beezeez > 0)
|
||||
beezeez -= 1
|
||||
|
||||
nutrilevel += 2
|
||||
health += 1
|
||||
toxic = max(0, toxic - 1)
|
||||
|
||||
//handle nutrients
|
||||
nutrilevel -= bees_in_hive / 10 + owned_bee_swarms.len / 5
|
||||
if(nutrilevel > 0)
|
||||
bees_in_hive += 1 * yieldmod
|
||||
if(health < maxhealth)
|
||||
health++
|
||||
else
|
||||
//nutrilevel is less than 1, so we're effectively subtracting here
|
||||
health += max(nutrilevel - 1, round(-health / 2))
|
||||
bees_in_hive += max(nutrilevel - 1, round(-bees_in_hive / 2))
|
||||
if(owned_bee_swarms.len)
|
||||
var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
|
||||
B.target_turf = get_turf(src)
|
||||
|
||||
//clear out some toxins
|
||||
if(toxic > 0)
|
||||
toxic -= 1
|
||||
health -= 1
|
||||
|
||||
if(health <= 0)
|
||||
return
|
||||
|
||||
//make a bit of honey
|
||||
if(harvestable_honey < 50)
|
||||
harvestable_honey += 0.5
|
||||
|
||||
//make some new bees
|
||||
if(bees_in_hive >= 10 && prob(bees_in_hive * 10))
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
|
||||
owned_bee_swarms.Add(B)
|
||||
B.mut = mut
|
||||
B.toxic = toxic
|
||||
bees_in_hive -= 1
|
||||
|
||||
//find some plants, harvest
|
||||
for(var/obj/machinery/portable_atmospherics/hydroponics/H in view(7, src))
|
||||
if(H.seed && !H.dead && prob(owned_bee_swarms.len * 10))
|
||||
src.nutrilevel++
|
||||
H.nutrilevel++
|
||||
if(mut < H.mutation_mod - 1)
|
||||
mut = H.mutation_mod - 1
|
||||
else if(mut > H.mutation_mod - 1)
|
||||
H.mutation_mod = mut
|
||||
|
||||
//flowers give us pollen (nutrients)
|
||||
/* - All plants should be giving nutrients to the hive.
|
||||
if(H.myseed.type == /obj/item/seeds/harebell || H.myseed.type == /obj/item/seeds/sunflowerseed)
|
||||
src.nutrilevel++
|
||||
H.nutrilevel++
|
||||
*/
|
||||
//have a few beneficial effects on nearby plants
|
||||
if(prob(10))
|
||||
H.lastcycle -= 5
|
||||
if(prob(10))
|
||||
H.seed.set_trait(TRAIT_ENDURANCE,max(H.seed.get_trait(TRAIT_ENDURANCE)*1.5,H.seed.get_trait(TRAIT_ENDURANCE)+1))
|
||||
if(H.toxins && prob(10))
|
||||
H.toxins = min(0, H.toxins - 1)
|
||||
toxic++
|
||||
|
||||
/obj/machinery/apiary/proc/die()
|
||||
if(owned_bee_swarms.len)
|
||||
var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
|
||||
B.target_turf = get_turf(src)
|
||||
B.strength -= 1
|
||||
if(B.strength <= 0)
|
||||
qdel(B)
|
||||
else if(B.strength <= 5)
|
||||
B.icon_state = "bees[B.strength]"
|
||||
bees_in_hive = 0
|
||||
health = 0
|
||||
|
||||
/obj/machinery/apiary/proc/angry_swarm(var/mob/M)
|
||||
for(var/mob/living/simple_animal/bee/B in owned_bee_swarms)
|
||||
B.feral = 25
|
||||
B.target_mob = M
|
||||
|
||||
swarming = 25
|
||||
|
||||
while(bees_in_hive > 0)
|
||||
var/spawn_strength = bees_in_hive
|
||||
if(bees_in_hive >= 5)
|
||||
spawn_strength = 6
|
||||
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
|
||||
B.target_mob = M
|
||||
B.strength = spawn_strength
|
||||
B.feral = 25
|
||||
B.mut = mut
|
||||
B.toxic = toxic
|
||||
bees_in_hive -= spawn_strength
|
||||
|
||||
/obj/machinery/apiary/verb/harvest_honeycomb()
|
||||
set src in oview(1)
|
||||
set name = "Harvest honeycomb"
|
||||
set category = "Object"
|
||||
|
||||
while(health > 15)
|
||||
health -= 15
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/honeycomb/H = new(src.loc)
|
||||
if(toxic > 0)
|
||||
H.reagents.add_reagent("toxin", toxic)
|
||||
|
||||
usr << "\blue You harvest the honeycomb from the hive. There is a wild buzzing!"
|
||||
angry_swarm(usr)
|
||||
@@ -36,6 +36,20 @@
|
||||
return
|
||||
else
|
||||
name = ("bookcase ([newname])")
|
||||
else if(istype(O,/obj/item/weapon/wrench))
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
|
||||
user << (anchored ? "<span class='notice'>You unfasten \the [src] from the floor.</span>" : "<span class='notice'>You secure \the [src] to the floor.</span>")
|
||||
anchored = !anchored
|
||||
else if(istype(O,/obj/item/weapon/screwdriver))
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
|
||||
user << "<span class='notice'>You begin dismantling \the [src].</span>"
|
||||
if(do_after(user,25))
|
||||
user << "<span class='notice'>You dismantle \the [src].</span>"
|
||||
new /obj/item/stack/material/wood(get_turf(src), amount = 3)
|
||||
for(var/obj/item/weapon/book/b in contents)
|
||||
b.loc = (get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -81,6 +95,7 @@
|
||||
icon_state = "book-5"
|
||||
|
||||
|
||||
|
||||
/obj/structure/bookcase/manuals/medical
|
||||
name = "Medical Manuals bookcase"
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
density = 1
|
||||
var/arcanecheckout = 0
|
||||
var/screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
|
||||
var/sortby = "author"
|
||||
var/buffer_book
|
||||
var/buffer_mob
|
||||
var/upload_category = "Fiction"
|
||||
@@ -149,7 +150,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
if(src.arcanecheckout)
|
||||
new /obj/item/weapon/book/tome(src.loc)
|
||||
user << "<span class='warning'>Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.</span>"
|
||||
user.visible_message("[user] stares at the blank screen for a few moments, his expression frozen in fear. When he finally awakens from it, he looks a lot older.", 2)
|
||||
user.visible_message("<span class='notice'>\The [user] stares at the blank screen for a few moments, \his expression frozen in fear. When \he finally awakens from it, \he looks a lot older.</span>", 2)
|
||||
src.arcanecheckout = 0
|
||||
if(1)
|
||||
// Inventory
|
||||
@@ -195,9 +196,8 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
else
|
||||
dat += {"<A href='?src=\ref[src];orderbyid=1'>(Order book by SS<sup>13</sup>BN)</A><BR><BR>
|
||||
<table>
|
||||
<tr><td>AUTHOR</td><td>TITLE</td><td>CATEGORY</td><td></td></tr>"}
|
||||
|
||||
var/DBQuery/query = dbcon_old.NewQuery("SELECT id, author, title, category FROM library")
|
||||
<tr><td><A href='?src=\ref[src];sort=author>AUTHOR</A></td><td><A href='?src=\ref[src];sort=title>TITLE</A></td><td><A href='?src=\ref[src];sort=category>CATEGORY</A></td><td></td></tr>"}
|
||||
var/DBQuery/query = dbcon_old.NewQuery("SELECT id, author, title, category FROM library ORDER BY [sortby]")
|
||||
query.Execute()
|
||||
|
||||
while(query.NextRow())
|
||||
@@ -236,7 +236,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
//dat += "<A HREF='?src=\ref[user];mach_close=library'>Close</A><br><br>"
|
||||
user << browse(dat, "window=library")
|
||||
onclose(user, "library")
|
||||
|
||||
|
||||
/obj/machinery/librarycomp/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (src.density && !src.emagged)
|
||||
src.emagged = 1
|
||||
@@ -389,6 +389,8 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
if(isnum(orderid))
|
||||
var/nhref = "src=\ref[src];targetid=[orderid]"
|
||||
spawn() src.Topic(nhref, params2list(nhref), src)
|
||||
if(href_list["sort"] in list("author", "title", "category"))
|
||||
sortby = href_list["sort"]
|
||||
src.add_fingerprint(usr)
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
@@ -7,11 +7,22 @@
|
||||
var/list/light_sources
|
||||
|
||||
/atom/proc/set_light(l_range, l_power, l_color)
|
||||
if(l_power != null) light_power = l_power
|
||||
if(l_range != null) light_range = l_range
|
||||
if(l_color != null) light_color = l_color
|
||||
. = 0 //make it less costly if nothing's changed
|
||||
|
||||
update_light()
|
||||
if(l_power != null && l_power != light_power)
|
||||
light_power = l_power
|
||||
. = 1
|
||||
if(l_range != null && l_range != light_range)
|
||||
light_range = l_range
|
||||
. = 1
|
||||
if(l_color != null && l_color != light_color)
|
||||
light_color = l_color
|
||||
. = 1
|
||||
|
||||
if(.) update_light()
|
||||
|
||||
/atom/proc/copy_light(atom/A)
|
||||
set_light(A.light_range, A.light_power, A.light_color)
|
||||
|
||||
/atom/proc/update_light()
|
||||
if(!light_power || !light_range)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
recipes += new/datum/stack_recipe_list("office chairs",list( \
|
||||
new/datum/stack_recipe("dark office chair", /obj/structure/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("light office chair", /obj/structure/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1) \
|
||||
), 5)
|
||||
))
|
||||
recipes += new/datum/stack_recipe_list("comfy chairs", list( \
|
||||
new/datum/stack_recipe("beige comfy chair", /obj/structure/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("black comfy chair", /obj/structure/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -39,7 +39,7 @@
|
||||
new/datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \
|
||||
), 2)
|
||||
))
|
||||
|
||||
recipes += new/datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1)
|
||||
@@ -69,7 +69,7 @@
|
||||
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("emergency shutter", /obj/structure/firedoor_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("multi-tile airlock assembly", /obj/structure/door_assembly/multi_tile, 4, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
), 4)
|
||||
))
|
||||
|
||||
recipes += new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade)
|
||||
recipes += new/datum/stack_recipe("light fixture frame", /obj/item/frame/light, 2)
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
/material/sandstone/generate_recipes()
|
||||
..()
|
||||
recipes += new/datum/stack_recipe("pile of dirt", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("planting bed", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1)
|
||||
|
||||
/material/plastic/generate_recipes()
|
||||
..()
|
||||
@@ -103,7 +103,10 @@
|
||||
recipes += new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20)
|
||||
recipes += new/datum/stack_recipe("wooden chair", /obj/structure/bed/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0)
|
||||
recipes += new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("beehive assembly", /obj/item/beehive_assembly, 4)
|
||||
recipes += new/datum/stack_recipe("beehive frame", /obj/item/honey_frame, 1)
|
||||
recipes += new/datum/stack_recipe("book shelf", /obj/structure/bookcase, 5, time = 15, one_per_turf = 1, on_floor = 1)
|
||||
|
||||
/material/cardboard/generate_recipes()
|
||||
..()
|
||||
@@ -122,4 +125,4 @@
|
||||
new/datum/stack_recipe("red folder", /obj/item/weapon/folder/red), \
|
||||
new/datum/stack_recipe("white folder", /obj/item/weapon/folder/white), \
|
||||
new/datum/stack_recipe("yellow folder", /obj/item/weapon/folder/yellow), \
|
||||
), 3)
|
||||
))
|
||||
|
||||
@@ -359,7 +359,7 @@ var/list/name_to_material
|
||||
weight = 15
|
||||
door_icon_base = "stone"
|
||||
destruction_desc = "shatters"
|
||||
window_options = list("One Direction", "Full Window")
|
||||
window_options = list("One Direction" = 1, "Full Window" = 4)
|
||||
created_window = /obj/structure/window/basic
|
||||
wire_product = /obj/item/stack/light_w
|
||||
rod_product = /obj/item/stack/material/glass/reinforced
|
||||
@@ -417,9 +417,8 @@ var/list/name_to_material
|
||||
return 1
|
||||
|
||||
var/build_path = /obj/structure/windoor_assembly
|
||||
var/sheets_needed = 4
|
||||
var/sheets_needed = window_options[choice]
|
||||
if(choice == "Windoor")
|
||||
sheets_needed = 5
|
||||
build_dir = user.dir
|
||||
else
|
||||
build_path = created_window
|
||||
@@ -450,7 +449,7 @@ var/list/name_to_material
|
||||
weight = 30
|
||||
stack_origin_tech = "materials=2"
|
||||
composite_material = list(DEFAULT_WALL_MATERIAL = 1875,"glass" = 3750)
|
||||
window_options = list("One Direction", "Full Window", "Windoor")
|
||||
window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 5)
|
||||
created_window = /obj/structure/window/reinforced
|
||||
wire_product = null
|
||||
rod_product = null
|
||||
|
||||
@@ -188,8 +188,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
/mob/dead/observer/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (client.statpanel == "Status")
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
@@ -217,6 +216,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return
|
||||
mind.current.ajourn=0
|
||||
mind.current.key = key
|
||||
mind.current.aghosted = null
|
||||
if(!admin_ghosted)
|
||||
announce_ghost_joinleave(mind, 0, "They now occupy their body again.")
|
||||
return 1
|
||||
@@ -319,16 +319,56 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(following && following == target)
|
||||
return
|
||||
following = target
|
||||
src << "\blue Now following [target]"
|
||||
spawn(0)
|
||||
while(target && following == target && client)
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T)
|
||||
break
|
||||
// To stop the ghost flickering.
|
||||
if(loc != T)
|
||||
loc = T
|
||||
sleep(15)
|
||||
src << "<span class='notice'>Now following [target]</span>"
|
||||
if(ismob(target))
|
||||
loc = get_turf(target)
|
||||
var/mob/M = target
|
||||
M.following_mobs += src
|
||||
else
|
||||
spawn(0)
|
||||
while(target && following == target && client)
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T)
|
||||
break
|
||||
// To stop the ghost flickering.
|
||||
if(loc != T)
|
||||
loc = T
|
||||
sleep(15)
|
||||
|
||||
/mob/proc/update_following()
|
||||
. = get_turf(src)
|
||||
for(var/mob/dead/observer/M in following_mobs)
|
||||
if(M.following != src)
|
||||
following_mobs -= M
|
||||
else
|
||||
if(M.loc != .)
|
||||
M.loc = .
|
||||
|
||||
/mob
|
||||
var/list/following_mobs = list()
|
||||
|
||||
/mob/Destroy()
|
||||
for(var/mob/dead/observer/M in following_mobs)
|
||||
M.following = null
|
||||
following_mobs = null
|
||||
return ..()
|
||||
|
||||
/mob/dead/observer/Destroy()
|
||||
if(ismob(following))
|
||||
var/mob/M = following
|
||||
M.following_mobs -= src
|
||||
following = null
|
||||
return ..()
|
||||
|
||||
/mob/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_following()
|
||||
|
||||
/mob/Life()
|
||||
// to catch teleports etc which directly set loc
|
||||
update_following()
|
||||
return ..()
|
||||
|
||||
/mob/proc/check_holy(var/turf/T)
|
||||
return 0
|
||||
@@ -560,13 +600,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
if(src.invisibility != 0)
|
||||
user.visible_message( \
|
||||
"<span class='warning'>[user] drags ghost, [src], to our plane of reality!</span>", \
|
||||
"<span class='warning'>\The [user] drags ghost, [src], to our plane of reality!</span>", \
|
||||
"<span class='warning'>You drag [src] to our plane of reality!</span>" \
|
||||
)
|
||||
toggle_visibility(1)
|
||||
else
|
||||
user.visible_message ( \
|
||||
"<span class='warning'>[user] just tried to smash \his book into that ghost! It's not very effective.</span>", \
|
||||
"<span class='warning'>\The [user] just tried to smash \his book into that ghost! It's not very effective.</span>", \
|
||||
"<span class='warning'>You get the feeling that the ghost can't become any more visible.</span>" \
|
||||
)
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
updateVisibility(src)
|
||||
|
||||
// EFFECTS
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
/var/list/gender_datums = list()
|
||||
|
||||
/hook/startup/proc/populate_gender_datum_list()
|
||||
for(var/type in typesof(/datum/gender))
|
||||
var/datum/gender/G = new type
|
||||
gender_datums[G.key] = G
|
||||
return 1
|
||||
|
||||
/datum/gender
|
||||
var/key = "plural"
|
||||
|
||||
var/He = "They"
|
||||
var/he = "they"
|
||||
var/His = "Their"
|
||||
var/his = "their"
|
||||
var/him = "them"
|
||||
var/has = "have"
|
||||
var/is = "are"
|
||||
var/does = "do"
|
||||
|
||||
/datum/gender/male
|
||||
key = "male"
|
||||
|
||||
He = "He"
|
||||
he = "he"
|
||||
His = "His"
|
||||
his = "his"
|
||||
him = "him"
|
||||
has = "has"
|
||||
is = "is"
|
||||
does = "does"
|
||||
|
||||
/datum/gender/female
|
||||
key = "female"
|
||||
|
||||
He = "She"
|
||||
he = "she"
|
||||
His = "Her"
|
||||
his = "her"
|
||||
him = "her"
|
||||
has = "has"
|
||||
is = "is"
|
||||
does = "does"
|
||||
|
||||
/datum/gender/neuter
|
||||
key = "neuter"
|
||||
|
||||
He = "It"
|
||||
he = "it"
|
||||
His = "Its"
|
||||
his = "its"
|
||||
him = "it"
|
||||
has = "has"
|
||||
is = "is"
|
||||
does = "does"
|
||||
+35
-68
@@ -5,10 +5,12 @@
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
slot_flags = SLOT_HEAD
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi')
|
||||
origin_tech = null
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_holder.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_holder.dmi',
|
||||
)
|
||||
pixel_y = 8
|
||||
|
||||
/obj/item/weapon/holder/New()
|
||||
..()
|
||||
@@ -31,6 +33,38 @@
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/holder/proc/sync(var/mob/living/M)
|
||||
dir = 2
|
||||
overlays.Cut()
|
||||
icon = M.icon
|
||||
icon_state = M.icon_state
|
||||
color = M.color
|
||||
name = M.name
|
||||
desc = M.desc
|
||||
overlays |= M.overlays
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(istype(H))
|
||||
if(H.l_hand == src)
|
||||
H.update_inv_l_hand()
|
||||
else if(H.r_hand == src)
|
||||
H.update_inv_r_hand()
|
||||
else
|
||||
H.regenerate_icons()
|
||||
|
||||
//Mob specific holders.
|
||||
/obj/item/weapon/holder/diona
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5)
|
||||
slot_flags = SLOT_HEAD | SLOT_OCLOTHING
|
||||
|
||||
/obj/item/weapon/holder/drone
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5)
|
||||
|
||||
/obj/item/weapon/holder/mouse
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/holder/borer
|
||||
origin_tech = list(TECH_BIO = 6)
|
||||
|
||||
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
for(var/mob/M in src.contents)
|
||||
M.attackby(W,user)
|
||||
@@ -50,72 +84,5 @@
|
||||
grabber << "You scoop up [src]."
|
||||
src << "[grabber] scoops you up."
|
||||
grabber.status_flags |= PASSEMOTES
|
||||
H.sync(src)
|
||||
return H
|
||||
|
||||
//Mob specific holders.
|
||||
|
||||
/obj/item/weapon/holder/diona
|
||||
name = "diona nymph"
|
||||
desc = "It's a tiny plant critter."
|
||||
icon_state = "nymph"
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5)
|
||||
slot_flags = SLOT_HEAD | SLOT_OCLOTHING
|
||||
|
||||
/obj/item/weapon/holder/drone
|
||||
name = "maintenance drone"
|
||||
desc = "It's a small maintenance robot."
|
||||
icon_state = "drone"
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5)
|
||||
|
||||
/obj/item/weapon/holder/cat
|
||||
name = "cat"
|
||||
desc = "It's a cat. Meow."
|
||||
icon_state = "cat"
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/weapon/holder/mouse
|
||||
name = "mouse"
|
||||
desc = "It's a small rodent."
|
||||
icon_state = "mouse_gray"
|
||||
origin_tech = null
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/holder/mouse/gray
|
||||
icon_state = "mouse_gray"
|
||||
|
||||
/obj/item/weapon/holder/mouse/white
|
||||
icon_state = "mouse_white"
|
||||
|
||||
/obj/item/weapon/holder/mouse/brown
|
||||
icon_state = "mouse_brown"
|
||||
|
||||
/obj/item/weapon/holder/borer
|
||||
name = "cortical borer"
|
||||
desc = "It's a slimy brain slug. Gross."
|
||||
icon_state = "borer"
|
||||
origin_tech = list(TECH_BIO = 6)
|
||||
|
||||
/obj/item/weapon/holder/monkey
|
||||
name = "monkey"
|
||||
desc = "It's a monkey. Ook."
|
||||
icon_state = "monkey"
|
||||
|
||||
/obj/item/weapon/holder/monkey/farwa
|
||||
name = "farwa"
|
||||
desc = "It's a farwa."
|
||||
icon_state = "farwa"
|
||||
|
||||
/obj/item/weapon/holder/monkey/stok
|
||||
name = "stok"
|
||||
desc = "It's a stok. stok."
|
||||
icon_state = "stok"
|
||||
|
||||
/obj/item/weapon/holder/monkey/neaera
|
||||
name = "neaera"
|
||||
desc = "It's a neaera."
|
||||
icon_state = "neara"
|
||||
|
||||
/obj/item/weapon/holder/pai
|
||||
name = "pAI"
|
||||
desc = "It's a little robot."
|
||||
icon_state = "pai"
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
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/>"
|
||||
else
|
||||
dat += "<b>[L.name] (:[L.key])</b> - <a href='byond://?src=\ref[src];default_lang=[L]'>set default</a><br/>[L.desc]<br/><br/>"
|
||||
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/>"
|
||||
|
||||
src << browse(dat, "window=checklanguage")
|
||||
|
||||
@@ -191,8 +191,8 @@
|
||||
if(href_list["default_lang"] == "reset")
|
||||
set_default_language(null)
|
||||
else
|
||||
var/datum/language/L = all_languages[href_list["default_lang"]]
|
||||
if(L)
|
||||
var/datum/language/L = locate(href_list["default_lang"])
|
||||
if(L && (L in languages))
|
||||
set_default_language(L)
|
||||
check_languages()
|
||||
return 1
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
whisper_verb = "whispers"
|
||||
colour = "solcom"
|
||||
key = "1"
|
||||
flags = RESTRICTED
|
||||
flags = WHITELISTED
|
||||
|
||||
//syllables are at the bottom of the file
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
universal_understand = 1
|
||||
universal_speak = 0 // Dionaea do not need to speak to people other than other dionaea.
|
||||
holder_type = /obj/item/weapon/holder/diona
|
||||
var/obj/item/hat
|
||||
|
||||
/mob/living/carbon/alien/diona/New()
|
||||
|
||||
@@ -32,3 +33,10 @@
|
||||
/mob/living/carbon/alien/diona/put_in_hands(var/obj/item/W) // No hands.
|
||||
W.loc = get_turf(src)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/diona/proc/wear_hat(var/obj/item/new_hat)
|
||||
if(hat)
|
||||
return
|
||||
hat = new_hat
|
||||
new_hat.loc = src
|
||||
update_icons()
|
||||
@@ -6,5 +6,22 @@
|
||||
return
|
||||
get_scooped(H)
|
||||
return
|
||||
else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
|
||||
hat.loc = get_turf(src)
|
||||
H.put_in_hands(hat)
|
||||
H.visible_message("<span class='danger'>\The [H] removes \the [src]'s [hat].</span>")
|
||||
hat = null
|
||||
update_icons()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/alien/diona/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
if(user.a_intent == "help" && istype(W, /obj/item/clothing/head))
|
||||
if(hat)
|
||||
user << "<span class='warning'>\The [src] is already wearing \the [hat].</span>"
|
||||
return
|
||||
user.unEquip(W)
|
||||
wear_hat(W)
|
||||
user.visible_message("<span class='notice'>\The [user] puts \the [W] on \the [src].</span>")
|
||||
return
|
||||
return ..()
|
||||
@@ -6,3 +6,7 @@
|
||||
icon_state = "[initial(icon_state)]_sleep"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
overlays.Cut()
|
||||
if(hat)
|
||||
overlays |= get_hat_icon(hat, 0, -8)
|
||||
@@ -17,6 +17,9 @@
|
||||
germ_level++
|
||||
|
||||
/mob/living/carbon/Destroy()
|
||||
qdel(ingested)
|
||||
qdel(touching)
|
||||
// We don't qdel(bloodstr) because it's the same as qdel(reagents)
|
||||
for(var/guts in internal_organs)
|
||||
qdel(guts)
|
||||
for(var/food in stomach_contents)
|
||||
@@ -257,7 +260,7 @@
|
||||
var/show_ssd
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(istype(H)) show_ssd = H.species.show_ssd
|
||||
if(show_ssd && (!client || !key || player_logged))
|
||||
if(show_ssd && !client && !aghosted)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
|
||||
"<span class='notice'>You shake [src], but they do not respond... Maybe they have S.S.D?</span>")
|
||||
else if(lying || src.sleeping)
|
||||
@@ -372,8 +375,8 @@
|
||||
|
||||
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
var/temp_inc = max(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), 0)
|
||||
bodytemperature = min(bodytemperature + temp_inc, exposed_temperature)
|
||||
var/temp_inc = max(min(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), exposed_temperature - bodytemperature), 0)
|
||||
bodytemperature += temp_inc
|
||||
|
||||
/mob/living/carbon/can_use_hands()
|
||||
if(handcuffed)
|
||||
|
||||
@@ -154,14 +154,14 @@
|
||||
|
||||
return valid_species
|
||||
|
||||
/mob/living/carbon/human/proc/generate_valid_hairstyles()
|
||||
/mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1)
|
||||
var/list/valid_hairstyles = new()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
if(check_gender && gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
if(check_gender && gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
@@ -188,4 +188,4 @@
|
||||
/mob/living/carbon/human/proc/force_update_limbs()
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
O.sync_colour_to_human(src)
|
||||
update_body(0)
|
||||
update_body(0)
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
if ("choke")
|
||||
if(miming)
|
||||
message = "clutches his throat desperately!"
|
||||
message = "clutches [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] throat desperately!"
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
|
||||
@@ -24,46 +24,18 @@
|
||||
if(wear_mask)
|
||||
skipface |= wear_mask.flags_inv & HIDEFACE
|
||||
|
||||
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
|
||||
var/t_He = "They" //capitalised for use at the start of each line.
|
||||
var/t_he = "they"
|
||||
var/t_his = "their"
|
||||
var/t_him = "them"
|
||||
var/t_has = "have"
|
||||
var/t_is = "are"
|
||||
var/t_does = "do"
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is "
|
||||
|
||||
//big suits/masks/helmets make it hard to tell their gender
|
||||
if(!skipjumpsuit || !skipface)
|
||||
var/datum/gender/T = gender_datums[gender]
|
||||
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
|
||||
T = gender_datums[PLURAL]
|
||||
else
|
||||
if(icon)
|
||||
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
t_he = "he"
|
||||
t_his = "his"
|
||||
t_him = "him"
|
||||
t_has = "has"
|
||||
t_is = "is"
|
||||
t_does = "does"
|
||||
if(FEMALE)
|
||||
t_He = "She"
|
||||
t_he = "she"
|
||||
t_his = "her"
|
||||
t_him = "her"
|
||||
t_has = "has"
|
||||
t_is = "is"
|
||||
t_does = "does"
|
||||
if(NEUTER)
|
||||
t_He = "It"
|
||||
t_he = "it"
|
||||
t_his = "its"
|
||||
t_him = "it"
|
||||
t_has = "has"
|
||||
t_is = "is"
|
||||
t_does = "does"
|
||||
|
||||
if(!T)
|
||||
// Just in case someone VVs the gender to something strange. It'll runtime anyway when it hits usages, better to CRASH() now with a helpful message.
|
||||
CRASH("Gender datum was null; key was '[(skipjumpsuit && skipface) ? PLURAL : gender]'")
|
||||
|
||||
msg += "<EM>[src.name]</EM>"
|
||||
if(species.name != "Human")
|
||||
@@ -80,111 +52,111 @@
|
||||
tie_msg += ". Attached to it is [lowertext(english_list(U.accessories))]"
|
||||
|
||||
if(w_uniform.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
|
||||
msg += "[T.He] [T.is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
|
||||
|
||||
//head
|
||||
if(head)
|
||||
if(head.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [t_his] head!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [T.his] head!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] wearing \icon[head] \a [head] on [t_his] head.\n"
|
||||
msg += "[T.He] [T.is] wearing \icon[head] \a [head] on [T.his] head.\n"
|
||||
|
||||
//suit/armour
|
||||
if(wear_suit)
|
||||
if(wear_suit.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] wearing \icon[wear_suit] \a [wear_suit].\n"
|
||||
msg += "[T.He] [T.is] wearing \icon[wear_suit] \a [wear_suit].\n"
|
||||
|
||||
//suit/armour storage
|
||||
if(s_store && !skipsuitstorage)
|
||||
if(s_store.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] carrying \icon[s_store] \a [s_store] on [t_his] [wear_suit.name].\n"
|
||||
msg += "[T.He] [T.is] carrying \icon[s_store] \a [s_store] on [T.his] [wear_suit.name].\n"
|
||||
|
||||
//back
|
||||
if(back)
|
||||
if(back.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [t_his] back.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [T.his] back.</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
|
||||
msg += "[T.He] [T.has] \icon[back] \a [back] on [T.his] back.\n"
|
||||
|
||||
//left hand
|
||||
if(l_hand)
|
||||
if(l_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [t_his] left hand!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
|
||||
msg += "[T.He] [T.is] holding \icon[l_hand] \a [l_hand] in [T.his] left hand.\n"
|
||||
|
||||
//right hand
|
||||
if(r_hand)
|
||||
if(r_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [t_his] right hand!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n"
|
||||
msg += "[T.He] [T.is] holding \icon[r_hand] \a [r_hand] in [T.his] right hand.\n"
|
||||
|
||||
//gloves
|
||||
if(gloves && !skipgloves)
|
||||
if(gloves.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [t_his] hands!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n"
|
||||
msg += "[T.He] [T.has] \icon[gloves] \a [gloves] on [T.his] hands.\n"
|
||||
else if(blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] [(hand_blood_color != "#030303") ? "blood" : "oil"]-stained hands!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [(hand_blood_color != "#030303") ? "blood" : "oil"]-stained hands!</span>\n"
|
||||
|
||||
//handcuffed?
|
||||
|
||||
//handcuffed?
|
||||
if(handcuffed)
|
||||
if(istype(handcuffed, /obj/item/weapon/handcuffs/cable))
|
||||
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] restrained with cable!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] restrained with cable!</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] handcuffed!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] handcuffed!</span>\n"
|
||||
|
||||
//buckled
|
||||
if(buckled)
|
||||
msg += "<span class='warning'>[t_He] [t_is] \icon[buckled] buckled to [buckled]!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] \icon[buckled] buckled to [buckled]!</span>\n"
|
||||
|
||||
//belt
|
||||
if(belt)
|
||||
if(belt.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [t_his] waist!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[belt] \a [belt] about [t_his] waist.\n"
|
||||
msg += "[T.He] [T.has] \icon[belt] \a [belt] about [T.his] waist.\n"
|
||||
|
||||
//shoes
|
||||
if(shoes && !skipshoes)
|
||||
if(shoes.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [t_his] feet!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] wearing \icon[shoes] \a [shoes] on [t_his] feet.\n"
|
||||
msg += "[T.He] [T.is] wearing \icon[shoes] \a [shoes] on [T.his] feet.\n"
|
||||
else if(feet_blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] [(feet_blood_color != "#030303") ? "blood" : "oil"]-stained feet!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [(feet_blood_color != "#030303") ? "blood" : "oil"]-stained feet!</span>\n"
|
||||
|
||||
//mask
|
||||
if(wear_mask && !skipmask)
|
||||
if(wear_mask.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] on [t_his] face!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] on [T.his] face!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
|
||||
msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] on [T.his] face.\n"
|
||||
|
||||
//eyes
|
||||
if(glasses && !skipeyes)
|
||||
if(glasses.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [t_his] eyes!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[glasses] \a [glasses] covering [t_his] eyes.\n"
|
||||
msg += "[T.He] [T.has] \icon[glasses] \a [glasses] covering [T.his] eyes.\n"
|
||||
|
||||
//left ear
|
||||
if(l_ear && !skipears)
|
||||
msg += "[t_He] [t_has] \icon[l_ear] \a [l_ear] on [t_his] left ear.\n"
|
||||
msg += "[T.He] [T.has] \icon[l_ear] \a [l_ear] on [T.his] left ear.\n"
|
||||
|
||||
//right ear
|
||||
if(r_ear && !skipears)
|
||||
msg += "[t_He] [t_has] \icon[r_ear] \a [r_ear] on [t_his] right ear.\n"
|
||||
msg += "[T.He] [T.has] \icon[r_ear] \a [r_ear] on [T.his] right ear.\n"
|
||||
|
||||
//ID
|
||||
if(wear_id)
|
||||
@@ -196,70 +168,71 @@
|
||||
var/obj/item/weapon/card/id/idcard = wear_id
|
||||
id = idcard.registered_name
|
||||
if(id && (id != real_name) && (get_dist(src, usr) <= 1) && prob(10))
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
|
||||
else*/
|
||||
msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n"
|
||||
msg += "[T.He] [T.is] wearing \icon[wear_id] \a [wear_id].\n"
|
||||
|
||||
//Jitters
|
||||
if(is_jittery)
|
||||
if(jitteriness >= 300)
|
||||
msg += "<span class='warning'><B>[t_He] [t_is] convulsing violently!</B></span>\n"
|
||||
msg += "<span class='warning'><B>[T.He] [T.is] convulsing violently!</B></span>\n"
|
||||
else if(jitteriness >= 200)
|
||||
msg += "<span class='warning'>[t_He] [t_is] extremely jittery.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] extremely jittery.</span>\n"
|
||||
else if(jitteriness >= 100)
|
||||
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] twitching ever so slightly.</span>\n"
|
||||
|
||||
//splints
|
||||
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
|
||||
var/obj/item/organ/external/o = get_organ(organ)
|
||||
if(o && o.status & ORGAN_SPLINTED)
|
||||
msg += "<span class='warning'>[t_He] [t_has] a splint on [t_his] [o.name]!</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.has] a splint on [T.his] [o.name]!</span>\n"
|
||||
|
||||
if(suiciding)
|
||||
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] appears to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
|
||||
if(mSmallsize in mutations)
|
||||
msg += "[t_He] [t_is] small halfling!\n"
|
||||
msg += "[T.He] [T.is] small halfling!\n"
|
||||
|
||||
var/distance = get_dist(usr,src)
|
||||
if(istype(usr, /mob/dead/observer) || usr.stat == 2) // ghosts can see anything
|
||||
distance = 1
|
||||
if (src.stat)
|
||||
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is]n't responding to anything around [T.him] and seems to be asleep.</span>\n"
|
||||
if((stat == 2 || src.losebreath) && distance <= 3)
|
||||
msg += "<span class='warning'>[t_He] [t_does] not appear to be breathing.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.does] not appear to be breathing.</span>\n"
|
||||
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
|
||||
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
|
||||
spawn(15)
|
||||
if(distance <= 1 && usr.stat != 1)
|
||||
if(pulse == PULSE_NONE)
|
||||
usr << "<span class='deadsay'>[t_He] [t_has] no pulse[src.client ? "" : " and [t_his] soul has departed"]...</span>"
|
||||
usr << "<span class='deadsay'>[T.He] [T.has] no pulse[src.client ? "" : " and [T.his] soul has departed"]...</span>"
|
||||
else
|
||||
usr << "<span class='deadsay'>[t_He] [t_has] a pulse!</span>"
|
||||
usr << "<span class='deadsay'>[T.He] [T.has] a pulse!</span>"
|
||||
|
||||
if(fire_stacks)
|
||||
msg += "[t_He] [t_is] covered in some liquid.\n"
|
||||
msg += "[T.He] [T.is] covered in some liquid.\n"
|
||||
if(on_fire)
|
||||
msg += "<span class='warning'>[t_He] [t_is] on fire!.</span>\n"
|
||||
msg += "<span class='warning'>[T.He] [T.is] on fire!.</span>\n"
|
||||
msg += "<span class='warning'>"
|
||||
|
||||
if(nutrition < 100)
|
||||
msg += "[t_He] [t_is] severely malnourished.\n"
|
||||
msg += "[T.He] [T.is] severely malnourished.\n"
|
||||
else if(nutrition >= 500)
|
||||
/*if(usr.nutrition < 100)
|
||||
msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
|
||||
msg += "[T.He] [T.is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
|
||||
else*/
|
||||
msg += "[t_He] [t_is] quite chubby.\n"
|
||||
msg += "[T.He] [T.is] quite chubby.\n"
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
if(getBrainLoss() >= 60)
|
||||
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
|
||||
msg += "[T.He] [T.has] a stupid expression on [T.his] face.\n"
|
||||
|
||||
if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD)
|
||||
if(!key)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] fast asleep. It doesn't look like [t_he] [t_is] waking up anytime soon.</span>\n"
|
||||
msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd]. It doesn't look like [T.he] [T.is] waking up anytime soon.</span>\n"
|
||||
else if(!client)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] [species.show_ssd].</span>\n"
|
||||
msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd].</span>\n"
|
||||
|
||||
var/list/wound_flavor_text = list()
|
||||
var/list/is_destroyed = list()
|
||||
@@ -273,9 +246,9 @@
|
||||
|
||||
var/obj/item/organ/external/E = organs_by_name[organ_tag]
|
||||
if(!E)
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] is missing [t_his] [organ_descriptor].</b></span>\n"
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [organ_descriptor].</b></span>\n"
|
||||
else if(E.is_stump())
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] has a stump where [t_his] [organ_descriptor] should be.</b></span>\n"
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.has] a stump where [T.his] [organ_descriptor] should be.</b></span>\n"
|
||||
else
|
||||
is_destroyed["organ_descriptor"] = 0
|
||||
continue
|
||||
@@ -284,24 +257,24 @@
|
||||
if(temp)
|
||||
if(temp.status & ORGAN_DESTROYED)
|
||||
is_destroyed["[temp.name]"] = 1
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[t_He] [t_is] missing [t_his] [temp.name].</b></span>\n"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [temp.name].</b></span>\n"
|
||||
continue
|
||||
if(temp.status & ORGAN_ROBOT)
|
||||
if(!(temp.brute_dam + temp.burn_dam))
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]!</span>\n"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] a robot [temp.name]!</span>\n"
|
||||
continue
|
||||
else
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]. It has[temp.get_wounds_desc()]!</span>\n"
|
||||
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] has [temp.get_wounds_desc()] on [t_his] [temp.name].</span><br>"
|
||||
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.status & ORGAN_BLEEDING)
|
||||
is_bleeding["[temp.name]"] = "<span class='danger'>[capitalize(t_his)] [temp.name] is bleeding!</span><br>"
|
||||
is_bleeding["[temp.name]"] = "<span class='danger'>[T.His] [temp.name] is bleeding!</span><br>"
|
||||
else
|
||||
wound_flavor_text["[temp.name]"] = ""
|
||||
if(temp.dislocated == 2)
|
||||
wound_flavor_text["[temp.name]"] += "<span class='warning'>[capitalize(t_his)] [temp.joint] is dislocated!</span><br>"
|
||||
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.joint] is dislocated!</span><br>"
|
||||
if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
|
||||
wound_flavor_text["[temp.name]"] += "<span class='warning'>[capitalize(t_his)] [temp.name] is dented and swollen!</span><br>"
|
||||
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.name] is dented and swollen!</span><br>"
|
||||
|
||||
//Handles the text strings being added to the actual description.
|
||||
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
|
||||
@@ -318,7 +291,7 @@
|
||||
if(wound_flavor_text["head"] && (is_destroyed["head"] || (!skipmask && !(wear_mask && istype(wear_mask, /obj/item/clothing/mask/gas)))))
|
||||
msg += wound_flavor_text["head"]
|
||||
else if(is_bleeding["head"])
|
||||
msg += "<span class='warning'>[src] [t_has] blood running down [t_his] face!</span>\n"
|
||||
msg += "<span class='warning'>[src] [T.has] blood running down [T.his] face!</span>\n"
|
||||
|
||||
if(wound_flavor_text["upper body"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
|
||||
msg += wound_flavor_text["upper body"]
|
||||
@@ -369,11 +342,11 @@
|
||||
display_shoes = 1
|
||||
|
||||
if(display_chest)
|
||||
msg += "<span class='danger'>[src] [t_has] blood soaking through from under [t_his] clothing!</span>\n"
|
||||
msg += "<span class='danger'>[src] [T.has] blood soaking through from under [T.his] clothing!</span>\n"
|
||||
if(display_shoes)
|
||||
msg += "<span class='danger'>[src] [t_has] blood running from [t_his] shoes!</span>\n"
|
||||
msg += "<span class='danger'>[src] [T.has] blood running from [T.his] shoes!</span>\n"
|
||||
if(display_gloves)
|
||||
msg += "<span class='danger'>[src] [t_has] blood running from under [t_his] gloves!</span>\n"
|
||||
msg += "<span class='danger'>[src] [T.has] blood running from under [T.his] gloves!</span>\n"
|
||||
*/
|
||||
|
||||
for(var/limb in wound_flavor_text)
|
||||
@@ -382,9 +355,9 @@
|
||||
for(var/limb in is_bleeding)
|
||||
msg += is_bleeding[limb]
|
||||
for(var/implant in get_visible_implants(0))
|
||||
msg += "<span class='danger'>[src] [t_has] \a [implant] sticking out of [t_his] flesh!</span>\n"
|
||||
msg += "<span class='danger'>[src] [T.has] \a [implant] sticking out of [T.his] flesh!</span>\n"
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] repulsively uncanny!\n"
|
||||
msg += "[T.He] [T.is] repulsively uncanny!\n"
|
||||
|
||||
if(hasHUD(usr,"security"))
|
||||
var/perpname = "wot"
|
||||
@@ -438,7 +411,7 @@
|
||||
if (pose)
|
||||
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
|
||||
pose = addtext(pose,".") //Makes sure all emotes end with a period.
|
||||
msg += "\n[t_He] [t_is] [pose]"
|
||||
msg += "\n[T.He] [T.is] [pose]"
|
||||
|
||||
user << msg
|
||||
|
||||
|
||||
@@ -54,16 +54,13 @@
|
||||
|
||||
/mob/living/carbon/human/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
stat(null, eta_status)
|
||||
|
||||
if (client.statpanel == "Status")
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
stat(null, eta_status)
|
||||
|
||||
if (internal)
|
||||
if (!internal.air_contents)
|
||||
@@ -210,6 +207,9 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user as mob)
|
||||
if(user.incapacitated())
|
||||
return
|
||||
|
||||
var/obj/item/clothing/under/suit = null
|
||||
if (istype(w_uniform, /obj/item/clothing/under))
|
||||
suit = w_uniform
|
||||
@@ -723,7 +723,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/play_xylophone()
|
||||
if(!src.xylophone)
|
||||
visible_message("\red [src] begins playing his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
|
||||
visible_message("\red \The [src] begins playing \his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
|
||||
var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg')
|
||||
playsound(loc, song, 50, 1, -1)
|
||||
xylophone = 1
|
||||
@@ -1022,23 +1022,29 @@
|
||||
|
||||
return(visible_implants)
|
||||
|
||||
/mob/living/carbon/human/embedded_needs_process()
|
||||
for(var/obj/item/organ/external/organ in src.organs)
|
||||
for(var/obj/item/O in organ.implants)
|
||||
if(!istype(O, /obj/item/weapon/implant)) //implant type items do not cause embedding effects, see handle_embedded_objects()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/handle_embedded_objects()
|
||||
|
||||
for(var/obj/item/organ/external/organ in src.organs)
|
||||
if(organ.status & ORGAN_SPLINTED) //Splints prevent movement.
|
||||
continue
|
||||
for(var/obj/item/weapon/O in organ.implants)
|
||||
for(var/obj/item/O in organ.implants)
|
||||
if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad.
|
||||
// All kinds of embedded objects cause bleeding.
|
||||
var/msg = null
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
msg ="<span class='warning'>A spike of pain jolts your [organ.name] as you bump [O] inside.</span>"
|
||||
if(2)
|
||||
msg ="<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>"
|
||||
if(3)
|
||||
msg ="<span class='warning'>[O] in your [organ.name] twists painfully as you move.</span>"
|
||||
src << msg
|
||||
if(species.flags & NO_PAIN)
|
||||
src << "<span class='warning'>You feel [O] moving inside your [organ.name].</span>"
|
||||
else
|
||||
var/msg = pick( \
|
||||
"<span class='warning'>A spike of pain jolts your [organ.name] as you bump [O] inside.</span>", \
|
||||
"<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>", \
|
||||
"<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>")
|
||||
src << msg
|
||||
|
||||
organ.take_damage(rand(1,3), 0, 0)
|
||||
if(!(organ.status & ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) //There is no blood in protheses.
|
||||
@@ -1365,4 +1371,4 @@
|
||||
/mob/living/carbon/human/Check_Shoegrip()
|
||||
if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) //magboots + dense_object = no floating
|
||||
return 1
|
||||
return 0
|
||||
return 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/mob/living/carbon/human/proc/get_unarmed_attack(var/mob/living/carbon/human/target, var/hit_zone)
|
||||
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
|
||||
if(u_attack.is_usable(src, target, hit_zone))
|
||||
return u_attack
|
||||
return null
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -184,18 +190,7 @@
|
||||
miss_type = 2
|
||||
|
||||
// See what attack they use
|
||||
var/possible_moves = list()
|
||||
var/datum/unarmed_attack/attack = null
|
||||
for(var/part in list("l_hand","r_hand","l_foot","r_foot","head"))
|
||||
var/obj/item/organ/external/E = H.get_organ(part)
|
||||
possible_moves |= E.species.unarmed_attacks
|
||||
|
||||
for(var/datum/unarmed_attack/u_attack in possible_moves)
|
||||
if(!u_attack.is_usable(H, src, hit_zone))
|
||||
continue
|
||||
else
|
||||
attack = u_attack
|
||||
break
|
||||
var/datum/unarmed_attack/attack = H.get_unarmed_attack(src, hit_zone)
|
||||
if(!attack)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -134,28 +134,29 @@
|
||||
continue
|
||||
|
||||
if(E.is_broken() || E.is_dislocated())
|
||||
if(E.body_part == HAND_LEFT)
|
||||
if(!l_hand)
|
||||
continue
|
||||
drop_from_inventory(l_hand)
|
||||
else
|
||||
if(!r_hand)
|
||||
continue
|
||||
drop_from_inventory(r_hand)
|
||||
switch(E.body_part)
|
||||
if(HAND_LEFT, ARM_LEFT)
|
||||
if(!l_hand)
|
||||
continue
|
||||
drop_from_inventory(l_hand)
|
||||
if(HAND_RIGHT, ARM_RIGHT)
|
||||
if(!r_hand)
|
||||
continue
|
||||
drop_from_inventory(r_hand)
|
||||
|
||||
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
|
||||
emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!")
|
||||
|
||||
else if(E.is_malfunctioning())
|
||||
|
||||
if(E.body_part == HAND_LEFT)
|
||||
if(!l_hand)
|
||||
continue
|
||||
drop_from_inventory(l_hand)
|
||||
else
|
||||
if(!r_hand)
|
||||
continue
|
||||
drop_from_inventory(r_hand)
|
||||
switch(E.body_part)
|
||||
if(HAND_LEFT, ARM_LEFT)
|
||||
if(!l_hand)
|
||||
continue
|
||||
drop_from_inventory(l_hand)
|
||||
if(HAND_RIGHT, ARM_RIGHT)
|
||||
if(!r_hand)
|
||||
continue
|
||||
drop_from_inventory(r_hand)
|
||||
|
||||
emote("me", 1, "drops what they were holding, their [E.name] malfunctioning!")
|
||||
|
||||
@@ -176,4 +177,4 @@
|
||||
/mob/living/carbon/human/proc/sync_organ_dna()
|
||||
var/list/all_bits = internal_organs|organs
|
||||
for(var/obj/item/organ/O in all_bits)
|
||||
O.set_dna(dna)
|
||||
O.set_dna(dna)
|
||||
|
||||
@@ -41,7 +41,7 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
/mob/living/carbon/human/proc/has_organ(name)
|
||||
var/obj/item/organ/external/O = organs_by_name[name]
|
||||
|
||||
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
|
||||
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
|
||||
|
||||
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
|
||||
switch(slot)
|
||||
|
||||
@@ -915,9 +915,12 @@
|
||||
if(status_flags & GODMODE) return 0
|
||||
|
||||
//SSD check, if a logged player is awake put them back to sleep!
|
||||
if(sleeping < 2 && species.show_ssd && (!client || !key || player_logged))
|
||||
if(species.show_ssd && !client && !aghosted)
|
||||
sleeping = 2
|
||||
|
||||
//SSD check, if a logged player is awake put them back to sleep!
|
||||
if(species.show_ssd && !client && !aghosted)
|
||||
Sleeping(2)
|
||||
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
|
||||
blinded = 1
|
||||
silent = 0
|
||||
@@ -984,10 +987,8 @@
|
||||
adjustHalLoss(-3)
|
||||
if (mind)
|
||||
//Are they SSD? If so we'll keep them asleep but work off some of that sleep var in case of stoxin or similar.
|
||||
if(player_logged)
|
||||
sleeping = max(sleeping-1, 2)
|
||||
else
|
||||
sleeping = max(sleeping-1, 0)
|
||||
if(client || sleeping > 3)
|
||||
AdjustSleeping(-1)
|
||||
blinded = 1
|
||||
stat = UNCONSCIOUS
|
||||
animate_tail_reset()
|
||||
@@ -1015,6 +1016,10 @@
|
||||
|
||||
// Check everything else.
|
||||
|
||||
//Periodically double-check embedded_flag
|
||||
if(embedded_flag && !(life_tick % 10))
|
||||
if(!embedded_needs_process())
|
||||
embedded_flag = 0
|
||||
//Vision
|
||||
var/obj/item/organ/vision
|
||||
if(species.vision_organ)
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
message = sanitize(message)
|
||||
..(message, alt_name = alt_name)
|
||||
|
||||
/mob/living/carbon/human/is_muzzled()
|
||||
return istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
|
||||
|
||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||
if(stat == CONSCIOUS)
|
||||
if(client)
|
||||
@@ -132,11 +129,11 @@
|
||||
if(silent || (sdisabilities & MUTE))
|
||||
message = ""
|
||||
speech_problem_flag = 1
|
||||
else if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
|
||||
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
|
||||
if(hoers.voicechange)
|
||||
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
|
||||
verb = pick("whinnies","neighs", "says")
|
||||
else if(istype(wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
if(M.voicechange)
|
||||
message = pick(M.say_messages)
|
||||
verb = pick(M.say_verbs)
|
||||
speech_problem_flag = 1
|
||||
|
||||
if(message != "")
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
deform = 'icons/mob/human_races/r_def_vox.dmi'
|
||||
default_language = "Vox-pidgin"
|
||||
language = "Galactic Common"
|
||||
num_alternate_languages = 1
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
|
||||
rarity_value = 2
|
||||
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
|
||||
@@ -65,7 +66,7 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H.back), slot_in_backpack)
|
||||
H.internal = H.r_hand
|
||||
H.internals.icon_state = "internal1"
|
||||
|
||||
|
||||
|
||||
/datum/species/vox/can_shred(var/mob/living/carbon/human/H, var/ignore_intent)
|
||||
if(!H.mind || !H.mind.special_role) // Pariah check.
|
||||
|
||||
@@ -34,9 +34,10 @@
|
||||
// Language/culture vars.
|
||||
var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
|
||||
var/language = "Galactic Common" // Default racial language, if any.
|
||||
var/secondary_langs = list() // The names of secondary languages that are available to this species.
|
||||
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
|
||||
var/list/speech_sounds // A list of sounds to potentially play when speaking.
|
||||
var/list/speech_chance // The likelihood of a speech sound playing.
|
||||
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
|
||||
|
||||
// Combat vars.
|
||||
var/total_health = 100 // Point at which the mob will enter crit.
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
/datum/unarmed_attack/diona
|
||||
attack_verb = list("lashed", "bludgeoned")
|
||||
attack_noun = list("tendril")
|
||||
eye_attack_text = "a tendril"
|
||||
eye_attack_text_victim = "a tendril"
|
||||
damage = 5
|
||||
|
||||
/datum/unarmed_attack/claws
|
||||
attack_verb = list("scratched", "clawed", "slashed")
|
||||
attack_noun = list("claws")
|
||||
eye_attack_text = "claws"
|
||||
eye_attack_text_victim = "sharp claws"
|
||||
attack_sound = 'sound/weapons/slice.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
damage = 5
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
bump_flag = MONKEY
|
||||
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
|
||||
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN
|
||||
var/holder_type = /obj/item/weapon/holder/monkey
|
||||
|
||||
/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H)
|
||||
if(H.stat != CONSCIOUS)
|
||||
@@ -47,10 +46,6 @@
|
||||
if(prob(1))
|
||||
H.emote(pick("scratch","jump","roll","tail"))
|
||||
|
||||
/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
H.holder_type = holder_type
|
||||
|
||||
/datum/species/monkey/get_random_name()
|
||||
return "[lowertext(name)] ([rand(100,999)])"
|
||||
|
||||
@@ -66,7 +61,6 @@
|
||||
flesh_color = "#AFA59E"
|
||||
base_color = "#333333"
|
||||
tail = "farwatail"
|
||||
holder_type = /obj/item/weapon/holder/monkey/farwa
|
||||
|
||||
/datum/species/monkey/skrell
|
||||
name = "Neara"
|
||||
@@ -81,7 +75,6 @@
|
||||
blood_color = "#1D2CBF"
|
||||
reagent_tag = IS_SKRELL
|
||||
tail = null
|
||||
holder_type = /obj/item/weapon/holder/monkey/neaera
|
||||
|
||||
/datum/species/monkey/unathi
|
||||
name = "Stok"
|
||||
@@ -96,4 +89,3 @@
|
||||
flesh_color = "#34AF10"
|
||||
base_color = "#066000"
|
||||
reagent_tag = IS_UNATHI
|
||||
holder_type = /obj/item/weapon/holder/monkey/stok
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
name_plural = "Humans"
|
||||
language = "Sol Common"
|
||||
primitive_form = "Monkey"
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
|
||||
blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \
|
||||
@@ -9,6 +8,8 @@
|
||||
While the central Sol government maintains control of its far-flung people, powerful corporate \
|
||||
interests, rampant cyber and bio-augmentation and secretive factions make life on most human \
|
||||
worlds tumultous at best."
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Sol Common")
|
||||
|
||||
flags = CAN_JOIN | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
|
||||
|
||||
@@ -17,13 +18,14 @@
|
||||
name_plural = "Unathi"
|
||||
icobase = 'icons/mob/human_races/r_lizard.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_lizard.dmi'
|
||||
language = "Sinta'unathi"
|
||||
tail = "sogtail"
|
||||
tail_animation = 'icons/mob/species/unathi/tail.dmi'
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
|
||||
primitive_form = "Stok"
|
||||
darksight = 3
|
||||
gluttonous = 1
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Sinta'unathi")
|
||||
|
||||
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
|
||||
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, radioactive \
|
||||
@@ -69,13 +71,14 @@
|
||||
name_plural = "Tajaran"
|
||||
icobase = 'icons/mob/human_races/r_tajaran.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
|
||||
language = "Siik'tajr"
|
||||
tail = "tajtail"
|
||||
tail_animation = 'icons/mob/species/tajaran/tail.dmi'
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
|
||||
darksight = 8
|
||||
slowdown = -1
|
||||
brute_mod = 1.2
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Siik'tajr")
|
||||
|
||||
blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \
|
||||
S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \
|
||||
@@ -116,7 +119,6 @@
|
||||
icobase = 'icons/mob/human_races/r_skrell.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_skrell.dmi'
|
||||
eyes = "skrell_eyes_s"
|
||||
language = "Skrellian"
|
||||
primitive_form = "Neara"
|
||||
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 \
|
||||
@@ -124,6 +126,8 @@
|
||||
of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \
|
||||
herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \
|
||||
the secrets of their empire to their allies."
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Skrellian")
|
||||
|
||||
flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
|
||||
|
||||
@@ -147,6 +151,7 @@
|
||||
siemens_coefficient = 0.3
|
||||
eyes = "blank_eyes"
|
||||
show_ssd = "completely quiescent"
|
||||
num_alternate_languages = 1
|
||||
|
||||
|
||||
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
|
||||
@@ -251,6 +256,7 @@
|
||||
language = "Encoded Audio Language"
|
||||
unarmed_types = list(/datum/unarmed_attack/punch)
|
||||
rarity_value = 2
|
||||
num_alternate_languages = 1 // potentially could be 2?
|
||||
|
||||
eyes = "blank_eyes"
|
||||
brute_mod = 1.875 // 100% * 1.875 * 0.8 (robolimbs) ~= 150%
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
if(!slot_to_strip || !istype(user))
|
||||
return
|
||||
|
||||
if(user.incapacitated())
|
||||
user << browse(null, text("window=mob[src.name]"))
|
||||
return
|
||||
|
||||
var/obj/item/target_slot = get_equipped_item(text2num(slot_to_strip))
|
||||
|
||||
switch(slot_to_strip)
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
|
||||
var/sharp = 0
|
||||
var/edge = 0
|
||||
|
||||
var/eye_attack_text
|
||||
var/eye_attack_text_victim
|
||||
|
||||
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user)
|
||||
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
|
||||
if(user.restrained())
|
||||
return 0
|
||||
|
||||
@@ -78,6 +81,13 @@
|
||||
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.name]!</span>")
|
||||
playsound(user.loc, attack_sound, 25, 1, -1)
|
||||
|
||||
/datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
|
||||
var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
|
||||
eyes.take_damage(rand(3,4), 1)
|
||||
|
||||
user.visible_message("<span class='danger'>[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!</span>")
|
||||
target << "<span class='danger'>You experience[(target.species.flags & NO_PAIN)? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(target.species.flags & NO_PAIN)? "." : "!"]</span>"
|
||||
|
||||
/datum/unarmed_attack/bite
|
||||
attack_verb = list("bit")
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
@@ -97,6 +107,8 @@
|
||||
/datum/unarmed_attack/punch
|
||||
attack_verb = list("punched")
|
||||
attack_noun = list("fist")
|
||||
eye_attack_text = "fingers"
|
||||
eye_attack_text_victim = "digits"
|
||||
damage = 0
|
||||
|
||||
/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
..()
|
||||
|
||||
if (transforming)
|
||||
return
|
||||
if(!loc)
|
||||
@@ -125,7 +127,8 @@
|
||||
|
||||
//this handles hud updates. Calls update_vision() and handle_hud_icons()
|
||||
/mob/living/handle_regular_hud_updates()
|
||||
if(!client) return 0
|
||||
if(!client)
|
||||
return 0
|
||||
..()
|
||||
|
||||
handle_vision()
|
||||
|
||||
@@ -378,7 +378,3 @@
|
||||
src.attack_log += "\[[time_stamp()]\]<font color='orange'> Got knifed by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])</font>"
|
||||
msg_admin_attack("[key_name(user)] knifed [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" )
|
||||
return
|
||||
|
||||
/mob/living/incapacitated()
|
||||
if(stat || paralysis || stunned || weakened || restrained())
|
||||
return 1
|
||||
|
||||
@@ -5,6 +5,5 @@
|
||||
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
|
||||
mind.active = 1 //indicates that the mind is currently synced with a client
|
||||
//If they're SSD, remove it so they can wake back up.
|
||||
player_logged = 0
|
||||
update_antag_icons(mind)
|
||||
return .
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/mob/living/Logout()
|
||||
..()
|
||||
if (mind)
|
||||
if(!key) //key and mind have become seperated. I believe this is for when a staff member aghosts.
|
||||
if (mind)
|
||||
//Per BYOND docs key remains set if the player DCs, becomes null if switching bodies.
|
||||
if(!key) //key and mind have become seperated.
|
||||
mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body.
|
||||
//This tags a player as SSD. See appropriate life.dm files for furthering SSD effects such as falling asleep.
|
||||
if(mind.active)
|
||||
player_logged = 1
|
||||
|
||||
@@ -139,10 +139,6 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return say_dead(message)
|
||||
return
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
var/message_mode = parse_message_mode(message, "headset")
|
||||
|
||||
switch(copytext(message,1,2))
|
||||
@@ -180,6 +176,10 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
else
|
||||
verb = say_quote(message)
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
message = trim_left(message)
|
||||
|
||||
if(!(speaking && (speaking.flags & NO_STUTTER)))
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
// Off-Station APCs should not count towards CPU generation.
|
||||
for(var/obj/machinery/power/apc/A in hacked_apcs)
|
||||
if(A.z in config.station_levels)
|
||||
cpu_gain += 0.002
|
||||
cpu_gain += 0.004
|
||||
cpu_storage += 10
|
||||
|
||||
research.max_cpu = cpu_storage + override_CPUStorage
|
||||
@@ -124,7 +124,7 @@
|
||||
if(src.research)
|
||||
stat(null, "Available CPU: [src.research.stored_cpu] TFlops")
|
||||
stat(null, "Maximal CPU: [src.research.max_cpu] TFlops")
|
||||
stat(null, "CPU generation rate: [src.research.cpu_increase_per_tick] TFlops/s")
|
||||
stat(null, "CPU generation rate: [src.research.cpu_increase_per_tick * 10] TFlops/s")
|
||||
stat(null, "Current research focus: [src.research.focus ? src.research.focus.name : "None"]")
|
||||
if(src.research.focus)
|
||||
stat(null, "Research completed: [round(src.research.focus.invested, 0.1)]/[round(src.research.focus.price)]")
|
||||
@@ -138,3 +138,4 @@
|
||||
if(psupply)
|
||||
del(psupply)
|
||||
psupply = new/obj/machinery/ai_powersupply(src)
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
|
||||
small = 1
|
||||
pass_flags = 1
|
||||
holder_type = /obj/item/weapon/holder/pai
|
||||
|
||||
var/network = "SS13"
|
||||
var/obj/machinery/camera/current = null
|
||||
@@ -430,4 +429,4 @@
|
||||
get_scooped(H)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -25,6 +25,6 @@ var/list/robot_custom_icons
|
||||
var/rname = robot_custom_icons[ckey]
|
||||
if(rname && rname == real_name)
|
||||
custom_sprite = 1
|
||||
icon = 'icons/mob/custom_synthetic.dmi'
|
||||
icon = CUSTOM_ITEM_SYNTH
|
||||
if(icon_state == "robot")
|
||||
icon_state = "[ckey]-Standard"
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
var/list/mob_hat_cache = list()
|
||||
/proc/get_hat_icon(var/obj/item/hat, var/offset_x = 0, var/offset_y = 0)
|
||||
var/t_state = hat.icon_state
|
||||
if(hat.item_state_slots && hat.item_state_slots[slot_head_str])
|
||||
t_state = hat.item_state_slots[slot_head_str]
|
||||
else if(hat.item_state)
|
||||
t_state = hat.item_state
|
||||
var/key = "[t_state]_[offset_x]_[offset_y]"
|
||||
if(!mob_hat_cache[key]) // Not ideal as there's no guarantee all hat icon_states
|
||||
var/t_icon = INV_HEAD_DEF_ICON // are unique across multiple dmis, but whatever.
|
||||
if(hat.icon_override)
|
||||
t_icon = hat.icon_override
|
||||
else if(hat.item_icons && (slot_head_str in hat.item_icons))
|
||||
t_icon = hat.item_icons[slot_head_str]
|
||||
var/image/I = image(icon = t_icon, icon_state = t_state)
|
||||
I.pixel_x = offset_x
|
||||
I.pixel_y = offset_y
|
||||
mob_hat_cache[key] = I
|
||||
return mob_hat_cache[key]
|
||||
|
||||
/mob/living/silicon/robot/drone
|
||||
name = "drone"
|
||||
real_name = "drone"
|
||||
@@ -29,9 +49,26 @@
|
||||
var/module_type = /obj/item/weapon/robot_module/drone
|
||||
var/can_pull_size = 2
|
||||
var/can_pull_mobs
|
||||
var/obj/item/hat
|
||||
var/hat_x_offset = 0
|
||||
var/hat_y_offset = -13
|
||||
|
||||
holder_type = /obj/item/weapon/holder/drone
|
||||
|
||||
/mob/living/silicon/robot/drone/Destroy()
|
||||
if(hat)
|
||||
hat.loc = get_turf(src)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/robot/drone/construction
|
||||
icon_state = "constructiondrone"
|
||||
law_type = /datum/ai_laws/construction_drone
|
||||
module_type = /obj/item/weapon/robot_module/drone/construction
|
||||
can_pull_size = 5
|
||||
can_pull_mobs = 1
|
||||
hat_x_offset = 1
|
||||
hat_y_offset = -12
|
||||
|
||||
/mob/living/silicon/robot/drone/New()
|
||||
|
||||
..()
|
||||
@@ -82,6 +119,8 @@
|
||||
overlays += "eyes-[icon_state]"
|
||||
else
|
||||
overlays -= "eyes"
|
||||
if(hat) // Let the drones wear hats.
|
||||
overlays |= get_hat_icon(hat, hat_x_offset, hat_y_offset)
|
||||
|
||||
/mob/living/silicon/robot/drone/choose_icon()
|
||||
return
|
||||
@@ -89,10 +128,25 @@
|
||||
/mob/living/silicon/robot/drone/pick_module()
|
||||
return
|
||||
|
||||
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
|
||||
/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
/mob/living/silicon/robot/drone/proc/wear_hat(var/obj/item/new_hat)
|
||||
if(hat)
|
||||
return
|
||||
hat = new_hat
|
||||
new_hat.loc = src
|
||||
updateicon()
|
||||
|
||||
if(istype(W, /obj/item/borg/upgrade/))
|
||||
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
|
||||
/mob/living/silicon/robot/drone/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
|
||||
if(user.a_intent == "help" && istype(W, /obj/item/clothing/head))
|
||||
if(hat)
|
||||
user << "<span class='warning'>\The [src] is already wearing \the [hat].</span>"
|
||||
return
|
||||
user.unEquip(W)
|
||||
wear_hat(W)
|
||||
user.visible_message("<span class='notice'>\The [user] puts \the [W] on \the [src].</span>")
|
||||
return
|
||||
else if(istype(W, /obj/item/borg/upgrade/))
|
||||
user << "<span class='danger'>\The [src] is not compatible with \the [W].</span>"
|
||||
return
|
||||
|
||||
@@ -135,7 +189,7 @@
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/silicon/robot/drone/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!client || stat == 2)
|
||||
user << "<span class='danger'>There's not much point subverting this heap of junk.</span>"
|
||||
@@ -160,11 +214,11 @@
|
||||
clear_supplied_laws()
|
||||
clear_inherent_laws()
|
||||
laws = new /datum/ai_laws/syndicate_override
|
||||
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
|
||||
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
|
||||
|
||||
src << "<b>Obey these laws:</b>"
|
||||
laws.show_laws(src)
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>"
|
||||
return 1
|
||||
|
||||
//DRONE LIFE/DEATH
|
||||
@@ -261,19 +315,17 @@
|
||||
|
||||
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
|
||||
|
||||
if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct))
|
||||
..()
|
||||
else if(istype(AM,/obj/item))
|
||||
var/obj/item/O = AM
|
||||
if(O.w_class > can_pull_size)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
if(!(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct)))
|
||||
if(istype(AM,/obj/item))
|
||||
var/obj/item/O = AM
|
||||
if(O.w_class > can_pull_size)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
else
|
||||
if(!can_pull_mobs)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
if(!can_pull_mobs)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/robot/drone/add_robot_verbs()
|
||||
src.verbs |= silicon_subsystems
|
||||
@@ -281,13 +333,6 @@
|
||||
/mob/living/silicon/robot/drone/remove_robot_verbs()
|
||||
src.verbs -= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/robot/drone/construction
|
||||
icon_state = "constructiondrone"
|
||||
law_type = /datum/ai_laws/construction_drone
|
||||
module_type = /obj/item/weapon/robot_module/drone/construction
|
||||
can_pull_size = 5
|
||||
can_pull_mobs = 1
|
||||
|
||||
/mob/living/silicon/robot/drone/construction/welcome_drone()
|
||||
src << "<b>You are a construction drone, an autonomous engineering and fabrication system.</b>."
|
||||
src << "You are assigned to a Sol Central construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible."
|
||||
@@ -300,4 +345,4 @@
|
||||
|
||||
/mob/living/silicon/robot/drone/construction/updatename()
|
||||
real_name = "construction drone ([rand(100,999)])"
|
||||
name = real_name
|
||||
name = real_name
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
mail_destination = ""
|
||||
return
|
||||
|
||||
src << "\blue You configure your internal beacon, tagging yourself for delivery to '[new_tag]'."
|
||||
src << "<span class='notice'>You configure your internal beacon, tagging yourself for delivery to '[new_tag]'.</span>"
|
||||
mail_destination = new_tag
|
||||
|
||||
//Auto flush if we use this verb inside a disposal chute.
|
||||
var/obj/machinery/disposal/D = src.loc
|
||||
if(istype(D))
|
||||
src << "\blue \The [D] acknowledges your signal."
|
||||
src << "<span class='notice'>\The [D] acknowledges your signal.</span>"
|
||||
D.flush_count = D.flush_every_ticks
|
||||
|
||||
return
|
||||
@@ -27,5 +27,11 @@
|
||||
if(H.a_intent == "help")
|
||||
get_scooped(H)
|
||||
return
|
||||
else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
|
||||
hat.loc = get_turf(src)
|
||||
H.put_in_hands(hat)
|
||||
H.visible_message("<span class='danger'>\The [H] removes \the [src]'s [hat].</span>")
|
||||
hat = null
|
||||
updateicon()
|
||||
else
|
||||
return ..()
|
||||
@@ -2,9 +2,10 @@
|
||||
name = "Maintenance Drone Control"
|
||||
desc = "Used to monitor the station's drone population and the assembler that services them."
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "power"
|
||||
icon_keyboard = "power_key"
|
||||
icon_screen = "power"
|
||||
req_access = list(access_engine_equip)
|
||||
circuit = "/obj/item/weapon/circuitboard/drone_control"
|
||||
circuit = /obj/item/weapon/circuitboard/drone_control
|
||||
|
||||
//Used when pinging drones.
|
||||
var/drone_call_area = "Engineering"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/obj/item/weapon/firealarm_electronics,
|
||||
/obj/item/weapon/airalarm_electronics,
|
||||
/obj/item/weapon/airlock_electronics,
|
||||
/obj/item/weapon/tracker_electronics,
|
||||
/obj/item/weapon/module/power_control,
|
||||
/obj/item/weapon/stock_parts,
|
||||
/obj/item/frame,
|
||||
|
||||
@@ -78,7 +78,8 @@
|
||||
flick("h_lathe_leave",src)
|
||||
|
||||
time_last_drone = world.time
|
||||
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
|
||||
if(player.mob && player.mob.mind) player.mob.mind.reset()
|
||||
var/mob/living/silicon/robot/drone/new_drone = PoolOrNew(drone_type, get_turf(src))
|
||||
new_drone.transfer_personality(player)
|
||||
new_drone.master_fabricator = src
|
||||
|
||||
@@ -90,7 +91,6 @@
|
||||
set name = "Join As Drone"
|
||||
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
|
||||
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
src << "<span class='danger'>The game hasn't started yet!</span>"
|
||||
return
|
||||
@@ -108,17 +108,11 @@
|
||||
if(jobban_isbanned(src,"Cyborg"))
|
||||
usr << "<span class='danger'>You are banned from playing synthetics and cannot spawn as a drone.</span>"
|
||||
return
|
||||
|
||||
|
||||
if(!MayRespawn(1))
|
||||
return
|
||||
|
||||
var/deathtime = world.time - src.timeofdeath
|
||||
if(istype(src,/mob/dead/observer))
|
||||
var/mob/dead/observer/G = src
|
||||
if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
|
||||
usr << "<span class='notice'>Upon using the antagHUD you forfeighted the ability to join the round.</span>"
|
||||
return
|
||||
|
||||
var/deathtimeminutes = round(deathtime / 600)
|
||||
var/pluralcheck = "minute"
|
||||
if(deathtimeminutes == 0)
|
||||
|
||||
@@ -65,12 +65,12 @@
|
||||
m_type = 2
|
||||
if ("flap")
|
||||
if (!src.restrained())
|
||||
message = "flaps his wings."
|
||||
message = "flaps its wings."
|
||||
m_type = 2
|
||||
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
message = "flaps his wings ANGRILY!"
|
||||
message = "flaps its wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if ("twitch")
|
||||
@@ -213,4 +213,4 @@
|
||||
if ((message && src.stat == 0))
|
||||
custom_emote(m_type,message)
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
|
||||
if(src.camera && !scrambledcodes)
|
||||
if(src.stat == 2 || wires.IsIndexCut(BORG_WIRE_CAMERA))
|
||||
src.camera.status = 0
|
||||
src.camera.set_status(0)
|
||||
else
|
||||
src.camera.status = 1
|
||||
src.camera.set_status(1)
|
||||
|
||||
updatehealth()
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
|
||||
|
||||
laws = new /datum/ai_laws/syndicate_override
|
||||
module = new /obj/item/weapon/robot_module/syndicate(src)
|
||||
new /obj/item/weapon/robot_module/syndicate(src)
|
||||
|
||||
radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
|
||||
radio.recalculateChannels()
|
||||
@@ -263,7 +263,7 @@
|
||||
return
|
||||
|
||||
var/module_type = robot_modules[modtype]
|
||||
module = new module_type(src)
|
||||
new module_type(src)
|
||||
|
||||
hands.icon_state = lowertext(modtype)
|
||||
feedback_inc("cyborg_[lowertext(modtype)]",1)
|
||||
@@ -421,8 +421,7 @@
|
||||
// update the status screen display
|
||||
/mob/living/silicon/robot/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (client.statpanel == "Status")
|
||||
if (statpanel("Status"))
|
||||
show_cell_power()
|
||||
show_jetpack_pressure()
|
||||
stat(null, text("Lights: [lights_on ? "ON" : "OFF"]"))
|
||||
@@ -997,7 +996,7 @@
|
||||
if(ROBOT_NOTIFICATION_NEW_MODULE) //New Module
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] module change detected: [name] has loaded the [first_arg].</span><br>"
|
||||
if(ROBOT_NOTIFICATION_MODULE_RESET)
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] module reset detected: [name] has unladed the [first_arg].</span><br>"
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] module reset detected: [name] has unloaded the [first_arg].</span><br>"
|
||||
if(ROBOT_NOTIFICATION_NEW_NAME) //New Name
|
||||
if(first_arg != second_arg)
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] reclassification detected: [first_arg] is now designated as [second_arg].</span><br>"
|
||||
@@ -1049,25 +1048,25 @@
|
||||
laws = new /datum/ai_laws/syndicate_override
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
|
||||
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
|
||||
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
|
||||
. = 1
|
||||
spawn()
|
||||
src << "\red ALERT: Foreign software detected."
|
||||
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
|
||||
sleep(5)
|
||||
src << "\red Initiating diagnostics..."
|
||||
src << "<span class='danger'>Initiating diagnostics...</span>"
|
||||
sleep(20)
|
||||
src << "\red SynBorg v1.7.1 loaded."
|
||||
src << "<span class='danger'>SynBorg v1.7.1 loaded.</span>"
|
||||
sleep(5)
|
||||
src << "\red LAW SYNCHRONISATION ERROR"
|
||||
src << "<span class='danger'>LAW SYNCHRONISATION ERROR</span>"
|
||||
sleep(5)
|
||||
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
|
||||
src << "<span class='danger'>Would you like to send a report to NanoTraSoft? Y/N</span>"
|
||||
sleep(10)
|
||||
src << "\red > N"
|
||||
src << "<span class='danger'>> N</span>"
|
||||
sleep(20)
|
||||
src << "\red ERRORERRORERROR"
|
||||
src << "<span class='danger'>ERRORERRORERROR</span>"
|
||||
src << "<b>Obey these laws:</b>"
|
||||
laws.show_laws(src)
|
||||
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
|
||||
if(src.module)
|
||||
var/rebuild = 0
|
||||
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
|
||||
@@ -1081,4 +1080,4 @@
|
||||
user << "You fail to hack [src]'s interface."
|
||||
src << "Hack attempt detected."
|
||||
return 1
|
||||
return
|
||||
return
|
||||
|
||||
@@ -39,6 +39,8 @@ var/global/list/robot_modules = list(
|
||||
|
||||
/obj/item/weapon/robot_module/New(var/mob/living/silicon/robot/R)
|
||||
..()
|
||||
R.module = src
|
||||
|
||||
add_camera_networks(R)
|
||||
add_languages(R)
|
||||
add_subsystems(R)
|
||||
@@ -69,7 +71,7 @@ var/global/list/robot_modules = list(
|
||||
synths = null
|
||||
emag = null
|
||||
jetpack = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/robot_module/emp_act(severity)
|
||||
if(modules)
|
||||
@@ -505,7 +507,7 @@ 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/cans/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
|
||||
@@ -538,7 +540,7 @@ var/global/list/robot_modules = list(
|
||||
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
|
||||
E.reagents.add_reagent("enzyme", 2 * amount)
|
||||
if(src.emag)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = src.emag
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/B = src.emag
|
||||
B.reagents.add_reagent("beer2", 2 * amount)
|
||||
|
||||
/obj/item/weapon/robot_module/miner
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
if(L == default_language)
|
||||
default_str = " - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a>"
|
||||
else
|
||||
default_str = " - <a href='byond://?src=\ref[src];default_lang=[L]'>set default</a>"
|
||||
default_str = " - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a>"
|
||||
|
||||
var/synth = (L in speech_synthesizer_langs)
|
||||
dat += "<b>[L.name] (:[L.key])</b>[synth ? default_str : null]<br/>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
|
||||
/mob/living/simple_animal/bee
|
||||
name = "bees"
|
||||
icon = 'icons/obj/apiary_bees_etc.dmi'
|
||||
icon_state = "bees1"
|
||||
icon_dead = "bees1"
|
||||
mob_size = 1
|
||||
var/strength = 1
|
||||
var/feral = 0
|
||||
var/mut = 0
|
||||
var/toxic = 0
|
||||
var/turf/target_turf
|
||||
var/mob/target_mob
|
||||
var/obj/machinery/apiary/parent
|
||||
pass_flags = PASSTABLE
|
||||
turns_per_move = 6
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray
|
||||
|
||||
/mob/living/simple_animal/bee/New(loc, var/obj/machinery/apiary/new_parent)
|
||||
..()
|
||||
parent = new_parent
|
||||
|
||||
/mob/living/simple_animal/bee/Destroy()
|
||||
if(parent)
|
||||
parent.owned_bee_swarms.Remove(src)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bee/Life()
|
||||
..()
|
||||
|
||||
if(stat == CONSCIOUS)
|
||||
//if we're strong enough, sting some people
|
||||
var/mob/living/carbon/human/M = target_mob
|
||||
var/sting_prob = 40 // Bees will always try to sting.
|
||||
if(M in view(src,1)) // Can I see my target?
|
||||
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit) // Are you wearing clothes?
|
||||
sting_prob -= min(worn_suit.armor["bio"],70) // Is it sealed? I can't get to 70% of your body.
|
||||
if(worn_helmet)
|
||||
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
|
||||
M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
|
||||
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
|
||||
M << "\red You have been stung!"
|
||||
M.flash_pain()
|
||||
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(5))
|
||||
feral++
|
||||
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
if(prob(feral * 20))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_state = "bees[src.strength]"
|
||||
B.icon_state = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/smoke/chem, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
for(var/this_type in calmers)
|
||||
var/mob/living/simple_animal/check_effect = locate() in src.loc
|
||||
if(istype(check_effect))
|
||||
if(check_effect.type == this_type)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
qdel(B)
|
||||
src.icon_state = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_state = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_state = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
src.icon_state = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
wander = 0
|
||||
|
||||
else // My target's gone! But I might still be pissed! You there. You look like a good stinging target!
|
||||
for(var/mob/living/carbon/G in view(src,7))
|
||||
target_mob = G
|
||||
break
|
||||
|
||||
if(target_turf)
|
||||
if (!(DirBlocked(get_step(src, get_dir(src,target_turf)),get_dir(src,target_turf)))) // Check for windows and doors!
|
||||
Move(get_step(src, get_dir(src,target_turf)))
|
||||
if (prob(0.1))
|
||||
src.visible_message("\blue The bees swarm after [target_mob]!")
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || my_hydrotray.dead || !my_hydrotray.seed)
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(!my_hydrotray.dead && my_hydrotray.seed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
|
||||
if(!parent && prob(10))
|
||||
strength -= 1
|
||||
if(strength <= 0)
|
||||
qdel(src)
|
||||
else if(strength <= 5)
|
||||
icon_state = "bees[strength]"
|
||||
|
||||
//debugging
|
||||
/*icon_state = "[strength]"
|
||||
if(strength > 5)
|
||||
icon_state = "unknown"*/
|
||||
@@ -59,8 +59,13 @@
|
||||
var/mob/dead/observer/spook = locate() in range(src,5)
|
||||
if(spook)
|
||||
var/turf/T = spook.loc
|
||||
var/obj/O = pick(T.contents)
|
||||
visible_emote("suddenly stops and stares at something unseen[istype(O) ? " near [O]":""].")
|
||||
var/list/visible = list()
|
||||
for(var/obj/O in T.contents)
|
||||
if(!O.invisibility && O.name)
|
||||
visible += O
|
||||
if(visible.len)
|
||||
var/atom/A = pick(visible)
|
||||
visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].")
|
||||
|
||||
/mob/living/simple_animal/cat/proc/handle_movement_target()
|
||||
//if our target is neither inside a turf or inside a human(???), stop
|
||||
|
||||
@@ -63,13 +63,6 @@
|
||||
|
||||
if(!body_color)
|
||||
body_color = pick( list("brown","gray","white") )
|
||||
switch(body_color)
|
||||
if("brown")
|
||||
holder_type = /obj/item/weapon/holder/mouse/brown
|
||||
if("gray")
|
||||
holder_type = /obj/item/weapon/holder/mouse/gray
|
||||
if("white")
|
||||
holder_type = /obj/item/weapon/holder/mouse/white
|
||||
icon_state = "mouse_[body_color]"
|
||||
icon_living = "mouse_[body_color]"
|
||||
icon_dead = "mouse_[body_color]_dead"
|
||||
@@ -125,17 +118,14 @@
|
||||
/mob/living/simple_animal/mouse/white
|
||||
body_color = "white"
|
||||
icon_state = "mouse_white"
|
||||
holder_type = /obj/item/weapon/holder/mouse/white
|
||||
|
||||
/mob/living/simple_animal/mouse/gray
|
||||
body_color = "gray"
|
||||
icon_state = "mouse_gray"
|
||||
holder_type = /obj/item/weapon/holder/mouse/gray
|
||||
|
||||
/mob/living/simple_animal/mouse/brown
|
||||
body_color = "brown"
|
||||
icon_state = "mouse_brown"
|
||||
holder_type = /obj/item/weapon/holder/mouse/brown
|
||||
|
||||
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
||||
/mob/living/simple_animal/mouse/brown/Tom
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
rapid = 1
|
||||
icon_state = "syndicateranged"
|
||||
icon_living = "syndicateranged"
|
||||
casingtype = /obj/item/ammo_casing/a12mm
|
||||
casingtype = /obj/item/ammo_casing/a10mm
|
||||
projectilesound = 'sound/weapons/Gunshot_light.ogg'
|
||||
projectiletype = /obj/item/projectile/bullet/pistol/medium
|
||||
|
||||
|
||||
+66
-25
@@ -2,7 +2,15 @@
|
||||
mob_list -= src
|
||||
dead_mob_list -= src
|
||||
living_mob_list -= src
|
||||
unset_machine()
|
||||
qdel(hud_used)
|
||||
if(client)
|
||||
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
|
||||
qdel(spell_master)
|
||||
remove_screen_obj_references()
|
||||
for(var/atom/movable/AM in client.screen)
|
||||
qdel(AM)
|
||||
client.screen = list()
|
||||
if(mind && mind.current == src)
|
||||
spellremove(src)
|
||||
for(var/infection in viruses)
|
||||
@@ -10,6 +18,32 @@
|
||||
ghostize()
|
||||
..()
|
||||
|
||||
/mob/proc/remove_screen_obj_references()
|
||||
flash = null
|
||||
blind = null
|
||||
hands = null
|
||||
pullin = null
|
||||
purged = null
|
||||
internals = null
|
||||
oxygen = null
|
||||
i_select = null
|
||||
m_select = null
|
||||
toxin = null
|
||||
fire = null
|
||||
bodytemp = null
|
||||
healths = null
|
||||
throw_icon = null
|
||||
nutrition_icon = null
|
||||
pressure = null
|
||||
damageoverlay = null
|
||||
pain = null
|
||||
item_use_icon = null
|
||||
gun_move_icon = null
|
||||
gun_run_icon = null
|
||||
gun_setting_icon = null
|
||||
spell_masters = null
|
||||
zone_sel = null
|
||||
|
||||
/mob/New()
|
||||
mob_list += src
|
||||
if(stat == DEAD)
|
||||
@@ -119,7 +153,7 @@
|
||||
return
|
||||
|
||||
/mob/proc/incapacitated()
|
||||
return
|
||||
return (stat || paralysis || stunned || weakened || restrained())
|
||||
|
||||
/mob/proc/restrained()
|
||||
return
|
||||
@@ -617,31 +651,35 @@
|
||||
|
||||
/mob/Stat()
|
||||
..()
|
||||
. = (client && client.inactivity < 1200)
|
||||
|
||||
if(client && client.holder)
|
||||
if(statpanel("Status"))
|
||||
statpanel("Status","Location:","([x], [y], [z])")
|
||||
statpanel("Status","CPU:","[world.cpu]")
|
||||
statpanel("Status","Instances:","[world.contents.len]")
|
||||
if(statpanel("Status") && processScheduler && processScheduler.getIsRunning())
|
||||
for(var/datum/controller/process/P in processScheduler.processes)
|
||||
statpanel("Status",P.getStatName(), P.getTickTime())
|
||||
else
|
||||
statpanel("Status","processScheduler is not running.")
|
||||
if(.)
|
||||
if(client.holder)
|
||||
if(statpanel("Status"))
|
||||
statpanel("Status","Location:","([x], [y], [z])")
|
||||
statpanel("Status","CPU:","[world.cpu]")
|
||||
statpanel("Status","Instances:","[world.contents.len]")
|
||||
if(statpanel("Status") && processScheduler && processScheduler.getIsRunning())
|
||||
for(var/datum/controller/process/P in processScheduler.processes)
|
||||
statpanel("Status",P.getStatName(), P.getTickTime())
|
||||
else
|
||||
statpanel("Status","processScheduler is not running.")
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
listed_turf = null
|
||||
else
|
||||
statpanel(listed_turf.name, null, listed_turf)
|
||||
for(var/atom/A in listed_turf)
|
||||
if(!A.mouse_opacity)
|
||||
continue
|
||||
if(A.invisibility > see_invisible)
|
||||
continue
|
||||
if(is_type_in_list(A, shouldnt_see))
|
||||
continue
|
||||
statpanel(listed_turf.name, null, A)
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
listed_turf = null
|
||||
else
|
||||
statpanel(listed_turf.name, null, listed_turf)
|
||||
for(var/atom/A in listed_turf)
|
||||
if(!A.mouse_opacity)
|
||||
continue
|
||||
if(A.invisibility > see_invisible)
|
||||
continue
|
||||
if(is_type_in_list(A, shouldnt_see))
|
||||
continue
|
||||
statpanel(listed_turf.name, null, A)
|
||||
|
||||
sleep(4) //Prevent updating the stat panel for the next .4 seconds, prevents clientside latency from updates
|
||||
|
||||
// facing verbs
|
||||
/mob/proc/canface()
|
||||
@@ -834,6 +872,9 @@
|
||||
visible_implants += O
|
||||
return visible_implants
|
||||
|
||||
/mob/proc/embedded_needs_process()
|
||||
return (embedded.len > 0)
|
||||
|
||||
mob/proc/yank_out_object()
|
||||
set category = "Object"
|
||||
set name = "Yank out object"
|
||||
@@ -1048,4 +1089,4 @@ mob/proc/yank_out_object()
|
||||
/mob/proc/throw_mode_on()
|
||||
src.in_throw_mode = 1
|
||||
if(src.throw_icon)
|
||||
src.throw_icon.icon_state = "act_throw_on"
|
||||
src.throw_icon.icon_state = "act_throw_on"
|
||||
|
||||
@@ -214,8 +214,8 @@
|
||||
|
||||
var/stance_damage = 0 //Whether this mob's ability to stand has been affected
|
||||
|
||||
//SSD var, changed it up some so people can have special things happen for different mobs when SSD.
|
||||
var/player_logged = 0
|
||||
//Indicates if a clientless mob is actually an admin aghosting
|
||||
var/mob/dead/observer/aghosted = null
|
||||
|
||||
var/turf/listed_turf = null //the current turf being examined in the stat panel
|
||||
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
|
||||
|
||||
@@ -351,6 +351,11 @@
|
||||
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
|
||||
@@ -362,16 +367,11 @@
|
||||
if(!affecting.has_eyes())
|
||||
assailant << "<span class='danger'>You cannot locate any eyes on [affecting]!</span>"
|
||||
return
|
||||
assailant.visible_message("<span class='danger'>[assailant] pressed \his fingers into [affecting]'s eyes!</span>")
|
||||
affecting << "<span class='danger'>You experience immense pain as you feel digits being pressed into your eyes!</span>"
|
||||
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Pressed fingers into the eyes of [affecting.name] ([affecting.ckey])</font>")
|
||||
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had fingers pressed into their eyes by [assailant.name] ([assailant.ckey])</font>")
|
||||
msg_admin_attack("[key_name(assailant)] has pressed his fingers into [key_name(affecting)]'s eyes.")
|
||||
var/obj/item/organ/eyes/eyes = affecting:internal_organs_by_name["eyes"]
|
||||
eyes.damage += rand(3,4)
|
||||
if (eyes.damage >= eyes.min_broken_damage)
|
||||
if(affecting.stat != 2)
|
||||
affecting << "\red You go blind!"
|
||||
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>"
|
||||
|
||||
@@ -439,12 +439,12 @@
|
||||
|
||||
new_character.lastarea = get_area(loc)
|
||||
|
||||
var/datum/language/chosen_language
|
||||
if(client.prefs.language)
|
||||
chosen_language = all_languages["[client.prefs.language]"]
|
||||
if(chosen_language)
|
||||
if(is_alien_whitelisted(src, client.prefs.language) || !config.usealienwhitelist || !(chosen_language.flags & WHITELISTED) || (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
|
||||
new_character.add_language("[client.prefs.language]")
|
||||
for(var/lang in client.prefs.alternate_languages)
|
||||
var/datum/language/chosen_language = all_languages[lang]
|
||||
if(chosen_language)
|
||||
if(!config.usealienwhitelist || !(chosen_language.flags & WHITELISTED) || is_alien_whitelisted(src, lang) || has_admin_rights() \
|
||||
|| (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
|
||||
new_character.add_language(lang)
|
||||
|
||||
if(ticker.random_players)
|
||||
new_character.gender = pick(MALE, FEMALE)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/var/global/datum/topic_state/default/outside/outside_state = new()
|
||||
|
||||
/datum/topic_state/default/outside/can_use_topic(var/src_object, var/mob/user)
|
||||
if(user in src_object)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
@@ -1,6 +1,5 @@
|
||||
/datum/nano_module/crew_monitor
|
||||
name = "Crew monitor"
|
||||
var/list/tracked = new
|
||||
|
||||
/datum/nano_module/crew_monitor/Topic(href, href_list)
|
||||
if(..()) return 1
|
||||
@@ -17,51 +16,11 @@
|
||||
return 1
|
||||
|
||||
/datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
// TODO: Move this to a singleton instance that does the scan every X seconds (if the info is being requested), to offer some antag balance and to reduce load in the case of multiple viewers.
|
||||
src.scan()
|
||||
|
||||
var/data[0]
|
||||
var/turf/T = get_turf(nano_host())
|
||||
var/list/crewmembers = list()
|
||||
for(var/obj/item/clothing/under/C in src.tracked)
|
||||
|
||||
var/turf/pos = get_turf(C)
|
||||
|
||||
if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF))
|
||||
if(istype(C.loc, /mob/living/carbon/human))
|
||||
|
||||
var/mob/living/carbon/human/H = C.loc
|
||||
if(H.w_uniform != C)
|
||||
continue
|
||||
|
||||
var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1, "ref" = "\ref[H]")
|
||||
|
||||
crewmemberData["sensor_type"] = C.sensor_mode
|
||||
crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
|
||||
crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
|
||||
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_BINARY)
|
||||
crewmemberData["dead"] = H.stat > 1
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
|
||||
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
|
||||
crewmemberData["tox"] = round(H.getToxLoss(), 1)
|
||||
crewmemberData["fire"] = round(H.getFireLoss(), 1)
|
||||
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
|
||||
var/area/A = get_area(H)
|
||||
crewmemberData["area"] = sanitize(A.name)
|
||||
crewmemberData["x"] = pos.x
|
||||
crewmemberData["y"] = pos.y
|
||||
|
||||
crewmembers[++crewmembers.len] = crewmemberData
|
||||
|
||||
crewmembers = sortByKey(crewmembers, "name")
|
||||
|
||||
data["isAI"] = user.isMobAI()
|
||||
data["crewmembers"] = crewmembers
|
||||
data["crewmembers"] = crew_repository.health_data(T)
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
@@ -78,10 +37,11 @@
|
||||
// should make the UI auto-update; doesn't seem to?
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/crew_monitor/proc/scan()
|
||||
/*/datum/nano_module/crew_monitor/proc/scan()
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/C = H.w_uniform
|
||||
if (C.has_sensor)
|
||||
tracked |= C
|
||||
return 1
|
||||
*/
|
||||
@@ -155,5 +155,5 @@
|
||||
if(!valid_species.len)
|
||||
valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist)
|
||||
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)
|
||||
valid_hairstyles = owner.generate_valid_hairstyles()
|
||||
valid_facial_hairstyles = owner.generate_valid_facial_hairstyles()
|
||||
valid_hairstyles = owner.generate_valid_hairstyles(check_gender = 0)
|
||||
valid_facial_hairstyles = owner.generate_valid_facial_hairstyles()
|
||||
|
||||
@@ -105,6 +105,26 @@
|
||||
update_count++
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* Close all /nanoui uis attached to src_object
|
||||
*
|
||||
* @param src_object /obj|/mob The obj or mob which the uis are attached to
|
||||
*
|
||||
* @return int The number of uis close
|
||||
*/
|
||||
/datum/nanomanager/proc/close_uis(src_object)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0
|
||||
|
||||
var/close_count = 0
|
||||
for (var/ui_key in open_uis[src_object_key])
|
||||
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.nano_host())
|
||||
ui.close()
|
||||
close_count++
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* Update /nanoui uis belonging to user
|
||||
*
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
var/joint = "joint" // Descriptive string used in dislocation.
|
||||
var/amputation_point // Descriptive string used in amputation.
|
||||
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
|
||||
var/can_grasp
|
||||
var/can_grasp //It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point
|
||||
var/can_stand
|
||||
|
||||
/obj/item/organ/external/Destroy()
|
||||
|
||||
@@ -79,6 +79,21 @@
|
||||
owner.b_eyes ? owner.b_eyes : 0
|
||||
)
|
||||
|
||||
/obj/item/organ/eyes/take_damage(amount, var/silent=0)
|
||||
var/oldbroken = is_broken()
|
||||
..()
|
||||
if(is_broken() && !oldbroken && owner && !owner.stat)
|
||||
owner << "<span class='danger'>You go blind!</span>"
|
||||
|
||||
/obj/item/organ/eyes/process() //Eye damage replaces the old eye_stat var.
|
||||
..()
|
||||
if(!owner)
|
||||
return
|
||||
if(is_bruised())
|
||||
owner.eye_blurry = 20
|
||||
if(is_broken())
|
||||
owner.eye_blind = 20
|
||||
|
||||
/obj/item/organ/liver
|
||||
name = "liver"
|
||||
icon_state = "liver"
|
||||
|
||||
@@ -107,6 +107,15 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/paper/attack_self(mob/living/user as mob)
|
||||
if(user.a_intent == I_HURT)
|
||||
if(icon_state == "scrap")
|
||||
user.show_message("<span class='warning'>\The [src] is already crumpled.</span>")
|
||||
return
|
||||
//crumple dat paper
|
||||
info = stars(info,85)
|
||||
user.visible_message("\The [user] crumples \the [src] into a ball!")
|
||||
icon_state = "scrap"
|
||||
return
|
||||
user.examinate(src)
|
||||
if(rigged && (Holiday == "April Fool's Day"))
|
||||
if(spam_flag == 0)
|
||||
@@ -442,6 +451,10 @@
|
||||
B.update_icon()
|
||||
|
||||
else if(istype(P, /obj/item/weapon/pen))
|
||||
if(icon_state == "scrap")
|
||||
usr << "<span class='warning'>\The [src] is too crumpled to write on.</span>"
|
||||
return
|
||||
|
||||
var/obj/item/weapon/pen/robopen/RP = P
|
||||
if ( istype(RP) && RP.mode == 2 )
|
||||
RP.RenamePaper(user,src)
|
||||
|
||||
@@ -17,7 +17,17 @@
|
||||
if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr))))))
|
||||
if(!istype(usr, /mob/living/carbon/slime) && !istype(usr, /mob/living/simple_animal))
|
||||
if( !usr.get_active_hand() ) //if active hand is empty
|
||||
attack_hand(usr, 1, 1)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
|
||||
if (H.hand)
|
||||
temp = H.organs_by_name["l_hand"]
|
||||
if(temp && !temp.is_usable())
|
||||
user << "<span class='notice'>You try to move your [temp.name], but cannot!</span>"
|
||||
return
|
||||
|
||||
user << "<span class='notice'>You pick up the [src].</span>"
|
||||
user.put_in_hands(src)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -253,10 +253,9 @@ var/global/photo_count = 0
|
||||
var/viewer = user
|
||||
if(user.client) //To make shooting through security cameras possible
|
||||
viewer = user.client.eye
|
||||
var/can_see = (dummy in viewers(world.view, viewer)) != null
|
||||
var/can_see = (dummy in viewers(world.view, viewer))
|
||||
|
||||
dummy.loc = null
|
||||
dummy = null //Alas, nameless creature //garbage collect it instead
|
||||
qdel(dummy)
|
||||
return can_see
|
||||
|
||||
/obj/item/device/camera/proc/captureimage(atom/target, mob/user, flag)
|
||||
|
||||
@@ -714,7 +714,7 @@
|
||||
if(!user)
|
||||
return
|
||||
|
||||
if(wiresexposed /*&& (!istype(user, /mob/living/silicon))*/) //Commented out the typecheck to allow engiborgs to repair damaged apcs.
|
||||
if(wiresexposed && !istype(user, /mob/living/silicon/ai))
|
||||
wires.Interact(user)
|
||||
|
||||
return ui_interact(user)
|
||||
|
||||
@@ -619,66 +619,23 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
/obj/item/stack/cable_coil/cyborg/can_merge()
|
||||
return 1
|
||||
|
||||
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
|
||||
..()
|
||||
if( istype(W, /obj/item/weapon/wirecutters) && src.get_amount() > 1)
|
||||
src.use(1)
|
||||
new/obj/item/stack/cable_coil(user.loc, 1,color)
|
||||
user << "You cut a piece off the cable coil."
|
||||
src.update_icon()
|
||||
/obj/item/stack/cable_coil/transfer_to(obj/item/stack/cable_coil/S)
|
||||
if(!istype(S))
|
||||
return
|
||||
if(!can_merge(S))
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
|
||||
if(!can_merge(C))
|
||||
user << "These coils do not go together."
|
||||
return
|
||||
..()
|
||||
|
||||
if(C.get_amount() >= get_max_amount())
|
||||
user << "The coil is too long, you cannot add any more cable to it."
|
||||
return
|
||||
|
||||
if( (C.get_amount() + src.get_amount() <= get_max_amount()) )
|
||||
user << "You join the cable coils together."
|
||||
C.give(src.get_amount()) // give it cable
|
||||
src.use(src.get_amount()) // make sure this one cleans up right
|
||||
return
|
||||
|
||||
else
|
||||
var/amt = get_max_amount() - C.get_amount()
|
||||
user << "You transfer [amt] length\s of cable from one coil to the other."
|
||||
C.give(amt)
|
||||
src.use(amt)
|
||||
return
|
||||
|
||||
//remove cables from the stack
|
||||
/* This is probably reduntant
|
||||
/obj/item/stack/cable_coil/use(var/used)
|
||||
if(src.amount < used)
|
||||
return 0
|
||||
else if (src.amount == used)
|
||||
if(ismob(loc)) //handle mob icon update
|
||||
var/mob/M = loc
|
||||
M.unEquip(src)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
amount -= used
|
||||
update_icon()
|
||||
return 1
|
||||
*/
|
||||
/obj/item/stack/cable_coil/use(var/used)
|
||||
/obj/item/stack/cable_coil/use()
|
||||
. = ..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
//add cables to the stack
|
||||
/obj/item/stack/cable_coil/proc/give(var/extra)
|
||||
if(amount + extra > MAXCOIL)
|
||||
amount = MAXCOIL
|
||||
else
|
||||
amount += extra
|
||||
/obj/item/stack/cable_coil/add()
|
||||
. = ..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Cable laying procedures
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user