Merge remote-tracking branch 'citadel/master' into tgsync
This commit is contained in:
@@ -48,6 +48,8 @@
|
||||
if(C.prefs.toggles & SOUND_PRAYERS)
|
||||
if(usr.job == "Chaplain")
|
||||
SEND_SOUND(C, sound('sound/effects/pray.ogg'))
|
||||
else
|
||||
SEND_SOUND(C, sound('sound/effects/ding.ogg'))
|
||||
to_chat(usr, "<span class='info'>You pray to the gods: \"[msg_tmp]\"</span>")
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Prayer") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
return
|
||||
flick("blob_resource_glow", src)
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
overmind.add_points(2)
|
||||
resource_delay = world.time + 40 + overmind.resource_blobs.len * 2.5 //4 seconds plus a quarter second for each resource blob the overmind has
|
||||
else
|
||||
resource_delay = world.time + 40
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
set category = "Blob"
|
||||
set name = "Create Factory Blob (60)"
|
||||
set desc = "Create a spore tower that will spawn spores to harass your enemies."
|
||||
createSpecial(60, /obj/structure/blob/factory, 7, 1)
|
||||
createSpecial(60, /obj/structure/blob/factory, 5, 1)
|
||||
|
||||
/mob/camera/blob/verb/create_blobbernaut()
|
||||
set category = "Blob"
|
||||
@@ -195,6 +195,7 @@
|
||||
to_chat(blobber, "The <b><font color=\"[blobstrain.color]\">[blobstrain.name]</b></font> reagent [blobstrain.shortdesc ? "[blobstrain.shortdesc]" : "[blobstrain.description]"]")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You could not conjure a sentience for your blobbernaut. Your points have been refunded. Try again later.</span>")
|
||||
B.naut = FALSE
|
||||
add_points(40)
|
||||
|
||||
/mob/camera/blob/verb/relocate_core()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(user.stat != DEAD)
|
||||
user.emote("deathgasp")
|
||||
user.tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
|
||||
user.fakedeath("changeling") //play dead
|
||||
user.fakedeath("changeling", TRUE) //play dead
|
||||
user.update_stat()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
chemical_cost = 1000
|
||||
dna_cost = -1
|
||||
|
||||
var/recharge_slowdown = 0
|
||||
var/silent = FALSE
|
||||
var/weapon_type
|
||||
var/weapon_name_simple
|
||||
@@ -37,6 +38,8 @@
|
||||
if(!silent)
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
user.visible_message("<span class='warning'>With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chem_recharge_slowdown -= recharge_slowdown
|
||||
user.update_inv_hands()
|
||||
return 1
|
||||
|
||||
@@ -57,6 +60,8 @@
|
||||
user.put_in_hands(W)
|
||||
if(!silent)
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chem_recharge_slowdown += recharge_slowdown
|
||||
return W
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user)
|
||||
@@ -141,10 +146,11 @@
|
||||
name = "Arm Blade"
|
||||
desc = "We reform one of our arms into a deadly blade."
|
||||
helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 10
|
||||
chemical_cost = 5
|
||||
dna_cost = 2
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.6
|
||||
weapon_type = /obj/item/melee/arm_blade
|
||||
weapon_name_simple = "blade"
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
@@ -487,7 +493,7 @@
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/changeling
|
||||
suit_name_simple = "flesh shell"
|
||||
helmet_name_simple = "space helmet"
|
||||
recharge_slowdown = 0.5
|
||||
recharge_slowdown = 0.6
|
||||
blood_on_castoff = 1
|
||||
|
||||
/obj/item/clothing/suit/space/changeling
|
||||
@@ -532,11 +538,11 @@
|
||||
name = "Chitinous Armor"
|
||||
desc = "We turn our skin into tough chitin to protect us from damage."
|
||||
helptext = "Upkeep of the armor requires a constant expenditure of chemicals, resulting in a reduced chemical generation. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 20
|
||||
chemical_cost = 10
|
||||
dna_cost = 1
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.5
|
||||
recharge_slowdown = 0.6
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_armor"
|
||||
action_background_icon_state = "bg_ling"
|
||||
@@ -662,10 +668,11 @@
|
||||
name = "Bone Gauntlets"
|
||||
desc = "We turn our hands into solid bone and chitin, sacrificing dexterity for raw strength."
|
||||
helptext = "These grotesque, bone-and-chitin gauntlets are remarkably good at beating victims senseless, and cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 10 // same cost as armblade because its a sidegrade (sacrifice utility for punching people violently)
|
||||
chemical_cost = 5 // same cost as armblade because its a sidegrade (sacrifice utility for punching people violently)
|
||||
dna_cost = 2
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.6
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_gauntlets"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert")
|
||||
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [get_area_name(src)] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
|
||||
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 10, null, FALSE, 0)
|
||||
SSpersistence.station_was_destroyed = TRUE
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
|
||||
GLOB.ratvar_awakens--
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
name = "Codex Cicatrix"
|
||||
desc = "Book describing the secrets of the veil."
|
||||
icon = 'icons/obj/eldritch.dmi'
|
||||
icon_state = "book"
|
||||
item_state = "book"
|
||||
icon_state = "codex"
|
||||
item_state = "codex"
|
||||
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
///Last person that touched this
|
||||
var/mob/living/last_user
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
/obj/screen,
|
||||
/obj/singularity,
|
||||
/mob/living/simple_animal/hostile/morph,
|
||||
/obj/effect))
|
||||
/obj/effect,
|
||||
/mob/camera
|
||||
))
|
||||
|
||||
var/playstyle_string = "<span class='big bold'>You are a morph,</span></b> an abomination of science created primarily with changeling cells. \
|
||||
You may take the form of anything nearby by shift-clicking it. This process will alert any nearby \
|
||||
|
||||
@@ -68,10 +68,6 @@
|
||||
R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
|
||||
if(!turfing)
|
||||
R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
|
||||
|
||||
overlay_fullscreen("flash", /obj/screen/fullscreen/flash) // To be more true to the hentai
|
||||
clear_fullscreen("flash", 20)
|
||||
|
||||
G.last_orgasmed = world.time
|
||||
R.clear_reagents()
|
||||
|
||||
|
||||
@@ -40,17 +40,18 @@
|
||||
var/rounded_length = round(length)
|
||||
var/new_size
|
||||
var/enlargement = FALSE
|
||||
var/max_D = CONFIG_GET(number/penis_max_inches_prefs)
|
||||
switch(rounded_length)
|
||||
if(0 to 6) //If modest size
|
||||
new_size = 1
|
||||
if(7 to 11) //If large
|
||||
new_size = 2
|
||||
if(12 to 20) //If massive
|
||||
if(12 to max_D) //If massive
|
||||
new_size = 3
|
||||
if(21 to 34) //If massive and due for large effects
|
||||
if(max_D + 1 to max_D+13) //If massive and due for large effects, modified in case some server owner running recent citcode decides to be insane with dick sizes in the config
|
||||
new_size = 3
|
||||
enlargement = TRUE
|
||||
if(35 to INFINITY) //If comical
|
||||
if(max_D+14 to INFINITY) //If comical
|
||||
new_size = 4 //no new sprites for anything larger yet
|
||||
enlargement = TRUE
|
||||
if(owner)
|
||||
|
||||
@@ -179,6 +179,10 @@
|
||||
if((pack.hidden && !(obj_flags & EMAGGED)) || (pack.contraband && !contraband) || pack.DropPodOnly)
|
||||
return
|
||||
|
||||
if(self_paid && !pack.can_private_buy)
|
||||
say("This cannot be bought privately.")
|
||||
return
|
||||
|
||||
var/name = "*None Provided*"
|
||||
var/rank = "*None Provided*"
|
||||
var/ckey = usr.ckey
|
||||
|
||||
@@ -34,10 +34,57 @@
|
||||
|
||||
/datum/supply_pack/critter/parrot/generate()
|
||||
. = ..()
|
||||
for(var/i in 1 to 4)
|
||||
new /mob/living/simple_animal/parrot(.)
|
||||
if(prob(1))
|
||||
new /mob/living/simple_animal/parrot/clock_hawk(.)
|
||||
for(var/i in 1 to 5)
|
||||
switch(rand(1, 24))
|
||||
if(1)
|
||||
new /mob/living/simple_animal/parrot(.)
|
||||
if(2)
|
||||
new /mob/living/simple_animal/parrot/clock_hawk(.)
|
||||
if(3)
|
||||
new /mob/living/simple_animal/parrot/kea(.)
|
||||
if(4)
|
||||
new /mob/living/simple_animal/parrot/eclectus(.)
|
||||
if(5)
|
||||
new /mob/living/simple_animal/parrot/eclectusf(.)
|
||||
if(6)
|
||||
new /mob/living/simple_animal/parrot/greybird(.)
|
||||
if(7)
|
||||
new /mob/living/simple_animal/parrot/blue_caique(.)
|
||||
if(8)
|
||||
new /mob/living/simple_animal/parrot/white_caique(.)
|
||||
if(9)
|
||||
new /mob/living/simple_animal/parrot/green_budgerigar(.)
|
||||
if(10)
|
||||
new /mob/living/simple_animal/parrot/blue_Budgerigar(.)
|
||||
if(11)
|
||||
new /mob/living/simple_animal/parrot/bluegreen_Budgerigar(.)
|
||||
if(12)
|
||||
new /mob/living/simple_animal/parrot/commonblackbird(.)
|
||||
if(13)
|
||||
new /mob/living/simple_animal/parrot/azuretit(.)
|
||||
if(14)
|
||||
new /mob/living/simple_animal/parrot/europeanrobin(.)
|
||||
if(15)
|
||||
new /mob/living/simple_animal/parrot/goldcrest(.)
|
||||
if(16)
|
||||
new /mob/living/simple_animal/parrot/ringneckdove(.)
|
||||
if(17)
|
||||
new /mob/living/simple_animal/parrot/cockatiel(.)
|
||||
if(18)
|
||||
new /mob/living/simple_animal/parrot/white_cockatiel(.)
|
||||
if(19)
|
||||
new /mob/living/simple_animal/parrot/yellowish_cockatiel(.)
|
||||
if(20)
|
||||
new /mob/living/simple_animal/parrot/grey_cockatiel(.)
|
||||
if(21)
|
||||
new /mob/living/simple_animal/parrot/too(.)
|
||||
if(22)
|
||||
new /mob/living/simple_animal/parrot/hooded_too(.)
|
||||
if(23)
|
||||
new /mob/living/simple_animal/parrot/pink_too(.)
|
||||
if(24)
|
||||
new /mob/living/simple_animal/parrot/eclectusr(.)
|
||||
|
||||
|
||||
/datum/supply_pack/critter/butterfly
|
||||
name = "Butterflies Crate"
|
||||
|
||||
@@ -90,6 +90,18 @@
|
||||
crate_name = "medical hardsuit"
|
||||
crate_type = /obj/structure/closet/crate/secure/medical
|
||||
|
||||
/datum/supply_pack/medical/paramedicevasuit
|
||||
name = "Paramedic EVA Suit"
|
||||
desc = "Greytide pushing up daisies with the carp outside the station? Chemistry vented in a meth experiment gone wrong? Be the blue saviour this station desperately needs and get your Paramedical EVA suit today! Requires medical access to open."
|
||||
cost = 1975
|
||||
access = ACCESS_MEDICAL
|
||||
contains = list(/obj/item/tank/internals/emergency_oxygen,
|
||||
/obj/item/clothing/head/helmet/space/eva/paramedic,
|
||||
/obj/item/clothing/suit/space/eva/paramedic,
|
||||
/obj/item/clothing/mask/breath)
|
||||
crate_name = "paramedic EVA suit"
|
||||
crate_type = /obj/structure/closet/crate/secure/medical
|
||||
|
||||
/datum/supply_pack/medical/supplies
|
||||
name = "Medical Supplies Crate"
|
||||
desc = "Contains seven beakers, syringes, and bodybags. Three morphine bottles, four insulin pills. Two charcoal bottles, epinephrine bottles, antitoxin bottles, and large beakers. Finally, a single roll of medical gauze, as well as a bottle of stimulant pills for long, hard work days. German doctor not included."
|
||||
|
||||
@@ -261,9 +261,9 @@
|
||||
/obj/item/reagent_containers/glass/bucket,
|
||||
/obj/item/reagent_containers/glass/bucket,
|
||||
/obj/item/mop,
|
||||
/obj/item/caution,
|
||||
/obj/item/caution,
|
||||
/obj/item/caution,
|
||||
/obj/item/clothing/suit/caution,
|
||||
/obj/item/clothing/suit/caution,
|
||||
/obj/item/clothing/suit/caution,
|
||||
/obj/item/storage/bag/trash,
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/obj/item/reagent_containers/rag,
|
||||
|
||||
@@ -1024,3 +1024,25 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
verb_tabs |= verb_to_init.category
|
||||
verblist[++verblist.len] = list(verb_to_init.category, verb_to_init.name)
|
||||
src << output("[url_encode(json_encode(verb_tabs))];[url_encode(json_encode(verblist))]", "statbrowser:init_verbs")
|
||||
|
||||
//increment progress for an unlockable loadout item
|
||||
/client/proc/increment_progress(key, amount)
|
||||
if(prefs)
|
||||
var/savefile/S = new /savefile(prefs.path)
|
||||
var/list/unlockable_loadout_data = prefs.unlockable_loadout_data
|
||||
if(!length(unlockable_loadout_data))
|
||||
unlockable_loadout_data = list()
|
||||
unlockable_loadout_data[key] = amount
|
||||
WRITE_FILE(S["unlockable_loadout"], safe_json_encode(unlockable_loadout_data))
|
||||
prefs.unlockable_loadout_data = unlockable_loadout_data
|
||||
return TRUE
|
||||
else
|
||||
if(unlockable_loadout_data[key])
|
||||
unlockable_loadout_data[key] += amount
|
||||
else
|
||||
unlockable_loadout_data[key] = amount
|
||||
WRITE_FILE(S["unlockable_loadout"], safe_json_encode(unlockable_loadout_data))
|
||||
prefs.unlockable_loadout_data = unlockable_loadout_data
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/gear_points = 10
|
||||
var/list/gear_categories
|
||||
var/list/loadout_data = list()
|
||||
var/list/unlockable_loadout_data = list()
|
||||
var/loadout_slot = 1 //goes from 1 to MAXIMUM_LOADOUT_SAVES
|
||||
var/gear_category
|
||||
var/gear_subcategory
|
||||
@@ -907,12 +908,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
loadout_color_non_poly = loadout_item[LOADOUT_COLOR][1]
|
||||
extra_color_data += "<BR><a href='?_src_=prefs;preference=gear;loadout_color=1;loadout_gear_name=[html_encode(gear.name)];'>Color</a>"
|
||||
extra_color_data += "<span style='border: 1px solid #161616; background-color: [loadout_color_non_poly];'> </span>"
|
||||
else if(gear_points <= 0)
|
||||
else if((gear_points - gear.cost) < 0)
|
||||
class_link = "style='white-space:normal;' class='linkOff'"
|
||||
else if(donoritem)
|
||||
class_link = "style='white-space:normal;background:#ebc42e;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'"
|
||||
else
|
||||
else if(!istype(gear, /datum/gear/unlockable) || can_use_unlockable(gear))
|
||||
class_link = "style='white-space:normal;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'"
|
||||
else
|
||||
class_link = "style='white-space:normal;background:#eb2e2e;' class='linkOff'"
|
||||
dat += "<tr style='vertical-align:top;'><td width=15%><a [class_link]>[name]</a>[extra_color_data]</td>"
|
||||
dat += "<td width = 5% style='vertical-align:top'>[gear.cost]</td><td>"
|
||||
if(islist(gear.restricted_roles))
|
||||
@@ -925,7 +928,16 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<font size=2>"
|
||||
dat += gear.restricted_roles.Join(";")
|
||||
dat += "</font>"
|
||||
dat += "</td><td><font size=2><i>[gear.description]</i></font></td></tr>"
|
||||
if(!istype(gear, /datum/gear/unlockable))
|
||||
dat += "</td><td><font size=2><i>[gear.description]</i></font></td></tr>"
|
||||
else
|
||||
//we add the user's progress to the description assuming they have progress
|
||||
var/datum/gear/unlockable/unlockable = gear
|
||||
var/progress_made = unlockable_loadout_data[unlockable.progress_key]
|
||||
if(!progress_made)
|
||||
progress_made = 0
|
||||
dat += "</td><td><font size=2><i>[gear.description] Progress: [min(progress_made, unlockable.progress_required)]/[unlockable.progress_required]</i></font></td></tr>"
|
||||
|
||||
dat += "</table>"
|
||||
if(4) // Content preferences
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
@@ -2675,6 +2687,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(G.donoritem && !G.donator_ckey_check(user.ckey))
|
||||
to_chat(user, "<span class='danger'>This is an item intended for donator use only. You are not authorized to use this item.</span>")
|
||||
return
|
||||
if(istype(G, /datum/gear/unlockable) && !can_use_unlockable(G))
|
||||
to_chat(user, "<span class='danger'>To use this item, you need to meet the defined requirements!</span>")
|
||||
return
|
||||
if(gear_points >= initial(G.cost))
|
||||
var/list/new_loadout_data = list(LOADOUT_ITEM = "[G.type]")
|
||||
if(length(G.loadout_initial_colors))
|
||||
@@ -2960,6 +2975,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(find_gear)
|
||||
loadout_data["SAVE_[save_slot]"] -= list(find_gear)
|
||||
|
||||
/datum/preferences/proc/can_use_unlockable(datum/gear/unlockable/unlockable_gear)
|
||||
if(unlockable_loadout_data[unlockable_gear.progress_key] >= unlockable_gear.progress_required)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
#undef DEFAULT_SLOT_AMT
|
||||
#undef HANDS_SLOT_AMT
|
||||
#undef BACKPACK_SLOT_AMT
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 47
|
||||
#define SAVEFILE_VERSION_MAX 48
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -285,6 +285,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
S["loadout"] = safe_json_encode(loadout_data)
|
||||
|
||||
if(current_version < 48) //unlockable loadout items but we need to clear bad data from a mistake
|
||||
S["unlockable_loadout"] = list()
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey)
|
||||
return
|
||||
@@ -427,6 +430,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped
|
||||
|
||||
if(S["unlockable_loadout"])
|
||||
unlockable_loadout_data = safe_json_decode(S["unlockable_loadout"])
|
||||
else
|
||||
unlockable_loadout_data = list()
|
||||
|
||||
if(needs_update >= 0) //save the updated version
|
||||
var/old_default_slot = default_slot
|
||||
var/old_max_save_slots = max_save_slots
|
||||
@@ -532,6 +540,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["auto_ooc"], auto_ooc)
|
||||
WRITE_FILE(S["no_tetris_storage"], no_tetris_storage)
|
||||
|
||||
if(length(unlockable_loadout_data))
|
||||
WRITE_FILE(S["unlockable_loadout"], safe_json_encode(unlockable_loadout_data))
|
||||
else
|
||||
WRITE_FILE(S["unlockable_loadout"], safe_json_encode(list()))
|
||||
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/load_character(slot, bypass_cooldown = FALSE)
|
||||
@@ -736,7 +749,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
belly_prefs = json_from_file["belly_prefs"]
|
||||
|
||||
//gear loadout
|
||||
loadout_data = safe_json_decode(S["loadout"])
|
||||
if(S["loadout"])
|
||||
loadout_data = safe_json_decode(S["loadout"])
|
||||
else
|
||||
loadout_data = list()
|
||||
|
||||
//try to fix any outdated data if necessary
|
||||
//preference updating will handle saving the updated data for us.
|
||||
|
||||
@@ -541,6 +541,21 @@
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
allowed = list(/obj/item/clothing/mask/facehugger/toy)
|
||||
|
||||
/obj/item/clothing/suit/caution
|
||||
name = "wet floor sign"
|
||||
desc = "Caution! Wet Floor!"
|
||||
icon_state = "caution"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
|
||||
force = 1
|
||||
throwforce = 3
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
body_parts_covered = CHEST|GROIN
|
||||
attack_verb = list("warned", "cautioned", "smashed")
|
||||
armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
|
||||
// WINTER COATS
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat
|
||||
|
||||
@@ -244,35 +244,33 @@
|
||||
/obj/item/clothing/under/proc/rolldown()
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!can_adjust)
|
||||
to_chat(usr, "<span class='warning'>You cannot wear this suit any differently!</span>")
|
||||
return
|
||||
if(toggle_jumpsuit_adjust())
|
||||
to_chat(usr, "<span class='notice'>You adjust the suit to wear it more casually.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You adjust the suit back to normal.</span>")
|
||||
if(ishuman(usr))
|
||||
if(toggle_jumpsuit_adjust() && ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.update_inv_w_uniform()
|
||||
H.update_body()
|
||||
|
||||
/obj/item/clothing/under/proc/toggle_jumpsuit_adjust()
|
||||
if(!can_adjust)
|
||||
to_chat(usr, "<span class='warning'>You cannot wear this suit any differently!</span>")
|
||||
return FALSE
|
||||
adjusted = !adjusted
|
||||
|
||||
if(adjusted)
|
||||
to_chat(usr, "<span class='notice'>You adjust the suit to wear it more casually.</span>")
|
||||
if(fitted != FEMALE_UNIFORM_TOP)
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted
|
||||
body_parts_covered &= ~CHEST
|
||||
mutantrace_variation &= ~USE_TAUR_CLIP_MASK //How are we supposed to see the uniform otherwise?
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You adjust the suit back to normal.</span>")
|
||||
fitted = initial(fitted)
|
||||
if(!alt_covers_chest)
|
||||
body_parts_covered |= CHEST
|
||||
if(initial(mutantrace_variation) & USE_TAUR_CLIP_MASK)
|
||||
mutantrace_variation |= USE_TAUR_CLIP_MASK
|
||||
|
||||
return adjusted
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/under/rank
|
||||
dying_key = DYE_REGISTRY_UNDER
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/under/rank/civilian/util
|
||||
name = "generic utility uniform"
|
||||
name = "utility uniform"
|
||||
desc = "A utility uniform worn by various crew."
|
||||
icon_state = "utilgen"
|
||||
item_state = "utilgen"
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
name = "captain's jumpsuit"
|
||||
icon_state = "captain"
|
||||
item_state = "b_suit"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15)
|
||||
sensor_mode = SENSOR_COORDS
|
||||
random_sensor = FALSE
|
||||
|
||||
/obj/item/clothing/under/rank/captain/util
|
||||
name = "Command Utiltiy Uniform"
|
||||
name = "command utility uniform"
|
||||
desc = "A utility uniform for command personnel."
|
||||
icon_state = "utilcom"
|
||||
item_state = "utilcom"
|
||||
@@ -26,7 +27,6 @@
|
||||
/obj/item/clothing/under/rank/captain/suit
|
||||
name = "captain's suit"
|
||||
desc = "A green suit and yellow necktie. Exemplifies authority."
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15)
|
||||
icon_state = "green_suit"
|
||||
item_state = "dg_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
|
||||
|
||||
/obj/item/clothing/under/rank/medical/doctor/util
|
||||
name = "Medical Utility Uniform"
|
||||
name = "medical utility uniform"
|
||||
desc = "Utility jumpsuit for medical personnel"
|
||||
icon_state = "utilmed"
|
||||
item_state = "utilmed"
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
|
||||
|
||||
/obj/item/clothing/under/rank/rnd/scientist/util
|
||||
name = "Science Utility Uniform"
|
||||
name = "science utility uniform"
|
||||
desc = "A utility uniform for science personnel"
|
||||
icon_state = "utilsci"
|
||||
item_state = "utilsci"
|
||||
|
||||
@@ -172,11 +172,13 @@
|
||||
body_parts_covered = CHEST|GROIN
|
||||
|
||||
/obj/item/clothing/under/misc/gear_harness/toggle_jumpsuit_adjust()
|
||||
adjusted = !adjusted
|
||||
if(adjusted)
|
||||
body_parts_covered = NONE
|
||||
else
|
||||
if(!body_parts_covered)
|
||||
to_chat(usr, "<span class='notice'>Your gear harness is now covering your chest and groin.</span>")
|
||||
body_parts_covered = CHEST|GROIN
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>Your gear harness is no longer covering anything.</span>")
|
||||
body_parts_covered = NONE
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/under/misc/durathread
|
||||
name = "durathread jumpsuit"
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
foodtype = GRAIN
|
||||
dunkable = TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/store/bread/proc/bread_teleport()
|
||||
// you did WHAT?
|
||||
new /mob/living/simple_animal/hostile/bread(get_turf(src))
|
||||
visible_message("<span class='warning'>[src] begins to deform and grow grotesque tumors!</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/breadslice
|
||||
icon = 'icons/obj/food/burgerbread.dmi'
|
||||
bitesize = 2
|
||||
@@ -228,3 +234,25 @@
|
||||
/obj/item/reagent_containers/food/snacks/butterdog/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, 80)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/store/bread/tumor_bread
|
||||
name = "dead tumor bread"
|
||||
desc = "It's still within its expiration date, right?."
|
||||
icon_state = "tumorbread"
|
||||
slice_path = /obj/item/reagent_containers/food/snacks/breadslice/tumor_bread
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/toxin = 10)
|
||||
foodtype = GROSS | GRAIN
|
||||
tastes = list("wheat and tumors" = 10)
|
||||
|
||||
//teleporting tumor bread kills it
|
||||
/obj/item/reagent_containers/food/snacks/store/bread/tumor_bread/bread_teleport()
|
||||
visible_message(src, "<span class='warning'>[src] explodes in a horrible mess of tumor and flour!</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/breadslice/tumor_bread
|
||||
name = "tumor bread slice"
|
||||
desc = "A slice of bread filled with tumors!"
|
||||
icon_state = "tumorbreadslice"
|
||||
filling_color = "#B2D72C"
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/toxin = 2)
|
||||
foodtype = GROSS | GRAIN
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
/obj/machinery/microwave/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
cook()
|
||||
cook(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/microwave/ui_interact(mob/user)
|
||||
@@ -226,7 +226,7 @@
|
||||
if("eject")
|
||||
eject()
|
||||
if("use")
|
||||
cook()
|
||||
cook(user)
|
||||
if("examine")
|
||||
examine(user)
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
AM.forceMove(drop_location())
|
||||
ingredients.Cut()
|
||||
|
||||
/obj/machinery/microwave/proc/cook()
|
||||
/obj/machinery/microwave/proc/cook(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(operating || broken > 0 || panel_open || !anchored || dirty == 100)
|
||||
@@ -257,7 +257,7 @@
|
||||
start_can_fail()
|
||||
return
|
||||
break
|
||||
start()
|
||||
start(user)
|
||||
|
||||
/obj/machinery/microwave/proc/turn_on()
|
||||
visible_message("\The [src] turns on.", "<span class='italics'>You hear a microwave humming.</span>")
|
||||
@@ -277,9 +277,9 @@
|
||||
#define MICROWAVE_MUCK 1
|
||||
#define MICROWAVE_PRE 2
|
||||
|
||||
/obj/machinery/microwave/proc/start()
|
||||
/obj/machinery/microwave/proc/start(mob/user)
|
||||
turn_on()
|
||||
loop(MICROWAVE_NORMAL, 10)
|
||||
loop(MICROWAVE_NORMAL, 10, user = user)
|
||||
|
||||
/obj/machinery/microwave/proc/start_can_fail()
|
||||
turn_on()
|
||||
@@ -292,7 +292,7 @@
|
||||
update_icon()
|
||||
loop(MICROWAVE_MUCK, 4)
|
||||
|
||||
/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * productivity, 2)) // standard wait is 10
|
||||
/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * productivity, 2), mob/user) // standard wait is 10
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(type == MICROWAVE_PRE)
|
||||
pre_fail()
|
||||
@@ -300,7 +300,7 @@
|
||||
if(!time)
|
||||
switch(type)
|
||||
if(MICROWAVE_NORMAL)
|
||||
loop_finish()
|
||||
loop_finish(user)
|
||||
if(MICROWAVE_MUCK)
|
||||
muck_finish()
|
||||
if(MICROWAVE_PRE)
|
||||
@@ -308,16 +308,21 @@
|
||||
return
|
||||
time--
|
||||
use_power(500)
|
||||
addtimer(CALLBACK(src, .proc/loop, type, time, wait), wait)
|
||||
addtimer(CALLBACK(src, .proc/loop, type, time, wait, user), wait)
|
||||
|
||||
/obj/machinery/microwave/proc/loop_finish()
|
||||
/obj/machinery/microwave/proc/loop_finish(mob/user)
|
||||
operating = FALSE
|
||||
|
||||
var/metal = 0
|
||||
var/cooked_food = 0
|
||||
for(var/obj/item/O in ingredients)
|
||||
O.microwave_act(src)
|
||||
var/cooked_result = O.microwave_act(src)
|
||||
if(!istype(cooked_result, /obj/item/reagent_containers/food/snacks/badrecipe))
|
||||
cooked_food += 1
|
||||
if(O.custom_materials?.len)
|
||||
metal += O.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)]
|
||||
if(cooked_food && user.client)
|
||||
user.client.increment_progress("cook", cooked_food)
|
||||
|
||||
if(metal)
|
||||
spark()
|
||||
@@ -336,8 +341,8 @@
|
||||
spark()
|
||||
after_finish_loop()
|
||||
|
||||
/obj/machinery/microwave/proc/pre_success()
|
||||
loop(MICROWAVE_NORMAL, 10)
|
||||
/obj/machinery/microwave/proc/pre_success(mob/user)
|
||||
loop(MICROWAVE_NORMAL, 10, user)
|
||||
|
||||
/obj/machinery/microwave/proc/muck_finish()
|
||||
visible_message("<span class='warning'>\The [src] gets covered in muck!</span>")
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
var/map_name = "Box Station"
|
||||
var/map_path = "map_files/BoxStation"
|
||||
var/map_file = "BoxStation.dmm"
|
||||
/// Persistence key: Defaults to ckey(map_name). If set to "NO_PERSIST", this map will have NO persistence.
|
||||
var/persistence_key
|
||||
|
||||
var/traits = null
|
||||
var/space_ruin_levels = 4
|
||||
@@ -99,6 +101,16 @@
|
||||
map_path = json["map_path"]
|
||||
|
||||
map_file = json["map_file"]
|
||||
|
||||
persistence_key = ckey(map_name)
|
||||
|
||||
var/json_persistence_key = json["persistence_key"]
|
||||
if(json_persistence_key)
|
||||
if(json_persistence_key == "NO_PERSIST")
|
||||
persistence_key = null
|
||||
else
|
||||
persistence_key = json_persistence_key
|
||||
|
||||
// "map_file": "BoxStation.dmm"
|
||||
if (istext(map_file))
|
||||
if (!fexists("_maps/[map_path]/[map_file]"))
|
||||
|
||||
@@ -397,6 +397,17 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one length of cable to attach a string to the coin!</span>")
|
||||
return
|
||||
else if(istype(W, /obj/item/card/id))
|
||||
var/obj/item/card/id/ID = W
|
||||
if(!ID.registered_account)
|
||||
to_chat(user, "<span class='warning'>[ID] doesn't have a linked account to deposit into!</span>")
|
||||
return
|
||||
for(var/obj/item/holochip/money in src.loc.contents)
|
||||
ID.attackby(money, user)
|
||||
for(var/obj/item/stack/spacecash/money in src.loc.contents)
|
||||
ID.attackby(money, user)
|
||||
for(var/obj/item/coin/money in src.loc.contents)
|
||||
ID.attackby(money, user)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
if(points)
|
||||
if(I)
|
||||
I.mining_points += points
|
||||
if(usr.client)
|
||||
usr.client.increment_progress("miner", points)
|
||||
points = 0
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>No ID detected.</span>")
|
||||
|
||||
@@ -138,6 +138,18 @@
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
//INSECT WINGS
|
||||
|
||||
/datum/sprite_accessory/insect_wings
|
||||
|
||||
@@ -380,6 +380,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
|
||||
/mob/dead/observer/Move(NewLoc, direct)
|
||||
if (SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, NewLoc) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
|
||||
return
|
||||
if(updatedir)
|
||||
setDir(direct)//only update dir if we actually need it, so overlays won't spin on base sprites that don't have directions of their own
|
||||
var/oldloc = loc
|
||||
|
||||
@@ -68,7 +68,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/plant
|
||||
name = "Plant Weeds"
|
||||
desc = "Plants some alien weeds."
|
||||
desc = "Plants Alien weeds which spread resin which heals any alien. These weeds also regenerate plasma faster. Costs 50 Plasma."
|
||||
plasma_cost = 50
|
||||
check_turf = TRUE
|
||||
action_icon_state = "alien_plant"
|
||||
@@ -83,7 +83,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/whisper
|
||||
name = "Whisper"
|
||||
desc = "Whisper to someone."
|
||||
desc = "Whisper to someone through the hivemind. Costs 10 Plasma."
|
||||
plasma_cost = 10
|
||||
action_icon_state = "alien_whisper"
|
||||
|
||||
@@ -143,7 +143,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/acid
|
||||
name = "Corrosive Acid"
|
||||
desc = "Drench an object in acid, destroying it over time."
|
||||
desc = "Drench an object in acid, destroying it over time. Costs 200 Plasma."
|
||||
plasma_cost = 200
|
||||
action_icon_state = "alien_acid"
|
||||
|
||||
@@ -189,7 +189,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin
|
||||
name = "Spit Neurotoxin"
|
||||
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
|
||||
desc = "Activates your Neurotoxin glands. You can shoot paralyzing shots. Each shot costs 50 Plasma."
|
||||
action_icon_state = "alien_neurotoxin_0"
|
||||
active = FALSE
|
||||
|
||||
@@ -254,7 +254,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/resin
|
||||
name = "Secrete Resin"
|
||||
desc = "Secrete tough malleable resin."
|
||||
desc = "Secrete tough malleable resin. Costs 55 Plasma."
|
||||
plasma_cost = 55
|
||||
check_turf = TRUE
|
||||
var/list/structures = list(
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/obj/effect/proc_holder/alien/royal/praetorian/evolve
|
||||
name = "Evolve"
|
||||
desc = "Produce an internal egg sac capable of spawning children. Only one queen can exist at a time."
|
||||
desc = "Produce an internal egg sac capable of spawning children. Only one queen can exist at a time. Costs 500 Plasma."
|
||||
plasma_cost = 500
|
||||
|
||||
action_icon_state = "alien_evolve_praetorian"
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
//Queen verbs
|
||||
/obj/effect/proc_holder/alien/lay_egg
|
||||
name = "Lay Egg"
|
||||
desc = "Lay an egg to produce huggers to impregnate prey with."
|
||||
desc = "Lay an egg to produce huggers to impregnate prey with. Costs 75 Plasma."
|
||||
plasma_cost = 75
|
||||
check_turf = TRUE
|
||||
action_icon_state = "alien_egg"
|
||||
@@ -77,7 +77,7 @@
|
||||
//Button to let queen choose her praetorian.
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote
|
||||
name = "Create Royal Parasite"
|
||||
desc = "Produce a royal parasite to grant one of your children the honor of being your Praetorian."
|
||||
desc = "Produce a royal parasite to grant one of your children the honor of being your Praetorian. Costs 500 Plasma."
|
||||
plasma_cost = 500 //Plasma cost used on promotion, not spawning the parasite.
|
||||
|
||||
action_icon_state = "alien_queen_promote"
|
||||
|
||||
@@ -190,6 +190,11 @@
|
||||
message = "chimes."
|
||||
sound = 'sound/machines/chime.ogg'
|
||||
|
||||
/datum/emote/sound/human/squeak
|
||||
key = "squeak"
|
||||
message = "squeaks."
|
||||
sound = 'sound/effects/mousesqueek.ogg'
|
||||
|
||||
//rock paper scissors emote handling
|
||||
/mob/living/carbon/human/proc/beginRockPaperScissors(var/chosen_move)
|
||||
GLOB.rockpaperscissors_players[src] = list(chosen_move, ROCKPAPERSCISSORS_NOT_DECIDED)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
block_parry_data = /datum/block_parry_data/unarmed/human
|
||||
default_block_parry_data = /datum/block_parry_data/unarmed/human
|
||||
causes_dirt_buildup_on_floor = TRUE
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
|
||||
@@ -100,3 +100,8 @@
|
||||
if(dna.species.space_move(src))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/dirt_buildup(strength)
|
||||
if(!shoes || !(shoes.body_parts_covered & FEET))
|
||||
return // barefoot advantage
|
||||
return ..()
|
||||
|
||||
@@ -18,3 +18,33 @@
|
||||
species_category = SPECIES_CATEGORY_FURRY
|
||||
|
||||
allowed_limb_ids = list("mammal","aquatic","avian")
|
||||
|
||||
/datum/species/mammal/synthetic
|
||||
name = "Synthetic Anthromorph"
|
||||
id = SPECIES_MAMMAL_SYNTHETIC
|
||||
|
||||
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE,WINGCOLOR,HORNCOLOR)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID|MOB_BEAST
|
||||
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
mutantliver = /obj/item/organ/liver/ipc
|
||||
mutantstomach = /obj/item/organ/stomach/ipc
|
||||
mutanteyes = /obj/item/organ/eyes/ipc
|
||||
mutantears = /obj/item/organ/ears/ipc
|
||||
mutanttongue = /obj/item/organ/tongue/robot/ipc
|
||||
mutant_brain = /obj/item/organ/brain/ipc
|
||||
|
||||
//special cybernetic organ for getting power from apcs
|
||||
mutant_organs = list(/obj/item/organ/cyberimp/arm/power_cord)
|
||||
|
||||
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
allowed_limb_ids = list("mammal","aquatic","avian", "human")
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR,HAS_FLESH)
|
||||
mutantlungs = /obj/item/organ/lungs/slime
|
||||
mutant_heart = /obj/item/organ/heart/slime
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade")
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
|
||||
@@ -406,7 +406,7 @@
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "legs" = "Plantigrade")
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 160 //a notch brighter so it blends better.
|
||||
|
||||
@@ -203,6 +203,15 @@
|
||||
var/obj/item/I = AM
|
||||
if(I.light_range && I.light_power)
|
||||
disintegrate(I)
|
||||
else if (isstructure(AM))
|
||||
var/obj/structure/S = AM
|
||||
if(istype(S, /obj/structure/glowshroom) || istype(S, /obj/structure/marker_beacon))
|
||||
qdel(S)
|
||||
visible_message("<span class='danger'>[S] is disintegrated by [src]!</span>")
|
||||
else if(AM.light_range && AM.light_power && !(istype(AM, /obj/machinery/power/apc) || istype(AM, /obj/machinery/airalarm)))
|
||||
var/obj/target_object = AM
|
||||
target_object.take_damage(force * 5, BRUTE, "melee", 0)
|
||||
|
||||
|
||||
/obj/item/light_eater/proc/disintegrate(obj/item/O)
|
||||
if(istype(O, /obj/item/pda))
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR)
|
||||
mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade")
|
||||
mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade","deco_wings"= "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
/mob/living/proc/initiate_parry_sequence()
|
||||
if(parrying)
|
||||
return // already parrying
|
||||
if(!(mobility_flags & MOBILITY_USE))
|
||||
to_chat(src, "<span class='warning'>You can't move your arms!</span>")
|
||||
return
|
||||
if(!(combat_flags & COMBAT_FLAG_PARRY_CAPABLE))
|
||||
to_chat(src, "<span class='warning'>You are not something that can parry attacks.</span>")
|
||||
return
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
|
||||
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
|
||||
/// Do we make floors dirty as we move?
|
||||
var/causes_dirt_buildup_on_floor = FALSE
|
||||
|
||||
var/list/roundstart_quirks = list()
|
||||
|
||||
|
||||
@@ -102,6 +102,38 @@
|
||||
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
|
||||
makeTrail(newloc, T, old_direction)
|
||||
|
||||
if(causes_dirt_buildup_on_floor && (movement_type & GROUND))
|
||||
dirt_buildup()
|
||||
|
||||
/**
|
||||
* Attempts to make the floor dirty.
|
||||
*/
|
||||
/mob/living/proc/dirt_buildup(strength = 1)
|
||||
var/turf/open/T = loc
|
||||
if(!istype(T) || !T.dirt_buildup_allowed)
|
||||
return
|
||||
var/area/A = T.loc
|
||||
if(!A.dirt_buildup_allowed)
|
||||
return
|
||||
var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
|
||||
strength *= multiplier
|
||||
var/obj/effect/decal/cleanable/dirt/D = locate() in T
|
||||
if(D)
|
||||
D.dirty(strength)
|
||||
else
|
||||
T.dirtyness += strength
|
||||
if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
|
||||
D = new /obj/effect/decal/cleanable/dirt(T)
|
||||
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
|
||||
T.dirtyness = 0 // reset.
|
||||
|
||||
/mob/living/Move_Pulled(atom/A)
|
||||
. = ..()
|
||||
if(!. || !isliving(A))
|
||||
return
|
||||
var/mob/living/L = A
|
||||
set_pull_offsets(L, grab_state)
|
||||
|
||||
/mob/living/forceMove(atom/destination)
|
||||
stop_pulling()
|
||||
if(buckled)
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/mob/living/silicon/verb/clear_custom_holoform()
|
||||
set name = "Clear Custom Holoform"
|
||||
set desc = "Clear your current custom holoform"
|
||||
set category = "OOC"
|
||||
if(!client.prefs)
|
||||
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
|
||||
return
|
||||
client.prefs.custom_holoform_icon = null
|
||||
client.prefs.cached_holoform_icons = null
|
||||
to_chat(src, "<span class='boldnotice'>Holoform removed.</span>")
|
||||
|
||||
/mob/living/silicon/verb/set_custom_holoform()
|
||||
set name = "Set Custom Holoform"
|
||||
set desc = "Set your custom holoform using your current preferences slot and a specified set of gear."
|
||||
if(!client.prefs)
|
||||
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
|
||||
return
|
||||
if(client.prefs.last_custom_holoform > world.time - CUSTOM_HOLOFORM_DELAY)
|
||||
to_chat(src, "<span class='warning'>You are attempting to change custom holoforms too fast!</span>")
|
||||
|
||||
var/icon/new_holoform = user_interface_custom_holoform(client)
|
||||
if(new_holoform)
|
||||
client.prefs.custom_holoform_icon = new_holoform
|
||||
client.prefs.cached_holoform_icons = null
|
||||
client.prefs.last_custom_holoform = world.time
|
||||
to_chat(src, "<span class='boldnotice'>Holoform set.</span>")
|
||||
|
||||
/mob/living/silicon/proc/attempt_set_custom_holoform()
|
||||
if(!client.prefs)
|
||||
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
|
||||
|
||||
@@ -9,6 +9,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
real_name = "Guardian Spirit"
|
||||
desc = "A mysterious being that stands by its charge, ever vigilant."
|
||||
speak_emote = list("hisses")
|
||||
rad_flags = RAD_NO_CONTAMINATE | RAD_PROTECT_CONTENTS
|
||||
gender = NEUTER
|
||||
mob_biotypes = NONE
|
||||
bubble_icon = "guardian"
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//funny reference to the video 'Expiration Date'
|
||||
|
||||
/mob/living/simple_animal/hostile/bread
|
||||
name = "tumor bread"
|
||||
desc = "I have done nothing but teleport bread for three days."
|
||||
icon_state = "tumorbread"
|
||||
health = 1
|
||||
maxHealth = 1
|
||||
turns_per_move = 5 //this isn't player speed =|
|
||||
speed = 2 //this is player speed
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 2
|
||||
obj_damage = 0
|
||||
loot = list(/obj/item/reagent_containers/food/snacks/store/bread/tumor_bread)
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 270
|
||||
maxbodytemp = INFINITY
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
response_help_continuous = "pokes"
|
||||
response_help_simple = "poke"
|
||||
response_disarm_continuous = "shoos"
|
||||
response_disarm_simple = "shoo"
|
||||
response_harm_continuous = "punches"
|
||||
response_harm_simple = "punch"
|
||||
speak_emote = list("growls")
|
||||
mouse_opacity = 2
|
||||
density = TRUE
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
verb_say = "growls"
|
||||
verb_ask = "growls inquisitively"
|
||||
verb_exclaim = "growls loudly"
|
||||
verb_yell = "growls loudly"
|
||||
del_on_death = TRUE
|
||||
|
||||
/mob/living/simple_animal/bread/hostile/Initialize()
|
||||
. = ..()
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
notify_ghosts("A tumor bread has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/bread/attack_ghost(mob/user)
|
||||
if(key) //please stop using src. without a good reason.
|
||||
return
|
||||
if(CONFIG_GET(flag/use_age_restriction_for_jobs))
|
||||
if(!isnum(user.client.player_age))
|
||||
return
|
||||
if(isobserver(user))
|
||||
var/mob/dead/observer/O = user
|
||||
if(!O.can_reenter_round())
|
||||
return
|
||||
if(!SSticker.mode)
|
||||
to_chat(user, "Can't become a tumor bread before the game has started.")
|
||||
return
|
||||
var/be_bread = alert("Become a tumor bread? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(be_bread == "No" || QDELETED(src) || !isobserver(user))
|
||||
return
|
||||
if(key)
|
||||
to_chat(user, "<span class='notice'>Someone else already took this tumor bread.</span>")
|
||||
return
|
||||
sentience_act()
|
||||
user.transfer_ckey(src, FALSE)
|
||||
density = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/bread/ex_act()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/bread/start_pulling()
|
||||
return FALSE
|
||||
@@ -1034,3 +1034,159 @@
|
||||
|
||||
/mob/living/simple_animal/parrot/clock_hawk/ratvar_act()
|
||||
return
|
||||
|
||||
// Different Parrot Breeds
|
||||
|
||||
/mob/living/simple_animal/parrot/kea
|
||||
name = "Kea"
|
||||
icon_state = "kea-flap"
|
||||
icon_living = "kea-flap"
|
||||
icon_dead = "kea-dead"
|
||||
icon_sit = "kea_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/eclectusr
|
||||
name = "Eclectus"
|
||||
icon_state = "eclectusr-flap"
|
||||
icon_living = "eclectusr-flap"
|
||||
icon_dead = "eclectusr-dead"
|
||||
icon_sit = "electusr_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/eclectus
|
||||
name = "Eclectus"
|
||||
icon_state = "eclectus-flap"
|
||||
icon_living = "eclectus-flap"
|
||||
icon_dead = "eclectus-dead"
|
||||
icon_sit = "electus_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/eclectusf
|
||||
name = "Eclectus"
|
||||
icon_state = "eclectusf-flap"
|
||||
icon_living = "eclectusf-flap"
|
||||
icon_dead = "eclectusf-dead"
|
||||
icon_sit = "electusf_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/greybird
|
||||
name = "Grey Bird"
|
||||
icon_state = "agrey-flap"
|
||||
icon_living = "agrey-flap"
|
||||
icon_dead = "agrey-dead"
|
||||
icon_sit = "agrey_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/blue_caique
|
||||
name = "Blue Caique "
|
||||
icon_state = "bcaique-flap"
|
||||
icon_living = "bcaique-flap"
|
||||
icon_dead = "bcaique-dead"
|
||||
icon_sit = "bcaique_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/white_caique
|
||||
name = "White caique"
|
||||
icon_state = "wcaique-flap"
|
||||
icon_living = "wcaique-flap"
|
||||
icon_dead = "wcaique-dead"
|
||||
icon_sit = "wcaique_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/green_budgerigar
|
||||
name = "Green Budgerigar"
|
||||
icon_state = "gbudge-flap"
|
||||
icon_living = "gbudge-flap"
|
||||
icon_dead = "gbudge-dead"
|
||||
icon_sit = "gbudge_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/blue_Budgerigar
|
||||
name = "Blue Budgerigar"
|
||||
icon_state = "bbudge-flap"
|
||||
icon_living = "bbudge-flap"
|
||||
icon_dead = "bbudge-dead"
|
||||
icon_sit = "bbudge_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/bluegreen_Budgerigar
|
||||
name = "Bluegreen Budgerigar"
|
||||
icon_state = "bgbudge-flap"
|
||||
icon_living = "bgbudge-flap"
|
||||
icon_dead = "bgbudge-dead"
|
||||
icon_sit = "bgbudge_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/commonblackbird
|
||||
name = "Black Bird"
|
||||
icon_state = "commonblackbird"
|
||||
icon_living = "commonblackbird"
|
||||
icon_dead = "commonblackbird-dead"
|
||||
icon_sit = "commonblackbird_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/azuretit
|
||||
name = "Azure Tit"
|
||||
icon_state = "azuretit"
|
||||
icon_living = "azuretit"
|
||||
icon_dead = "azuretit-dead"
|
||||
icon_sit = "azuretit_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/europeanrobin
|
||||
name = "European Robin"
|
||||
icon_state = "europeanrobin"
|
||||
icon_living = "europeanrobin"
|
||||
icon_dead = "europeanrobin-dead"
|
||||
icon_sit = "europeanrobin_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/goldcrest
|
||||
name = "Goldcrest"
|
||||
icon_state = "goldcrest"
|
||||
icon_living = "goldcrest"
|
||||
icon_dead = "goldcrest-dead"
|
||||
icon_sit = "goldencrest_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/ringneckdove
|
||||
name = "Ringneck Dove"
|
||||
icon_state = "ringneckdove"
|
||||
icon_living = "ringneckdove"
|
||||
icon_dead = "ringneckdove-dead"
|
||||
icon_sit = "ringneckdove_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/cockatiel
|
||||
name = "Cockatiel"
|
||||
icon_state = "tiel-flap"
|
||||
icon_living = "tiel-flap"
|
||||
icon_dead = "tiel-dead"
|
||||
icon_sit = "tiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/white_cockatiel
|
||||
name = "White Cockatiel"
|
||||
icon_state = "wtiel-flap"
|
||||
icon_living = "wtiel-flap"
|
||||
icon_dead = "wtiel-dead"
|
||||
icon_sit = "wtiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/yellowish_cockatiel
|
||||
name = "Yellowish Cockatiel"
|
||||
icon_state = "luttiel-flap"
|
||||
icon_living = "luttiel-flap"
|
||||
icon_dead = "luttiel-dead"
|
||||
icon_sit = "luttiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/grey_cockatiel
|
||||
name = "Grey Cockatiel"
|
||||
icon_state = "blutiel-flap"
|
||||
icon_living = "blutiel-flap"
|
||||
icon_dead = "blutiel-dead"
|
||||
icon_sit = "blutiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/too
|
||||
name = "Too"
|
||||
icon_state = "too-flap"
|
||||
icon_living = "too-flap"
|
||||
icon_dead = "too-dead"
|
||||
icon_sit = "too_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/hooded_too
|
||||
name = "Utoo"
|
||||
icon_state = "utoo-flap"
|
||||
icon_living = "utoo-flap"
|
||||
icon_dead = "utoo-dead"
|
||||
icon_sit = "utoo_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/pink_too
|
||||
name = "Mtoo"
|
||||
icon_state = "mtoo-flap"
|
||||
icon_living = "mtoo-flap"
|
||||
icon_dead = "mtoo-dead"
|
||||
icon_sit = "mtoo_sit"
|
||||
@@ -354,7 +354,7 @@
|
||||
/mob/living/simple_animal/proc/drop_loot()
|
||||
if(loot.len)
|
||||
for(var/i in loot)
|
||||
new i(loc)
|
||||
new i(loc, dir = src.dir)
|
||||
|
||||
/mob/living/simple_animal/death(gibbed)
|
||||
movement_type &= ~FLYING
|
||||
|
||||
@@ -508,7 +508,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
if(LOG_EMOTE)
|
||||
colored_message = "(EMOTE) [colored_message]"
|
||||
|
||||
var/list/timestamped_message = list("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(src)] [loc_name(src)]" = colored_message)
|
||||
var/list/timestamped_message = list("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(src)] [loc_name(src)] (Event #[LAZYLEN(logging[smessage_type])])" = colored_message)
|
||||
|
||||
logging[smessage_type] += timestamped_message
|
||||
|
||||
|
||||
@@ -148,8 +148,8 @@ proc/get_top_level_mob(var/mob/S)
|
||||
var/safety = 25
|
||||
for(var/obj/structure/table/T in range(user, 1))
|
||||
processing |= T
|
||||
for(var/i in processing)
|
||||
var/obj/structure/table/T = i
|
||||
for(var/i = 1; i <= processing.len; ++i)
|
||||
var/obj/structure/table/T = processing[i]
|
||||
if(safety-- <= 0)
|
||||
to_chat(user, "Table scan aborted early, some people might have not received the message (max 25)")
|
||||
break
|
||||
|
||||
@@ -182,8 +182,9 @@
|
||||
if(..())
|
||||
if(reagents.total_volume)
|
||||
if(M.reagents)
|
||||
log_combat(user, M, "injected with sleepypen", src, reagents.log_list())
|
||||
reagents.reaction(M, INJECT)
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
reagents.trans_to(M, reagents.total_volume, log = "sleepypen inject")
|
||||
|
||||
|
||||
/obj/item/pen/sleepy/Initialize()
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
set_security_level("delta")
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
SSshuttle.lockdown = TRUE
|
||||
SSpersistence.station_was_destroyed = TRUE
|
||||
sleep(600)
|
||||
if(resolved == FALSE)
|
||||
resolved = TRUE
|
||||
|
||||
@@ -257,9 +257,9 @@
|
||||
var/amount = text2num(params["amount"])
|
||||
if(amount == null)
|
||||
amount = text2num(input(usr,
|
||||
"Max 10. Buffer content will be split evenly.",
|
||||
"Max 20. Buffer content will be split evenly.",
|
||||
"How many to make?", 1))
|
||||
amount = clamp(round(amount), 0, 10)
|
||||
amount = clamp(round(amount), 0, 20)
|
||||
if (amount <= 0)
|
||||
return FALSE
|
||||
// Get units per item
|
||||
|
||||
@@ -633,7 +633,7 @@
|
||||
value = REAGENT_VALUE_RARE
|
||||
|
||||
/datum/reagent/medicine/sal_acid
|
||||
name = "Salicyclic Acid"
|
||||
name = "Salicylic Acid"
|
||||
description = "Stimulates the healing of severe bruises. Extremely rapidly heals severe bruising and slowly heals minor ones. Overdose will worsen existing bruising."
|
||||
reagent_state = LIQUID
|
||||
color = "#D2D2D2"
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
required_reagents = list(/datum/reagent/medicine/pen_acid = 1, /datum/reagent/toxin/slimejelly = 1)
|
||||
|
||||
/datum/chemical_reaction/sal_acid
|
||||
name = "Salicyclic Acid"
|
||||
name = "Salicylic Acid"
|
||||
id = /datum/reagent/medicine/sal_acid
|
||||
results = list(/datum/reagent/medicine/sal_acid = 5)
|
||||
required_reagents = list(/datum/reagent/sodium = 1, /datum/reagent/phenol = 1, /datum/reagent/carbon = 1, /datum/reagent/oxygen = 1, /datum/reagent/toxin/acid = 1)
|
||||
|
||||
@@ -104,3 +104,11 @@
|
||||
build_path = /obj/item/circuitboard/machine/thermomachine
|
||||
category = list ("Engineering Machinery")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/board/spaceship_navigation_beacon
|
||||
name = "Machine Design (Bluespace Navigation Gigabeacon)"
|
||||
desc = "The circuit board for a Bluespace Navigation Gigabeacon."
|
||||
id = "spaceship_navigation_beacon"
|
||||
build_path = /obj/item/circuitboard/machine/spaceship_navigation_beacon
|
||||
category = list ("Teleportation Machinery")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
|
||||
@@ -726,6 +726,32 @@
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/////////////////////
|
||||
/////Synth Organs////
|
||||
/////////////////////
|
||||
|
||||
/datum/design/ipc_stomach
|
||||
name = "IPC cell"
|
||||
desc = "Effectively the robot equivalent of a stomach, handling power storage."
|
||||
id = "ipc_stomach"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 40
|
||||
materials = list(/datum/material/iron = 1000, /datum/material/glass = 300, /datum/material/silver = 500, /datum/material/gold = 400)
|
||||
build_path = /obj/item/organ/stomach/ipc
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cyberimp_power_cord
|
||||
name = "IPC power cord"
|
||||
desc = "A implant for Robots designed to siphon power from APCs to recharge their own cell."
|
||||
id = "ci-power-cord"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 75
|
||||
materials = list(/datum/material/iron = 4000, /datum/material/glass = 1500, /datum/material/silver = 1200, /datum/material/gold = 1600, /datum/material/plasma = 1000)
|
||||
build_path = /obj/item/organ/cyberimp/arm/power_cord
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/////////////////////
|
||||
///Surgery Designs///
|
||||
/////////////////////
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
display_name = "Biological Technology"
|
||||
description = "What makes us tick." //the MC, silly!
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv", "medspray","genescanner","chem_pack")
|
||||
design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv", "medspray","genescanner","chem_pack", "portable_chem_mixer")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
|
||||
/datum/techweb_node/adv_biotech
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
display_name = "Basic Shuttle Research"
|
||||
description = "Research the technology required to create and use basic shuttles."
|
||||
prereq_ids = list("practical_bluespace", "adv_engi")
|
||||
design_ids = list("shuttle_creator", "engine_plasma", "engine_heater", "shuttle_control", "shuttle_docker")
|
||||
design_ids = list("shuttle_creator", "engine_plasma", "engine_heater", "shuttle_control", "shuttle_docker","spaceship_navigation_beacon")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
|
||||
|
||||
/datum/techweb_node/shuttle_route_upgrade
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
display_name = "Upgraded Cybernetic Organs"
|
||||
description = "We have the technology to upgrade him."
|
||||
prereq_ids = list("cyber_organs")
|
||||
design_ids = list("cybernetic_ears_u", "cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u")
|
||||
design_ids = list("cybernetic_ears_u", "cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u", "ipc_stomach")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500)
|
||||
|
||||
/datum/techweb_node/cyber_implants
|
||||
@@ -88,7 +88,7 @@
|
||||
display_name = "Cybernetic Implants"
|
||||
description = "Electronic implants that improve humans."
|
||||
prereq_ids = list("adv_biotech", "adv_datatheory")
|
||||
design_ids = list("ci-nutriment", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud", "ci-service")
|
||||
design_ids = list("ci-nutriment", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud", "ci-service", "ci-power-cord")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
|
||||
/datum/techweb_node/adv_cyber_implants
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
var/list/jumpto_ports = list() //hashset of ports to jump to and ignore for collision purposes
|
||||
var/obj/docking_port/stationary/my_port //the custom docking port placed by this console
|
||||
var/obj/docking_port/mobile/shuttle_port //the mobile docking port of the connected shuttle
|
||||
var/list/locked_traits = list(ZTRAIT_RESERVED, ZTRAIT_CENTCOM, ZTRAIT_AWAY, ZTRAIT_REEBE) //traits forbided for custom docking
|
||||
var/view_range = 0
|
||||
var/x_offset = 0
|
||||
var/y_offset = 0
|
||||
@@ -186,7 +187,7 @@
|
||||
var/turf/eyeturf = get_turf(the_eye)
|
||||
if(!eyeturf)
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
if(z_lock.len && !(eyeturf.z in z_lock))
|
||||
if(!eyeturf.z || SSmapping.level_has_any_trait(eyeturf.z, locked_traits))
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
|
||||
. = SHUTTLE_DOCKER_LANDING_CLEAR
|
||||
@@ -224,9 +225,9 @@
|
||||
if(hidden_turf_info)
|
||||
. = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT
|
||||
|
||||
if(space_turfs_only)
|
||||
if(length(whitelist_turfs))
|
||||
var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type
|
||||
if(!ispath(turf_type, /turf/open/space))
|
||||
if(!is_type_in_typecache(turf_type, whitelist_turfs))
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
|
||||
if(length(whitelist_turfs))
|
||||
@@ -324,12 +325,25 @@
|
||||
var/list/L = list()
|
||||
for(var/V in SSshuttle.stationary)
|
||||
if(!V)
|
||||
stack_trace("SSshuttle.stationary have null entry!")
|
||||
continue
|
||||
var/obj/docking_port/stationary/S = V
|
||||
if(console.z_lock.len && !(S.z in console.z_lock))
|
||||
continue
|
||||
if(console.jumpto_ports[S.id])
|
||||
L[S.name] = S
|
||||
L["([L.len])[S.name]"] = S
|
||||
|
||||
for(var/V in SSshuttle.beacons)
|
||||
if(!V)
|
||||
stack_trace("SSshuttle.beacons have null entry!")
|
||||
continue
|
||||
var/obj/machinery/spaceship_navigation_beacon/nav_beacon = V
|
||||
if(!nav_beacon.z || SSmapping.level_has_any_trait(nav_beacon.z, console.locked_traits))
|
||||
break
|
||||
if(!nav_beacon.locked)
|
||||
L["([L.len]) [nav_beacon.name] located: [nav_beacon.x] [nav_beacon.y] [nav_beacon.z]"] = nav_beacon
|
||||
else
|
||||
L["([L.len]) [nav_beacon.name] locked"] = null
|
||||
|
||||
playsound(console, 'sound/machines/terminal_prompt.ogg', 25, 0)
|
||||
var/selected = input("Choose location to jump to", "Locations", null) as null|anything in L
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/obj/item/circuitboard/machine/spaceship_navigation_beacon
|
||||
name = "Bluespace Navigation Gigabeacon (Machine Board)"
|
||||
build_path = /obj/machinery/spaceship_navigation_beacon
|
||||
req_components = list()
|
||||
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon
|
||||
name = "Bluespace Navigation Gigabeacon"
|
||||
desc = "A device that creates a bluespace anchor that allow ships jump near to it."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "core"
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 0
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/spaceship_navigation_beacon
|
||||
|
||||
var/locked = FALSE //Locked beacons don't allow to jump to it.
|
||||
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon/Initialize()
|
||||
. = ..()
|
||||
SSshuttle.beacons |= src
|
||||
|
||||
obj/machinery/spaceship_navigation_beacon/emp_act()
|
||||
locked = TRUE
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon/Destroy()
|
||||
SSshuttle.beacons -= src
|
||||
return ..()
|
||||
|
||||
// update the icon_state
|
||||
/obj/machinery/spaceship_navigation_beacon/update_icon()
|
||||
if(powered())
|
||||
icon_state = "core"
|
||||
else
|
||||
icon_state = "core-open"
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon/power_change()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if(panel_open)
|
||||
var/new_name = "Beacon_[input("Enter the custom name for this beacon", "It be Beacon ..your input..") as text]"
|
||||
if(new_name && Adjacent(user))
|
||||
name = new_name
|
||||
to_chat(user, "<span class='notice'>You change beacon name to [name].</span>")
|
||||
else
|
||||
locked =!locked
|
||||
to_chat(user, "<span class='notice'>You [locked ? "" : "un"]lock [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon/examine()
|
||||
.=..()
|
||||
. += "<span class='[locked ? "warning" : "nicegreen"]'>Status: [locked ? "LOCKED" : "Stable"] </span>"
|
||||
|
||||
/obj/machinery/spaceship_navigation_beacon/attackby(obj/item/W, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "core-open", "core", W))
|
||||
return
|
||||
if(default_deconstruction_crowbar(W))
|
||||
return
|
||||
|
||||
return ..()
|
||||
@@ -394,11 +394,10 @@
|
||||
var/datum/wound/new_wound
|
||||
if(replaced_wound)
|
||||
new_wound = replaced_wound.replace_wound(possible_wound)
|
||||
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned
|
||||
else
|
||||
new_wound = new possible_wound
|
||||
new_wound.apply_wound(src)
|
||||
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
|
||||
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned
|
||||
return new_wound
|
||||
|
||||
// try forcing a specific wound, but only if there isn't already a wound of that severity or greater for that type on this bodypart
|
||||
|
||||
@@ -98,18 +98,19 @@
|
||||
return json_encode(response)
|
||||
|
||||
/datum/tgs_api/v5/OnTopic(T)
|
||||
if(!initialized)
|
||||
return FALSE //continue world/Topic
|
||||
|
||||
var/list/params = params2list(T)
|
||||
var/json = params[DMAPI5_TOPIC_DATA]
|
||||
if(!json)
|
||||
return FALSE
|
||||
return FALSE // continue to /world/Topic
|
||||
|
||||
var/list/topic_parameters = json_decode(json)
|
||||
if(!topic_parameters)
|
||||
return TopicResponse("Invalid topic parameters json!");
|
||||
|
||||
if(!initialized)
|
||||
TGS_WARNING_LOG("Missed topic due to not being initialized: [T]")
|
||||
return TRUE // too early to handle, but it's still our responsibility
|
||||
|
||||
var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER]
|
||||
if(their_sCK != access_identifier)
|
||||
return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] from: [json]!");
|
||||
|
||||
@@ -142,6 +142,14 @@
|
||||
cost = 4 // Has syndie tools + gloves + a robust weapon
|
||||
restricted_roles = list("Assistant", "Curator") //Curator due to this being made of gold - It fits the theme
|
||||
|
||||
/datum/uplink_item/role_restricted/oldtoolboxclean // this is the fourth item relating to toolboxes to be placed into this godforsaken bloated uplink
|
||||
name = "Ancient Toolbox"
|
||||
desc = "An iconic toolbox design notorious with Assistants everywhere, this design was especially made to become more robust the more telecrystals it has inside it! Tools and insulated gloves included."
|
||||
item = /obj/item/storage/toolbox/mechanical/old/clean
|
||||
cost = 2 // with eighteen telecrystals you are still weaker than a desword and without any of its defenses -- the scary part comes from collaborating with allies for a fifty eight force toolbox oh fuck
|
||||
restricted_roles = list("Assistant")
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/role_restricted/mimery
|
||||
name = "Guide to Advanced Mimery Series"
|
||||
desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. \
|
||||
@@ -242,3 +250,11 @@
|
||||
cost = 2
|
||||
item = /obj/item/clothing/shoes/magboots/crushing
|
||||
restricted_roles = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
|
||||
|
||||
/datum/uplink_item/role_restricted/turretbox
|
||||
name = "Disposable Sentry Gun"
|
||||
desc = "A disposable sentry gun deployment system cleverly disguised as a toolbox, apply wrench for functionality."
|
||||
item = /obj/item/storage/toolbox/emergency/turret
|
||||
cost = 11
|
||||
restricted_roles = list("Station Engineer")
|
||||
|
||||
|
||||
@@ -18,14 +18,12 @@
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/horn/clowncar, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/driver_move(mob/user, direction) //Prevent it from moving onto space
|
||||
if(isspaceturf(get_step(src, direction)))
|
||||
return FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/auto_assign_occupant_flags(mob/M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -138,3 +136,24 @@
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/StopDroppingOil()
|
||||
droppingoil = FALSE
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays
|
||||
key_type = null
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/twitch_plays/simple_movement)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
GLOB.poi_list |= src
|
||||
notify_ghosts("Twitch Plays: Clown Car")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.poi_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/process()
|
||||
var/dir = SEND_SIGNAL(src, COMSIG_TWITCH_PLAYS_MOVEMENT_DATA, TRUE)
|
||||
if(!dir)
|
||||
return
|
||||
driver_move(null, dir)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
canmove = TRUE
|
||||
density = FALSE //Thought I couldn't fix this one easily, phew
|
||||
arms_required = 1
|
||||
var/override_movespeed = FALSE
|
||||
|
||||
/obj/vehicle/ridden/wheelchair/Initialize()
|
||||
. = ..()
|
||||
@@ -42,10 +43,11 @@
|
||||
canmove = FALSE
|
||||
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
|
||||
return FALSE
|
||||
var/datum/component/riding/D = GetComponent(/datum/component/riding)
|
||||
//1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
|
||||
//if that made no sense this simply makes the wheelchair speed change along with movement speed delay
|
||||
D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag)
|
||||
if(!override_movespeed)
|
||||
var/datum/component/riding/D = GetComponent(/datum/component/riding)
|
||||
//1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
|
||||
//if that made no sense this simply makes the wheelchair speed change along with movement speed delay
|
||||
D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag)
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/ridden/wheelchair/Moved()
|
||||
|
||||
@@ -375,7 +375,7 @@
|
||||
/obj/item/paint/paint_remover = 2,
|
||||
/obj/item/melee/flyswatter = 2,
|
||||
/obj/item/flashlight = 2,
|
||||
/obj/item/caution = 8,
|
||||
/obj/item/clothing/suit/caution = 8,
|
||||
/obj/item/holosign_creator = 2,
|
||||
/obj/item/lightreplacer = 2,
|
||||
/obj/item/soap = 2,
|
||||
@@ -544,7 +544,7 @@
|
||||
/obj/item/clothing/glasses/sunglasses/gar/supergar = 1,
|
||||
/obj/item/clothing/gloves/color/captain = 1)
|
||||
refill_canister = /obj/item/vending_refill/wardrobe/cap_wardrobe
|
||||
payment_department = ACCOUNT_CIV
|
||||
payment_department = ACCOUNT_SEC
|
||||
default_price = PRICE_ALMOST_EXPENSIVE
|
||||
extra_price = PRICE_ABOVE_EXPENSIVE
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/obj/belly
|
||||
name = "belly" // Name of this location
|
||||
desc = "It's a belly! You're in it!" // Flavor text description of inside sight/sound/smells/feels.
|
||||
rad_flags = RAD_NO_CONTAMINATE | RAD_PROTECT_CONTENTS
|
||||
var/vore_sound = "Gulp" // Sound when ingesting someone
|
||||
var/vore_verb = "ingest" // Verb for eating with this in messages
|
||||
var/release_sound = "Splatter" // Sound for letting someone out.
|
||||
|
||||
Reference in New Issue
Block a user