Merge branch 'master' of https://github.com/PolarisSS13/Polaris into make_ai_great_again

This commit is contained in:
Anewbe
2018-07-21 12:49:19 -05:00
116 changed files with 1379 additions and 299 deletions
+3
View File
@@ -194,6 +194,9 @@
#define O_LIVER "liver"
#define O_KIDNEYS "kidneys"
#define O_APPENDIX "appendix"
#define O_VOICE "voicebox"
// Non-Standard organs
#define O_PLASMA "plasma vessel"
#define O_HIVE "hive node"
#define O_NUTRIENT "nutrient vessel"
+1 -1
View File
@@ -50,7 +50,7 @@
#define LANGUAGE_MINBUS "Minbus"
#define LANGUAGE_EVENT1 "Occursus"
#define LANGUAGE_AKHANI "Akhani"
#define LANGUAGE_SIIK_ALAI "Siik'alai"
#define LANGUAGE_ALAI "Alai"
// Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
+5 -4
View File
@@ -56,13 +56,14 @@ SUBSYSTEM_DEF(planets)
P.planet_floors -= T
else
P.planet_walls -= T
T.vis_contents -= P.weather_holder.visuals
/datum/controller/subsystem/planets/proc/allocateTurfs(var/initial = FALSE)
var/list/currentlist = new_outdoor_turfs
while(currentlist.len)
var/turf/simulated/OT = currentlist[currentlist.len]
currentlist.len--
if(istype(OT) && z_to_planet[OT.z])
if(istype(OT) && OT.outdoors && z_to_planet.len >= OT.z && z_to_planet[OT.z])
var/datum/planet/P = z_to_planet[OT.z]
P.planet_floors |= OT
OT.vis_contents |= P.weather_holder.visuals
@@ -73,7 +74,7 @@ SUBSYSTEM_DEF(planets)
while(currentlist.len)
var/turf/unsimulated/wall/planetary/PW = currentlist[currentlist.len]
currentlist.len--
if(istype(PW) && z_to_planet[PW.z])
if(istype(PW) && z_to_planet.len >= PW.z && z_to_planet[PW.z])
var/datum/planet/P = z_to_planet[PW.z]
P.planet_walls |= PW
if(!initial && MC_TICK_CHECK)
@@ -113,9 +114,9 @@ SUBSYSTEM_DEF(planets)
while(currentrun.len)
var/datum/planet/P = currentrun[currentrun.len]
currentrun.len--
P.process(last_fire)
//Sun light needs changing
if(P.needs_work & PLANET_PROCESS_SUN)
P.needs_work &= ~PLANET_PROCESS_SUN
+2 -4
View File
@@ -84,10 +84,8 @@
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones.
if(robot.module && robot.module.hide_on_manifest)
continue
bot[robot.name] = "[robot.modtype] [robot.braintype]"
if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest))
bot[robot.name] = "[robot.modtype] [robot.braintype]"
if(heads.len > 0)
+1 -1
View File
@@ -144,7 +144,7 @@ var/global/list/PDA_Manifest = list()
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones.
if(robot.module && robot.module.hide_on_manifest)
if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest))
continue
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
+3 -1
View File
@@ -79,7 +79,9 @@
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those without explicit exceptions apply to antagonists.</b>"
var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it.
// var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it.
var/can_hear_aooc = TRUE // If FALSE, the antag can neither speak nor hear AOOC. If TRUE, they can at least hear it.
var/can_speak_aooc = TRUE // If TRUE, the antag can freely spean in AOOC.
/datum/antagonist/New()
..()
+1 -1
View File
@@ -36,7 +36,7 @@
and it otherwise has no bearing on your round.</span>"
player.current.verbs |= /mob/living/proc/write_ambition
if(can_use_aooc)
if(can_speak_aooc)
player.current.client.verbs += /client/proc/aooc
// Handle only adding a mind and not bothering with gear etc.
+2 -1
View File
@@ -25,7 +25,8 @@ var/datum/antagonist/ert/ert
initial_spawn_req = 5
initial_spawn_target = 7
can_use_aooc = FALSE // They're the good guys.
can_hear_aooc = FALSE // They're the good guys.
can_speak_aooc = FALSE // Just in case the above var bugs, or gets touched.
/datum/antagonist/ert/create_default(var/mob/source)
var/mob/living/carbon/human/M = ..()
+1 -1
View File
@@ -24,7 +24,7 @@ var/datum/antagonist/trader/traders
initial_spawn_req = 5
initial_spawn_target = 7
can_use_aooc = FALSE // They're not real antags.
can_speak_aooc = FALSE // They're not real antags.
/datum/antagonist/trader/create_default(var/mob/source)
var/mob/living/carbon/human/M = ..()
+1 -3
View File
@@ -17,7 +17,7 @@ var/datum/antagonist/renegade/renegades
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those without explicit exceptions apply to antagonists.</b>"
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_use_aooc = FALSE
can_speak_aooc = FALSE // They aren't 'true' antags, but they still need to hear blanket antag instructions
hard_cap = 8
hard_cap_round = 12
@@ -61,8 +61,6 @@ var/datum/antagonist/renegade/renegades
list(/obj/item/weapon/gun/projectile/luger,/obj/item/weapon/gun/projectile/luger/brown)
)
can_use_aooc = FALSE // They aren't 'true' antags.
/datum/antagonist/renegade/New()
..()
renegades = src
+1 -1
View File
@@ -15,4 +15,4 @@ var/datum/antagonist/thug/thugs
Think through your actions and make the roleplay immersive! <b>Please remember all \
rules aside from those with explicit exceptions apply to antagonists.</b>"
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_use_aooc = FALSE
can_speak_aooc = FALSE
+1 -1
View File
@@ -5,7 +5,7 @@ var/datum/antagonist/traitor/traitors
id = MODE_TRAITOR
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_use_aooc = FALSE
can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly.
/datum/antagonist/traitor/auto
id = MODE_AUTOTRAITOR
@@ -5,12 +5,14 @@
var/list/languages
var/identifying_gender
var/list/flavour_texts
var/list/genMods
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour)
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour, var/list/newGenMods)
..()
name = newName
dna = newDNA
speciesName = newSpecies
languages = newLanguages
identifying_gender = newIdentifying_Gender
flavour_texts = newFlavour ? newFlavour.Copy() : null
flavour_texts = newFlavour ? newFlavour.Copy() : null
genMods = newGenMods ? newGenMods.Copy() : null
@@ -78,7 +78,7 @@
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts)
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts, T.modifiers)
absorbDNA(newDNA)
if(T.mind && T.mind.changeling)
@@ -48,6 +48,13 @@
src.UpdateAppearance()
domutcheck(src, null)
changeling_update_languages(changeling.absorbed_languages)
if(chosen_dna.genMods)
var/mob/living/carbon/human/self = src
for(var/datum/modifier/mod in self.modifiers)
self.modifiers.Remove(mod.type)
for(var/datum/modifier/mod in chosen_dna.genMods)
self.modifiers.Add(mod.type)
src.verbs -= /mob/proc/changeling_transform
spawn(10)
+2
View File
@@ -149,5 +149,7 @@
feedback_set_details("religion_book","[new_book_style]")
return 1
/* If you uncomment this, every time the mob preview updates it makes a new PDA. It seems to work just fine and display without it, so why this exists, haven't a clue. -Hawk
/datum/job/chaplain/equip_preview(var/mob/living/carbon/human/H, var/alt_title)
return equip(H, alt_title, FALSE)
*/
+2 -1
View File
@@ -378,7 +378,8 @@ var/global/datum/controller/occupations/job_master
H.amend_exploitable(G.path)
if(G.slot == "implant")
H.implant_loadout(G)
var/obj/item/weapon/implant/I = G.spawn_item(H)
I.implant_loadout(H)
continue
if(G.slot && !(G.slot in custom_equip_slots))
+1
View File
@@ -31,6 +31,7 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
return
/obj/effect/portal/New()
..() // Necessary for the list boilerplate to work
spawn(300)
qdel(src)
return
+2 -1
View File
@@ -52,8 +52,9 @@
/obj/structure/largecrate/animal/crashedshuttle
name = "SCP"
/obj/structure/largecrate/animal/crashedshuttle/initialize()
starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble)
starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble, /obj/item/weapon/deadringer)
name = pick("Spicy Crust Pizzeria", "Soap and Care Products", "Sally's Computer Parts", "Steve's Chocolate Pastries", "Smith & Christian's Plastics","Standard Containers & Packaging Co.", "Sanitary Chemical Purgation (LTD)")
name += " delivery crate"
return ..()
@@ -199,3 +199,9 @@
throw_range = 20
flags = 0
no_variants = FALSE
/obj/item/stack/tile/roofing
name = "roofing"
singular_name = "roofing"
desc = "A section of roofing material. You can use it to repair the ceiling, or expand it."
icon_state = "techtile_grid"
+1 -1
View File
@@ -153,7 +153,7 @@
return 0
if(build_turf)
T.ChangeTurf(build_turf)
T.ChangeTurf(build_turf, preserve_outdoors = TRUE)
else if(build_other)
new build_other(T)
else
+6 -3
View File
@@ -167,21 +167,24 @@
if(!istype(M))
return 0
if (user.a_intent == I_HELP)
return ..()
if(target_name != M.name)
target_name = M.name
src.wdata = list()
src.chemtraces = list()
src.timeofdeath = null
user << "<span class='notice'>A new patient has been registered. Purging data for previous patient.</span>"
to_chat(user, "<span class='notice'>A new patient has been registered. Purging data for previous patient.</span>")
src.timeofdeath = M.timeofdeath
var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting)
if(!S)
usr << "<span class='warning'>You can't scan this body part.</span>"
to_chat(user, "<span class='warning'>You can't scan this body part.</span>")
return
if(!S.open)
usr << "<span class='warning'>You have to cut [S] open first!</span>"
to_chat(user, "<span class='warning'>You have to cut [S] open first!</span>")
return
M.visible_message("<span class='notice'>\The [user] scans the wounds on [M]'s [S.name] with [src]</span>")
@@ -21,12 +21,26 @@
/obj/item/weapon/implant/proc/activate()
return
// What does the implant do upon injection?
// return 0 if the implant fails (ex. Revhead and loyalty implant.)
// return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
/obj/item/weapon/implant/proc/implanted(var/mob/source)
// Moves the implant where it needs to go, and tells it if there's more to be done in post_implant
/obj/item/weapon/implant/proc/handle_implant(var/mob/source, var/target_zone = BP_TORSO)
. = TRUE
imp_in = source
implanted = TRUE
if(ishuman(source))
var/mob/living/carbon/human/H = source
var/obj/item/organ/external/affected = H.get_organ(target_zone)
if(affected)
affected.implants += src
part = affected
if(part)
forceMove(part)
else
forceMove(source)
listening_objects |= src
return 1
// Takes place after handle_implant, if that returns TRUE
/obj/item/weapon/implant/proc/post_implant(var/mob/source)
/obj/item/weapon/implant/proc/get_data()
return "No information available"
@@ -49,6 +63,12 @@
icon_state = "implant_melted"
malfunction = MALFUNCTION_PERMANENT
/obj/item/weapon/implant/proc/implant_loadout(var/mob/living/carbon/human/H)
if(H)
var/obj/item/organ/external/affected = H.organs_by_name[BP_HEAD]
if(handle_implant(H, affected))
post_implant(H)
/obj/item/weapon/implant/Destroy()
if(part)
part.implants.Remove(src)
@@ -69,6 +89,11 @@
else
..()
//////////////////////////////
// Tracking Implant
//////////////////////////////
GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking)
/obj/item/weapon/implant/tracking
@@ -84,9 +109,8 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking
id = rand(1, 1000)
..()
/obj/item/weapon/implant/tracking/implanted(var/mob/source)
/obj/item/weapon/implant/tracking/post_implant(var/mob/source)
processing_objects.Add(src)
return 1
/obj/item/weapon/implant/tracking/Destroy()
processing_objects.Remove(src)
@@ -142,7 +166,9 @@ Implant Specifics:<BR>"}
spawn(delay)
malfunction--
//////////////////////////////
// Death Explosive Implant
//////////////////////////////
/obj/item/weapon/implant/dexplosive
name = "explosive"
desc = "And boom goes the weasel."
@@ -177,7 +203,9 @@ Implant Specifics:<BR>"}
/obj/item/weapon/implant/dexplosive/islegal()
return 0
//BS12 Explosive
//////////////////////////////
// Explosive Implant
//////////////////////////////
/obj/item/weapon/implant/explosive
name = "explosive implant"
desc = "A military grade micro bio-explosive. Highly dangerous."
@@ -249,15 +277,13 @@ Implant Specifics:<BR>"}
if(t)
t.hotspot_expose(3500,125)
/obj/item/weapon/implant/explosive/implanted(mob/source as mob)
/obj/item/weapon/implant/explosive/post_implant(mob/source as mob)
elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
phrase = input("Choose activation phrase:") as text
var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
phrase = replace_characters(phrase, replacechars)
usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate.", 0, 0)
usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/explosive/emp_act(severity)
if (malfunction)
@@ -311,6 +337,9 @@ Implant Specifics:<BR>"}
explosion(get_turf(imp_in), -1, -1, 1, 3)
qdel(src)
//////////////////////////////
// Chemical Implant
//////////////////////////////
GLOBAL_LIST_BOILERPLATE(all_chem_implants, /obj/item/weapon/implant/chem)
/obj/item/weapon/implant/chem
@@ -336,20 +365,17 @@ Can only be loaded while still in its original case.<BR>
the implant may become unstable and either pre-maturely inject the subject or simply break."}
return dat
/obj/item/weapon/implant/chem/New()
..()
var/datum/reagents/R = new/datum/reagents(50)
reagents = R
R.my_atom = src
/obj/item/weapon/implant/chem/trigger(emote, source as mob)
if(emote == "deathgasp")
src.activate(src.reagents.total_volume)
return
/obj/item/weapon/implant/chem/activate(var/cause)
if((!cause) || (!src.imp_in)) return 0
var/mob/living/carbon/R = src.imp_in
@@ -384,6 +410,9 @@ the implant may become unstable and either pre-maturely inject the subject or si
spawn(20)
malfunction--
//////////////////////////////
// Loyalty Implant
//////////////////////////////
/obj/item/weapon/implant/loyalty
name = "loyalty implant"
desc = "Makes you loyal or such."
@@ -401,20 +430,24 @@ the implant may become unstable and either pre-maturely inject the subject or si
<b>Integrity:</b> Implant will last so long as the nanobots are inside the bloodstream."}
return dat
/obj/item/weapon/implant/loyalty/implanted(mob/M)
if(!istype(M, /mob/living/carbon/human)) return 0
/obj/item/weapon/implant/loyalty/handle_implant(mob/M, target_zone = BP_TORSO)
. = ..(M, target_zone)
if(!istype(M, /mob/living/carbon/human))
. = FALSE
var/mob/living/carbon/human/H = M
var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [using_map.company_name] try to invade your mind!")
return 0
else
clear_antag_roles(H.mind, 1)
H << "<span class='notice'>You feel a surge of loyalty towards [using_map.company_name].</span>"
return 1
. = FALSE
/obj/item/weapon/implant/loyalty/post_implant(mob/M)
var/mob/living/carbon/human/H = M
clear_antag_roles(H.mind, 1)
to_chat(H, "<span class='notice'>You feel a surge of loyalty towards [using_map.company_name].</span>")
//////////////////////////////
// Adrenaline Implant
//////////////////////////////
/obj/item/weapon/implant/adrenalin
name = "adrenalin"
desc = "Removes all stuns and knockdowns."
@@ -445,14 +478,13 @@ the implant may become unstable and either pre-maturely inject the subject or si
return
/obj/item/weapon/implant/adrenalin/implanted(mob/source)
/obj/item/weapon/implant/adrenalin/post_implant(mob/source)
source.mind.store_memory("A implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate.", 0, 0)
source << "The implanted freedom implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate."
listening_objects |= src
return 1
//////////////////////////////
// Death Alarm Implant
//////////////////////////////
/obj/item/weapon/implant/death_alarm
name = "death alarm implant"
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
@@ -529,11 +561,13 @@ the implant may become unstable and either pre-maturely inject the subject or si
spawn(20)
malfunction--
/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob)
/obj/item/weapon/implant/death_alarm/post_implant(mob/source as mob)
mobname = source.real_name
processing_objects.Add(src)
return 1
//////////////////////////////
// Compressed Matter Implant
//////////////////////////////
/obj/item/weapon/implant/compressed
name = "compressed matter implant"
desc = "Based on compressed matter technology, can store a single item."
@@ -571,13 +605,12 @@ the implant may become unstable and either pre-maturely inject the subject or si
scanned.loc = t
qdel(src)
/obj/item/weapon/implant/compressed/implanted(mob/source as mob)
/obj/item/weapon/implant/compressed/post_implant(mob/source)
src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
if (source.mind)
source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/compressed/islegal()
return 0
@@ -135,10 +135,9 @@
for (var/mob/O in viewers(M, null))
O.show_message("<span class='warning'>\The [M] has been implanted by \the [src].</span>", 1)
if(imp.implanted(M))
imp.loc = M
imp.imp_in = M
imp.implanted = 1
if(imp.handle_implant(M, BP_TORSO))
imp.post_implant(M)
implant_list -= imp
break
return
@@ -56,16 +56,11 @@
add_attack_logs(user,M,"Implanted with [imp.name] using [name]")
if(src.imp.implanted(M))
src.imp.loc = M
src.imp.imp_in = M
src.imp.implanted = 1
if (ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
affected.implants += src.imp
imp.part = affected
if(imp.handle_implant(M))
imp.post_implant(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
src.imp = null
@@ -16,7 +16,9 @@
/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
if (src.uses < 1) return 0
if (src.uses < 1)
return 0
if (emote == src.activation_emote)
src.uses--
source << "You feel a faint click."
@@ -46,13 +48,9 @@
W.layer = initial(W.layer)
return
/obj/item/weapon/implant/freedom/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/freedom/post_implant(mob/source)
source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/freedom/get_data()
var/dat = {"
@@ -4,7 +4,26 @@
/obj/item/weapon/implant/language
name = "GalCom language implant"
desc = "An implant allowing someone to speak and hear the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them."
desc = "An implant allowing someone to speak the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with producing sounds, not understanding them."
var/list/languages = list(LANGUAGE_GALCOM) // List of languages that this assists with
/obj/item/weapon/implant/language/post_implant(mob/M) // Amends the mob's voice organ, then deletes itself
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/voicebox/V = locate() in H.internal_organs
if(V)
var/list/need_amend = list() // If they've already got all the languages they need, then they don't need this implant to do anything
for(var/L in languages)
if(L in V.will_assist_languages)
continue
else
need_amend |= L
if(LAZYLEN(need_amend))
if(V.robotic < ORGAN_ASSISTED)
V.mechassist()
for(var/L in need_amend)
V.add_assistable_langs(L)
qdel_null(src)
/obj/item/weapon/implant/language/get_data()
var/dat = {"
@@ -14,16 +33,19 @@
<b>Important Notes:</b> Affects hearing and speech.<BR>
<HR>
<b>Implant Details:</b><BR>
<b>Function:</b> Allows a being otherwise incapable to both hear the frequencies Galactic Common is generally spoken at, as well as to produce the phonemes of the language.<BR>
<b>Function:</b> Allows a being otherwise incapable of speaking Galactic Common to produce the phonemes of the language.<BR>
<b>Special Features:</b> None.<BR>
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
return dat
// EAL Implant
/obj/item/weapon/implant/language/eal
name = "EAL language implant"
desc = "An implant allowing an organic to both hear and speak Encoded Audio Language accurately. Only helps with hearing and producing sounds, not understanding them."
desc = "An implant allowing an organic to speak Encoded Audio Language passably. Only helps with producing sounds, not understanding them."
languages = list(LANGUAGE_EAL)
/obj/item/weapon/implant/language/get_data()
/obj/item/weapon/implant/language/eal/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Vey-Med L-2 Encoded Audio Language Implant<BR>
@@ -31,7 +53,25 @@
<b>Important Notes:</b> Affects hearing and speech.<BR>
<HR>
<b>Implant Details:</b><BR>
<b>Function:</b> Allows an organic to accurately process and speak Encoded Audio Language.<BR>
<b>Function:</b> Allows an organic to accurately speak Encoded Audio Language.<BR>
<b>Special Features:</b> None.<BR>
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
return dat
/obj/item/weapon/implant/language/skrellian
name = "Skrellian language implant"
desc = "An implant allowing someone to speak the range of frequencies used in Skrellian, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them."
languages = list(LANGUAGE_SKRELLIAN)
/obj/item/weapon/implant/language/skrellian/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Vey-Med L-1 Galactic Common Implant<BR>
<b>Life:</b> 5 years<BR>
<b>Important Notes:</b> Affects hearing and speech.<BR>
<HR>
<b>Implant Details:</b><BR>
<b>Function:</b> Allows a being otherwise incapable of speaking Skrellian to produce the phonemes of the language.<BR>
<b>Special Features:</b> None.<BR>
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
return dat
@@ -11,15 +11,13 @@
..()
return
/obj/item/weapon/implant/uplink/implanted(mob/source)
/obj/item/weapon/implant/uplink/post_implant(mob/source)
listening_objects |= src
activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
listening_objects |= src
return 1
/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob)
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
hidden_uplink.check_trigger(source, emote, activation_emote)
return
return
+1
View File
@@ -16,6 +16,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/weapon/mop)
/obj/item/weapon/mop/New()
create_reagents(30)
..()
/obj/item/weapon/mop/afterattack(atom/A, mob/user, proximity)
if(!proximity) return
@@ -4,6 +4,9 @@
icon = 'icons/policetape.dmi'
icon_state = "tape"
w_class = ITEMSIZE_SMALL
toolspeed = 3 //You can use it in surgery. It's stupid, but you can.
var/turf/start
var/turf/end
var/tape_type = /obj/item/tape
@@ -86,7 +86,6 @@
/obj/item/weapon/weldingtool,
/obj/item/weapon/crowbar,
/obj/item/weapon/wirecutters,
/obj/item/device/t_scanner
)
/obj/item/weapon/storage/belt/utility/chief
+4
View File
@@ -5,8 +5,12 @@
icon_state = "taperoll"
w_class = ITEMSIZE_TINY
toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed.
/obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user)
if(istype(H))
if(user.a_intent == I_HELP)
return
var/can_place = 0
if(istype(user, /mob/living/silicon/robot))
can_place = 1
+1
View File
@@ -20,6 +20,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
/obj/structure/janitorialcart/New()
create_reagents(300)
..()
/obj/structure/janitorialcart/examine(mob/user)
+11 -8
View File
@@ -12,6 +12,7 @@
nitrogen = MOLES_N2STANDARD
var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
var/can_dirty = TRUE // If false, tile never gets dirty
var/dirt = 0
// This is not great.
@@ -65,12 +66,13 @@
tracks.AddTracks(bloodDNA,comingdir,goingdir,bloodcolor)
/turf/simulated/proc/update_dirt()
dirt = min(dirt+1, 101)
var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, src)
if (dirt > 50)
if (!dirtoverlay)
dirtoverlay = new/obj/effect/decal/cleanable/dirt(src)
dirtoverlay.alpha = min((dirt - 50) * 5, 255)
if(can_dirty)
dirt = min(dirt+1, 101)
var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, src)
if (dirt > 50)
if (!dirtoverlay)
dirtoverlay = new/obj/effect/decal/cleanable/dirt(src)
dirtoverlay.alpha = min((dirt - 50) * 5, 255)
/turf/simulated/Entered(atom/A, atom/OL)
if(movement_disabled && usr.ckey != movement_disabled_exception)
@@ -82,8 +84,9 @@
if(M.lying)
return ..()
// Dirt overlays.
update_dirt()
if(M.dirties_floor())
// Dirt overlays.
update_dirt()
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
@@ -9,6 +9,50 @@
attack_tile(C, L) // Be on help intent if you want to decon something.
return
if(istype(C, /obj/item/stack/tile/roofing))
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
var/turf/T = GetAbove(src)
var/obj/item/stack/tile/roofing/R = C
// Patch holes in the ceiling
if(T)
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
// Must be build adjacent to an existing floor/wall, no floating floors
var/list/cardinalTurfs = list() // Up a Z level
for(var/dir in cardinal)
var/turf/B = get_step(T, dir)
if(B)
cardinalTurfs += B
var/turf/simulated/A = locate(/turf/simulated/floor) in cardinalTurfs
if(!A)
A = locate(/turf/simulated/wall) in cardinalTurfs
if(!A)
to_chat(user, "<span class='warning'>There's nothing to attach the ceiling to!</span>")
return
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
T.ReplaceWithLattice()
T.ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] patches a hole in the ceiling.</span>", "<span class='notice'>You patch a hole in the ceiling.</span>")
expended_tile = TRUE
else
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
return
// Create a ceiling to shield from the weather
if(src.outdoors)
for(var/dir in cardinal)
var/turf/A = get_step(src, dir)
if(A && !A.outdoors)
if(expended_tile || R.use(1))
make_indoors()
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] roofs a tile, shielding it from the elements.</span>", "<span class='notice'>You roof this tile, shielding it from the elements.</span>")
break
return
if(flooring)
if(istype(C, /obj/item/weapon))
try_deconstruct_tile(C, user)
+61 -32
View File
@@ -84,16 +84,16 @@
if(rotting)
if(reinf_material)
user << "<span class='danger'>\The [reinf_material.display_name] feels porous and crumbly.</span>"
to_chat(user, "<span class='danger'>\The [reinf_material.display_name] feels porous and crumbly.</span>")
else
user << "<span class='danger'>\The [material.display_name] crumbles under your touch!</span>"
to_chat(user, "<span class='danger'>\The [material.display_name] crumbles under your touch!</span>")
dismantle_wall()
return 1
if(..()) return 1
if(!can_open)
user << "<span class='notice'>You push the wall, but nothing happens.</span>"
to_chat(user, "<span class='notice'>You push the wall, but nothing happens.</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 25, 1)
else
toggle_open(user)
@@ -138,28 +138,57 @@
user.setClickCooldown(user.get_attack_speed(W))
if (!user.)
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
//get the user's location
if(!istype(user.loc, /turf)) return //can't do this stuff whilst inside objects and such
if(!istype(user.loc, /turf))
return //can't do this stuff whilst inside objects and such
if(W)
radiate()
if(is_hot(W))
burn(is_hot(W))
if(istype(W, /obj/item/stack/tile/roofing))
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
var/turf/T = GetAbove(src)
var/obj/item/stack/tile/roofing/R = W
// Place plating over a wall
if(T)
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
T.ReplaceWithLattice()
T.ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] patches a hole in the ceiling.</span>", "<span class='notice'>You patch a hole in the ceiling.</span>")
expended_tile = TRUE
else
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
return
// Create a ceiling to shield from the weather
if(outdoors)
if(expended_tile || R.use(1)) // Don't need to check adjacent turfs for a wall, we're building on one
make_indoors()
if(!expended_tile) // Would've already played a sound
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] roofs \the [src], shielding it from the elements.</span>", "<span class='notice'>You roof \the [src] tile, shielding it from the elements.</span>")
return
if(locate(/obj/effect/overlay/wallrot) in src)
if(istype(W, /obj/item/weapon/weldingtool) )
var/obj/item/weapon/weldingtool/WT = W
if( WT.remove_fuel(0,user) )
user << "<span class='notice'>You burn away the fungi with \the [WT].</span>"
to_chat(user, "<span class='notice'>You burn away the fungi with \the [WT].</span>")
playsound(src, WT.usesound, 10, 1)
for(var/obj/effect/overlay/wallrot/WR in src)
qdel(WR)
return
else if(!is_sharp(W) && W.force >= 10 || W.force >= 20)
user << "<span class='notice'>\The [src] crumbles away under the force of your [W.name].</span>"
to_chat(user, "<span class='notice'>\The [src] crumbles away under the force of your [W.name].</span>")
src.dismantle_wall(1)
return
@@ -179,7 +208,7 @@
var/obj/item/weapon/melee/energy/blade/EB = W
EB.spark_system.start()
user << "<span class='notice'>You slash \the [src] with \the [EB]; the thermite ignites!</span>"
to_chat(user, "<span class='notice'>You slash \the [src] with \the [EB]; the thermite ignites!</span>")
playsound(src, "sparks", 50, 1)
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
@@ -196,13 +225,13 @@
return
if(WT.remove_fuel(0,user))
user << "<span class='notice'>You start repairing the damage to [src].</span>"
to_chat(user, "<span class='notice'>You start repairing the damage to [src].</span>")
playsound(src.loc, WT.usesound, 100, 1)
if(do_after(user, max(5, damage / 5) * WT.toolspeed) && WT && WT.isOn())
user << "<span class='notice'>You finish repairing the damage to [src].</span>"
to_chat(user, "<span class='notice'>You finish repairing the damage to [src].</span>")
take_damage(-damage)
else
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
user.update_examine_panel(src)
return
@@ -219,7 +248,7 @@
if(!WT.isOn())
return
if(!WT.remove_fuel(0,user))
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
dismantle_verb = "cutting"
dismantle_sound = W.usesound
@@ -236,7 +265,7 @@
if(dismantle_verb)
user << "<span class='notice'>You begin [dismantle_verb] through the outer plating.</span>"
to_chat(user, "<span class='notice'>You begin [dismantle_verb] through the outer plating.</span>")
if(dismantle_sound)
playsound(src, dismantle_sound, 100, 1)
@@ -246,7 +275,7 @@
if(!do_after(user,cut_delay * W.toolspeed))
return
user << "<span class='notice'>You remove the outer plating.</span>"
to_chat(user, "<span class='notice'>You remove the outer plating.</span>")
dismantle_wall()
user.visible_message("<span class='warning'>The wall was torn open by [user]!</span>")
return
@@ -259,24 +288,24 @@
playsound(src, W.usesound, 100, 1)
construction_stage = 5
user.update_examine_panel(src)
user << "<span class='notice'>You cut through the outer grille.</span>"
to_chat(user, "<span class='notice'>You cut through the outer grille.</span>")
update_icon()
return
if(5)
if (istype(W, /obj/item/weapon/screwdriver))
user << "<span class='notice'>You begin removing the support lines.</span>"
to_chat(user, "<span class='notice'>You begin removing the support lines.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 5)
return
construction_stage = 4
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You unscrew the support lines.</span>"
to_chat(user, "<span class='notice'>You unscrew the support lines.</span>")
return
else if (istype(W, /obj/item/weapon/wirecutters))
construction_stage = 6
user.update_examine_panel(src)
user << "<span class='notice'>You mend the outer grille.</span>"
to_chat(user, "<span class='notice'>You mend the outer grille.</span>")
playsound(src, W.usesound, 100, 1)
update_icon()
return
@@ -289,51 +318,51 @@
if(WT.remove_fuel(0,user))
cut_cover=1
else
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter))
cut_cover = 1
if(cut_cover)
user << "<span class='notice'>You begin slicing through the metal cover.</span>"
to_chat(user, "<span class='notice'>You begin slicing through the metal cover.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user, 60 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4)
return
construction_stage = 3
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You press firmly on the cover, dislodging it.</span>"
to_chat(user, "<span class='notice'>You press firmly on the cover, dislodging it.</span>")
return
else if (istype(W, /obj/item/weapon/screwdriver))
user << "<span class='notice'>You begin screwing down the support lines.</span>"
to_chat(user, "<span class='notice'>You begin screwing down the support lines.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4)
return
construction_stage = 5
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You screw down the support lines.</span>"
to_chat(user, "<span class='notice'>You screw down the support lines.</span>")
return
if(3)
if (istype(W, /obj/item/weapon/crowbar))
user << "<span class='notice'>You struggle to pry off the cover.</span>"
to_chat(user, "<span class='notice'>You struggle to pry off the cover.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 3)
return
construction_stage = 2
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You pry off the cover.</span>"
to_chat(user, "<span class='notice'>You pry off the cover.</span>")
return
if(2)
if (istype(W, /obj/item/weapon/wrench))
user << "<span class='notice'>You start loosening the anchoring bolts which secure the support rods to their frame.</span>"
to_chat(user, "<span class='notice'>You start loosening the anchoring bolts which secure the support rods to their frame.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 2)
return
construction_stage = 1
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>You remove the bolts anchoring the support rods.</span>"
to_chat(user, "<span class='notice'>You remove the bolts anchoring the support rods.</span>")
return
if(1)
var/cut_cover
@@ -342,28 +371,28 @@
if( WT.remove_fuel(0,user) )
cut_cover=1
else
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
cut_cover = 1
if(cut_cover)
user << "<span class='notice'>You begin slicing through the support rods.</span>"
to_chat(user, "<span class='notice'>You begin slicing through the support rods.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,70 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 1)
return
construction_stage = 0
user.update_examine_panel(src)
update_icon()
user << "<span class='notice'>The slice through the support rods.</span>"
to_chat(user, "<span class='notice'>The slice through the support rods.</span>")
return
if(0)
if(istype(W, /obj/item/weapon/crowbar))
user << "<span class='notice'>You struggle to pry off the outer sheath.</span>"
to_chat(user, "<span class='notice'>You struggle to pry off the outer sheath.</span>")
playsound(src, W.usesound, 100, 1)
if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || !user || !W || !T )
return
if(user.loc == T && user.get_active_hand() == W )
user << "<span class='notice'>You pry off the outer sheath.</span>"
to_chat(user, "<span class='notice'>You pry off the outer sheath.</span>")
dismantle_wall()
return
+1
View File
@@ -19,6 +19,7 @@
..() // To get the edges.
icon_state = water_state
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
underlays.Cut() // To clear the old underlay, so the list doesn't expand infinitely
underlays.Add(floorbed_sprite)
update_icon_edge()
+31 -5
View File
@@ -33,18 +33,18 @@
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
if (istype(C, /obj/item/stack/rods))
if(istype(C, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = C
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
to_chat(user, "<span class='notice'>Constructing support lattice ...</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ReplaceWithLattice()
return
if (istype(C, /obj/item/stack/tile/floor))
if(istype(C, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = C
@@ -56,7 +56,33 @@
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
to_chat(user, "<span class='warning'>The plating is going to need some support.</span>")
if(istype(C, /obj/item/stack/tile/roofing))
var/turf/T = GetAbove(src)
var/obj/item/stack/tile/roofing/R = C
// Patch holes in the ceiling
if(T)
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
// Must be build adjacent to an existing floor/wall, no floating floors
var/turf/simulated/A = locate(/turf/simulated/floor) in T.CardinalTurfs()
if(!A)
A = locate(/turf/simulated/wall) in T.CardinalTurfs()
if(!A)
to_chat(user, "<span class='warning'>There's nothing to attach the ceiling to!</span>")
return
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
T.ReplaceWithLattice()
T.ChangeTurf(/turf/simulated/floor)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] expands the ceiling.</span>", "<span class='notice'>You expand the ceiling.</span>")
else
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
return
// Space shouldn't have weather of the sort planets with atmospheres do.
// If that's changed, then you'll want to swipe the rest of the roofing code from code/game/turfs/simulated/floor_attackby.dm
return
@@ -64,7 +90,7 @@
/turf/space/Entered(atom/movable/A as mob|obj)
if(movement_disabled)
usr << "<span class='warning'>Movement is admin-disabled.</span>" //This is to identify lag problems
to_chat(usr, "<span class='warning'>Movement is admin-disabled.</span>") //This is to identify lag problems
return
..()
if ((!(A) || src != A.loc)) return
+5 -1
View File
@@ -22,7 +22,7 @@
below.update_icon() // To add or remove the 'ceiling-less' overlay.
//Creates a new turf
/turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0)
/turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0, var/preserve_outdoors = FALSE)
if (!N)
return
@@ -38,6 +38,7 @@
var/old_affecting_lights = affecting_lights
var/old_lighting_overlay = lighting_overlay
var/old_corners = corners
var/old_outdoors = outdoors
//world << "Replacing [src.type] with [N]"
@@ -106,3 +107,6 @@
lighting_build_overlay()
else
lighting_clear_overlay()
if(preserve_outdoors)
outdoors = old_outdoors
+2 -2
View File
@@ -12,7 +12,7 @@
else if(is_antag && !is_admin) // Is an antag, and not an admin, meaning we need to check if their antag type allows AOOC.
var/datum/antagonist/A = get_antag_data(usr.mind.special_role)
if(!A || !A.can_use_aooc)
if(!A || !A.can_speak_aooc || !A.can_hear_aooc)
to_chat(usr, "<span class='warning'>Sorry, but your antagonist type is not allowed to speak in AOOC.</span>")
return
@@ -36,7 +36,7 @@
var/datum/antagonist/A = null
if(M.mind) // Observers don't have minds, but they should still see AOOC.
A = get_antag_data(M.mind.special_role)
if((M.mind && M.mind.special_role && A && A.can_use_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
if((M.mind && M.mind.special_role && A && A.can_hear_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
to_chat(M, "<span class='ooc'><span class='aooc'>[create_text_tag("aooc", "Antag-OOC:", M.client)] <EM>[player_display]:</EM> <span class='message'>[msg]</span></span></span>")
log_aooc(msg,src)
+184
View File
@@ -0,0 +1,184 @@
/obj/item/weapon/deadringer
name = "silver pocket watch"
desc = "A fancy silver-plated digital pocket watch. Looks expensive."
icon = 'icons/obj/deadringer.dmi'
icon_state = "deadringer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_ID | SLOT_BELT | SLOT_TIE
origin_tech = list(TECH_ILLEGAL = 3)
var/activated = 0
var/timer = 0
var/bruteloss_prev = 999999
var/fireloss_prev = 999999
var/mob/living/carbon/human/corpse = null
var/mob/living/carbon/human/watchowner = null
/obj/item/weapon/deadringer/New()
..()
processing_objects |= src
/obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch
uncloak()
processing_objects -= src
..()
/obj/item/weapon/deadringer/dropped()
if(timer > 20)
uncloak()
watchowner = null
return
/obj/item/weapon/deadringer/attack_self(var/mob/living/user as mob)
var/mob/living/H = src.loc
if (!istype(H, /mob/living/carbon/human))
to_chat(H,"<font color='blue'>You have no clue what to do with this thing.</font>")
return
if(!activated)
if(timer == 0)
to_chat(H, "<font color='blue'>You press a small button on [src]'s side. It starts to hum quietly.</font>")
bruteloss_prev = H.getBruteLoss()
fireloss_prev = H.getFireLoss()
activated = 1
return
else
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It buzzes a little.</font>")
return
if(activated)
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It stops humming.</font>")
activated = 0
return
/obj/item/weapon/deadringer/process()
if(activated)
if (ismob(src.loc))
var/mob/living/carbon/human/H = src.loc
watchowner = H
if(H.getBruteLoss() > bruteloss_prev || H.getFireLoss() > fireloss_prev)
deathprevent()
activated = 0
if(watchowner.isSynthetic())
to_chat(watchowner, "<font color='blue'>You fade into nothingness! [src]'s screen blinks, being unable to copy your synthetic body!</font>")
else
to_chat(watchowner, "<font color='blue'>You fade into nothingness, leaving behind a fake body!</font>")
icon_state = "deadringer_cd"
timer = 50
return
if(timer > 0)
timer--
if(timer == 20)
uncloak()
if(corpse)
new /obj/effect/effect/smoke/chem(corpse.loc)
qdel(corpse)
if(timer == 0)
icon_state = "deadringer"
return
/obj/item/weapon/deadringer/proc/deathprevent()
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
watchowner.emote("deathgasp")
watchowner.invisibility = 85
watchowner.alpha = 127
makeacorpse(watchowner)
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
return
/obj/item/weapon/deadringer/proc/uncloak()
if(watchowner)
watchowner.invisibility = 0
watchowner.alpha = 255
playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1)
return
/obj/item/weapon/deadringer/proc/makeacorpse(var/mob/living/carbon/human/H)
if(H.isSynthetic())
return
corpse = new /mob/living/carbon/human(H.loc)
corpse.setDNA(H.dna.Clone())
corpse.death(1) //Kills the new mob
var/obj/item/clothing/temp = null
if(H.get_equipped_item(slot_w_uniform))
corpse.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon/changeling(corpse), slot_w_uniform)
temp = corpse.get_equipped_item(slot_w_uniform)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_w_uniform)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_wear_suit))
corpse.equip_to_slot_or_del(new /obj/item/clothing/suit/chameleon/changeling(corpse), slot_wear_suit)
temp = corpse.get_equipped_item(slot_wear_suit)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_suit)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_shoes))
corpse.equip_to_slot_or_del(new /obj/item/clothing/shoes/chameleon/changeling(corpse), slot_shoes)
temp = corpse.get_equipped_item(slot_shoes)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_shoes)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_gloves))
corpse.equip_to_slot_or_del(new /obj/item/clothing/gloves/chameleon/changeling(corpse), slot_gloves)
temp = corpse.get_equipped_item(slot_gloves)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_gloves)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_l_ear))
temp = H.get_equipped_item(slot_l_ear)
corpse.equip_to_slot_or_del(new temp.type(corpse), slot_l_ear)
temp = corpse.get_equipped_item(slot_l_ear)
temp.canremove = 0
if(H.get_equipped_item(slot_glasses))
corpse.equip_to_slot_or_del(new /obj/item/clothing/glasses/chameleon/changeling(corpse), slot_glasses)
temp = corpse.get_equipped_item(slot_glasses)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_glasses)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_wear_mask))
corpse.equip_to_slot_or_del(new /obj/item/clothing/mask/chameleon/changeling(corpse), slot_wear_mask)
temp = corpse.get_equipped_item(slot_wear_mask)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_mask)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_head))
corpse.equip_to_slot_or_del(new /obj/item/clothing/head/chameleon/changeling(corpse), slot_head)
temp = corpse.get_equipped_item(slot_head)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_head)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_belt))
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/chameleon/changeling(corpse), slot_belt)
temp = corpse.get_equipped_item(slot_belt)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_belt)
temp.disguise(c_type.type)
temp.canremove = 0
if(H.get_equipped_item(slot_back))
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chameleon/changeling(corpse), slot_back)
temp = corpse.get_equipped_item(slot_back)
var/obj/item/clothing/c_type = H.get_equipped_item(slot_back)
temp.disguise(c_type.type)
temp.canremove = 0
corpse.identifying_gender = H.identifying_gender
corpse.flavor_texts = H.flavor_texts.Copy()
corpse.real_name = H.real_name
corpse.name = H.name
corpse.set_species(corpse.dna.species)
corpse.change_hair(H.h_style)
corpse.change_facial_hair(H.f_style)
corpse.change_hair_color(H.r_hair, H.g_hair, H.b_hair)
corpse.change_facial_hair_color(H.r_facial, H.g_facial, H.b_facial)
corpse.change_skin_color(H.r_skin, H.g_skin, H.b_skin)
corpse.adjustFireLoss(H.getFireLoss())
corpse.adjustBruteLoss(H.getBruteLoss())
corpse.UpdateAppearance()
corpse.regenerate_icons()
for(var/obj/item/organ/internal/I in corpse.internal_organs)
var/obj/item/organ/internal/G = I
G.Destroy()
return
+3 -4
View File
@@ -250,9 +250,8 @@
return
/obj/effect/beam/i_beam/Destroy()
. = ..()
if(master.first == src)
master.first = null
if(next)
qdel(next)
next = null
..()
if(next && !next.gc_destroyed)
qdel_null(next)
@@ -71,8 +71,8 @@ datum/preferences/proc/set_biological_gender(var/gender)
. += "<b>Nickname:</b> "
. += "<a href='?src=\ref[src];nickname=1'><b>[pref.nickname]</b></a>"
. += "<br>"
. += "<b>Biological Gender:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Gender Identity:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
. += "<b>Biological Sex:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
. += "<b>Pronouns:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
. += "<b>Age:</b> <a href='?src=\ref[src];age=1'>[pref.age]</a><br>"
. += "<b>Spawn Point</b>: <a href='?src=\ref[src];spawnpoint=1'>[pref.spawnpoint]</a><br>"
if(config.allow_Metadata)
@@ -111,13 +111,13 @@ datum/preferences/proc/set_biological_gender(var/gender)
return TOPIC_NOACTION
else if(href_list["bio_gender"])
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
var/new_gender = input(user, "Choose your character's biological sex:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
if(new_gender && CanUseTopic(user))
pref.set_biological_gender(new_gender)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["id_gender"])
var/new_gender = input(user, "Choose your character's identifying gender:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
var/new_gender = input(user, "Choose your character's pronouns:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
if(new_gender && CanUseTopic(user))
pref.identifying_gender = new_gender
return TOPIC_REFRESH
@@ -158,4 +158,4 @@ datum/preferences/proc/set_biological_gender(var/gender)
return possible_genders
possible_genders = possible_genders.Copy()
possible_genders |= NEUTER
return possible_genders
return possible_genders
@@ -36,6 +36,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["synth_red"] >> pref.r_synth
S["synth_green"] >> pref.g_synth
S["synth_blue"] >> pref.b_synth
S["synth_markings"] >> pref.synth_markings
pref.preview_icon = null
S["bgstate"] >> pref.bgstate
@@ -65,6 +66,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["synth_red"] << pref.r_synth
S["synth_green"] << pref.g_synth
S["synth_blue"] << pref.b_synth
S["synth_markings"] << pref.synth_markings
S["bgstate"] << pref.bgstate
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
@@ -120,6 +122,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
character.r_synth = pref.r_synth
character.g_synth = pref.g_synth
character.b_synth = pref.b_synth
character.synth_markings = pref.synth_markings
// Destroy/cyborgize organs and limbs.
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
@@ -305,6 +308,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<br>"
. += "<br>"
. += "<b>Allow Synth markings:</b> <a href='?src=\ref[src];synth_markings=1'><b>[pref.synth_markings ? "Yes" : "No"]</b></a><br>"
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
if(pref.synth_color)
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><tr><td>__</td></tr></table></font> "
@@ -702,6 +706,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.b_synth = hex2num(copytext(new_color, 6, 8))
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth_markings"])
pref.synth_markings = !pref.synth_markings
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["cycle_bg"])
pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options)
return TOPIC_REFRESH_UPDATE_PREVIEW
@@ -241,6 +241,46 @@ datum/gear/suit/duster
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
allowed_roles = list("Head of Personnel")
/datum/gear/suit/roles/poncho/cloak/cargo
display_name = "cloak, cargo"
path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo
allowed_roles = list("Cargo Technician","Quartermaster")
/datum/gear/suit/roles/poncho/cloak/mining
display_name = "cloak, cargo"
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
allowed_roles = list("Quartermaster","Shaft Miner")
/datum/gear/suit/roles/poncho/cloak/security
display_name = "cloak, security"
path = /obj/item/clothing/accessory/poncho/roles/cloak/security
allowed_roles = list("Head of Security","Detective","Warden","Security Officer")
/datum/gear/suit/roles/poncho/cloak/service
display_name = "cloak, service"
path = /obj/item/clothing/accessory/poncho/roles/cloak/service
allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian")
/datum/gear/suit/roles/poncho/cloak/engineer
display_name = "cloak, engineer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/engineer
allowed_roles = list("Chief Engineer","Station Engineer")
/datum/gear/suit/roles/poncho/cloak/atmos
display_name = "cloak, atmos"
path = /obj/item/clothing/accessory/poncho/roles/cloak/atmos
allowed_roles = list("Chief Engineer","Atmospheric Technician")
/datum/gear/suit/roles/poncho/cloak/research
display_name = "cloak, science"
path = /obj/item/clothing/accessory/poncho/roles/cloak/research
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist")
/datum/gear/suit/roles/poncho/cloak/medical
display_name = "cloak, medical"
path = /obj/item/clothing/accessory/poncho/roles/cloak/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe
@@ -114,12 +114,6 @@
path = /obj/item/weapon/cell/device
/datum/gear/utility/implant
exploitable = 1
/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL.
display_name = "implant, language, EAL"
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
exploitable = 1
@@ -127,8 +121,20 @@
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 10
slot = "implant"
exploitable = 1
/datum/gear/utility/implant/language
cost = 2
exploitable = 0
/datum/gear/utility/implant/language/eal
display_name = "vocal synthesizer, EAL"
description = "A surgically implanted vocal synthesizer which allows the owner to speak EAL, if they know it."
path = /obj/item/weapon/implant/language/eal
/datum/gear/utility/implant/language/skrellian
display_name = "vocal synthesizer, Skrellian"
description = "A surgically implanted vocal synthesizer which allows the owner to speak Common Skrellian, if they know it."
path = /obj/item/weapon/implant/language/skrellian
/datum/gear/utility/pen
display_name = "Fountain Pen"
+1
View File
@@ -60,6 +60,7 @@ datum/preferences
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
var/synth_markings = 0 //Enable/disable markings on synth parts.
//Some faction information.
var/home_system = "Unset" //System of birth.
@@ -128,6 +128,7 @@
/obj/item/clothing/suit/syndicatefake
name = "red space suit replica"
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "syndicate"
desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
w_class = ITEMSIZE_NORMAL
@@ -121,8 +121,8 @@
* Cloak
*/
/obj/item/clothing/accessory/poncho/roles/cloak
name = "brown cloak"
desc = "An elaborate brown cloak."
name = "quartermaster's cloak"
desc = "An elaborate brown and gold cloak."
icon_state = "qmcloak"
item_state = "qmcloak"
body_parts_covered = null
@@ -169,6 +169,54 @@
icon_state = "capcloak"
item_state = "capcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/cargo
name = "brown cloak"
desc = "A simple brown and black cloak."
icon_state = "cargocloak"
item_state = "cargocloak"
/obj/item/clothing/accessory/poncho/roles/cloak/mining
name = "trimmed purple cloak"
desc = "A trimmed purple and brown cloak."
icon_state = "miningcloak"
item_state = "miningcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/security
name = "red cloak"
desc = "A simple red and black cloak."
icon_state = "seccloak"
item_state = "seccloak"
/obj/item/clothing/accessory/poncho/roles/cloak/service
name = "green cloak"
desc = "A simple green and blue cloak."
icon_state = "servicecloak"
item_state = "servicecloak"
/obj/item/clothing/accessory/poncho/roles/cloak/engineer
name = "gold cloak"
desc = "A simple gold and brown cloak."
icon_state = "engicloak"
item_state = "engicloak"
/obj/item/clothing/accessory/poncho/roles/cloak/atmos
name = "yellow cloak"
desc = "A trimmed yellow and blue cloak."
icon_state = "atmoscloak"
item_state = "atmoscloak"
/obj/item/clothing/accessory/poncho/roles/cloak/research
name = "purple cloak"
desc = "A simple purple and white cloak."
icon_state = "scicloak"
item_state = "scicloak"
/obj/item/clothing/accessory/poncho/roles/cloak/medical
name = "blue cloak"
desc = "A simple blue and white cloak."
icon_state = "medcloak"
item_state = "medcloak"
/obj/item/clothing/accessory/hawaii
name = "flower-pattern shirt"
desc = "You probably need some welder googles to look at this."
@@ -162,13 +162,16 @@
return 1
var/cost = 1
if(isnull(current_category))
current_category = recipe_list[1]
if(ispath(build_type, /obj/item/device/electronic_assembly))
var/obj/item/device/electronic_assembly/E = build_type
cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4)
else if(ispath(build_type, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/IC = build_type
cost = initial(IC.w_class)
else
var/obj/item/I = build_type
cost = initial(I.w_class)
if(!(locate(build_type) in recipe_list[current_category]))
return
if(metal - cost < 0)
@@ -198,4 +201,4 @@
name = "integrated circuit printer upgrade disk - circuit cloner"
desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
icon_state = "upgrade_disk_clone"
origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6)
origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6)
@@ -53,6 +53,7 @@
recipes += new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0)
recipes += new/datum/stack_recipe("regular floor tile", /obj/item/stack/tile/floor, 1, 4, 20)
recipes += new/datum/stack_recipe("roofing tile", /obj/item/stack/tile/roofing, 3, 4, 20)
recipes += new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60)
recipes += new/datum/stack_recipe("frame", /obj/item/frame, 5, time = 25, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1)
+6
View File
@@ -168,6 +168,12 @@ var/list/mining_overlay_cache = list()
if(istype(get_step(src, direction), /turf/space) && !istype(get_step(src, direction), /turf/space/cracked_asteroid))
add_overlay(get_cached_border("asteroid_edge",direction,icon,"asteroid_edges", 0))
//Or any time
else
var/turf/T = get_step(src, direction)
if(istype(T) && T.density)
add_overlay(get_cached_border("rock_side",direction,'icons/turf/walls.dmi',"rock_side"))
if(overlay_detail)
add_overlay('icons/turf/flooring/decals.dmi',overlay_detail)
+1 -1
View File
@@ -133,6 +133,6 @@
key = "s"
flags = SIGNLANG|NO_STUTTER|NONVERBAL
/datum/language/sign/can_speak_special(var/mob/speaker)
/datum/language/sign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
return (hands || !iscarbon(speaker))
+9 -1
View File
@@ -133,7 +133,15 @@
return speech_verb
/datum/language/proc/can_speak_special(var/mob/speaker)
return 1
. = TRUE
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(src.name in H.species.assisted_langs)
. = FALSE
var/obj/item/organ/internal/voicebox/vox = locate() in H.internal_organs // Only voiceboxes for now. Maybe someday it'll include other organs, but I'm not that clever
if(vox)
if(!vox.is_broken() && (src in vox.assists_languages))
. = TRUE
// Language handling.
/mob/proc/add_language(var/language)
+20 -13
View File
@@ -63,6 +63,14 @@
"ka","aasi","far","wa","baq","ara","qara","zir","saam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
"hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra")
/datum/language/tajaran/get_random_name(var/gender)
var/new_name = ..(gender,1)
if(prob(50))
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
else
new_name += " [..(gender,1)]"
return new_name
/datum/language/tajaranakhani
name = LANGUAGE_AKHANI
desc = "The language of the sea-faring Njarir'Akhan Tajaran. Borrowing some elements from Siik, the language is distinctly more structured."
@@ -78,7 +86,7 @@
"nai","ou","kah","oa","ama","uuk","bel","chi","ayt","kay","kas","akor","tam","yir","enai")
/datum/language/tajsign
name = LANGUAGE_SIIK_ALAI
name = LANGUAGE_ALAI
desc = "A standardized Tajaran sign language that was developed in Zarraya and gradually adopted by other nations, incorporating \
hand gestures and movements of the ears and tail."
signlang_verb = list("gestures with their hands", "gestures with their ears and tail", "gestures with their ears, tail and hands")
@@ -86,14 +94,18 @@
key = "l"
flags = WHITELISTED | SIGNLANG | NO_STUTTER | NONVERBAL
/datum/language/tajaran/get_random_name(var/gender)
/datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this.
if(iscarbon(speaker))
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
if(!hands)
return FALSE
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(H.species.get_bodytype(H) in allowed_species)
return TRUE
var/new_name = ..(gender,1)
if(prob(50))
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
else
new_name += " [..(gender,1)]"
return new_name
return FALSE
/datum/language/skrell
name = LANGUAGE_SKRELLIAN
@@ -161,11 +173,6 @@
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz","shh","shk")
space_chance = 10
/datum/language/machine/can_speak_special(var/mob/speaker)
var/obj/item/weapon/implant/language/eal/beep = locate() in speaker
return ((beep && beep.implanted) || speaker.isSynthetic() || isvoice(speaker))
//thank you sweet zuhayr
/datum/language/machine/get_random_name()
if(prob(70))
return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
@@ -14,9 +14,10 @@
var/muzzled = is_muzzled()
//var/m_type = 1
for (var/obj/item/weapon/implant/I in src)
if (I.implanted)
I.trigger(act, src)
for(var/obj/item/organ/O in src.organs)
for (var/obj/item/weapon/implant/I in O)
if (I.implanted)
I.trigger(act, src)
if(src.stat == 2.0 && (act != "deathgasp"))
return
+4 -15
View File
@@ -165,25 +165,12 @@
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if(update) UpdateDamageIcon()
/mob/living/carbon/human/proc/implant_loadout(var/datum/gear/G = new/datum/gear/utility/implant)
var/obj/item/weapon/implant/I = new G.path(src)
I.imp_in = src
I.implanted = 1
var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD]
affected.implants += I
I.part = affected
I.implanted(src)
/mob/living/carbon/human/proc/implant_loyalty(override = FALSE) // Won't override by default.
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)
L.imp_in = src
L.implanted = 1
var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD]
affected.implants += L
L.part = affected
L.implanted(src)
if(L.handle_implant(src, BP_HEAD))
L.post_implant(src)
/mob/living/carbon/human/proc/is_loyalty_implanted()
for(var/L in src.contents)
@@ -1120,6 +1107,8 @@
remove_language(species.language)
if(species.default_language)
remove_language(species.default_language)
for(var/datum/language/L in species.assisted_langs)
remove_language(L)
// Clear out their species abilities.
species.remove_inherent_verbs(src)
holder_type = null
@@ -167,45 +167,35 @@ emp_act
//this proc returns the armour value for a particular external organ.
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
if(!type || !def_zone)
return 0
var/protection = 0
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
var/list/protective_gear = def_zone.get_covering_clothing()
for(var/obj/item/clothing/gear in protective_gear)
if(gear.body_parts_covered & def_zone.body_part)
protection += gear.armor[type]
if(LAZYLEN(gear.accessories))
for(var/obj/item/clothing/accessory/bling in gear.accessories)
if(bling.body_parts_covered & def_zone.body_part)
protection += bling.armor[type]
protection += gear.armor[type]
return protection
/mob/living/carbon/human/proc/getsoak_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
if(!type || !def_zone)
return 0
var/soaked = 0
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
var/list/protective_gear = def_zone.get_covering_clothing()
for(var/obj/item/clothing/gear in protective_gear)
if(gear.body_parts_covered & def_zone.body_part)
soaked += gear.armorsoak[type]
if(LAZYLEN(gear.accessories))
for(var/obj/item/clothing/accessory/bling in gear.accessories)
if(bling.body_parts_covered & def_zone.body_part)
soaked += bling.armorsoak[type]
soaked += gear.armorsoak[type]
return soaked
// Checked in borer code
/mob/living/carbon/human/proc/check_head_coverage()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
for(var/bp in body_parts)
if(!bp) continue
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & HEAD)
return 1
var/obj/item/organ/external/H = organs_by_name[BP_HEAD]
var/list/body_parts = H.get_covering_clothing()
if(LAZYLEN(body_parts))
return 1
return 0
//Used to check if they can be fed food/drinks/pills
/mob/living/carbon/human/proc/check_mouth_coverage()
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform)
var/obj/item/organ/external/H = organs_by_name[BP_HEAD]
var/list/protective_gear = H.get_covering_clothing()
for(var/obj/item/gear in protective_gear)
if(istype(gear) && (gear.body_parts_covered & FACE) && !(gear.item_flags & FLEXIBLEMATERIAL))
return gear
@@ -30,6 +30,7 @@
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
var/synth_markings = 0 //Enables/disables markings on synth parts.
var/damage_multiplier = 1 //multiplies melee combat damage
var/icon_update = 1 //whether icon updating shall take place
@@ -70,6 +70,7 @@ Variables you may want to make use of are:
num_alternate_languages = 3
species_language = LANGUAGE_GALCOM
secondary_langs = list()
assisted_langs = list()
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 0
@@ -25,6 +25,8 @@
genders = list(NEUTER)
assisted_langs = list()
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
spawn(1)
new /obj/effect/decal/cleanable/ash(H.loc)
@@ -7,6 +7,7 @@
language = LANGUAGE_GALCOM
species_language = LANGUAGE_VOX
num_alternate_languages = 1
assisted_langs = list(LANGUAGE_ROOTGLOBAL)
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 4
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
@@ -71,6 +72,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart/vox,
O_LUNGS = /obj/item/organ/internal/lungs/vox,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver/vox,
O_KIDNEYS = /obj/item/organ/internal/kidneys/vox,
O_BRAIN = /obj/item/organ/internal/brain/vox,
@@ -52,13 +52,17 @@
// Language/culture vars.
var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers.
var/language = LANGUAGE_GALCOM // Default racial language, if any.
var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen
var/list/species_language = list(LANGUAGE_GALCOM) // Used on the Character Setup screen
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds = list() // A list of sounds to potentially play when speaking.
var/list/speech_chance = list() // The likelihood of a speech sound playing.
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator
// The languages the species can't speak without an assisted organ.
// This list is a guess at things that no one other than the parent species should be able to speak
var/list/assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
//Soundy emotey things.
var/scream_verb = "screams"
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
@@ -183,6 +187,7 @@
var/list/has_organ = list( // which required-organ checks are conducted.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
@@ -11,6 +11,8 @@
spawn_flags = SPECIES_IS_RESTRICTED
siemens_coefficient = 0
assisted_langs = list()
breath_type = null
poison_type = null
@@ -45,6 +45,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
@@ -30,6 +30,7 @@ var/datum/species/shapeshifter/promethean/prometheans
health_hud_intensity = 2
num_alternate_languages = 3
species_language = LANGUAGE_SOL_COMMON
assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language.
breath_type = null
poison_type = null
@@ -104,6 +104,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
@@ -12,6 +12,7 @@
species_language = LANGUAGE_SOL_COMMON
secondary_langs = list(LANGUAGE_SOL_COMMON, LANGUAGE_TERMINUS)
name_language = null // Use the first-name last-name generator rather than a language scrambler
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
min_age = 17
max_age = 130
@@ -157,7 +158,7 @@
metabolic_rate = 1.1
gluttonous = 1
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_SIIK, LANGUAGE_AKHANI, LANGUAGE_SIIK_ALAI)
secondary_langs = list(LANGUAGE_SIIK, LANGUAGE_AKHANI, LANGUAGE_ALAI)
name_language = LANGUAGE_SIIK
species_language = LANGUAGE_SIIK
health_hud_intensity = 2.5
@@ -215,6 +216,7 @@
has_organ = list( //No appendix.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
@@ -241,6 +243,7 @@
secondary_langs = list(LANGUAGE_SKRELLIAN, LANGUAGE_SCHECHI)
name_language = LANGUAGE_SKRELLIAN
species_language = LANGUAGE_SKRELLIAN
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
health_hud_intensity = 2
water_movement = -3
@@ -315,13 +318,14 @@
hud_type = /datum/hud_data/diona
siemens_coefficient = 0.3
show_ssd = "completely quiescent"
num_alternate_languages = 2
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
name_language = LANGUAGE_ROOTLOCAL
species_language = LANGUAGE_ROOTLOCAL
health_hud_intensity = 2.5
item_slowdown_mod = 0.25
num_alternate_languages = 2
name_language = LANGUAGE_ROOTLOCAL
species_language = LANGUAGE_ROOTLOCAL
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
assisted_langs = list(LANGUAGE_VOX) // Diona are weird, let's just assume they can use basically any language.
min_age = 1
max_age = 300
@@ -16,6 +16,8 @@
speech_bubble_appearance = "cyber"
assisted_langs = list()
male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg')
male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'
@@ -5,6 +5,7 @@
default_language = "Xenomorph"
language = "Hivemind"
assisted_langs = list()
unarmed_types = list(/datum/unarmed_attack/claws/strong/xeno, /datum/unarmed_attack/bite/strong/xeno)
hud_type = /datum/hud_data/alien
rarity_value = 3
+5 -1
View File
@@ -1239,4 +1239,8 @@ default behaviour is:
/mob/living/proc/has_vision()
return !(eye_blind || (disabilities & BLIND) || stat || blinded)
return !(eye_blind || (disabilities & BLIND) || stat || blinded)
/mob/living/proc/dirties_floor() // If we ever decide to add fancy conditionals for making dirty floors (floating, etc), here's the proc.
return makes_dirt
+2 -1
View File
@@ -18,7 +18,6 @@
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
var/halloss = 0 //Hallucination damage. 'Fake' damage obtained through hallucinating or the holodeck. Sleeping should cause it to wear off.
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm
@@ -62,3 +61,5 @@
var/list/hud_list //Holder for health hud, status hud, wanted hud, etc (not like inventory slots)
var/has_huds = FALSE //Whether or not we should bother initializing the above list
var/makes_dirt = TRUE //FALSE if the mob shouldn't be making dirt on the ground when it walks
+9 -4
View File
@@ -64,6 +64,7 @@ var/list/ai_verbs_default = list(
var/datum/announcement/priority/announcement
var/obj/machinery/ai_powersupply/psupply = null // Backwards reference to AI's powersupply object.
var/hologram_follow = 1 //This is used for the AI eye, to determine if a holopad's hologram should follow it or not.
var/is_dummy = 0 //Used to prevent dummy AIs from spawning with communicators.
//NEWMALF VARIABLES
var/malfunctioning = 0 // Master var that determines if AI is malfunctioning.
var/datum/malf_hardware/hardware = null // Installed piece of hardware.
@@ -111,15 +112,16 @@ var/list/ai_verbs_default = list(
possibleNames -= pickedName
pickedName = null
aiPDA = new/obj/item/device/pda/ai(src)
if(!is_dummy)
aiPDA = new/obj/item/device/pda/ai(src)
SetName(pickedName)
anchored = 1
canmove = 0
density = 1
loc = loc
aiCommunicator = new /obj/item/device/communicator/integrated(src)
if(!is_dummy)
aiCommunicator = new /obj/item/device/communicator/integrated(src)
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
@@ -792,6 +794,9 @@ var/list/ai_verbs_default = list(
return TRUE
//Special subtype kept around for global announcements
/mob/living/silicon/ai/announcer/
is_dummy = 1
/mob/living/silicon/ai/announcer/initialize()
. = ..()
mob_list -= src
+78 -3
View File
@@ -84,6 +84,7 @@ var/list/datum/ai_icon/ai_icons
/datum/ai_icon/glitchman
name = "Glitchman"
alive_icon = "ai-glitchman"
dead_icon = "ai-glitchman-crash"
/datum/ai_icon/goon
name = "Goon"
@@ -110,6 +111,7 @@ var/list/datum/ai_icon/ai_icons
name = "Inverted"
alive_icon = "ai-u"
alive_light = "#81DDFF"
dead_icon = "ai-u-crash"
/datum/ai_icon/lonestar
name = "Lonestar"
@@ -163,14 +165,87 @@ var/list/datum/ai_icon/ai_icons
/datum/ai_icon/trapped
name = "Trapped"
alive_icon = "ai-hades"
dead_icon = "ai-hades_dead"
dead_icon = "ai-hades-crash"
/datum/ai_icon/triumvirate_static
/datum/ai_icon/triumvirate
name = "Triumvirate"
alive_icon = "ai-triumvirate"
alive_light = "#020B2B"
/datum/ai_icon/triumvirate_static
name = "Triumvirate Static"
alive_icon = "ai-static"
alive_icon = "ai-triumvirate-malf"
alive_light = "#020B2B"
//Eros Research Platform Ports
/datum/ai_icon/clown2
name = "Honk"
alive_icon = "ai-clown2"
dead_icon = "ai-clown2-crash"
/datum/ai_icon/boxfort
name = "Boxfort"
alive_icon = "ai-boxfort"
dead_icon = "ai-boxfort_dead"
/datum/ai_icon/ravensdale
name = "Integration"
alive_icon = "ai-ravensdale"
dead_icon = "ai-ravensdale-crash"
/datum/ai_icon/gentoo
name = "Gentoo"
alive_icon = "ai-gentoo"
dead_icon = "ai-gentoo_dead"
/datum/ai_icon/serithi
name = "Mechanicus"
alive_icon = "ai-serithi"
dead_icon = "ai-serithi-crash"
/datum/ai_icon/alien
name = "Xenomorph"
alive_icon = "ai-alien"
dead_icon = "ai-alien-crash"
/datum/ai_icon/syndicat
name = "Syndi-cat"
alive_icon = "ai-syndicatmeow"
/datum/ai_icon/wasp
name = "Wasp"
alive_icon = "ai-wasp"
/datum/ai_icon/house
name = "Doctor"
alive_icon = "ai-house"
/datum/ai_icon/fabulous
name = "Fabulous"
alive_icon = "ai-fabulous"
/datum/ai_icon/yesman
name = "Yes Man"
alive_icon = "ai-yes-man"
dead_icon = "ai-alien-crash"
/datum/ai_icon/royal
name = "Royal"
alive_icon = "ai-royal"
/datum/ai_icon/pirate
name = "Pirate"
alive_icon = "ai-pirate"
/datum/ai_icon/gygas
name = "Love"
alive_icon = "ai-gygas"
/datum/ai_icon/xerxes
name = "Xerxes"
alive_icon = "ai-xerxes"
/datum/ai_icon/godfrey
name = "Godfrey"
alive_icon = "ai-godfrey"
@@ -213,6 +213,7 @@ var/global/list/robot_modules = list(
..()
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
src.modules += new /obj/item/weapon/autopsy_scanner(src)
src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)
@@ -148,6 +148,7 @@
src.modules += new /obj/item/weapon/reagent_containers/borghypo/merc(src)
// Surgery things.
src.modules += new /obj/item/weapon/autopsy_scanner(src)
src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)
@@ -763,6 +763,8 @@
var/mob/living/L = target_mob
if(L.stat != DEAD)
return 1
if(L.invisibility < INVISIBILITY_LEVEL_ONE)
return 1
if (istype(target_mob,/obj/mecha))
var/obj/mecha/M = target_mob
if (M.occupant)
@@ -882,6 +884,8 @@
continue
else if(L in friends)
continue
else if(L.invisibility >= INVISIBILITY_LEVEL_ONE)
continue
else if(!SA_attackable(L))
continue
else if(!special_target_check(L))
@@ -1209,7 +1213,7 @@
ai_log("AttackTarget() Bailing because we're disabled",2)
LoseTarget()
return 0
if(!target_mob || !SA_attackable(target_mob))
if(!target_mob || !SA_attackable(target_mob) || (target_mob.invisibility >= INVISIBILITY_LEVEL_ONE)) //if the target went invisible, you can't follow it
LoseTarget()
return 0
if(!(target_mob in ListTargets(view_range)))
@@ -1257,6 +1257,24 @@
name = "Tattoo (Campbell, L.Arm)"
body_parts = list(BP_L_ARM)
rightleg
name = "Tattoo (Campbell, R.Leg)"
body_parts = list(BP_R_LEG)
leftleg
name = "Tattoo (Campbell, L.Leg)"
body_parts = list (BP_L_LEG)
tat_silverburgh
name = "Tattoo (Silverburgh, R.Leg)"
icon_state = "tat_silverburgh"
body_parts = list (BP_R_LEG)
left
name = "Tattoo (Silverburgh, L.Leg)"
icon_state = "tat_silverburgh"
body_parts = list (BP_L_LEG)
tat_tiger
name = "Tattoo (Tiger Stripes, Body)"
icon_state = "tat_tiger"
+42
View File
@@ -0,0 +1,42 @@
/*
* Voicebox/Vocal Synthesizers
* TL;DR: Assists with speaking languages that a species doesn't normally have,
* such as EAL. Not standard or organic, because at the moment it's undesireable to completely mute characters.
*/
/obj/item/organ/internal/voicebox
name = "larynx"
icon_state = "larynx"
parent_organ = BP_TORSO // We don't have a neck area
organ_tag = O_VOICE
will_assist_languages = list(LANGUAGE_GALCOM)
/obj/item/organ/internal/voicebox/New()
..()
amend_assist_langs()
/obj/item/organ/internal/voicebox/proc/amend_assist_langs() // Adds the list of language datums assisted by the voicebox to the list used in speaking
for(var/L in will_assist_languages)
assists_languages |= all_languages[L]
/obj/item/organ/internal/voicebox/proc/add_assistable_langs(var/language) // Adds a new language (by string/define) to the list of things the voicebox can assist
will_assist_languages |= language
amend_assist_langs() // Can't think of a better place to put this, makes the voicebox actually start to assist with the added language
/////////////////////////////////
// Voicebox Subtypes
/////////////////////////////////
/obj/item/organ/internal/voicebox/assist // In the off chance we get a species that doesn't speak GalCom by default
/obj/item/organ/internal/voicebox/assist/New()
..()
mechassist()
/obj/item/organ/internal/voicebox/robot
name = "vocal synthesizer"
will_assist_languages = list(LANGUAGE_GALCOM, LANGUAGE_EAL) // Synthetics spawn with this by default
/obj/item/organ/internal/voicebox/robot/New()
..()
robotize()
+4
View File
@@ -31,6 +31,10 @@ var/list/organ_cache = list()
var/rejecting // Is this organ already being rejected?
var/preserved = 0 // If this is 1, prevents organ decay.
// Language vars. Putting them here in case we decide to do something crazy with sign-or-other-nonverbal languages.
var/list/will_assist_languages = list()
var/list/datum/language/assists_languages = list()
/obj/item/organ/Destroy()
if(owner) owner = null
+17
View File
@@ -72,6 +72,8 @@
var/open = 0
var/stage = 0
var/cavity = 0
var/burn_stage = 0 //Surgical repair stage for burn.
var/brute_stage = 0 //Surgical repair stage for brute.
// HUD element variable, see organ_icon.dm get_damage_hud_image()
var/image/hud_damage_image
@@ -1328,3 +1330,18 @@ Note that amputating the affected organ does in fact remove the infection from t
if(6 to INFINITY)
flavor_text += "a ton of [wound]\s"
return english_list(flavor_text)
// Returns a list of the clothing (not glasses) that are covering this part
/obj/item/organ/external/proc/get_covering_clothing()
var/list/covering_clothing = list()
if(owner)
var/list/protective_gear = list(owner.head, owner.wear_mask, owner.wear_suit, owner.w_uniform, owner.gloves, owner.shoes)
for(var/obj/item/clothing/gear in protective_gear)
if(gear.body_parts_covered & src.body_part)
covering_clothing |= gear
if(LAZYLEN(gear.accessories))
for(var/obj/item/clothing/accessory/bling in gear.accessories)
if(bling.body_parts_covered & src.body_part)
covering_clothing |= bling
return covering_clothing
+8
View File
@@ -179,6 +179,14 @@ var/global/list/limb_icon_cache = list()
if(model)
icon_cache_key += "_model_[model]"
apply_colouration(mob_icon)
if(owner && owner.synth_markings)
for(var/M in markings)
var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"]
var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]")
mark_s.Blend(markings[M]["color"], ICON_ADD)
add_overlay(mark_s) //So when it's not on your body, it has icons
mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons
icon_cache_key += "[M][markings[M]["color"]]"
dir = EAST
icon = mob_icon
+3 -2
View File
@@ -25,8 +25,9 @@
/obj/item/organ/external/chest/robotize()
if(..())
// Give them a new cell.
owner.internal_organs_by_name["cell"] = new /obj/item/organ/internal/cell(owner,1)
// Give them fancy new organs.
owner.internal_organs_by_name[O_CELL] = new /obj/item/organ/internal/cell(owner,1)
owner.internal_organs_by_name[O_VOICE] = new /obj/item/organ/internal/voicebox/robot(owner, 1)
/obj/item/organ/external/chest/handle_germ_effects()
. = ..() //Should return an infection level
+3 -3
View File
@@ -134,7 +134,7 @@ var/global/photo_count = 0
var/icon_on = "camera"
var/icon_off = "camera_off"
var/size = 3
var/picture_planes = list(PLANE_WORLD)
var/list/picture_planes = list()
/obj/item/device/camera/verb/change_size()
set name = "Set Photo Focus"
@@ -185,7 +185,7 @@ var/global/photo_count = 0
// As well as anything that isn't invisible.
for(var/atom/A in the_turf)
if(A.invisibility) continue
if(!(A.plane in picture_planes)) continue
if(A.plane > 0 && !(A.plane in picture_planes)) continue
atoms.Add(A)
// Sort the atoms into their layers
@@ -194,7 +194,7 @@ var/global/photo_count = 0
for(var/i; i <= sorted.len; i++)
var/atom/A = sorted[i]
if(A)
var/icon/img = getFlatIcon(A, picture_planes = picture_planes)//build_composite_icon(A)
var/icon/img = getFlatIcon(A, picture_planes)//build_composite_icon(A)
// If what we got back is actually a picture, draw it.
if(istype(img, /icon))
+6 -2
View File
@@ -160,6 +160,7 @@ var/list/possible_cable_coil_colours = list(
return
if(istype(W, /obj/item/weapon/wirecutters))
var/obj/item/stack/cable_coil/CC
if(d1 == UP || d2 == UP)
to_chat(user, "<span class='warning'>You must cut this cable from above.</span>")
return
@@ -172,9 +173,12 @@ var/list/possible_cable_coil_colours = list(
return
if(src.d1) // 0-X cables are 1 unit, X-X cables are 2 units long
new/obj/item/stack/cable_coil(T, 2, color)
CC = new/obj/item/stack/cable_coil(T, 2, color)
else
new/obj/item/stack/cable_coil(T, 1, color)
CC = new/obj/item/stack/cable_coil(T, 1, color)
src.add_fingerprint(user)
src.transfer_fingerprints_to(CC)
for(var/mob/O in viewers(src, null))
O.show_message("<span class='warning'>[user] cuts the cable.</span>", 1)
+23 -3
View File
@@ -3,21 +3,20 @@
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "core_control"
light_color = COLOR_ORANGE
circuit = /obj/item/weapon/circuitboard/fusion_core_control
var/id_tag
var/scan_range = 25
var/list/connected_devices = list()
var/obj/machinery/power/fusion_core/cur_viewed_device
/obj/machinery/computer/fusion_core_control/attackby(var/obj/item/thing, var/mob/user)
..()
if(ismultitool(thing))
var/new_ident = input("Enter a new ident tag.", "Core Control", id_tag) as null|text
if(new_ident && user.Adjacent(src))
id_tag = new_ident
cur_viewed_device = null
return
else
return ..()
/obj/machinery/computer/fusion_core_control/attack_ai(mob/user)
attack_hand(user)
@@ -28,6 +27,11 @@
/obj/machinery/computer/fusion_core_control/interact(mob/user)
if(stat & (BROKEN|NOPOWER))
user.unset_machine()
user << browse(null, "window=fusion_control")
return
if(!cur_viewed_device || !check_core_status(cur_viewed_device))
cur_viewed_device = null
@@ -174,3 +178,19 @@
if(C.idle_power_usage > C.avail())
return
. = 1
/obj/machinery/computer/fusion_core_control/update_icon()
if(stat & (BROKEN))
icon = 'icons/obj/computer.dmi'
icon_state = "broken"
set_light(0)
if(stat & (NOPOWER))
icon = 'icons/obj/computer.dmi'
icon_state = "computer"
set_light(0)
if(!stat & (BROKEN|NOPOWER))
icon = initial(icon)
icon_state = initial(icon_state)
set_light(light_range_on, light_power_on)
+2 -2
View File
@@ -35,7 +35,7 @@
/obj/structure/cable,
/obj/machinery/atmospherics,
/obj/machinery/air_sensor,
/mob/observer/dead,
/mob/observer,
/obj/machinery/power/hydromagnetic_trap
)
@@ -672,4 +672,4 @@
#undef FUSION_HEAT_CAP
#undef FUSION_MAX_ENVIRO_HEAT
#undef PLASMA_TEMP_RADIATION_DIVISIOR
#undef PLASMA_TEMP_RADIATION_DIVISIOR
@@ -2,6 +2,7 @@
name = "fuel injection control computer"
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "fuel"
circuit = /obj/item/weapon/circuitboard/fusion_fuel_control
var/id_tag
var/scan_range = 25
@@ -94,9 +95,25 @@
/obj/machinery/computer/fusion_fuel_control/attackby(var/obj/item/W, var/mob/user)
..()
if(ismultitool(W))
var/new_ident = input("Enter a new ident tag.", "Fuel Control", id_tag) as null|text
if(new_ident && user.Adjacent(src))
id_tag = new_ident
return
return ..()
/obj/machinery/computer/fusion_fuel_control/update_icon()
if(stat & (BROKEN))
icon = 'icons/obj/computer.dmi'
icon_state = "broken"
set_light(0)
if(stat & (NOPOWER))
icon = 'icons/obj/computer.dmi'
icon_state = "computer"
set_light(0)
if(!stat & (BROKEN|NOPOWER))
icon = initial(icon)
icon_state = initial(icon_state)
set_light(light_range_on, light_power_on)
@@ -3,6 +3,7 @@
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "engine"
light_color = COLOR_BLUE
circuit = /obj/item/weapon/circuitboard/gyrotron_control
var/id_tag
var/scan_range = 25
@@ -16,6 +17,11 @@
/obj/machinery/computer/gyrotron_control/interact(var/mob/user)
if(stat & (BROKEN|NOPOWER))
user.unset_machine()
user << browse(null, "window=gyrotron_controller_[id_tag]")
return
if(!id_tag)
to_chat(user, "<span class='warning'>This console has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>")
return
@@ -89,9 +95,25 @@
return 0
/obj/machinery/computer/gyrotron_control/attackby(var/obj/item/W, var/mob/user)
..()
if(ismultitool(W))
var/new_ident = input("Enter a new ident tag.", "Gyrotron Control", id_tag) as null|text
if(new_ident && user.Adjacent(src))
id_tag = new_ident
return
return ..()
/obj/machinery/computer/gyrotron_control/update_icon()
if(stat & (BROKEN))
icon = 'icons/obj/computer.dmi'
icon_state = "broken"
set_light(0)
if(stat & (NOPOWER))
icon = 'icons/obj/computer.dmi'
icon_state = "computer"
set_light(0)
if(!stat & (BROKEN|NOPOWER))
icon = initial(icon)
icon_state = initial(icon_state)
set_light(light_range_on, light_power_on)
@@ -325,6 +325,31 @@
/obj/item/ammo_magazine/box/c9mm/empty
initial_ammo = 0
/obj/item/ammo_magazine/m9mmR/saber
desc = "A very high capacity double stack magazine made specially for the SABER SMG. Filled with 22 9mm bullets."
icon_state = "S9mm-22"
mag_type = MAGAZINE
ammo_type = /obj/item/ammo_casing/a9mm
matter = list(DEFAULT_WALL_MATERIAL = 1200)
caliber = "9mm"
max_ammo = 22
origin_tech = list(TECH_COMBAT = 2, TECH_ILLEGAL = 1)
multiple_sprites = 1
/obj/item/ammo_magazine/m9mmR/saber/ap
desc = "A high capacity double stack magazine made specially for the SABER SMG. Filled with 22 9mm armor piercing bullets."
icon_state = "S9mm-22"
mag_type = MAGAZINE
ammo_type = /obj/item/ammo_casing/a9mm/ap
matter = list(DEFAULT_WALL_MATERIAL = 2000)
caliber = "9mm"
max_ammo = 22
origin_tech = list(TECH_COMBAT = 2, TECH_ILLEGAL = 1)
multiple_sprites = 1
/obj/item/ammo_magazine/m9mmR/saber/empty
initial_ammo = 0
///////// 10mm /////////
/obj/item/ammo_magazine/m10mm
@@ -1,25 +1,40 @@
/obj/item/weapon/gun/projectile/automatic //Hopefully someone will find a way to make these fire in bursts or something. --Superxpdude //Except burstfire isn't fit for an rp server --Mark
/obj/item/weapon/gun/projectile/automatic //This should never be spawned in, it is just here because of code necessities.
name = "daka SMG"
desc = "A small SMG. You really shouldn't be able to get this gun. Uses 9mm rounds."
icon_state = "c05r" //Used because it's not used anywhere else
load_method = SPEEDLOADER
ammo_type = /obj/item/ammo_casing/a9mm
projectile_type = /obj/item/projectile/bullet/pistol
//Burst is the number of bullets fired; Fire delay is the time you have to wait to shoot the gun again, Move delay is the same but for moving after shooting. .
//Burst accuracy is the accuracy of each bullet fired in the burst. Dispersion is how much the bullets will 'spread' away from where you aimed.
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)))
/obj/item/weapon/gun/projectile/automatic/saber //Fixed it
name = "prototype SMG"
desc = "A protoype lightweight, fast firing gun. Uses 9mm rounds."
icon_state = "saber" //ugly
icon = 'icons/obj/gun.dmi'
icon_state = "saber"//Still ugly
w_class = ITEMSIZE_NORMAL
load_method = SPEEDLOADER //yup. until someone sprites a magazine for it.
load_method = MAGAZINE //This should fix it
max_shells = 22
caliber = "9mm"
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
slot_flags = SLOT_BELT
ammo_type = /obj/item/ammo_casing/a9mm
magazine_type = /obj/item/ammo_magazine/m9mmR/saber
allowed_magazines = list(/obj/item/ammo_magazine/m9mmR/saber, /obj/item/ammo_magazine/m9mmR/saber/ap)
projectile_type = /obj/item/projectile/bullet/pistol
multi_aim = 1
burst_delay = 2
// one_handed_penalty = 15
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0))
// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/projectile/automatic/c20r
name = "submachine gun"
@@ -858,7 +858,7 @@
glass_name = "lime tea"
glass_desc = "A tasty mixture of lime and tea. It's apparently good for you!"
cup_name = "cup of berry tea"
cup_name = "cup of lime tea"
cup_desc = "A tasty mixture of lime and tea. It's apparently good for you!"
/datum/reagent/drink/tea/orangetea
@@ -49,7 +49,7 @@
if(H.a_intent != I_HELP)
to_chat(user, "<span class='notice'>[H] is resisting your attempt to inject them with \the [src].</span>")
to_chat(H, "<span class='danger'> [user] is trying to inject you with \the [src]!</span>")
if(!do_after(user, 30))
if(!do_after(user, 30, H))
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
+2 -1
View File
@@ -47,9 +47,10 @@
/datum/design/item/weapon/smg
id = "smg"
desc = "An compact reliable SMG firing armor piercing ammo."
req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3)
materials = list(DEFAULT_WALL_MATERIAL = 8000, "silver" = 2000, "diamond" = 1000)
build_path = /obj/item/weapon/gun/projectile/automatic
build_path = /obj/item/weapon/gun/projectile/automatic/saber
sort_string = "TAABA"
/datum/design/item/weapon/ammo_9mm
+215
View File
@@ -0,0 +1,215 @@
//Procedures in this file: Organic limb repair
//////////////////////////////////////////////////////////////////
// LIMB REPAIR SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/
priority = 1
can_infect = 1
blood_level = 1
req_open = 1
/datum/surgery_step/repairflesh/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (target.stat == DEAD) // Sorry defibs, your subjects need to have pumping fluids for these to work.
return 0
if (isslime(target))
return 0
if (target_zone == O_EYES || target_zone == O_MOUTH)
return 0
if (!hasorgans(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (affected == null)
return 0
if (affected.is_stump())
return 0
if (affected.robotic >= ORGAN_ROBOT)
return 0
return 1
//////////////////////////////////////////////////////////////////
// SCAN STEP //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/scan_injury
allowed_tools = list(
/obj/item/weapon/autopsy_scanner = 100,
/obj/item/device/healthanalyzer = 80,
/obj/item/device/analyzer = 10
)
priority = 2
can_infect = 0 //The only exception here. Sweeping a scanner probably won't transfer many germs.
min_duration = 20
max_duration = 40
/datum/surgery_step/repairflesh/scan_injury/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.burn_stage || affected.brute_stage)
return 0
return 1
return 0
/datum/surgery_step/repairflesh/scan_injury/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='notice'>[user] begins scanning [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin scanning [target]'s [affected] with \the [tool].</span>")
..()
/datum/surgery_step/repairflesh/scan_injury/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='notice'>[user] finishes scanning [target]'s [affected].</span>", \
"<span class='notice'>You finish scanning [target]'s [affected].</span>")
if(affected.brute_dam)
to_chat(user, "<span class='notice'>The muscle in [target]'s [affected] is notably bruised.</span>")
if(affected.status & ORGAN_BROKEN)
to_chat(user, "<span class='warning'>\The [target]'s [affected] is broken!</span>")
affected.brute_stage = max(1, affected.brute_stage)
if(affected.burn_dam)
to_chat(user, "<span class='notice'>\The muscle in [target]'s [affected] is notably charred.</span>")
affected.burn_stage = max(1, affected.burn_stage)
/datum/surgery_step/repairflesh/scan_injury/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='warning'>[user]'s hand slips, dropping \the [tool] onto [target]'s [affected]!</span>" , \
"<span class='warning'>Your hand slips, dropping \the [tool] onto [target]'s [affected]!</span>" )
affected.createwound(BRUISE, 10)
//////////////////////////////////////////////////////////////////
// BURN STEP //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/repair_burns
allowed_tools = list(
/obj/item/stack/medical/advanced/ointment = 100,
/obj/item/weapon/surgical/FixOVein = 100,
/obj/item/weapon/surgical/hemostat = 60,
/obj/item/stack/medical/ointment = 50,
/obj/item/weapon/tape_roll = 30,
/obj/item/taperoll = 10
)
priority = 3
min_duration = 90
max_duration = 120
/datum/surgery_step/repairflesh/repair_burns/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.burn_stage < 1 || !(affected.burn_dam))
return 0
if(affected.burn_dam < affected.brute_dam)
return 0
return 1
return 0
/datum/surgery_step/repairflesh/repair_burns/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='warning'>[user] begins taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin taping up [target]'s [affected] with \the [tool].</span>")
affected.jostle_bone(10)
else if(istype(tool, /obj/item/weapon/surgical/hemostat) || istype(tool, /obj/item/weapon/surgical/FixOVein))
user.visible_message("<span class='notice'>[user] begins mending the charred blood vessels in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin mending the charred blood vessels in [target]'s [affected] with \the [tool].</span>")
else
user.visible_message("<span class='notice'>[user] begins coating the charred tissue in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin coating the charred tissue in [target]'s [affected] with \the [tool].</span>")
..()
/datum/surgery_step/repairflesh/repair_burns/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='notice'>[user] finishes taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You finish taping up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.heal_damage(0, 25, 0, 0)
if(!(affected.burn_dam))
affected.burn_stage = 0
if(istype(tool, /obj/item/stack))
var/obj/item/stack/T = tool
T.use(1)
..()
/datum/surgery_step/repairflesh/repair_burns/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='danger'>[user]'s hand slips, tearing up [target]'s [affected] with \the [tool].</span>", \
"<span class='danger'>Your hand slips, tearing up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.createwound(CUT, 5)
if(istype(tool, /obj/item/stack) && prob(30))
var/obj/item/stack/T = tool
T.use(1)
..()
//////////////////////////////////////////////////////////////////
// BRUTE STEP //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/repair_brute
allowed_tools = list(
/obj/item/stack/medical/advanced/bruise_pack = 100,
/obj/item/weapon/surgical/cautery = 100,
/obj/item/weapon/surgical/bonesetter = 60,
/obj/item/stack/medical/bruise_pack = 50,
/obj/item/weapon/tape_roll = 40,
/obj/item/taperoll = 10
)
priority = 3
min_duration = 90
max_duration = 120
/datum/surgery_step/repairflesh/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.brute_stage < 1 || !(affected.brute_dam))
return 0
if(affected.brute_dam < affected.burn_dam)
return 0
return 1
return 0
/datum/surgery_step/repairflesh/repair_brute/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='warning'>[user] begins taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin taping up [target]'s [affected] with \the [tool].</span>")
affected.jostle_bone(10)
else if(istype(tool, /obj/item/weapon/surgical/FixOVein) || istype(tool, /obj/item/weapon/surgical/bonesetter))
user.visible_message("<span class='notice'>[user] begins mending the torn tissue in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin mending the torn tissue in [target]'s [affected] with \the [tool].</span>")
else
user.visible_message("<span class='notice'>[user] begins coating the tissue in [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You begin coating the tissue in [target]'s [affected] with \the [tool].</span>")
..()
/datum/surgery_step/repairflesh/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll))
user.visible_message("<span class='notice'>[user] finishes taping up [target]'s [affected] with \the [tool].</span>", \
"<span class='notice'>You finish taping up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.heal_damage(25, 0, 0, 0)
if(!(affected.brute_dam))
affected.brute_stage = 0
if(istype(tool, /obj/item/stack))
var/obj/item/stack/T = tool
T.use(1)
..()
/datum/surgery_step/repairflesh/repair_brute/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<span class='danger'>[user]'s hand slips, tearing up [target]'s [affected] with \the [tool].</span>", \
"<span class='danger'>Your hand slips, tearing up [target]'s [affected] with \the [tool].</span>")
affected.createwound(BRUISE, 10)
affected.createwound(CUT, 5)
if(istype(tool, /obj/item/stack) && prob(30))
var/obj/item/stack/T = tool
T.use(1)
..()
@@ -4,6 +4,7 @@
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "engspace_suit"
item_state = "engspace_suit"
update_icon_define = "icons/mob/spacesuit.dmi"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
/obj/item/clothing/head/bio_hood/anomaly
+27
View File
@@ -53,6 +53,33 @@
-->
<div class="commit sansserif">
<h2 class="date">14 July 2018</h2>
<h3 class="author">Anewbe updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Certain languages now require assistance for a species to speak, but not understand, much like EAL.</li>
<li class="tweak">Alai can only be `spoken` by Taj and Teshari.</li>
<li class="rscadd">Adds a voicebox/larynx organ. Its only purpose at the moment is to assist in speaking certain langauges.</li>
<li class="tweak">Language implants, like the EAL implant, now affect the voicebox organ, instead of being a freefloating implant.</li>
<li class="rscadd">Adds a language implant for Common Skrellian.</li>
</ul>
<h3 class="author">Atermonera updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Steel sheets can be used to construct Roofing Tiles</li>
<li class="rscadd">Roofing tiles can be used on tiles under open spaces or space tiles in multiZ maps to place a lattice and plating on the space above</li>
<li class="rscadd">Roofing tiles can be used on outdoor turfs to make them indoors</li>
<li class="rscadd">Both functions work together on multiZ maps with outdoor turfs, only one roofing tile is used per tile roofed.</li>
</ul>
<h3 class="author">Mechoid updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Adds a new surgical procedure for fixing brute and burn on limbs.</li>
</ul>
<h2 class="date">12 July 2018</h2>
<h3 class="author">Anewbe updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Technomancer Apportation now properly checks for range and scepter, again.</li>
</ul>
<h2 class="date">21 June 2018</h2>
<h3 class="author">Anewbe updated:</h3>
<ul class="changes bgimages16">
+22
View File
@@ -4167,3 +4167,25 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- rscdel: Makes VeyMed limbs more vulnerable to brute and burn.
Mechoid:
- rscadd: Allow AIs to create and take control of mindless drones from fabricators.
2018-07-12:
Anewbe:
- bugfix: Technomancer Apportation now properly checks for range and scepter, again.
2018-07-14:
Anewbe:
- tweak: Certain languages now require assistance for a species to speak, but not
understand, much like EAL.
- tweak: Alai can only be `spoken` by Taj and Teshari.
- rscadd: Adds a voicebox/larynx organ. Its only purpose at the moment is to assist
in speaking certain langauges.
- tweak: Language implants, like the EAL implant, now affect the voicebox organ,
instead of being a freefloating implant.
- rscadd: Adds a language implant for Common Skrellian.
Atermonera:
- rscadd: Steel sheets can be used to construct Roofing Tiles
- rscadd: Roofing tiles can be used on tiles under open spaces or space tiles in
multiZ maps to place a lattice and plating on the space above
- rscadd: Roofing tiles can be used on outdoor turfs to make them indoors
- rscadd: Both functions work together on multiZ maps with outdoor turfs, only one
roofing tile is used per tile roofed.
Mechoid:
- rscadd: Adds a new surgical procedure for fixing brute and burn on limbs.
-36
View File
@@ -1,36 +0,0 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Anewbe
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- bugfix: "Technomancer Apportation now properly checks for range and scepter, again."
+4
View File
@@ -0,0 +1,4 @@
author: Mewchild
delete-after: True
changes:
- rscadd: "Ports several AI core sprites from ages and places past"

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