Merge branch 'master' into upstream-merge-5424

This commit is contained in:
Spades
2018-09-01 18:40:37 -04:00
committed by GitHub
169 changed files with 4091 additions and 3974 deletions
+4 -1
View File
@@ -4,7 +4,7 @@
#define TRANSITIONEDGE 7 // Distance from edge to move to another z-level.
// Invisibility constants.
// Invisibility constants. These should only be used for TRUE invisibility, AKA nothing living players touch
#define INVISIBILITY_LIGHTING 20
#define INVISIBILITY_LEVEL_ONE 35
#define INVISIBILITY_LEVEL_TWO 45
@@ -21,6 +21,9 @@
#define SEE_INVISIBLE_MINIMUM 5
#define INVISIBILITY_MAXIMUM 100
// Pseudo-Invis, like Ninja, Ling, Etc.
#define EFFECTIVE_INVIS 50 // Below this, can't be examined, may as well be invisible to the game
// For the client FPS pref and anywhere else
#define MAX_CLIENT_FPS 200
+3
View File
@@ -177,6 +177,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"
+3
View File
@@ -13,6 +13,9 @@
#define O_ORCH "orchestrator"
#define O_FACT "refactory"
//Alraune organs
#define A_FRUIT "fruit gland"
//species defines
#define SPECIES_AKULA "Akula"
#define SPECIES_ALRAUNE "Alraune"
@@ -98,10 +98,10 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
autopilot = 1
set_launch_countdown(get_shuttle_prep_time())
auto_recall_time = rand(world.time + 300, launch_time - 300)
var/estimated_time = round(estimate_arrival_time()/60,1)
//reset the shuttle transit time if we need to
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
var/estimated_time = round(estimate_arrival_time()/60,1)
priority_announcement.Announce(replacetext(replacetext(using_map.shuttle_called_message, "%dock_name%", "[using_map.dock_name]"), "%ETA%", "[estimated_time] minute\s"))
atc.shift_ending()
@@ -274,4 +274,4 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z))
S.direction = spawndir
spawn()
S.startmove()
S.startmove()
+9 -3
View File
@@ -45,12 +45,18 @@ SUBSYSTEM_DEF(transcore)
current_run.len--
//Remove if not in a human anymore.
if(!imp || !ishuman(imp.loc))
if(!imp || !isorgan(imp.loc))
implants -= imp
continue
//We're in a human, at least.
var/mob/living/carbon/human/H = imp.loc
//We're in an organ, at least.
var/obj/item/organ/external/EO = imp.loc
var/mob/living/carbon/human/H = EO.owner
if(!H)
implants -= imp
continue
//In a human
BITSET(H.hud_updateflag, BACKUP_HUD)
if(H == imp.imp_in && H.mind && H.stat < DEAD)
+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)
+2 -2
View File
@@ -20,9 +20,9 @@ var/decl/observ/turf_changed/turf_changed_event = new()
* Turf Changed Handling *
************************/
/turf/ChangeTurf()
/turf/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
var/old_density = density
var/old_opacity = opacity
. = ..()
. = ..(N, tell_universe, force_lighting_update, preserve_outdoors)
if(.)
turf_changed_event.raise_event(src, old_density, density, old_opacity, opacity)
+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 = ..()
@@ -13,6 +13,7 @@ var/datum/antagonist/traitor/infiltrator/infiltrators
welcome_text = "To speak on your team's private channel, use :t."
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_speak_aooc = TRUE
/datum/antagonist/traitor/infiltrator/New()
..()
+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
+6
View File
@@ -199,6 +199,12 @@ var/global/list/datum/dna/gene/dna_genes[0]
src.base_species = CS.base_species
src.blood_color = CS.blood_color
if(istype(character.species,/datum/species/alraune))
var/datum/species/alraune/CS = character.species
//src.species_traits = CS.traits.Copy() //No traits
src.base_species = CS.base_species
src.blood_color = CS.blood_color
// +1 to account for the none-of-the-above possibility
SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1)
SetUIValueRange(DNA_UI_TAIL_STYLE, tail_style + 1, tail_styles_list.len + 1, 1)
+5
View File
@@ -233,6 +233,11 @@
var/datum/species/xenochimera/CS = H.species
var/datum/species/xenochimera/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
new_CS.blood_color = dna.blood_color
if(istype(H.species,/datum/species/alraune))
var/datum/species/alraune/CS = H.species
var/datum/species/alraune/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
new_CS.blood_color = dna.blood_color
// VOREStation Edit End
H.force_update_organs() //VOREStation Add - Gotta do this too
+2
View File
@@ -109,8 +109,10 @@
if(H.backbag > 0)
H.equip_to_slot_or_del(new /obj/item/weapon/stamp/clown(H.back), slot_in_backpack)
H.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(H.back), slot_in_backpack) //VOREStation Edit
else
H.equip_to_slot_or_del(new /obj/item/weapon/stamp/clown(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(H.back), slot_l_hand) //VOREStation Edit
return 1
+2 -1
View File
@@ -391,7 +391,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))
+3 -1
View File
@@ -38,11 +38,13 @@
projectiles--
var/P = new projectile(curloc)
Fire(P, target)
if(i == 1)
set_ready_state(0)
if(fire_cooldown)
sleep(fire_cooldown)
if(auto_rearm)
projectiles = projectiles_per_shot
set_ready_state(0)
// set_ready_state(0)
do_after_cooldown()
return
+2 -2
View File
@@ -1254,7 +1254,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(isnull(cartridge))
to_chat(usr, "<span class='notice'>There's no cartridge to eject.</span>")
return
return
cartridge.forceMove(get_turf(src))
if(ismob(loc))
@@ -1382,7 +1382,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
to_chat(user, "<span class='notice'>Blood type: [C:blood_DNA[blood]]\nDNA: [blood]</span>")
if(4)
user.visible_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", 1)
user.visible_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", "<span class='notice'>You have analyzed [C]'s radiation levels!</span>")
to_chat(user, "<span class='notice'>Analyzing Results for [C]:</span>")
if(C.radiation)
to_chat(user, "<span class='notice'>Radiation Level: [C.radiation]</span>")
+138 -20
View File
@@ -10,44 +10,162 @@
var/insults = 0
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TERRORIST!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "GLORY TO ALMACH!")
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
/obj/item/device/megaphone/proc/can_broadcast(var/mob/living/user)
if (user.client)
if(user.client.prefs.muted & MUTE_IC)
src << "<span class='warning'>You cannot speak in IC (muted).</span>"
return
if(!ishuman(user))
user << "<span class='warning'>You don't know how to use this!</span>"
return
to_chat(user, "<span class='warning'>You cannot speak in IC (muted).</span>")
return 0
if(!(ishuman(user) || user.isSynthetic()))
to_chat(user, "<span class='warning'>You don't know how to use this!</span>")
return 0
if(user.silent)
return
return 0
if(spamcheck)
user << "<span class='warning'>\The [src] needs to recharge!</span>"
return
to_chat(user, "<span class='warning'>\The [src] needs to recharge!</span>")
return 0
return 1
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
if(!message)
return
message = capitalize(message)
/obj/item/device/megaphone/proc/do_broadcast(var/mob/living/user, var/message)
if ((src.loc == user && usr.stat == 0))
if(emagged)
if(insults)
for(var/mob/O in (viewers(user)))
O.show_message("<B>[user]</B> broadcasts, <FONT size=3>\"[pick(insultmsg)]\"</FONT>",2) // 2 stands for hearable message
user.audible_message("<B>[user]</B> broadcasts, <FONT size=3>\"[pick(insultmsg)]\"</FONT>")
insults--
else
user << "<span class='warning'>*BZZZZzzzzzt*</span>"
to_chat(user, "<span class='warning'>*BZZZZzzzzzt*</span>")
else
for(var/mob/O in (viewers(user)))
O.show_message("<B>[user]</B> broadcasts, <FONT size=3>\"[message]\"</FONT>",2) // 2 stands for hearable message
user.audible_message("<B>[user]</B> broadcasts, <FONT size=3>\"[message]\"</FONT>")
spamcheck = 1
spawn(20)
spamcheck = 0
return
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
if(!can_broadcast(user))
return
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
if(!message)
return
message = capitalize(message)
do_broadcast(user, message)
/obj/item/device/megaphone/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
user << "<span class='warning'>You overload \the [src]'s voice synthesizer.</span>"
to_chat(user, "<span class='warning'>You overload \the [src]'s voice synthesizer.</span>")
emagged = 1
insults = rand(1, 3)//to prevent dickflooding
insults = rand(1, 3)//to prevent caps spam.
return 1
/obj/item/device/megaphone/super
name = "gigaphone"
desc = "A device used to project your voice. Loudly-er."
icon_state = "gigaphone"
var/broadcast_font = "verdana"
var/broadcast_size = 3
var/broadcast_color = "#000000" //Black by default.
var/list/volume_options = list(2, 3, 4)
var/list/font_options = list("times new roman", "times", "verdana", "sans-serif", "serif", "georgia")
var/list/color_options= list("#000000", "#ff0000", "#00ff00", "#0000ff")
insultmsg = list("HONK?!", "HONK!", "HOOOOOOOONK!", "...!", "HUNK.", "Honk?")
/obj/item/device/megaphone/super/emag_act(var/remaining_charges, var/mob/user)
..()
if(emagged)
if(!(11 in volume_options))
volume_options = list(11)
broadcast_size = 11
if(!("comic sans ms" in font_options))
font_options = list("comic sans ms")
broadcast_font = "comic sans ms"
to_chat(user, "<span class='notice'>\The [src] emits a <font face='comic sans ms' color='#ff69b4'>silly</font> sound.</span>")
if(!("#ff69b4" in color_options))
color_options = list("#ff69b4")
broadcast_color = "#ff69b4"
if(insults <= 0)
insults = rand(1,3)
to_chat(user, "<span class='warning'>You re-scramble \the [src]'s voice synthesizer.</span>")
return 1
/obj/item/device/megaphone/super/verb/turn_volume_dial(mob/living/user)
set name = "Change Volume"
set desc = "Allows you to change the megaphone's volume."
set category = "Object"
adjust_volume(user)
/obj/item/device/megaphone/super/proc/adjust_volume(var/mob/living/user)
var/new_volume = input(user, "Set Volume") as null|anything in volume_options
if(new_volume && Adjacent(user))
broadcast_size = new_volume
/obj/item/device/megaphone/super/verb/change_font(mob/living/user)
set name = "Change... Pronunciation?"
set desc = "Allows you to change the megaphone's font."
set category = "Object"
adjust_font(user)
/obj/item/device/megaphone/super/proc/adjust_font(var/mob/living/user)
var/new_font = input(user, "Set Volume") as null|anything in font_options
if(new_font && Adjacent(user))
broadcast_font = new_font
/obj/item/device/megaphone/super/verb/change_color(mob/living/user)
set name = "Change... Tune?"
set desc = "Allows you to change the megaphone's color."
set category = "Object"
adjust_color(user)
/obj/item/device/megaphone/super/proc/adjust_color(var/mob/living/user)
var/new_color = input(user, "Set Volume") as null|anything in color_options
if(new_color && Adjacent(user))
broadcast_color = new_color
/obj/item/device/megaphone/super/do_broadcast(var/mob/living/user, var/message)
if ((src.loc == user && usr.stat == 0))
if(emagged)
if(insults)
user.audible_message("<B>[user]</B> broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[pick(insultmsg)]\"</FONT>")
if(broadcast_size >= 11)
var/turf/T = get_turf(user)
playsound(T, 'sound/items/AirHorn.ogg', 100, 1)
for(var/mob/living/carbon/M in oviewers(4, T))
if(M.get_ear_protection() >= 2)
continue
M.sleeping = 0
M.stuttering += 20
M.ear_deaf += 30
M.Weaken(3)
if(prob(30))
M.Stun(10)
M.Paralyse(4)
else
M.make_jittery(50)
insults--
else
user.audible_message("<span class='critical'>*BZZZZzzzzzt*</span>")
if(prob(40) && insults <= 0)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, get_turf(user))
s.start()
user.visible_message("<span class='warning'>\The [src] sparks violently!</span>")
spawn(30)
explosion(get_turf(src), -1, -1, 1, 3, adminlog = 1)
qdel(src)
return
else
user.audible_message("<B>[user]</B> broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[message]\"</FONT>")
spamcheck = 1
spawn(20)
spamcheck = 0
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 ..()
@@ -198,3 +198,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"
+44
View File
@@ -1042,6 +1042,50 @@
name = "tuxedo cat plushie"
icon_state = "tuxedocat"
// nah, squids are better than foxes :>
/obj/item/toy/plushie/squid/green
name = "green squid plushie"
desc = "A small, cute and loveable squid friend. This one is green."
icon = 'icons/obj/toy.dmi'
icon_state = "greensquid"
slot_flags = SLOT_HEAD
/obj/item/toy/plushie/squid/mint
name = "mint squid plushie"
desc = "A small, cute and loveable squid friend. This one is mint coloured."
icon = 'icons/obj/toy.dmi'
icon_state = "mintsquid"
slot_flags = SLOT_HEAD
/obj/item/toy/plushie/squid/blue
name = "blue squid plushie"
desc = "A small, cute and loveable squid friend. This one is blue."
icon = 'icons/obj/toy.dmi'
icon_state = "bluesquid"
slot_flags = SLOT_HEAD
/obj/item/toy/plushie/squid/orange
name = "orange squid plushie"
desc = "A small, cute and loveable squid friend. This one is orange."
icon = 'icons/obj/toy.dmi'
icon_state = "orangesquid"
slot_flags = SLOT_HEAD
/obj/item/toy/plushie/squid/yellow
name = "yellow squid plushie"
desc = "A small, cute and loveable squid friend. This one is yellow."
icon = 'icons/obj/toy.dmi'
icon_state = "yellowsquid"
slot_flags = SLOT_HEAD
/obj/item/toy/plushie/squid/pink
name = "pink squid plushie"
desc = "A small, cute and loveable squid friend. This one is pink."
icon = 'icons/obj/toy.dmi'
icon_state = "pinksquid"
slot_flags = SLOT_HEAD
/obj/item/toy/plushie/therapy/red
name = "red therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is red."
+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
@@ -3,43 +3,39 @@
desc = "Allows the user to understand and speak almost all known languages.."
var/uses = 1
get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Language Implant<BR>
<b>Life:</b> One day.<BR>
<b>Important Notes:</b> Personnel with this implant can speak almost all known languages.<BR>
<HR>
<b>Implant Details:</b> Subjects injected with implant can understand and speak almost all known languages.<BR>
<b>Function:</b> Contains specialized nanobots to stimulate the brain so the user can speak and understand previously unknown languages.<BR>
<b>Special Features:</b> Will allow the user to understand almost all languages.<BR>
<b>Integrity:</b> Implant can only be used once before the nanobots are depleted."}
return dat
/obj/item/weapon/implant/vrlanguage/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Language Implant<BR>
<b>Life:</b> One day.<BR>
<b>Important Notes:</b> Personnel with this implant can speak almost all known languages.<BR>
<HR>
<b>Implant Details:</b> Subjects injected with implant can understand and speak almost all known languages.<BR>
<b>Function:</b> Contains specialized nanobots to stimulate the brain so the user can speak and understand previously unknown languages.<BR>
<b>Special Features:</b> Will allow the user to understand almost all languages.<BR>
<b>Integrity:</b> Implant can only be used once before the nanobots are depleted."}
return dat
/obj/item/weapon/implant/vrlanguage/trigger(emote, mob/source as mob)
if (src.uses < 1)
return 0
if (emote == "smile")
src.uses--
to_chat(source,"<span class='notice'>You suddenly feel as if you can understand other languages!</span>")
source.add_language(LANGUAGE_CHIMPANZEE)
source.add_language(LANGUAGE_NEAERA)
source.add_language(LANGUAGE_STOK)
source.add_language(LANGUAGE_FARWA)
source.add_language(LANGUAGE_UNATHI)
source.add_language(LANGUAGE_SIIK)
source.add_language(LANGUAGE_SKRELLIAN)
source.add_language(LANGUAGE_SCHECHI)
source.add_language(LANGUAGE_BIRDSONG)
source.add_language(LANGUAGE_SAGARU)
source.add_language(LANGUAGE_CANILUNZT)
source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something.
trigger(emote, mob/source as mob)
if (src.uses < 1) return 0
if (emote == "smile")
src.uses--
source << "<span class='notice'>You suddenly feel as if you can understand other languages!</span>"
source.add_language(LANGUAGE_CHIMPANZEE)
source.add_language(LANGUAGE_NEAERA)
source.add_language(LANGUAGE_STOK)
source.add_language(LANGUAGE_FARWA)
source.add_language(LANGUAGE_UNATHI)
source.add_language(LANGUAGE_SIIK)
source.add_language(LANGUAGE_SKRELLIAN)
source.add_language(LANGUAGE_SCHECHI)
source.add_language(LANGUAGE_BIRDSONG)
source.add_language(LANGUAGE_SAGARU)
source.add_language(LANGUAGE_CANILUNZT)
source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something.
return
implanted(mob/source)
source.mind.store_memory("A implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.", 0, 0)
source << "The implanted language implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate."
return 1
/obj/item/weapon/implant/vrlanguage/post_implant(mob/source)
source.mind.store_memory("A implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.", 0, 0)
to_chat(source,"The implanted language implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.")
return 1
@@ -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)
BITSET(H.hud_updateflag, BACKUP_HUD) //VOREStation Add - Backup HUD updates
@@ -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
@@ -30,7 +30,7 @@
update()
return
/obj/item/weapon/implant/reagent_generator/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
assigned_proc = new assigned_proc(source, verb_name, verb_desc)
@@ -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
@@ -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
+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
+2 -1
View File
@@ -4,7 +4,8 @@
anchored = 1
density = 1
pixel_x = -16
layer = MOB_LAYER // You know what, let's play it safe.
plane = MOB_LAYER // You know what, let's play it safe.
layer = ABOVE_MOB_LAYER
var/base_state = null // Used for stumps.
var/health = 200 // Used for chopping down trees.
var/max_health = 200
+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
+1 -1
View File
@@ -156,4 +156,4 @@
return
if(flooring)
return
attackby(T, user)
attackby(T, user)
@@ -54,8 +54,8 @@ var/list/turf_edge_cache = list()
if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state)
var/cache_key = "[T.get_edge_icon_state()]-[checkdir]"
if(!turf_edge_cache[cache_key])
var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
I.plane = 0
var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir, layer = ABOVE_TURF_LAYER)
I.plane = TURF_PLANE
turf_edge_cache[cache_key] = I
add_overlay(turf_edge_cache[cache_key])
@@ -403,3 +403,5 @@
else if(!istype(W,/obj/item/weapon/rcd) && !istype(W, /obj/item/weapon/reagent_containers))
return attack_hand(user)
+2 -2
View File
@@ -115,9 +115,9 @@
plant.pixel_y = 0
plant.update_neighbors()
/turf/simulated/wall/ChangeTurf(var/newtype)
/turf/simulated/wall/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
clear_plants()
..(newtype)
..(N, tell_universe, force_lighting_update, preserve_outdoors)
//Appearance
/turf/simulated/wall/examine(mob/user)
+33 -7
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
@@ -187,5 +213,5 @@
A.loc.Entered(A)
return
/turf/space/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0)
return ..(N, tell_universe, 1)
/turf/space/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
return ..(N, tell_universe, 1, preserve_outdoors)
+1 -1
View File
@@ -109,4 +109,4 @@
lighting_clear_overlay()
if(preserve_outdoors)
outdoors = old_outdoors
outdoors = old_outdoors
+12 -20
View File
@@ -53,30 +53,22 @@
Lines += entry
else
for(var/client/C in clients)
var/entry = "\t"
if(C.holder && C.holder.fakekey)
var/entry = "\t[C.key]"
var/mob/observer/dead/O = C.mob
entry = C.holder.fakekey
if(isobserver(O))
entry += " - <font color='gray'>Observing</font>"
else if(istype(O,/mob/new_player))
entry += " - <font color='blue'>In Lobby</font>"
else
entry += " - <font color='green'>Playing</font>"
Lines += entry
entry += "[C.holder.fakekey]"
else
var/entry = "\t[C.key]"
var/mob/observer/dead/O = C.mob
if(isobserver(O)) //Woo, players can see
entry += " - <font color='gray'>Observing</font>"
else if(istype(O,/mob/new_player))
entry += " - <font color='blue'>In Lobby</font>"
else
entry += " - <font color='green'>Playing</font>"
Lines += entry
entry += "[C.key]"
var/mob/observer/dead/O = C.mob
if(isobserver(O))
entry += " - <font color='gray'>Observing</font>"
else if(istype(O,/mob/new_player))
entry += " - <font color='blue'>In Lobby</font>"
else
entry += " - <font color='green'>Playing</font>"
Lines += entry
for(var/line in sortList(Lines))
msg += "[line]\n"
msg += "<b>Total Players: [length(Lines)]</b>"
src << msg
to_chat(src, msg)
+27
View File
@@ -5,3 +5,30 @@
robot_module_types += "Sci-borg"
robot_module_types += "Pupdozer"
return 1
var/global/list/acceptable_fruit_types= list(
"ambrosia",
"apple",
"banana",
"berry",
"cabbage",
"carrot",
"cherry",
"chili",
"eggplant",
"grape",
"greengrapes",
"lemon",
"lime",
"onion",
"orange",
"peanut",
"potato",
"pumpkin",
"rice",
"soybean",
"sugarcane",
"tomato",
"watermelon",
"wheat",
"whitebeet")
+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)
+177
View File
@@ -0,0 +1,177 @@
/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.alpha = 15
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.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
@@ -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
@@ -303,7 +303,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<br><a href='?src=\ref[src];marking_style=1'>Body Markings +</a><br>"
for(var/M in pref.body_markings)
. += "[M] <a href='?src=\ref[src];marking_remove=[M]'>-</a> <a href='?src=\ref[src];marking_color=[M]'>Color</a>"
. += "[M] [pref.body_markings.len > 1 ? "<a href='?src=\ref[src];marking_up=[M]'>&#708;</a> <a href='?src=\ref[src];marking_down=[M]'>&#709;</a> " : ""]<a href='?src=\ref[src];marking_remove=[M]'>-</a> <a href='?src=\ref[src];marking_color=[M]'>Color</a>"
. += "<font face='fixedsys' size='3' color='[pref.body_markings[M]]'><table style='display:inline;' bgcolor='[pref.body_markings[M]]'><tr><td>__</td></tr></table></font>"
. += "<br>"
@@ -500,6 +500,24 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.body_markings[new_marking] = "#000000" //New markings start black
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["marking_up"])
var/M = href_list["marking_up"]
var/start = pref.body_markings.Find(M)
if(start != 1) //If we're not the beginning of the list, swap with the previous element.
moveElement(pref.body_markings, start, start-1)
else //But if we ARE, become the final element -ahead- of everything else.
moveElement(pref.body_markings, start, pref.body_markings.len+1)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["marking_down"])
var/M = href_list["marking_down"]
var/start = pref.body_markings.Find(M)
if(start != pref.body_markings.len) //If we're not the end of the list, swap with the next element.
moveElement(pref.body_markings, start, start+2)
else //But if we ARE, become the first element -behind- everything else.
moveElement(pref.body_markings, start, 1)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["marking_remove"])
var/M = href_list["marking_remove"]
pref.body_markings -= M
@@ -247,7 +247,7 @@ datum/gear/suit/duster
allowed_roles = list("Cargo Technician","Quartermaster")
/datum/gear/suit/roles/poncho/cloak/mining
display_name = "cloak, cargo"
display_name = "cloak, mining"
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
allowed_roles = list("Quartermaster","Shaft Miner")
@@ -116,22 +116,28 @@
path = /obj/item/weapon/cell/device
/datum/gear/utility/implant
exploitable = 1
/* VOREStation Edit - Make languages great again
/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*/
exploitable = 1
/datum/gear/utility/implant/tracking
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 0 //VOREStation Edit. Changed cost to 0
slot = "implant"
exploitable = 1
/* VOREStation Edit - Make languages great again
/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"
path = /obj/item/weapon/pen/fountain
@@ -73,14 +73,16 @@
if(!(path in negative_traits))
pref.neg_traits -= path
if(pref.species == pref.custom_base && pref.species != SPECIES_CUSTOM)
var/datum/species/selected_species = all_species[pref.species]
if(selected_species.selects_bodytype)
// Allowed!
else if(!pref.custom_base || !(pref.custom_base in custom_species_bases))
pref.custom_base = SPECIES_HUMAN
/datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character)
character.custom_species = pref.custom_species
if(pref.species == SPECIES_CUSTOM || pref.species == SPECIES_XENOCHIMERA)
var/datum/species/selected_species = all_species[pref.species]
if(selected_species.selects_bodytype)
var/datum/species/custom/CS = character.species
var/S = pref.custom_base ? pref.custom_base : "Human"
var/datum/species/custom/new_CS = CS.produceCopy(S, pref.pos_traits + pref.neu_traits + pref.neg_traits, character)
@@ -92,7 +94,8 @@
. += "<b>Custom Species</b> "
. += "<a href='?src=\ref[src];custom_species=1'>[pref.custom_species ? pref.custom_species : "-Input Name-"]</a><br>"
if(pref.species == SPECIES_CUSTOM || pref.species == SPECIES_XENOCHIMERA)
var/datum/species/selected_species = all_species[pref.species]
if(selected_species.selects_bodytype)
. += "<b>Icon Base: </b> "
. += "<a href='?src=\ref[src];custom_base=1'>[pref.custom_base ? pref.custom_base : "Human"]</a><br>"
+1 -1
View File
@@ -60,7 +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.
var/synth_markings = 1 //VOREStation edit. Enable/disable markings on synth parts.
//Some faction information.
var/home_system = "Unset" //System of birth.
@@ -75,7 +75,6 @@
/obj/item/integrated_circuit/memory/constant
name = "constant chip"
desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly."
icon_state = "memory"
complexity = 1
inputs = list()
outputs = list("output pin" = IC_PINTYPE_ANY)
@@ -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)
+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)
+27 -16
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."
@@ -77,15 +85,6 @@
"kar","yar","kzar","rha","hrar","err","fer","rir","rar","yarr","arr","ii'r","jar","kur","ran","rii","ii",
"nai","ou","kah","oa","ama","uuk","bel","chi","ayt","kay","kas","akor","tam","yir","enai")
/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/tajsign
name = LANGUAGE_ALAI
desc = "A standardized Tajaran sign language that was developed in Zarraya and gradually adopted by other nations, incorporating \
@@ -95,6 +94,19 @@
key = "l"
flags = WHITELISTED | SIGNLANG | NO_STUTTER | NONVERBAL
/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
return FALSE
/datum/language/skrell
name = LANGUAGE_SKRELLIAN
desc = "A set of warbles and hums, the language itself a complex mesh of both melodic and rhythmic components, exceptionally capable of conveying intent and emotion of the speaker."
@@ -121,7 +133,11 @@
flags = WHITELISTED
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix", "...", "oo", "q", "nq", "x", "xq", "ll", "...", "...", "...") //should sound like there's holes in it
/datum/language/skrell/get_random_name(var/gender)
var/list/first_names = file2list('config/names/first_name_skrell.txt')
var/list/last_names = file2list('config/names/last_name_skrell.txt')
return "[pick(first_names)] [pick(last_names)]"
/datum/language/human
name = LANGUAGE_SOL_COMMON
desc = "A bastardized hybrid of many languages, including Chinese, English, French, and more; it is the common language of the Sol system."
@@ -161,11 +177,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)]"
@@ -281,4 +292,4 @@
"tod", "ser", "su", "no", "nue", "el",
"ad", "al", "an", "ar", "as", "ci", "co", "de", "do", "el", "en", "er", "es", "ie", "in", "la", "lo", "me", "na",
"no", "nt", "or", "os", "pa", "qu", "ra", "re", "ro", "se", "st", "ta", "te", "to", "ue", "un",
"tod", "ser", "su", "no", "nue", "el")
"tod", "ser", "su", "no", "nue", "el")
@@ -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
@@ -2,7 +2,7 @@
var/skip_gear = 0
var/skip_body = 0
if(alpha <= 50)
if(alpha <= EFFECTIVE_INVIS)
src.loc.examine(user)
return
+4 -15
View File
@@ -166,25 +166,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)
@@ -1139,6 +1126,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
@@ -6,4 +6,4 @@
var/wagging = 0 //UGH.
var/flapping = 0
var/vantag_pref = VANTAG_NONE //What's my status?
var/impersonate_bodytype //For impersonating a bodytype
var/impersonate_bodytype //For impersonating a bodytype
@@ -36,6 +36,16 @@
if(shock_stage >= 10) tally -= 1.5 //this gets a +3 later, feral critters take reduced penalty
if(reagents.has_reagent("numbenzyme"))
tally += 1.5 //A tad bit of slowdown.
if(riding_datum) //Bit of slowdown for taur rides if rider is bigger or fatter than mount.
var/datum/riding/R = riding_datum
var/mob/living/L = R.ridden
for(var/mob/living/M in L.buckled_mobs)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.size_multiplier > L.size_multiplier)
tally += 1
if(H.weight > L.weight)
tally += 1
//VOREstation end
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
@@ -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,
@@ -3,7 +3,6 @@
name_plural = "Alraunes"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
num_alternate_languages = 2
language = LANGUAGE_ROOTLOCAL
slowdown = 1 //slow, they're plants. Not as slow as full diona.
total_health = 100 //standard
brute_mod = 1 //nothing special
@@ -14,6 +13,8 @@
min_age = 18
max_age = 250
health_hud_intensity = 1.5
base_species = SPECIES_ALRAUNE
selects_bodytype = TRUE
body_temperature = T20C
breath_type = "carbon_dioxide"
@@ -48,7 +49,8 @@
/mob/living/carbon/human/proc/succubus_drain,
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/bloodsuck) //Give them the voremodes related to wrapping people in vines and sapping their fluids
/mob/living/carbon/human/proc/bloodsuck,
/mob/living/carbon/human/proc/alraune_fruit_select) //Give them the voremodes related to wrapping people in vines and sapping their fluids
color_mult = 1
icobase = 'icons/mob/human_races/r_human_vr.dmi'
@@ -86,6 +88,7 @@
O_KIDNEYS = /obj/item/organ/internal/kidneys/alraune,
O_BRAIN = /obj/item/organ/internal/brain/alraune,
O_EYES = /obj/item/organ/internal/eyes/alraune,
A_FRUIT = /obj/item/organ/internal/fruitgland,
)
/datum/species/alraune/can_breathe_water()
@@ -332,5 +335,164 @@
/obj/item/organ/internal/liver/alraune
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "phytoextractor"
name = "phytoextractor"
desc = "A bulbous gourd-like structure."
name = "enzoretector"
desc = "A bulbous gourd-like structure."
//Begin fruit gland and its code.
/obj/item/organ/internal/fruitgland //Amazing name, I know.
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "phytoextractor"
name = "fruit gland"
desc = "A bulbous gourd-like structure."
organ_tag = A_FRUIT
var/generated_reagents = list("sugar" = 2) //This actually allows them. This could be anything, but sugar seems most fitting.
var/usable_volume = 250 //Five fruit.
var/transfer_amount = 50
var/empty_message = list("Your have no fruit on you.", "You have a distinct lack of fruit..")
var/full_message = list("You have a multitude of fruit that is ready for harvest!", "You have fruit that is ready to be picked!")
var/emote_descriptor = list("fruit right off of the Alraune!", "a fruit from the Alraune!")
var/verb_descriptor = list("grabs", "snatches", "picks")
var/self_verb_descriptor = list("grab", "snatch", "pick")
var/short_emote_descriptor = list("picks", "grabs")
var/self_emote_descriptor = list("grab", "pick", "snatch")
var/fruit_type = "apple"
var/mob/organ_owner = null
var/gen_cost = 0.5
/obj/item/organ/internal/fruitgland/New()
..()
create_reagents(usable_volume)
/obj/item/organ/internal/fruitgland/process()
if(!owner) return
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
var/before_gen
if(parent && generated_reagents && organ_owner) //Is it in the chest/an organ, has reagents, and is 'activated'
before_gen = reagents.total_volume
if(reagents.total_volume < reagents.maximum_volume)
if(organ_owner.nutrition >= gen_cost)
do_generation()
if(reagents)
if(reagents.total_volume == reagents.maximum_volume * 0.05)
to_chat(organ_owner, "<span class='notice'>[pick(empty_message)]</span>")
else if(reagents.total_volume == reagents.maximum_volume && before_gen < reagents.maximum_volume)
to_chat(organ_owner, "<span class='warning'>[pick(full_message)]</span>")
/obj/item/organ/internal/fruitgland/proc/do_generation()
organ_owner.nutrition -= gen_cost
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent])
/mob/living/carbon/human/proc/alraune_fruit_select() //So if someone doesn't want fruit/vegetables, they don't have to select one.
set name = "Select fruit"
set desc = "Select what fruit/vegetable you wish to grow."
set category = "Object"
var/obj/item/organ/internal/fruitgland/fruit_gland
for(var/F in contents)
if(istype(F, /obj/item/organ/internal/fruitgland))
fruit_gland = F
break
if(fruit_gland)
var/selection = input(src, "Choose your character's fruit type. Choosing nothing will result in a default of apples.", "Fruit Type", fruit_gland.fruit_type) as null|anything in acceptable_fruit_types
if(selection)
fruit_gland.fruit_type = selection
verbs |= /mob/living/carbon/human/proc/alraune_fruit_pick
verbs -= /mob/living/carbon/human/proc/alraune_fruit_select
fruit_gland.organ_owner = src
fruit_gland.emote_descriptor = list("fruit right off of [fruit_gland.organ_owner]!", "a fruit from [fruit_gland.organ_owner]!")
else
to_chat(src, "<span class='notice'>You lack the organ required to produce fruit.</span>")
return
/mob/living/carbon/human/proc/alraune_fruit_pick()
set name = "Pick Fruit"
set desc = "Pick fruit off of [src]."
set category = "Object"
set src in view(1)
//do_reagent_implant(usr)
if(!isliving(usr) || !usr.canClick())
return
if(usr.incapacitated() || usr.stat > CONSCIOUS)
return
var/obj/item/organ/internal/fruitgland/fruit_gland
for(var/I in contents)
if(istype(I, /obj/item/organ/internal/fruitgland))
fruit_gland = I
break
if (fruit_gland) //Do they have the gland?
if(fruit_gland.reagents.total_volume < fruit_gland.transfer_amount)
to_chat(src, "<span class='notice'>[pick(fruit_gland.empty_message)]</span>")
return
var/datum/seed/S = plant_controller.seeds["[fruit_gland.fruit_type]"]
S.harvest(usr,0,0,1)
var/index = rand(0,2)
if (usr != src)
var/emote = fruit_gland.emote_descriptor[index]
var/verb_desc = fruit_gland.verb_descriptor[index]
var/self_verb_desc = fruit_gland.self_verb_descriptor[index]
usr.visible_message("<span class='notice'>[usr] [verb_desc] [emote]</span>",
"<span class='notice'>You [self_verb_desc] [emote]</span>")
else
visible_message("<span class='notice'>[src] [pick(fruit_gland.short_emote_descriptor)] a fruit.</span>",
"<span class='notice'>You [pick(fruit_gland.self_emote_descriptor)] a fruit.</span>")
fruit_gland.reagents.remove_any(fruit_gland.transfer_amount)
//End of fruit gland code.
/datum/species/alraune/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
ASSERT(to_copy)
ASSERT(istype(H))
if(ispath(to_copy))
to_copy = "[initial(to_copy.name)]"
if(istext(to_copy))
to_copy = all_species[to_copy]
var/datum/species/alraune/new_copy = new()
//Initials so it works with a simple path passed, or an instance
new_copy.base_species = to_copy.name
new_copy.icobase = to_copy.icobase
new_copy.deform = to_copy.deform
new_copy.tail = to_copy.tail
new_copy.tail_animation = to_copy.tail_animation
new_copy.icobase_tail = to_copy.icobase_tail
new_copy.color_mult = to_copy.color_mult
new_copy.primitive_form = to_copy.primitive_form
new_copy.appearance_flags = to_copy.appearance_flags
new_copy.flesh_color = to_copy.flesh_color
new_copy.base_color = to_copy.base_color
new_copy.blood_mask = to_copy.blood_mask
new_copy.damage_mask = to_copy.damage_mask
new_copy.damage_overlays = to_copy.damage_overlays
//Set up a mob
H.species = new_copy
H.icon_state = lowertext(new_copy.get_bodytype())
if(new_copy.holder_type)
H.holder_type = new_copy.holder_type
if(H.dna)
H.dna.ready_dna(H)
return new_copy
/datum/species/alraune/get_bodytype()
return base_species
/datum/species/alraune/get_race_key()
var/datum/species/real = all_species[base_species]
return real.race_key
@@ -1,15 +1,18 @@
/datum/species
//var/vore_numbing = 0
var/gets_food_nutrition = 1 // If this is set to 0, the person can't get nutrition from food.
var/gets_food_nutrition = TRUE // If this is set to 0, the person can't get nutrition from food.
var/metabolism = 0.0015
var/lightweight = 0 //Oof! Nonhelpful bump stumbles.
var/trashcan = 0 //It's always sunny in the wrestling ring.
var/lightweight = FALSE //Oof! Nonhelpful bump stumbles.
var/trashcan = FALSE //It's always sunny in the wrestling ring.
var/base_species = null // Unused outside of a few species
var/selects_bodytype = FALSE // Allows the species to choose from body types intead of being forced to be just one.
/datum/species/custom
name = SPECIES_CUSTOM
name_plural = "Custom"
var/base_species = "Human"
selects_bodytype = TRUE
base_species = SPECIES_HUMAN
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
@@ -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
@@ -53,7 +53,7 @@
var/datum/robolimb/M = chargen_robolimbs[company]
if(!(choice in M.parts))
continue
if(species.name in M.species_cannot_use)
if(impersonate_bodytype in M.species_cannot_use)
continue
if(M.whitelisted_to && !(ckey in M.whitelisted_to))
continue
@@ -106,7 +106,7 @@
var/datum/robolimb/M = chargen_robolimbs[company]
if(!(BP_TORSO in M.parts))
continue
if(species.name in M.species_cannot_use)
if(impersonate_bodytype in M.species_cannot_use)
continue
if(M.whitelisted_to && !(ckey in M.whitelisted_to))
continue
@@ -374,4 +374,4 @@
icon_state = "metal"
to_call = /mob/living/carbon/human/proc/nano_metalnom
#undef PER_LIMB_STEEL_COST
#undef PER_LIMB_STEEL_COST
@@ -1,7 +1,7 @@
#define DAM_SCALE_FACTOR 0.01
#define METAL_PER_TICK 150
/datum/species/protean
name = "Protean"
name = SPECIES_PROTEAN
name_plural = "Proteans"
blurb = "Sometimes very advanced civilizations will produce the ability to swap into manufactured, robotic bodies. And sometimes \
<i>VERY</i> advanced civilizations have the option of 'nanoswarm' bodies. Effectively a single robot body comprised \
@@ -139,7 +139,7 @@
if(H.backbag == 1) //Somewhat misleading, 1 == no bag (not boolean)
H.equip_to_slot_or_del(permit, slot_l_hand)
H.equip_to_slot_or_del(metal_stack, slot_r_hand)
H.equip_to_slot_or_del(metal_stack, slot_r_hand)
else
H.equip_to_slot_or_del(permit, slot_in_backpack)
H.equip_to_slot_or_del(metal_stack, slot_in_backpack)
@@ -172,7 +172,7 @@
var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs
if(refactory && !(refactory.status & ORGAN_DEAD))
//MHydrogen adds speeeeeed
if(refactory.get_stored_material("mhydrogen") >= METAL_PER_TICK)
H.add_modifier(/datum/modifier/protean/mhydrogen, origin = refactory)
@@ -233,7 +233,7 @@
var/obj/item/organ/internal/nano/refactory/refactory = origin.resolve()
if(!istype(refactory) || refactory.status & ORGAN_DEAD)
expire()
//Out of materials
if(!refactory.use_stored_material(material_name,material_use))
expire()
@@ -255,7 +255,7 @@
on_created_text = "<span class='notice'>You feel yourself become nearly impervious to physical attacks as plasteel nanites are made.</span>"
on_expired_text = "<span class='notice'>Your refactory finishes consuming the plasteel, and you return to your normal nanites.</span>"
material_name = "plasteel"
incoming_brute_damage_percent = 0.5
@@ -266,7 +266,7 @@
on_created_text = "<span class='notice'>You feel yourself become more reflective, able to resist heat and fire better for a time.</span>"
on_expired_text = "<span class='notice'>Your refactory finishes consuming the diamond, and you return to your normal nanites.</span>"
material_name = "diamond"
incoming_fire_damage_percent = 0.2
@@ -277,7 +277,7 @@
on_created_text = "<span class='notice'>You feel new nanites being produced from your stockpile of steel, healing you slowly.</span>"
on_expired_text = "<span class='notice'>Your steel supply has either run out, or is no longer needed, and your healing stops.</span>"
material_name = "steel"
/datum/modifier/protean/steel/tick()
@@ -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
@@ -217,6 +218,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,
@@ -243,6 +245,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
@@ -317,13 +320,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
@@ -5,7 +5,7 @@
/datum/species/xenochimera //Scree's race.
name = "Xenochimera"
name = SPECIES_XENOCHIMERA
name_plural = "Xenochimeras"
icobase = 'icons/mob/human_races/r_xenochimera.dmi'
deform = 'icons/mob/human_races/r_def_xenochimera.dmi'
@@ -14,7 +14,8 @@
slowdown = -0.2 //scuttly, but not as scuttly as a tajara or a teshari.
brute_mod = 0.8 //About as tanky to brute as a Unathi. They'll probably snap and go feral when hurt though.
burn_mod = 1.15 //As vulnerable to burn as a Tajara.
var/base_species = "Xenochimera"
base_species = "Xenochimera"
selects_bodytype = TRUE
num_alternate_languages = 2
secondary_langs = list("Sol Common")
@@ -300,7 +301,7 @@
/////SPIDER RACE/////
/////////////////////
/datum/species/spider //These actually look pretty damn spooky!
name = "Vasilissan"
name = SPECIES_VASILISSAN
name_plural = "Vasilissans"
icobase = 'icons/mob/human_races/r_spider.dmi'
deform = 'icons/mob/human_races/r_def_spider.dmi'
@@ -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
@@ -1277,4 +1277,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
+7 -2
View File
@@ -380,8 +380,13 @@
var/turf/location = get_turf(src)
location.hotspot_expose(fire_burn_temperature(), 50, 1)
/mob/living/fire_act()
adjust_fire_stacks(2)
//altered this to cap at the temperature of the fire causing it, using the same 1:1500 value as /mob/living/carbon/human/handle_fire() in human/life.dm
/mob/living/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature)
if(fire_stacks < exposed_temperature/1500) // Subject to balance
adjust_fire_stacks(2)
else
adjust_fire_stacks(2)
IgniteMob()
//Share fire evenly between the two mobs
+2 -1
View File
@@ -16,7 +16,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
@@ -59,3 +58,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
+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"
@@ -142,15 +142,27 @@
chargecost = 500
/obj/item/weapon/shockpaddles/robot/hound/jumper
name = "paws of life"
icon = 'icons/mob/dogborg_vr.dmi'
icon_state = "defibpaddles0"
name = "jumper paws"
desc = "Zappy paws. For rebooting a full body prostetic."
combat = 1
attack_verb = list("batted", "pawed", "bopped", "whapped")
chargecost = 500
use_on_synthetic = 1
/obj/item/weapon/reagent_containers/borghypo/hound
name = "MediHound hypospray"
desc = "An advanced chemical synthesizer and injection system utilizing carrier's reserves, designed for heavy-duty medical equipment."
charge_cost = 10
var/datum/matter_synth/water = null
/obj/item/weapon/reagent_containers/borghypo/hound/process() //Recharges in smaller steps and uses the water reserves as well.
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
if(R && R.cell)
for(var/T in reagent_ids)
if(reagent_volumes[T] < volume && water.energy >= charge_cost)
R.cell.use(charge_cost)
water.use_charge(charge_cost)
reagent_volumes[T] = min(reagent_volumes[T] + 1, volume)
return 1
//Tongue stuff
/obj/item/device/dogborg/tongue
name = "synthetic tongue"
@@ -188,7 +200,14 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(user.client && (target in user.client.screen))
to_chat(user, "<span class='warning'>You need to take \the [target.name] off before cleaning it!</span>")
else if(istype(target,/obj/effect/decal/cleanable) && water.energy >= 5)
if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/toilet)) //Dog vibes.
user.visible_message("[user] begins to lap up water from [target.name].", "<span class='notice'>You begin to lap up water from [target.name].</span>")
if(do_after (user, 50))
water.add_charge(50)
else if(water.energy < 5)
to_chat(user, "<span class='notice'>Your mouth feels dry.</span>")
return
else if(istype(target,/obj/effect/decal/cleanable))
user.visible_message("[user] begins to lick off \the [target.name].", "<span class='notice'>You begin to lick off \the [target.name]...</span>")
if(do_after (user, 50))
to_chat(user, "<span class='notice'>You finish licking off \the [target.name].</span>")
@@ -196,7 +215,7 @@
qdel(target)
var/mob/living/silicon/robot.R = user
R.cell.charge += 50
else if(istype(target,/obj/item) && water.energy >= 5)
else if(istype(target,/obj/item))
if(istype(target,/obj/item/trash))
user.visible_message("[user] nibbles away at \the [target.name].", "<span class='notice'>You begin to nibble away at \the [target.name]...</span>")
if(do_after (user, 50))
@@ -238,25 +257,14 @@
"<span class='userdanger'>[user] has shocked you with its tongue! You can feel the betrayal.</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
R.cell.charge -= 666
else if(water.energy >= 5)
else
user.visible_message("<span class='notice'>\the [user] affectionally licks all over \the [target]'s face!</span>", "<span class='notice'>You affectionally lick all over \the [target]'s face!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
water.use_charge(5)
var/mob/living/carbon/human/H = target
if(H.species.lightweight == 1)
H.Weaken(3)
return
else if(istype(target, /obj/structure/window) && water.energy >= 1)
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after (user, 50))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
water.use_charge(5)
target.color = initial(target.color)
else if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/toilet)) //Dog vibes.
user.visible_message("[user] begins to lap up water from [target.name].", "<span class='notice'>You begin to lap up water from [target.name].</span>")
if(do_after (user, 50))
water.add_charge(100)
else if(water.energy >= 5)
else
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after (user, 50))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
@@ -11,7 +11,6 @@
var/min_health = -100
var/cleaning = 0
var/patient_laststat = null
var/mob_energy = -100 //Energy gained from digesting dead mobs (including PCs)
var/list/injection_chems = list("inaprovaline", "dexalin", "bicaridine", "kelotane","anti_toxin", "alkysine", "imidazoline", "spaceacillin", "paracetamol") //The borg is able to heal every damage type. As a nerf, they use 750 charge per injection.
var/eject_port = "ingestion"
var/list/items_preserved = list()
@@ -19,6 +18,12 @@
var/compactor = FALSE
var/analyzer = FALSE
var/decompiler = FALSE
var/delivery = FALSE
var/delivery_tag = "Fuel"
var/list/deliverylists = list()
var/list/deliveryslot_1 = list()
var/list/deliveryslot_2 = list()
var/list/deliveryslot_3 = list()
var/datum/research/techonly/files //Analyzerbelly var.
var/synced = FALSE
var/startdrain = 500
@@ -50,52 +55,11 @@
return
if(target in hound.module.modules)
return
if(length(contents) > (max_item_count - 1))
if(length(contents) >= max_item_count)
to_chat(user, "<span class='warning'>Your [src.name] is full. Eject or process contents to continue.</span>")
return
if(analyzer == TRUE)
if(istype(target, /obj/item))
var/obj/target_obj = target
if(target_obj.w_class > ITEMSIZE_LARGE)
to_chat(user, "<span class='warning'>\The [target] is too large to fit into your [src.name]</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
if(do_after(user, 30, target) && length(contents) < max_item_count)
target.forceMove(src)
user.visible_message("<span class='warning'>[hound.name]'s internal analyzer groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your internal analyzer groans lightly as [target] slips inside.</span>")
playsound(hound, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(istype(target,/obj/item))
var/obj/item/tech_item = target
for(var/T in tech_item.origin_tech)
to_chat(user, "<span class='notice'>\The [tech_item] has level [tech_item.origin_tech[T]] in [CallTechName(T)].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
else if(ishuman(target))
var/mob/living/carbon/human/trashman = target
if(patient)
to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
return
if(trashman.buckled)
to_chat(user, "<span class='warning'>[trashman] is buckled and can not be put into your [src.name].</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashman] into their [src.name].</span>", "<span class='notice'>You start ingesting [trashman] into your [src.name]...</span>")
if(do_after(user, 30, trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
trashman.forceMove(src)
trashman.reset_view(src)
processing_objects |= src
user.visible_message("<span class='warning'>[hound.name]'s internal analyzer groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your internal analyzer groans lightly as [trashman] slips inside.</span>")
playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
return
if(compactor == TRUE)
if(compactor)
if(istype(target, /obj/item) || istype(target, /obj/effect/decal/remains))
var/obj/target_obj = target
if(target_obj.w_class > ITEMSIZE_LARGE)
@@ -104,11 +68,17 @@
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
if(do_after(user, 30, target) && length(contents) < max_item_count)
target.forceMove(src)
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [target] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your [src.name] groans lightly as [target] slips inside.</span>")
playsound(hound, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(analyzer && istype(target,/obj/item))
var/obj/item/tech_item = target
for(var/T in tech_item.origin_tech)
to_chat(user, "<span class='notice'>\The [tech_item] has level [tech_item.origin_tech[T]] in [CallTechName(T)].</span>")
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= target
to_chat(user, "<span class='notice'>\The [target.name] added to cargo compartment slot: [delivery_tag].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
if(istype(target, /mob/living/simple_animal/mouse)) //Edible mice, dead or alive whatever. Mostly for carcass picking you cruel bastard :v
@@ -117,11 +87,13 @@
if(do_after(user, 30, trashmouse) && length(contents) < max_item_count)
trashmouse.forceMove(src)
trashmouse.reset_view(src)
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashmouse] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashmouse] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] groans lightly as [trashmouse] slips inside.</span>", "<span class='notice'>Your [src.name] groans lightly as [trashmouse] slips inside.</span>")
playsound(hound, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= trashmouse
to_chat(user, "<span class='notice'>\The [trashmouse] added to cargo compartment slot: [delivery_tag].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
else if(ishuman(target))
@@ -137,13 +109,18 @@
trashman.forceMove(src)
trashman.reset_view(src)
processing_objects |= src
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your [src.name] groans lightly as [trashman] slips inside.</span>")
message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= trashman
to_chat(user, "<span class='notice'>\The [trashman] added to cargo compartment slot: [delivery_tag].</span>")
to_chat(trashman, "<span class='notice'>[hound.name] has added you to their cargo compartment slot: [delivery_tag].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
return
else if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.buckled)
@@ -154,50 +131,38 @@
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [H.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [H] into your [src]...</span>")
if(!patient && !H.buckled && do_after (user, 50, H))
if(!proximity) return //If they moved away, you can't eat them.
if(patient) return //If you try to eat two people at once, you can only eat one.
if(!proximity)
return //If they moved away, you can't eat them.
if(patient)
return //If you try to eat two people at once, you can only eat one.
else //If you don't have someone in you, proceed.
H.forceMove(src)
H.reset_view(src)
update_patient()
processing_objects |= src
user.visible_message("<span class='warning'>[hound.name]'s medical pod lights up as [H.name] slips inside into their [src.name].</span>", "<span class='notice'>Your medical pod lights up as [H] slips into your [src]. Life support functions engaged.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] lights up as [H.name] slips inside.</span>", "<span class='notice'>Your [src] lights up as [H] slips inside. Life support functions engaged.</span>")
message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(UI_open == TRUE)
sleeperUI(usr)
/obj/item/device/dogborg/sleeper/proc/go_out(var/target)
hound = src.loc
items_preserved.Cut()
cleaning = 0
for(var/list/dlist in deliverylists)
dlist.Cut()
if(length(contents) > 0)
hound.visible_message("<span class='warning'>[hound.name] empties out their contents via their [eject_port] port.</span>", "<span class='notice'>You empty your contents via your [eject_port] port.</span>")
if(target)
if(ishuman(target))
var/mob/living/carbon/human/person = target
for(var/C in contents)
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = target
var/obj/T = C
T.loc = hound.loc
else
for(var/C in contents)
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = C
T.loc = hound.loc
items_preserved.Cut()
cleaning = 0
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
update_patient()
else //You clicked eject with nothing in you, let's just reset stuff to be sure.
items_preserved.Cut()
cleaning = 0
update_patient()
/obj/item/device/dogborg/sleeper/proc/drain(var/amt = 3) //Slightly reduced cost (before, it was always injecting inaprov)
@@ -208,10 +173,9 @@
if(..())
return
sleeperUI(user)
UI_open = TRUE
/obj/item/device/dogborg/sleeper/proc/sleeperUI(mob/user)
var/dat
var/dat = "<TITLE>[name] Console</TITLE><BR>"
if(islist(injection_chems)) //Only display this if we're a drug-dispensing doggo.
dat += "<h3>Injector</h3>"
@@ -234,15 +198,33 @@
dat += "<A href='?src=\ref[src];clean=1'>Self-Clean</A>"
else
dat += "<span class='linkOff'>Self-Clean</span>"
if(delivery)
dat += "<BR><h3>Cargo Compartment</h3><BR>"
dat += "<A href='?src=\ref[src];deliveryslot=1'>Active Slot: [delivery_tag]</A>"
if(islist(deliverylists[delivery_tag]))
dat += "<A href='?src=\ref[src];slot_eject=1'>Eject Slot</A>"
dat += "<div class='statusDisplay'>"
if(compactor == TRUE && length(contents))//garbage counter for trashpup
var/obj/item/device/dogborg/sleeper/compactor/garbo = src
dat += "<font color='red'><B>Current load:</B> [length(contents)] / [garbo.max_item_count] objects.</font><BR>"
if(!delivery && compactor && length(contents))//garbage counter for trashpup
dat += "<font color='red'><B>Current load:</B> [length(contents)] / [max_item_count] objects.</font><BR>"
dat += "<font color='gray'>([list2text(contents,", ")])</font><BR><BR>"
if(analyzer == TRUE && synced == FALSE)
if(delivery && length(contents))
dat += "<font color='red'><B>Current load:</B> [length(contents)] / [max_item_count] objects.</font><BR>"
dat += "<font color='gray'>Cargo compartment slot: Cargo 1.</font><BR>"
if(length(deliveryslot_1))
dat += "<font color='gray'>([list2text(deliveryslot_1,", ")])</font><BR>"
dat += "<font color='gray'>Cargo compartment slot: Cargo 2.</font><BR>"
if(length(deliveryslot_2))
dat += "<font color='gray'>([list2text(deliveryslot_2,", ")])</font><BR>"
dat += "<font color='gray'>Cargo compartment slot: Cargo 3.</font><BR>"
if(length(deliveryslot_3))
dat += "<font color='gray'>([list2text(deliveryslot_3,", ")])</font><BR>"
dat += "<font color='red'>Cargo compartment slot: Fuel.</font><BR>"
dat += "<font color='red'>([list2text(contents - (deliveryslot_1 + deliveryslot_2 + deliveryslot_3),", ")])</font><BR><BR>"
if(analyzer && synced)
dat += "<A href='?src=\ref[src];sync=1'>Sync Files</A><BR>"
//Cleaning and there are still un-preserved items
@@ -295,10 +277,10 @@
dat += "<div class='line'><div style='width: 170px;' class='statusLabel'>[R.name]:</div><div class='statusValue'>[round(R.volume, 0.1)] units</div></div><br>"
dat += "</div>"
var/datum/browser/popup = new(user, "sleeper", "[name] Console", 520, 540) //Set up the popup browser window
//popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) //I have no idea what this is, but it feels irrelevant and causes runtimes idk.
var/datum/browser/popup = new(user, "sleeper_b", "[name] Console", 400, 500, src)
popup.set_content(dat)
popup.open()
UI_open = TRUE
return
/obj/item/device/dogborg/sleeper/Topic(href, href_list)
@@ -328,7 +310,6 @@
drain(startdrain)
processing_objects |= src
update_patient()
sleeperUI(usr)
if(patient)
to_chat(patient, "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>")
return
@@ -343,7 +324,29 @@
eject_port = "ingestion"
sleeperUI(usr)
return
if(href_list["deliveryslot"])
var/tag = input("Select active delivery slot.") as null|anything in deliverylists
if(!tag)
return 0
delivery_tag = tag
sleeperUI(usr)
return
if(href_list["slot_eject"])
if(length(deliverylists[delivery_tag]) > 0)
hound.visible_message("<span class='warning'>[hound.name] empties out their cargo compartment via their [eject_port] port.</span>", "<span class='notice'>You empty your cargo compartment via your [eject_port] port.</span>")
for(var/C in deliverylists[delivery_tag])
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = C
T.loc = hound.loc
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
update_patient()
deliverylists[delivery_tag].Cut()
sleeperUI(usr)
return
if(href_list["sync"])
synced = TRUE
var/success = 0
@@ -392,6 +395,15 @@
//For if the dogborg's existing patient uh, doesn't make it.
/obj/item/device/dogborg/sleeper/proc/update_patient()
hound = src.loc
if(UI_open == TRUE)
sleeperUI(hound)
//Cleaning looks better with red on, even with nobody in it
if(cleaning || (length(contents) > 10) || (decompiler && (length(contents) > 5)) || (analyzer && (length(contents) > 1)))
hound.sleeper_r = TRUE
hound.sleeper_g = FALSE
hound.updateicon()
return
//Well, we HAD one, what happened to them?
if(patient in contents)
@@ -411,8 +423,6 @@
//Update icon
hound.updateicon()
//Return original patient
if(UI_open == TRUE)
sleeperUI(usr)
return(patient)
//Check for a new patient
@@ -433,30 +443,16 @@
patient_laststat = patient.stat
//Update icon and return new patient
hound.updateicon()
if(UI_open == TRUE)
sleeperUI(usr)
return(C)
//Cleaning looks better with red on, even with nobody in it
if(cleaning || (length(contents) > 11))
hound.sleeper_r = TRUE
hound.sleeper_g = FALSE
//Letting analyzer gut swell if overloaded.
if(analyzer == TRUE && (length(contents) > 1))
hound.sleeper_r = TRUE
hound.sleeper_g = FALSE
//Couldn't find anyone, and not cleaning
else if(!cleaning && !patient && !length(contents))
if(!cleaning && !patient)
hound.sleeper_r = FALSE
hound.sleeper_g = FALSE
patient_laststat = null
patient = null
hound.updateicon()
if(UI_open == TRUE)
sleeperUI(usr)
return
//Gurgleborg process
@@ -467,10 +463,10 @@
if(!(I in contents))
items_preserved -= I
var/list/touchable_items = contents - items_preserved
var/list/touchable_items = contents - items_preserved - (deliveryslot_1 + deliveryslot_2 + deliveryslot_3)
//Belly is entirely empty
if(!length(contents))
if(!length(touchable_items))
var/finisher = pick(
'sound/vore/death1.ogg',
'sound/vore/death2.ogg',
@@ -508,9 +504,11 @@
if(air_master.current_cycle%3==1 && length(touchable_items))
//Burn all the mobs or add them to the exclusion list
var/volume = 0
for(var/mob/living/T in (touchable_items))
touchable_items -= T //Exclude mobs from loose item picking.
if((T.status_flags & GODMODE) || !T.digestable)
items_preserved += T
items_preserved |= T
else
var/old_brute = T.getBruteLoss()
var/old_burn = T.getFireLoss()
@@ -520,66 +518,55 @@
var/actual_burn = T.getFireLoss() - old_burn
var/damage_gain = actual_brute + actual_burn
drain(-25 * damage_gain) //25*total loss as with voreorgan stats.
update_patient()
water.add_charge(damage_gain)
if(T.stat == DEAD)
if(ishuman(T))
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound, "<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T, "<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
var/deathsound = pick(
'sound/vore/death1.ogg',
'sound/vore/death2.ogg',
'sound/vore/death3.ogg',
'sound/vore/death4.ogg',
'sound/vore/death5.ogg',
'sound/vore/death6.ogg',
'sound/vore/death7.ogg',
'sound/vore/death8.ogg',
'sound/vore/death9.ogg',
'sound/vore/death10.ogg')
playsound(hound, deathsound, vol = 100, vary = 1, falloff = 0.1, ignore_walls = TRUE, preference = /datum/client_preference/digestion_noises)
if(is_vore_predator(T))
for(var/belly in T.vore_organs)
var/obj/belly/B = belly
for(var/atom/movable/thing in B)
thing.forceMove(src)
if(ismob(thing))
to_chat(thing, "As [T] melts away around you, you find yourself in [hound]'s [name]")
for(var/obj/item/I in T)
if(istype(I,/obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = I
var/atom/movable/brain = MMI.removed()
if(brain)
hound.remove_from_mob(brain,src)
brain.forceMove(src)
items_preserved |= brain
else
T.drop_from_inventory(I, src)
if(ishuman(T))
var/mob/living/carbon/human/Prey = T
volume = (Prey.bloodstr.total_volume + Prey.ingested.total_volume + Prey.touching.total_volume + Prey.weight) * Prey.size_multiplier
water.add_charge(volume)
if(T.reagents)
volume = T.reagents.total_volume
water.add_charge(volume)
qdel(T)
//Pick a random item to deal with (if there are any)
var/atom/target = pick(touchable_items)
var/volume = 0
if(length(touchable_items))
var/atom/target = pick(touchable_items)
//Handle the target being a mob
if(isliving(target))
var/mob/living/T = target
//Mob is now dead
if(T.stat == DEAD)
if(ishuman(target))
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound, "<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T, "<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
drain(mob_energy) //Fueeeeellll
var/deathsound = pick(
'sound/vore/death1.ogg',
'sound/vore/death2.ogg',
'sound/vore/death3.ogg',
'sound/vore/death4.ogg',
'sound/vore/death5.ogg',
'sound/vore/death6.ogg',
'sound/vore/death7.ogg',
'sound/vore/death8.ogg',
'sound/vore/death9.ogg',
'sound/vore/death10.ogg')
playsound(hound, deathsound, vol = 100, vary = 1, falloff = 0.1, ignore_walls = TRUE, preference = /datum/client_preference/digestion_noises)
if(is_vore_predator(T))
for(var/belly in T.vore_organs)
var/obj/belly/B = belly
for(var/atom/movable/thing in B)
thing.forceMove(src)
if(ismob(thing))
to_chat(thing, "As [T] melts away around you, you find yourself in [hound]'s [name]")
for(var/obj/item/I in T)
if(istype(I,/obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = I
var/atom/movable/brain = MMI.removed()
if(brain)
hound.remove_from_mob(brain,src)
brain.forceMove(src)
items_preserved += brain
else
T.drop_from_inventory(I, src)
if(ishuman(T))
var/mob/living/carbon/human/Prey = T
volume = (Prey.bloodstr.total_volume + Prey.ingested.total_volume + Prey.touching.total_volume + Prey.weight) * Prey.size_multiplier
water.add_charge(volume)
if(T.reagents)
volume = T.reagents.total_volume
water.add_charge(volume)
qdel(T)
update_patient()
if(UI_open == TRUE)
sleeperUI(hound)
//Handle the target being anything but a /mob/living
else
//Handle the target being anything but a /mob/living
var/obj/item/T = target
if(istype(T))
if(T.reagents)
@@ -596,12 +583,12 @@
drain(-50 * digested)
if(volume)
water.add_charge(volume)
if(!analyzer && compactor && T.matter)
if(!analyzer && !delivery && compactor && T.matter)
for(var/material in T.matter)
var/total_material = T.matter[material]
if(istype(T,/obj/item/stack))
var/obj/item/stack/stack = T
total_material *= stack.get_amount()
total_material *= (0.5 * stack.get_amount())
if(material == DEFAULT_WALL_MATERIAL)
metal.add_charge(total_material)
if(material == "glass")
@@ -618,10 +605,8 @@
drain(-100)
else
items_preserved |= target
if(UI_open == TRUE)
update_patient()
sleeperUI(hound)
return
update_patient()
return
/obj/item/device/dogborg/sleeper/process()
@@ -671,4 +656,11 @@
desc = "A mounted matter decompiling unit with fuel processor."
icon_state = "decompiler"
max_item_count = 10
decompiler = TRUE
decompiler = TRUE
/obj/item/device/dogborg/sleeper/compactor/delivery //Unfinished and unimplemented, still testing.
name = "Cargo Belly"
desc = "A mounted cargo bay unit for tagged deliveries."
icon_state = "decompiler"
max_item_count = 20
delivery = TRUE
@@ -216,6 +216,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,7 +148,7 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
@@ -208,7 +208,6 @@
src.modules += new /obj/item/weapon/dogborg/jaws/small(src) //In case a patient is being attacked by carp.
src.modules += new /obj/item/device/dogborg/boop_module(src) //Boop the crew.
src.modules += new /obj/item/device/healthanalyzer(src) // See who's hurt specificially.
src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)//So medi-hounds aren't nearly useless
src.modules += new /obj/item/weapon/reagent_containers/syringe(src) //In case the chemist is nice!
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker(src)//For holding the chemicals when the chemist is nice
src.modules += new /obj/item/device/sleevemate(src) //Lets them scan people.
@@ -218,11 +217,15 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
var/obj/item/weapon/reagent_containers/borghypo/hound/H = new /obj/item/weapon/reagent_containers/borghypo/hound(src)
H.water = water
src.modules += H
var/obj/item/device/dogborg/tongue/T = new /obj/item/device/dogborg/tongue(src)
T.water = water
src.modules += T
@@ -264,7 +267,7 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
@@ -307,17 +310,17 @@
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
metal.name = "Steel reserves"
metal.recharge_rate = 0
metal.max_energy = 100000
metal.max_energy = 50000
metal.energy = 0
var/datum/matter_synth/glass = new /datum/matter_synth/glass()
glass.name = "Glass reserves"
glass.recharge_rate = 0
glass.max_energy = 100000
glass.max_energy = 50000
glass.energy = 0
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
@@ -390,7 +393,7 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
@@ -435,7 +438,7 @@
src.modules += new /obj/item/device/t_scanner(src)
src.modules += new /obj/item/taperoll/engineering(src)
src.modules += new /obj/item/weapon/inflatable_dispenser/robot(src)
src.modules += new /obj/item/device/geiger(src)
src.modules += new /obj/item/weapon/pickaxe(src)
src.modules += new /obj/item/weapon/dogborg/jaws/small(src)
src.modules += new /obj/item/device/dogborg/boop_module(src)
src.emag = new /obj/item/weapon/dogborg/pounce(src)
@@ -444,27 +447,27 @@
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
metal.name = "Steel reserves"
metal.recharge_rate = 50
metal.max_energy = 100000
metal.max_energy = 50000
metal.energy = 5000
var/datum/matter_synth/glass = new /datum/matter_synth/glass()
glass.name = "Glass reserves"
glass.recharge_rate = 50
glass.max_energy = 100000
glass.max_energy = 50000
glass.energy = 5000
var/datum/matter_synth/wood = new /datum/matter_synth/wood()
wood.name = "Wood reserves"
wood.recharge_rate = 50
wood.max_energy = 100000
wood.max_energy = 50000
wood.energy = 5000
var/datum/matter_synth/plastic = new /datum/matter_synth/plastic()
plastic.name = "Plastic reserves"
plastic.recharge_rate = 50
plastic.max_energy = 100000
plastic.max_energy = 50000
plastic.energy = 5000
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
@@ -489,6 +492,7 @@
MD.glass = glass
MD.wood = wood
MD.plastic = plastic
MD.water = water
src.modules += MD
var/obj/item/stack/material/cyborg/steel/M = new (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)
@@ -1,7 +1,7 @@
/mob/living/simple_animal/penguin
name = "space penguin"
desc = "An ungainly, waddling, cute, and VERY well-dressed bird."
tt_desc = "Aptenodytes forsteri"
tt_desc = "E Aptenodytes forsteri"
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"
@@ -915,6 +915,8 @@
continue
else if(L in friends)
continue
else if(L.alpha <= EFFECTIVE_INVIS)
continue
else if(!SA_attackable(L))
continue
else if(!special_target_check(L))
@@ -1242,7 +1244,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.alpha <= EFFECTIVE_INVIS)) //if the target went invisible, you can't follow it
LoseTarget()
return 0
if(!(target_mob in ListTargets(view_range)))
@@ -16,12 +16,16 @@
melee_damage_lower = 5
melee_damage_upper = 10
response_help = "pets the"
response_disarm = "gently baps the"
response_harm = "hits the"
speak_chance = 2
speak = list("Meow!","Esp!","Purr!","HSSSSS","Mew?","Nya~")
speak_emote = list("purrs","meows")
emote_hear = list("meows","mews")
emote_see = list("shakes her head","shivers")
attacktext = list("swatted")
emote_see = list("shakes her head","shivers","stretches","grooms herself")
attacktext = list("swatted","bapped")
var/random_skin = 1
var/list/skins = list(
@@ -161,7 +161,7 @@
// TODO - Customizable per mob
B.emote_lists[DM_HOLD] = list(
"The walls gently squeeze against you. The wet sounds of shifting flesh against your form fill the air.",
"The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxxing again.",
"The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxing again.",
"Your body is soaked in the fluids that cling to the churning walls. They squeeze across your form gently, conforming to your shape.",
"You can feel the world around you shift and sway as the creature moves! The flesh is stretchy, doughy. You can sink into it a little ways before it bounces back, curling you into a small shape."
)
@@ -200,7 +200,7 @@
. = ..()
if(ability_flags & AB_PHASE_SHIFTED)
density = FALSE
//Convert spare nutrition into energy at a certain ratio
if(. && nutrition > initial(nutrition) && energy < 100)
nutrition = max(0, nutrition-5)
@@ -208,7 +208,7 @@
/mob/living/simple_animal/shadekin/update_icon()
. = ..()
cut_overlay(tailimage)
tailimage.icon_state = icon_state
+4 -3
View File
@@ -482,9 +482,10 @@
if(mind)
mind.active = 0 //we wish to transfer the key manually
if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
new_character.rename_self("clown")
// VOREStation edit to disable the destructive forced renaming for our responsible whitelist clowns.
//if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
// new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
// new_character.rename_self("clown")
mind.original = new_character
// VOREStation
mind.loaded_from_ckey = client.ckey
+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
+2
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
+1 -1
View File
@@ -185,7 +185,7 @@ var/global/list/limb_icon_cache = list()
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"], mark_style.color_blend_mode) // VOREStation edit
overlays |= mark_s //So when it's not on your body, it has icons
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"]]"
+8
View File
@@ -86,6 +86,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Tajara"
/obj/item/weapon/disk/limb/dsi_tajaran
@@ -99,6 +100,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Unathi"
/obj/item/weapon/disk/limb/dsi_lizard
@@ -112,6 +114,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Sergal"
/obj/item/weapon/disk/limb/dsi_sergal
@@ -125,6 +128,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Nevrean"
/obj/item/weapon/disk/limb/dsi_nevrean
@@ -138,6 +142,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Vulpkanin"
/obj/item/weapon/disk/limb/dsi_vulpkanin
@@ -151,6 +156,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Akula"
/obj/item/weapon/disk/limb/dsi_akula
@@ -164,6 +170,7 @@
lifelike = 1
unavailable_to_build = 1
includes_tail = 1
skin_tone = 1
suggested_species = "Vasilissan"
/obj/item/weapon/disk/limb/dsi_spider
@@ -174,6 +181,7 @@
desc = "This limb has a thin synthflesh casing with a few connection ports."
icon = 'icons/mob/human_races/cyberlimbs/DSITeshari/dsi_teshari.dmi'
lifelike = 1
skin_tone = 1
suggested_species = "Teshari"
/datum/robolimb/dsi_teshari/New()

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