Your [name] starts to fall apart!")
/obj/item/clothing/proc/update_clothes_damaged_state(damaging = TRUE)
var/index = "\ref[initial(icon)]-[initial(icon_state)]"
diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm
index 448bf8a0a31..6ed63a3eaf8 100644
--- a/code/modules/clothing/spacesuits/flightsuit.dm
+++ b/code/modules/clothing/spacesuits/flightsuit.dm
@@ -663,6 +663,9 @@
flight = FALSE
if(suit.shoes)
suit.shoes.toggle(FALSE)
+ if(isturf(wearer.loc))
+ var/turf/T = wearer.loc
+ T.Entered(src)
else
if(override_safe)
disable_flight(TRUE)
diff --git a/code/modules/events/ghost_role.dm b/code/modules/events/ghost_role.dm
index 93eff54b270..2468ddb5c6a 100644
--- a/code/modules/events/ghost_role.dm
+++ b/code/modules/events/ghost_role.dm
@@ -59,7 +59,7 @@
var/list/mob/dead/observer/regular_candidates
// don't get their hopes up
if(priority_candidates.len < minimum_required)
- regular_candidates = pollCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, gametypecheck, be_special)
+ regular_candidates = pollGhostCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, gametypecheck, be_special)
else
regular_candidates = list()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 1b41cd45cd5..705c532260e 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -15,12 +15,21 @@
var/max_n_of_items = 1500
var/icon_on = "smartfridge"
var/icon_off = "smartfridge-off"
+ var/list/initial_contents
/obj/machinery/smartfridge/Initialize()
..()
create_reagents()
reagents.set_reacting(FALSE)
+ if(islist(initial_contents))
+ for(var/typekey in initial_contents)
+ var/amount = initial_contents[typekey]
+ if(isnull(amount))
+ amount = 1
+ for(var/i in 1 to amount)
+ load(new typekey(src))
+
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/smartfridge(null)
B.apply_default_parts(src)
@@ -51,7 +60,7 @@
else
return ..()
-/obj/item/weapon/circuitboard/machine/smartfridge/examine/(mob/user)
+/obj/item/weapon/circuitboard/machine/smartfridge/examine(mob/user)
..()
to_chat(user, "[src] is set to [fridges[build_path]]. You can use a screwdriver to reconfigure it.")
@@ -384,12 +393,8 @@
return TRUE
return FALSE
-/obj/machinery/smartfridge/extract/New()
- ..()
- var/obj/item/device/slime_scanner/I = new /obj/item/device/slime_scanner(src)
- load(I)
- var/obj/item/device/slime_scanner/T = new /obj/item/device/slime_scanner(src)
- load(T)
+/obj/machinery/smartfridge/extract/preloaded
+ initial_contents = list(/obj/item/device/slime_scanner = 2)
// -----------------------------
// Chemistry Medical Smartfridge
@@ -397,21 +402,6 @@
/obj/machinery/smartfridge/chemistry
name = "smart chemical storage"
desc = "A refrigerated storage unit for medicine storage."
- var/list/spawn_meds = list(
- /obj/item/weapon/reagent_containers/pill/epinephrine = 12,
- /obj/item/weapon/reagent_containers/pill/charcoal = 5,
- /obj/item/weapon/reagent_containers/glass/bottle/epinephrine = 1,
- /obj/item/weapon/reagent_containers/glass/bottle/charcoal = 1)
-
-/obj/machinery/smartfridge/chemistry/New()
- ..()
- for(var/typekey in spawn_meds)
- var/amount = spawn_meds[typekey]
- if(isnull(amount)) amount = 1
- while(amount)
- var/obj/item/I = new typekey(src)
- load(I)
- amount--
/obj/machinery/smartfridge/chemistry/accept_check(obj/item/O)
if(istype(O,/obj/item/weapon/storage/pill_bottle))
@@ -431,13 +421,22 @@
return TRUE
return FALSE
+/obj/machinery/smartfridge/chemistry/preloaded
+ initial_contents = list(
+ /obj/item/weapon/reagent_containers/pill/epinephrine = 12,
+ /obj/item/weapon/reagent_containers/pill/charcoal = 5,
+ /obj/item/weapon/reagent_containers/glass/bottle/epinephrine = 1,
+ /obj/item/weapon/reagent_containers/glass/bottle/charcoal = 1)
+
// ----------------------------
// Virology Medical Smartfridge
// ----------------------------
/obj/machinery/smartfridge/chemistry/virology
name = "smart virus storage"
desc = "A refrigerated storage unit for volatile sample storage."
- spawn_meds = list(
+
+/obj/machinery/smartfridge/chemistry/virology/preloaded
+ initial_contents = list(
/obj/item/weapon/reagent_containers/syringe/antiviral = 4,
/obj/item/weapon/reagent_containers/glass/bottle/cold = 1,
/obj/item/weapon/reagent_containers/glass/bottle/flu_virion = 1,
diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm
index 2f01cd06e0a..55a57de9941 100644
--- a/code/modules/language/language.dm
+++ b/code/modules/language/language.dm
@@ -1,4 +1,4 @@
-#define SCRAMBLE_CACHE_LEN 20
+#define SCRAMBLE_CACHE_LEN 50 //maximum of 50 specific scrambled lines per language
/*
Datum based languages. Easily editable and modular.
@@ -16,10 +16,10 @@
// If key is null, then the language isn't real or learnable.
var/flags // Various language flags.
var/list/syllables // Used when scrambling text for a non-speaker.
- var/list/sentence_chance = 5 // Likelihood of making a new sentence after each syllable.
- var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string
+ var/sentence_chance = 5 // Likelihood of making a new sentence after each syllable.
+ var/space_chance = 55 // Likelihood of getting a space in the random scramble string
var/list/spans = list()
- var/static/list/scramble_cache = list()
+ var/list/scramble_cache = list()
var/default_priority = 0 // the language that an atom knows with the highest "default_priority" is selected by default.
// if you are seeing someone speak popcorn language, then something is wrong.
diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm
index cd0ce23b23f..c8ba5094000 100644
--- a/code/modules/language/language_holder.dm
+++ b/code/modules/language/language_holder.dm
@@ -87,6 +87,10 @@
languages = list(/datum/language/common, /datum/language/ratvar)
only_speaks_language = /datum/language/ratvar
+/datum/language_holder/construct
+ languages = list(/datum/language/common, /datum/language/narsie)
+ only_speaks_language = /datum/language/narsie
+
/datum/language_holder/drone
languages = list(/datum/language/common, /datum/language/drone, /datum/language/machine)
only_speaks_language = /datum/language/drone
diff --git a/code/modules/language/narsian.dm b/code/modules/language/narsian.dm
new file mode 100644
index 00000000000..70966ad8802
--- /dev/null
+++ b/code/modules/language/narsian.dm
@@ -0,0 +1,43 @@
+/datum/language/narsie
+ name = "Nar-Sian"
+ desc = "The ancient, blood-soaked, impossibly complex language of Nar-Sian cultists."
+ speech_verb = "intones"
+ ask_verb = "inquires"
+ exclaim_verb = "invokes"
+ key = "n"
+ sentence_chance = 8
+ space_chance = 95 //very high due to the potential length of each syllable
+ var/static/list/base_syllables = list(
+ "h", "v", "c", "e", "g", "d", "r", "n", "h", "o", "p",
+ "ra", "so", "at", "il", "ta", "gh", "sh", "ya", "te", "sh", "ol", "ma", "om", "ig", "ni", "in",
+ "sha", "mir", "sas", "mah", "zar", "tok", "lyr", "nqa", "nap", "olt", "val", "qha",
+ "fwe", "ath", "yro", "eth", "gal", "gib", "bar", "jin", "kla", "atu", "kal", "lig",
+ "yoka", "drak", "loso", "arta", "weyh", "ines", "toth", "fara", "amar", "nyag", "eske", "reth", "dedo", "btoh", "nikt", "neth",
+ "kanas", "garis", "uloft", "tarat", "khari", "thnor", "rekka", "ragga", "rfikk", "harfr", "andid", "ethra", "dedol", "totum",
+ "ntrath", "keriam"
+ ) //the list of syllables we'll combine with itself to get a larger list of syllables
+ syllables = list(
+ "sha", "mir", "sas", "mah", "hra", "zar", "tok", "lyr", "nqa", "nap", "olt", "val",
+ "yam", "qha", "fel", "det", "fwe", "mah", "erl", "ath", "yro", "eth", "gal", "mud",
+ "gib", "bar", "tea", "fuu", "jin", "kla", "atu", "kal", "lig",
+ "yoka", "drak", "loso", "arta", "weyh", "ines", "toth", "fara", "amar", "nyag", "eske", "reth", "dedo", "btoh", "nikt", "neth", "abis",
+ "kanas", "garis", "uloft", "tarat", "khari", "thnor", "rekka", "ragga", "rfikk", "harfr", "andid", "ethra", "dedol", "totum",
+ "verbot", "pleggh", "ntrath", "barhah", "pasnar", "keriam", "usinar", "savrae", "amutan", "tannin", "remium", "barada",
+ "forbici"
+ ) //the base syllables, which include a few rare ones that won't appear in the mixed syllables
+ icon_state = "narsie"
+ default_priority = 10
+
+/datum/language/narsie/New()
+ for(var/syllable in base_syllables) //we only do this once, since there's only ever a single one of each language datum.
+ for(var/target_syllable in base_syllables)
+ if(syllable != target_syllable) //don't combine with yourself
+ if(length(syllable) + length(target_syllable) > 8) //if the resulting syllable would be very long, don't put anything between it
+ syllables += "[syllable][target_syllable]"
+ else if(prob(80)) //we'll be minutely different each round.
+ syllables += "[syllable]'[target_syllable]"
+ else if(prob(25)) //5% chance of - instead of '
+ syllables += "[syllable]-[target_syllable]"
+ else //15% chance of no ' or - at all
+ syllables += "[syllable][target_syllable]"
+ ..()
diff --git a/code/modules/language/ratvar.dm b/code/modules/language/ratvarian.dm
similarity index 51%
rename from code/modules/language/ratvar.dm
rename to code/modules/language/ratvarian.dm
index cef4a3164ec..b924d2fc79d 100644
--- a/code/modules/language/ratvar.dm
+++ b/code/modules/language/ratvarian.dm
@@ -1,14 +1,19 @@
/datum/language/ratvar
name = "Ratvarian"
desc = "A timeless language full of power and incomprehensible to the unenlightened."
- speech_verb = "clinks"
- ask_verb = "clunks"
- exclaim_verb = "clanks"
+ var/static/random_speech_verbs = list("clanks", "clinks", "clunks", "clangs")
+ ask_verb = "requests"
+ exclaim_verb = "proclaims"
+ whisper_verb = "imparts"
key = "r"
default_priority = 10
spans = list(SPAN_ROBOT)
-
icon_state = "ratvar"
/datum/language/ratvar/scramble(var/input)
. = text2ratvar(input)
+
+/datum/language/ratvar/get_spoken_verb(msg_end)
+ if(!msg_end)
+ return pick(random_speech_verbs)
+ return ..()
\ No newline at end of file
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index d93bcb50286..f3b66d91724 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -84,7 +84,7 @@
if(D.make_reagents.len)
return 0
- var/build_amount = 1
+ var/build_amount = 0
for(var/mat_id in D.materials)
var/M = D.materials[mat_id]
@@ -93,7 +93,15 @@
if(!M || !redemption_mat)
return 0
- build_amount = min(build_amount, round(redemption_mat.amount / M))
+ var/smeltable_sheets = round(redemption_mat.amount / M)
+
+ if(!smeltable_sheets)
+ return 0
+
+ if(!build_amount)
+ build_amount = smeltable_sheets
+
+ build_amount = min(build_amount, smeltable_sheets)
return build_amount
@@ -152,6 +160,7 @@
if(exchange_parts(user, W))
return
if(default_pry_open(W))
+ materials.retrieve_all()
return
if(default_unfasten_wrench(user, W))
return
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index ca8b8f2d9d5..8d842d8a48d 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -31,8 +31,23 @@
if(bodytemperature >= 225 && !(disabilities & NOCLONE)) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
- if(blood_volume < BLOOD_VOLUME_NORMAL)
- blood_volume += 0.1 // regenerate blood VERY slowly
+ if(blood_volume < BLOOD_VOLUME_NORMAL && !(NOHUNGER in dna.species.species_traits))
+ var/nutrition_ratio = 0
+ switch(nutrition)
+ if(0 to NUTRITION_LEVEL_STARVING)
+ nutrition_ratio = 0.2
+ if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
+ nutrition_ratio = 0.4
+ if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
+ nutrition_ratio = 0.6
+ if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
+ nutrition_ratio = 0.8
+ else
+ nutrition_ratio = 1
+ if(satiety > 80)
+ nutrition_ratio *= 1.25
+ nutrition = max(0, nutrition - nutrition_ratio * HUNGER_FACTOR)
+ blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index 7eb6d182ef4..86ea3d64e9e 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -69,7 +69,7 @@
bursting = TRUE
- var/list/candidates = pollCandidates("Do you want to play as an alien larva that will burst out of [owner]?", ROLE_ALIEN, null, ROLE_ALIEN, 100, POLL_IGNORE_ALIEN_LARVA)
+ var/list/candidates = pollGhostCandidates("Do you want to play as an alien larva that will burst out of [owner]?", ROLE_ALIEN, null, ROLE_ALIEN, 100, POLL_IGNORE_ALIEN_LARVA)
if(QDELETED(src) || QDELETED(owner))
return
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index c18f6721edc..06cfbe16cb1 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -165,5 +165,8 @@
dna.species.mutant_bodyparts -= "wingsopen"
dna.species.mutant_bodyparts |= "wings"
update_body()
+ if(isturf(loc))
+ var/turf/T = loc
+ T.Entered(src)
//Ayy lmao
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 52145f609b6..8a9efde9662 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -646,3 +646,18 @@
if(P.is_hot())
visible_message("[src] bursts into flames!")
fire_act()
+
+/datum/species/golem/plastic
+ name = "Plastic"
+ id = "plastic golem"
+ prefix = "Plastic"
+ fixed_mut_color = "fff"
+ info_text = "As a Plastic Golem, you are capable of ventcrawling, and passing through plastic flaps."
+
+/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species)
+ . = ..()
+ C.ventcrawler = VENTCRAWLER_NUDE
+
+/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
+ . = ..()
+ C.ventcrawler = initial(C.ventcrawler)
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 099cb03260a..b739a2a6c5c 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -49,8 +49,8 @@
timeofdeath = world.time
tod = worldtime2text()
var/turf/T = get_turf(src)
+ var/area/A = get_area(T)
if(mind && mind.name && mind.active && (!(T.flags & NO_DEATHRATTLE)))
- var/area/A = get_area(T)
var/rendered = "[mind.name] has died at [A.name]."
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if(mind)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 92725d73a65..4bbeb3bcfda 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -446,7 +446,7 @@
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
- if (s_active && !(s_active.ClickAccessible(src, depth=STORAGE_VIEW_DEPTH) || s_active.Adjacent(src)))
+ if (s_active && !(CanReach(s_active,view_only = TRUE)))
s_active.close(src)
/mob/living/movement_delay(ignorewalk = 0)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index d175054970c..568c9e87212 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -27,10 +27,13 @@
unique_name = 1
AIStatus = AI_OFF //normal constructs don't have AI
loot = list(/obj/item/weapon/ectoplasm)
- del_on_death = 1
+ del_on_death = TRUE
+ initial_language_holder = /datum/language_holder/construct
deathmessage = "collapses in a shattered heap."
var/list/construct_spells = list()
var/playstyle_string = "You are a generic construct! Your job is to not exist, and you should probably adminhelp this."
+ var/master = null
+ var/seeking = FALSE
/mob/living/simple_animal/hostile/construct/Initialize()
@@ -39,6 +42,11 @@
for(var/spell in construct_spells)
AddSpell(new spell(null))
+/mob/living/simple_animal/hostile/construct/Destroy()
+ for(var/X in actions)
+ var/datum/action/A = X
+ qdel(A)
+ ..()
/mob/living/simple_animal/hostile/construct/Login()
..()
@@ -278,6 +286,36 @@
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
+///////////////////////Master-Tracker///////////////////////
+
+/datum/action/innate/seek_master
+ name = "Seek your Master"
+ desc = "You and your master share a soul-link that informs you of their location"
+ background_icon_state = "bg_demon"
+ buttontooltipstyle = "cult"
+ button_icon_state = "cult_mark"
+ var/tracking = FALSE
+ var/mob/living/simple_animal/hostile/construct/the_construct
+
+/datum/action/innate/seek_master/Grant(var/mob/living/C)
+ the_construct = C
+ ..()
+
+/datum/action/innate/seek_master/Activate()
+ if(!the_construct.master)
+ to_chat(the_construct, "You have no master to seek!")
+ the_construct.seeking = FALSE
+ return
+ if(tracking)
+ tracking = FALSE
+ the_construct.seeking = FALSE
+ to_chat(the_construct, "You are no longer tracking your master.")
+ return
+ else
+ tracking = TRUE
+ the_construct.seeking = TRUE
+ to_chat(the_construct, "You are now tracking your master.")
+
/////////////////////////////ui stuff/////////////////////////////
@@ -294,4 +332,5 @@
else if(health > maxHealth*0.2)
hud_used.healths.icon_state = "[icon_state]_health5"
else
- hud_used.healths.icon_state = "[icon_state]_health6"
\ No newline at end of file
+ hud_used.healths.icon_state = "[icon_state]_health6"
+
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index be889a4183c..fe6e22bcab2 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -414,7 +414,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians
if(G)
to_chat(src, "You attempt to reset [G.real_name]'s personality...")
- var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", "pAI", null, FALSE, 100)
+ var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", "pAI", null, FALSE, 100)
var/mob/dead/observer/new_stand = null
if(candidates.len)
new_stand = pick(candidates)
@@ -489,7 +489,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
return
used = TRUE
to_chat(user, "[use_message]")
- var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100)
+ var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100)
var/mob/dead/observer/theghost = null
if(candidates.len)
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle_mobs.dm b/code/modules/mob/living/simple_animal/hostile/jungle_mobs.dm
new file mode 100644
index 00000000000..de1bf0b3083
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/jungle_mobs.dm
@@ -0,0 +1,85 @@
+/mob/living/simple_animal/hostile/jungle
+ vision_range = 5
+ 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)
+ faction = list("jungle")
+ weather_immunities = list("acid")
+ obj_damage = 30
+ environment_smash = 2
+ minbodytemp = 0
+ maxbodytemp = 450
+ response_help = "pokes"
+ response_disarm = "shoves"
+ response_harm = "strikes"
+ status_flags = 0
+ a_intent = INTENT_HARM
+ see_in_dark = 4
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ mob_size = MOB_SIZE_LARGE
+
+
+
+//Mega arachnid
+
+/mob/living/simple_animal/hostile/jungle/mega_arachnid
+ name = "mega arachnid"
+ desc = "Though physically imposing, it prefers to ambush its prey, and it will only engage with an already crippled opponent."
+ melee_damage_lower = 30
+ melee_damage_upper = 30
+ maxHealth = 300
+ health = 300
+ speed = 1
+ ranged = 1
+ pixel_x = -16
+ move_to_delay = 10
+ aggro_vision_range = 9
+ speak_emote = list("chitters")
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ ranged_cooldown_time = 60
+ projectiletype = /obj/item/projectile/mega_arachnid
+ projectilesound = 'sound/weapons/pierce.ogg'
+ icon = 'icons/mob/jungle/arachnid.dmi'
+ icon_state = "arachnid"
+ icon_living = "arachnid"
+ icon_dead = "dead_purple"
+ alpha = 50
+
+/mob/living/simple_animal/hostile/jungle/mega_arachnid/Life()
+ ..()
+ if(target && ranged_cooldown > world.time && iscarbon(target))
+ var/mob/living/carbon/C = target
+ if(!C.legcuffed && C.health < 50)
+ retreat_distance = 9
+ minimum_distance = 9
+ alpha = 125
+ return
+ retreat_distance = 0
+ minimum_distance = 0
+ alpha = 255
+
+
+/mob/living/simple_animal/hostile/jungle/mega_arachnid/Aggro()
+ ..()
+ alpha = 255
+
+/mob/living/simple_animal/hostile/jungle/mega_arachnid/LoseAggro()
+ ..()
+ alpha = 50
+
+/obj/item/projectile/mega_arachnid
+ name = "flesh snare"
+ nodamage = 1
+ damage = 0
+ icon_state = "tentacle_end"
+
+/obj/item/projectile/mega_arachnid/on_hit(atom/target, blocked = 0)
+ if(iscarbon(target) && blocked < 100)
+ var/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid/B = new /obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid(get_turf(target))
+ B.Crossed(target)
+ ..()
+
+/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid
+ name = "fleshy restraints"
+ desc = "Used by mega arachnids to immobilize their prey."
+ flags = DROPDEL
+ icon_state = "tentacle_end"
+ icon = 'icons/obj/projectiles.dmi'
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index b426aa996cb..404ad8b0a57 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -28,7 +28,8 @@
status_flags = CANPUSH
movement_type = FLYING
loot = list(/obj/item/weapon/ectoplasm)
- del_on_death = 1
+ del_on_death = TRUE
+ initial_language_holder = /datum/language_holder/construct
/mob/living/simple_animal/shade/death()
deathmessage = "lets out a contented sigh as [p_their()] form unwinds."
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 352b7b3b5ef..a5facfba089 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -16,7 +16,7 @@
response_disarm = "shoos"
response_harm = "stomps on"
emote_see = list("jiggles", "bounces in place")
- speak_emote = list("telepathically chirps")
+ speak_emote = list("blorbles")
bubble_icon = "slime"
initial_language_holder = /datum/language_holder/slime
@@ -31,10 +31,10 @@
see_in_dark = 8
- verb_say = "telepathically chirps"
- verb_ask = "telepathically asks"
- verb_exclaim = "telepathically cries"
- verb_yell = "telephatically cries"
+ verb_say = "blorbles"
+ verb_ask = "inquisitively blorbles"
+ verb_exclaim = "loudly blorbles"
+ verb_yell = "loudly blorbles"
// canstun and canweaken don't affect slimes because they ignore stun and weakened variables
// for the sake of cleanliness, though, here they are.
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index d3a002a4a56..e2b8d86e91e 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -567,6 +567,7 @@
var/datum/map_config/cached = SSmapping.next_map_config
if(cached)
stat(null, "Next Map: [cached.map_name]")
+ stat("Round ID:", "[GLOB.round_id ? GLOB.round_id : "NULL"]")
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
stat(null, "Station Time: [worldtime2text()]")
stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)")
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 7d0d4fdbb5f..fb2df4deebd 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -14,6 +14,7 @@
light_power = 0.7
light_range = 15
light_color = rgb(255, 0, 0)
+ gender = FEMALE
var/clashing = FALSE //If Nar-Sie is fighting Ratvar
/obj/singularity/narsie/large
diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm
index 4157462b77f..bf695cffedc 100644
--- a/code/modules/projectiles/ammunition/energy.dm
+++ b/code/modules/projectiles/ammunition/energy.dm
@@ -191,7 +191,7 @@
fire_sound = 'sound/magic/lightningbolt.ogg'
e_cost = 200
select_name = "stun"
- projectile_type = /obj/item/projectile/energy/tesla_revolver
+ projectile_type = /obj/item/projectile/energy/tesla/revolver
/obj/item/ammo_casing/energy/gravityrepulse
projectile_type = /obj/item/projectile/gravityrepulse
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 7c845759ea0..bd5ad14c48f 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -159,44 +159,34 @@
/obj/item/projectile/energy/bolt/large
damage = 20
-/obj/item/projectile/energy/tesla_revolver
+/obj/item/projectile/energy/tesla
name = "tesla bolt"
icon_state = "tesla_projectile"
impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser
var/chain
-/obj/item/projectile/energy/tesla_revolver/fire(setAngle)
+/obj/item/projectile/energy/tesla/fire(setAngle)
if(firer)
chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
..()
-/obj/item/projectile/energy/tesla_revolver/on_hit(atom/target)
+/obj/item/projectile/energy/tesla/Destroy()
+ qdel(chain)
+ return ..()
+
+/obj/item/projectile/energy/tesla/revolver
+ name = "energy orb"
+
+/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target)
. = ..()
if(isliving(target))
- tesla_zap(src, 3, 10000)
+ tesla_zap(target, 3, 10000)
qdel(src)
-/obj/item/projectile/energy/tesla_revolver/Destroy()
- qdel(chain)
- return ..()
+/obj/item/projectile/energy/tesla/cannon
+ name = "tesla orb"
-
-/obj/item/projectile/energy/tesla_cannon
- name = "tesla bolt"
- icon_state = "tesla_projectile"
- impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser
- var/chain
-
-/obj/item/projectile/energy/tesla_cannon/fire(setAngle)
- if(firer)
- chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
- ..()
-
-/obj/item/projectile/energy/tesla_cannon/on_hit(atom/target)
+/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target)
. = ..()
- tesla_zap(src, 3, 10000, explosive = FALSE, stun_mobs = FALSE)
+ tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE)
qdel(src)
-
-/obj/item/projectile/energy/tesla_cannon/Destroy()
- qdel(chain)
- return ..()
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 23836e866d2..31ec27fb79c 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -966,7 +966,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Only for the experienced. You think you see sand floating in the glass."
/datum/reagent/consumable/ethanol/bananahonk
- name = "Banana Mama"
+ name = "Banana Honk"
id = "bananahonk"
description = "A drink from Clown Heaven."
nutriment_factor = 1 * REAGENTS_METABOLISM
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 56a89fe389f..260d09a81a8 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -29,16 +29,11 @@
var/brute_heal = 1
var/burn_heal = 0
- var/blood_gain = 0.4
/datum/reagent/consumable/nutriment/on_mob_life(mob/living/M)
if(prob(50))
M.heal_bodypart_damage(brute_heal,burn_heal, 0)
. = 1
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(C.blood_volume < BLOOD_VOLUME_NORMAL)
- C.blood_volume += blood_gain
..()
/datum/reagent/consumable/nutriment/on_new(list/supplied_data)
@@ -82,7 +77,6 @@
brute_heal = 1
burn_heal = 1
- blood_gain = 0.5
/datum/reagent/consumable/nutriment/vitamin/on_mob_life(mob/living/M)
if(M.satiety < 600)
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 434161fa517..6d38e85ca86 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -347,10 +347,9 @@
/datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
if(method in list(INGEST, VAPOR, INJECT))
- M.Stun(4)
- M.Weaken(4)
+ M.nutrition -= 5
if(show_message)
- to_chat(M, "Your stomach agonizingly cramps!")
+ to_chat(M, "Your stomach feels empty and cramps!")
else
var/mob/living/carbon/C = M
for(var/s in C.surgeries)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index b38d39e1392..415b316dd17 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -189,7 +189,7 @@
/datum/reagent/water/holywater/on_mob_life(mob/living/M)
if(!data) data = 1
data++
- M.jitteriness = max(M.jitteriness-5,0)
+ M.jitteriness = min(M.jitteriness+4,10)
if(data >= 30) // 12 units, 54 seconds @ metabolism 0.4 units & tick rate 1.8 sec
if(!M.stuttering)
M.stuttering = 1
@@ -212,9 +212,9 @@
SSticker.mode.remove_cultist(M.mind, 1, 1)
else if(is_servant_of_ratvar(M))
remove_servant_of_ratvar(M)
- holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
M.jitteriness = 0
M.stuttering = 0
+ holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
return
holder.remove_reagent(id, 0.4) //fixed consumption to prevent balancing going out of whack
@@ -1570,6 +1570,13 @@
M.update_transform()
..()
+/datum/reagent/plastic_polymers
+ name = "plastic polymers"
+ id = "plastic_polymers"
+ description = "the petroleum based components of plastic."
+ color = "#f7eded"
+ taste_description = "plastic"
+
/datum/reagent/glitter
name = "generic glitter"
id = "glitter"
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 19bb28666d4..0bc843a6054 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -624,3 +624,14 @@
id = "laughter"
results = list("laughter" = 10) // Fuck it. I'm not touching this one.
required_reagents = list("sugar" = 1, "banana" = 1)
+
+/datum/chemical_reaction/plastic_polymers
+ name = "plastic polymers"
+ id = "plastic_polymers"
+ required_reagents = list("oil" = 5, "sodiumchloride" = 2, "ash" = 3)
+ required_temp = 374 //lazily consistent with soap & other crafted objects generically created with heat.
+
+/datum/chemical_reaction/plastic_polymers/on_reaction(datum/reagents/holder, created_volume)
+ var/location = get_turf(holder.my_atom)
+ for(var/i in 1 to 10)
+ new /obj/item/stack/sheet/plastic(location)
diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm
index d2931012299..a3544a9ba95 100644
--- a/code/modules/research/designs/biogenerator_designs.dm
+++ b/code/modules/research/designs/biogenerator_designs.dm
@@ -115,28 +115,12 @@
build_path = /obj/item/stack/sheet/cloth
category = list("initial","Leather and Cloth")
-/datum/design/wallet
- name = "Wallet"
- id = "wallet"
- build_type = BIOGENERATOR
- materials = list(MAT_BIOMASS = 100)
- build_path = /obj/item/weapon/storage/wallet
- category = list("initial","Leather and Cloth")
-
-/datum/design/botany_gloves
- name = "Botanical gloves"
- id = "botany_gloves"
+/datum/design/leather
+ name = "Sheet of Leather"
+ id = "leather"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 150)
- build_path = /obj/item/clothing/gloves/botanic_leather
- category = list("initial","Leather and Cloth")
-
-/datum/design/toolbelt
- name = "Utility Belt"
- id = "toolbelt"
- build_type = BIOGENERATOR
- materials = list(MAT_BIOMASS = 300)
- build_path = /obj/item/weapon/storage/belt/utility
+ build_path = /obj/item/stack/sheet/leather
category = list("initial","Leather and Cloth")
/datum/design/secbelt
@@ -163,14 +147,6 @@
build_path = /obj/item/weapon/storage/belt/janitor
category = list("initial","Leather and Cloth")
-/datum/design/bandolier
- name = "Bandolier belt"
- id = "bandolier"
- build_type = BIOGENERATOR
- materials = list(MAT_BIOMASS = 300)
- build_path = /obj/item/weapon/storage/belt/bandolier
- category = list("initial","Leather and Cloth")
-
/datum/design/s_holster
name = "Shoulder holster"
id = "s_holster"
@@ -179,30 +155,6 @@
build_path = /obj/item/weapon/storage/belt/holster
category = list("initial","Leather and Cloth")
-/datum/design/leather_satchel
- name = "Leather satchel"
- id = "leather_satchel"
- build_type = BIOGENERATOR
- materials = list(MAT_BIOMASS = 400)
- build_path = /obj/item/weapon/storage/backpack/satchel
- category = list("initial","Leather and Cloth")
-
-/datum/design/leather_jacket
- name = "Leather jacket"
- id = "leather_jacket"
- build_type = BIOGENERATOR
- materials = list(MAT_BIOMASS = 500)
- build_path = /obj/item/clothing/suit/jacket/leather
- category = list("initial","Leather and Cloth")
-
-/datum/design/leather_overcoat
- name = "Leather overcoat"
- id = "leather_overcoat"
- build_type = BIOGENERATOR
- materials = list(MAT_BIOMASS = 1000)
- build_path = /obj/item/clothing/suit/jacket/leather/overcoat
- category = list("initial","Leather and Cloth")
-
/datum/design/rice_hat
name = "Rice hat"
id = "rice_hat"
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 56fb705e578..e408333d286 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -90,14 +90,6 @@
build_path = /obj/item/weapon/circuitboard/machine/quantumpad
category = list ("Teleportation Machinery")
-/*/datum/design/board/telepad
- name = "Machine Design (Telepad Board)"
- desc = "The circuit board for a telescience telepad."
- id = "telepad"
- req_tech = list("programming" = 4, "bluespace" = 5, "plasmatech" = 4, "engineering" = 4)
- build_path = /obj/item/weapon/circuitboard/machine/telesci_pad
- category = list ("Teleportation Machinery")
-*/
/datum/design/board/teleconsole
name = "Computer Design (Teleporter Console)"
desc = "Allows for the construction of circuit boards used to build a teleporter control console."
@@ -106,14 +98,6 @@
build_path = /obj/item/weapon/circuitboard/computer/teleporter
category = list("Teleportation Machinery")
-/* /datum/design/board/telesci_console
- name = "Computer Design (Telepad Control Console Board)"
- desc = "Allows for the construction of circuit boards used to build a telescience console."
- id = "telesci_console"
- req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 4)
- build_path = /obj/item/weapon/circuitboard/computer/telesci_console
- category = list("Teleportation Machinery")
-*/
/datum/design/board/sleeper
name = "Machine Design (Sleeper Board)"
desc = "The circuit board for a sleeper."
diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm
index bdd85ae4d46..35ffdefce67 100644
--- a/code/modules/ruins/lavaland_ruin_code.dm
+++ b/code/modules/ruins/lavaland_ruin_code.dm
@@ -107,6 +107,9 @@
if(istype(O, /obj/item/stack/sheet/mineral/adamantine))
species = /datum/species/golem/adamantine
+ if(istype(O, /obj/item/stack/sheet/plastic))
+ species = /datum/species/golem/plastic
+
if(species)
if(O.use(10))
to_chat(user, "You finish up the golem shell with ten sheets of [O].")
diff --git a/code/modules/shuttle/elevator.dm b/code/modules/shuttle/elevator.dm
new file mode 100644
index 00000000000..12f9c24f9a4
--- /dev/null
+++ b/code/modules/shuttle/elevator.dm
@@ -0,0 +1,10 @@
+/obj/docking_port/mobile/elevator
+ name = "elevator"
+ id = "elevator"
+ dwidth = 3
+ width = 7
+ height = 7
+ knockdown = FALSE
+
+/obj/docking_port/mobile/elevator/request(obj/docking_port/stationary/S) //No transit, no ignition, just a simple up/down platform
+ dock(S, TRUE)
\ No newline at end of file
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index 756fad25b36..b5571164ffd 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -3,7 +3,7 @@
return
// Called when shuttle attempts to move an atom.
-/atom/movable/proc/onShuttleMove(turf/T1, rotation)
+/atom/movable/proc/onShuttleMove(turf/T1, rotation, knockdown = TRUE)
if(rotation)
shuttleRotate(rotation)
loc = T1
@@ -47,11 +47,11 @@
else
shake_camera(src, 7, 1)
-/mob/living/carbon/onShuttleMove()
+/mob/living/carbon/onShuttleMove(turf/T1, rotation, knockdown = TRUE)
. = ..()
if(!.)
return
- if(!buckled)
+ if(!buckled && knockdown)
Weaken(3)
/obj/effect/abstract/proximity_checker/onShuttleMove()
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 00ddecb7f82..656ba24da68 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -217,6 +217,8 @@
var/launch_status = NOLAUNCH
+ var/knockdown = TRUE //Will it knock down mobs when it docks?
+
// A timid shuttle will not register itself with the shuttle subsystem
// All shuttle templates are timid
var/timid = FALSE
@@ -517,7 +519,7 @@
//move mobile to new location
for(var/atom/movable/AM in T0)
- if(AM.onShuttleMove(T1, rotation))
+ if(AM.onShuttleMove(T1, rotation, knockdown))
moved_atoms += AM
if(rotation)
@@ -578,10 +580,7 @@
if(M.pulledby)
M.pulledby.stop_pulling()
M.stop_pulling()
- M.visible_message("[M] is hit by \
- a hyperspace ripple!",
- "You feel an immense \
- crushing pressure as the space around you ripples.")
+ M.visible_message("[src] slams into [M]!")
if(M.key || M.get_ghost(TRUE))
SSblackbox.add_details("shuttle_gib", "[type]")
else
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 82d5db8b209..e18b248e927 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -9,7 +9,6 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/singularity,
/obj/machinery/teleport/station,
/obj/machinery/teleport/hub,
- /obj/machinery/telepad,
/obj/machinery/quantumpad,
/obj/machinery/clonepod,
/obj/effect/mob_spawn,
diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm
index 6e3c224924d..9d88e491b2f 100644
--- a/code/modules/surgery/organ_manipulation.dm
+++ b/code/modules/surgery/organ_manipulation.dm
@@ -106,7 +106,7 @@
"You begin to mend the incision in [target]'s [parse_zone(target_zone)]...")
else if(istype(tool, /obj/item/weapon/reagent_containers/food/snacks/organ))
- to_chat(user, "[tool] was biten by someone! It's too damaged to use!")
+ to_chat(user, "[tool] was bitten by someone! It's too damaged to use!")
return -1
/datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index f3f9d7a8cd1..2636e2e5d55 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -15,6 +15,7 @@
/datum/language/common,
/datum/language/draconic,
/datum/language/monkey,
+ /datum/language/narsie,
/datum/language/ratvar
))
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index e817557cc25..edf083cd3ff 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -51,7 +51,7 @@
if(C.getorganslot("adamantine_resonator"))
to_chat(C, msg)
if(isobserver(m))
- var/link = FOLLOW_LINK(m, src)
+ var/link = FOLLOW_LINK(m, owner)
to_chat(m, "[link] [msg]")
//Colossus drop, forces the listeners to obey certain commands
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 9d3377cc9c2..887c26038a2 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -111,17 +111,8 @@
if(contents.len)
to_chat(user, "[src] already has something inside it.")
return
- if(isorgan(I))
- var/obj/item/organ/O = I
- if(O.status != ORGAN_ORGANIC)
- to_chat(user, "[src] can only hold organic body parts!")
- return
- else if(isbodypart(I))
- var/obj/item/bodypart/BP = I
- if(BP.status != BODYPART_ORGANIC)
- to_chat(user, "[src] can only hold organic body parts!")
- return
- else
+ if(!isorgan(I) && !isbodypart(I))
+ to_chat(user, "[src] can only hold body parts!")
return
user.visible_message("[user] puts [I] into [src].", "You put [I] inside [src].")
@@ -150,4 +141,4 @@
desc = "A container for holding body parts."
else
to_chat(user, "[src] is empty.")
- return
\ No newline at end of file
+ return
diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm
deleted file mode 100644
index 918ec309f2b..00000000000
--- a/code/modules/telesci/telepad.dm
+++ /dev/null
@@ -1,172 +0,0 @@
-///SCI TELEPAD///
-/obj/machinery/telepad
- name = "telepad"
- desc = "A bluespace telepad used for teleporting objects to and from a location."
- icon = 'icons/obj/telescience.dmi'
- icon_state = "pad-idle"
- anchored = 1
- use_power = 1
- idle_power_usage = 200
- active_power_usage = 5000
- var/efficiency
-
-/obj/machinery/telepad/Initialize()
- . = ..()
- var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/telesci_pad(null)
- B.apply_default_parts(src)
-
-/obj/item/weapon/circuitboard/machine/telesci_pad
- name = "Telepad (Machine Board)"
- build_path = /obj/machinery/telepad
- origin_tech = "programming=4;engineering=3;plasmatech=4;bluespace=4"
- req_components = list(
- /obj/item/weapon/ore/bluespace_crystal = 2,
- /obj/item/weapon/stock_parts/capacitor = 1,
- /obj/item/stack/cable_coil = 1,
- /obj/item/weapon/stock_parts/console_screen = 1)
- def_components = list(/obj/item/weapon/ore/bluespace_crystal = /obj/item/weapon/ore/bluespace_crystal/artificial)
-
-/obj/machinery/telepad/RefreshParts()
- var/E
- for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
- E += C.rating
- efficiency = E
-
-/obj/machinery/telepad/attackby(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "pad-idle-o", "pad-idle", I))
- return
-
- if(panel_open)
- if(istype(I, /obj/item/device/multitool))
- var/obj/item/device/multitool/M = I
- M.buffer = src
- to_chat(user, "You save the data in the [I.name]'s buffer.")
- return 1
-
- if(exchange_parts(user, I))
- return
-
- if(default_deconstruction_crowbar(I))
- return
-
- return ..()
-
-
-//CARGO TELEPAD//
-/obj/machinery/telepad_cargo
- name = "cargo telepad"
- desc = "A telepad used by the Rapid Crate Sender."
- icon = 'icons/obj/telescience.dmi'
- icon_state = "pad-idle"
- anchored = 1
- use_power = 1
- idle_power_usage = 20
- active_power_usage = 500
- var/stage = 0
-/obj/machinery/telepad_cargo/attackby(obj/item/weapon/W, mob/user, params)
- if(istype(W, /obj/item/weapon/wrench))
- anchored = 0
- playsound(src, 'sound/items/Ratchet.ogg', 50, 1)
- if(anchored)
- anchored = 0
- to_chat(user, "\The [src] can now be moved.")
- else if(!anchored)
- anchored = 1
- to_chat(user, "\The [src] is now secured.")
- else if(istype(W, /obj/item/weapon/screwdriver))
- if(stage == 0)
- playsound(src, W.usesound, 50, 1)
- to_chat(user, "You unscrew the telepad's tracking beacon.")
- stage = 1
- else if(stage == 1)
- playsound(src, W.usesound, 50, 1)
- to_chat(user, "You screw in the telepad's tracking beacon.")
- stage = 0
- else if(istype(W, /obj/item/weapon/weldingtool) && stage == 1)
- var/obj/item/weapon/weldingtool/WT = W
- if(WT.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
- to_chat(user, "You start disassembling [src]...")
- if(do_after(user,20*WT.toolspeed, target = src))
- if(!WT.isOn())
- return
- to_chat(user, "You disassemble [src].")
- new /obj/item/stack/sheet/metal(get_turf(src))
- new /obj/item/stack/sheet/glass(get_turf(src))
- qdel(src)
- else
- return ..()
-
-///TELEPAD CALLER///
-/obj/item/device/telepad_beacon
- name = "telepad beacon"
- desc = "Use to warp in a cargo telepad."
- icon = 'icons/obj/radio.dmi'
- icon_state = "beacon"
- item_state = "beacon"
- origin_tech = "bluespace=3"
-
-/obj/item/device/telepad_beacon/attack_self(mob/user)
- if(user)
- to_chat(user, "Locked In")
- new /obj/machinery/telepad_cargo(user.loc)
- playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
- qdel(src)
- return
-
-///HANDHELD TELEPAD USER///
-/obj/item/weapon/rcs
- name = "rapid-crate-sender (RCS)"
- desc = "Use this to send crates and closets to cargo telepads."
- icon = 'icons/obj/telescience.dmi'
- icon_state = "rcs"
- flags = CONDUCT
- force = 10
- throwforce = 10
- throw_speed = 2
- throw_range = 5
- var/rcharges = 10
- var/obj/machinery/pad = null
- var/last_charge = 30
- var/mode = 0
- var/rand_x = 0
- var/rand_y = 0
- var/emagged = 0
- var/teleporting = 0
-
-/obj/item/weapon/rcs/New()
- ..()
- START_PROCESSING(SSobj, src)
-
-/obj/item/weapon/rcs/examine(mob/user)
- ..()
- to_chat(user, "There are [rcharges] charge\s left.")
-
-/obj/item/weapon/rcs/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-/obj/item/weapon/rcs/process()
- if(rcharges > 10)
- rcharges = 10
- if(last_charge == 0)
- rcharges++
- last_charge = 30
- else
- last_charge--
-
-/obj/item/weapon/rcs/attack_self(mob/user)
- if(emagged)
- if(mode == 0)
- mode = 1
- playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
- to_chat(user, "The telepad locator has become uncalibrated.")
- else
- mode = 0
- playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
- to_chat(user, "You calibrate the telepad locator.")
-
-/obj/item/weapon/rcs/emag_act(mob/user)
- if(!emagged)
- emagged = TRUE
- do_sparks(5, TRUE, src)
- to_chat(user, "You emag the RCS. Click on it to toggle between modes.")
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
deleted file mode 100644
index 6c80a3ee1f4..00000000000
--- a/code/modules/telesci/telesci_computer.dm
+++ /dev/null
@@ -1,363 +0,0 @@
-/obj/machinery/computer/telescience
- name = "\improper Telepad Control Console"
- desc = "Used to teleport objects to and from the telescience telepad."
- icon_screen = "teleport"
- icon_keyboard = "teleport_key"
- circuit = /obj/item/weapon/circuitboard/computer/telesci_console
- var/sending = 1
- var/obj/machinery/telepad/telepad = null
- var/temp_msg = "Telescience control console initialized.
Welcome."
-
- // VARIABLES //
- var/teles_left // How many teleports left until it becomes uncalibrated
- var/datum/projectile_data/last_tele_data = null
- var/z_co = 1
- var/power_off
- var/rotation_off
- //var/angle_off
- var/last_target
-
- var/rotation = 0
- var/angle = 45
- var/power = 5
-
- // Based on the power used
- var/teleport_cooldown = 0 // every index requires a bluespace crystal
- var/list/power_options = list(5, 10, 20, 25, 30, 40, 50, 80, 100)
- var/teleporting = 0
- var/starting_crystals = 3
- var/max_crystals = 4
- var/list/crystals = list()
- var/obj/item/device/gps/inserted_gps
-
-/obj/machinery/computer/telescience/Initialize()
- recalibrate()
- . = ..()
-
-/obj/machinery/computer/telescience/Destroy()
- eject()
- if(inserted_gps)
- inserted_gps.loc = loc
- inserted_gps = null
- return ..()
-
-/obj/machinery/computer/telescience/examine(mob/user)
- ..()
- to_chat(user, "There are [crystals.len ? crystals.len : "no"] bluespace crystal\s in the crystal slots.")
-
-/obj/machinery/computer/telescience/Initialize(mapload)
- . = ..()
- if(mapload)
- for(var/i = 1; i <= starting_crystals; i++)
- crystals += new /obj/item/weapon/ore/bluespace_crystal/artificial(null) // starting crystals
-
-/obj/machinery/computer/telescience/attack_paw(mob/user)
- to_chat(user, "You are too primitive to use this computer!")
- return
-
-/obj/machinery/computer/telescience/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/weapon/ore/bluespace_crystal))
- if(crystals.len >= max_crystals)
- to_chat(user, "There are not enough crystal slots.")
- return
- if(!user.drop_item())
- return
- crystals += W
- W.loc = null
- user.visible_message("[user] inserts [W] into \the [src]'s crystal slot.", "You insert [W] into \the [src]'s crystal slot.")
- updateDialog()
- else if(istype(W, /obj/item/device/gps))
- if(!inserted_gps)
- if(!user.transferItemToLoc(W, src))
- return
- inserted_gps = W
- user.visible_message("[user] inserts [W] into \the [src]'s GPS device slot.", "You insert [W] into \the [src]'s GPS device slot.")
- else if(istype(W, /obj/item/device/multitool))
- var/obj/item/device/multitool/M = W
- if(M.buffer && istype(M.buffer, /obj/machinery/telepad))
- telepad = M.buffer
- M.buffer = null
- to_chat(user, "You upload the data from the [W.name]'s buffer.")
- else
- return ..()
-
-/obj/machinery/computer/telescience/attack_ai(mob/user)
- src.attack_hand(user)
-
-/obj/machinery/computer/telescience/attack_hand(mob/user)
- if(..())
- return
- interact(user)
-
-/obj/machinery/computer/telescience/interact(mob/user)
- var/t
- if(!telepad)
- in_use = 0 //Yeah so if you deconstruct teleporter while its in the process of shooting it wont disable the console
- t += "No telepad located.
Please add telepad data.
"
- else
- if(inserted_gps)
- t += "Eject GPS"
- t += "Set GPS memory"
- else
- t += "Eject GPS"
- t += "Set GPS memory"
- t += "[temp_msg]
"
- t += "Set Bearing"
- t += "[rotation]°
"
- t += "Set Elevation"
- t += "[angle]°
"
- t += "Set Power"
- t += ""
-
- for(var/i = 1; i <= power_options.len; i++)
- if(crystals.len + telepad.efficiency < i)
- t += "
[power_options[i]]"
- continue
- if(power == power_options[i])
- t += "
[power_options[i]]"
- continue
- t += "
[power_options[i]]"
- t += "
"
-
- t += "Set Sector"
- t += "[z_co ? z_co : "NULL"]
"
-
- t += "
Send"
- t += " Receive"
- t += "
Recalibrate Crystals Eject Crystals"
-
- // Information about the last teleport
- t += "
"
- if(!last_tele_data)
- t += "No teleport data found."
- else
- t += "Source Location: ([last_tele_data.src_x], [last_tele_data.src_y])
"
- //t += "Distance: [round(last_tele_data.distance, 0.1)]m
"
- t += "Time: [round(last_tele_data.time, 0.1)] secs
"
- t += "
"
-
- var/datum/browser/popup = new(user, "telesci", name, 300, 500)
- popup.set_content(t)
- popup.open()
-
-/obj/machinery/computer/telescience/proc/sparks()
- if(telepad)
- do_sparks(5, TRUE, get_turf(telepad))
-
-/obj/machinery/computer/telescience/proc/telefail()
- sparks()
- visible_message("The telepad weakly fizzles.")
-
-/obj/machinery/computer/telescience/proc/doteleport(mob/user)
-
- if(teleport_cooldown > world.time)
- temp_msg = "Telepad is recharging power.
Please wait [round((teleport_cooldown - world.time) / 10)] seconds."
- return
-
- if(teleporting)
- temp_msg = "Telepad is in use.
Please wait."
- return
-
- if(telepad)
-
- var/truePower = Clamp(power + power_off, 1, 1000)
- var/trueRotation = rotation + rotation_off
- var/trueAngle = Clamp(angle, 1, 90)
-
- var/datum/projectile_data/proj_data = projectile_trajectory(telepad.x, telepad.y, trueRotation, trueAngle, truePower)
- last_tele_data = proj_data
-
- var/trueX = Clamp(round(proj_data.dest_x, 1), 1, world.maxx)
- var/trueY = Clamp(round(proj_data.dest_y, 1), 1, world.maxy)
- var/spawn_time = round(proj_data.time) * 10
-
- var/turf/target = locate(trueX, trueY, z_co)
- last_target = target
- var/area/A = get_area(target)
- flick("pad-beam", telepad)
-
- if(spawn_time > 15) // 1.5 seconds
- playsound(telepad.loc, 'sound/weapons/flash.ogg', 25, 1)
- // Wait depending on the time the projectile took to get there
- teleporting = 1
- temp_msg = "Powering up bluespace crystals.
Please wait."
-
-
- spawn(round(proj_data.time) * 10) // in seconds
- if(!telepad)
- return
- if(telepad.stat & NOPOWER)
- return
- teleporting = 0
- teleport_cooldown = world.time + (power * 2)
- teles_left -= 1
-
- // use a lot of power
- use_power(power * 10)
-
- do_sparks(5, TRUE, get_turf(telepad))
-
- temp_msg = "Teleport successful.
"
- if(teles_left < 10)
- temp_msg += "
Calibration required soon."
- else
- temp_msg += "Data printed below."
-
- do_sparks(5, TRUE, get_turf(target))
-
- var/turf/source = target
- var/turf/dest = get_turf(telepad)
- var/log_msg = ""
- log_msg += ": [key_name(user)] has teleported "
-
- if(sending)
- source = dest
- dest = target
-
- flick("pad-beam", telepad)
- playsound(telepad.loc, 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
- for(var/atom/movable/ROI in source)
- // if is anchored, don't let through
- if(ROI.anchored)
- if(isliving(ROI))
- var/mob/living/L = ROI
- if(L.buckled)
- // TP people on office chairs
- if(L.buckled.anchored)
- continue
-
- log_msg += "[key_name(L)] (on a chair), "
- else
- continue
- else if(!isobserver(ROI))
- continue
- if(ismob(ROI))
- var/mob/T = ROI
- log_msg += "[key_name(T)], "
- else
- log_msg += "[ROI.name]"
- if (istype(ROI, /obj/structure/closet))
- var/obj/structure/closet/C = ROI
- log_msg += " ("
- for(var/atom/movable/Q as mob|obj in C)
- if(ismob(Q))
- log_msg += "[key_name(Q)], "
- else
- log_msg += "[Q.name], "
- if (dd_hassuffix(log_msg, "("))
- log_msg += "empty)"
- else
- log_msg = dd_limittext(log_msg, length(log_msg) - 2)
- log_msg += ")"
- log_msg += ", "
- do_teleport(ROI, dest)
-
- if (dd_hassuffix(log_msg, ", "))
- log_msg = dd_limittext(log_msg, length(log_msg) - 2)
- else
- log_msg += "nothing"
- log_msg += " [sending ? "to" : "from"] [trueX], [trueY], [z_co] ([A ? A.name : "null area"])"
- investigate_log(log_msg, "telesci")
- updateDialog()
-
-/obj/machinery/computer/telescience/proc/teleport(mob/user)
- if(rotation == null || angle == null || z_co == null)
- temp_msg = "ERROR!
Set a angle, rotation and sector."
- return
- if(power <= 0)
- telefail()
- temp_msg = "ERROR!
No power selected!"
- return
- if(angle < 1 || angle > 90)
- telefail()
- temp_msg = "ERROR!
Elevation is less than 1 or greater than 90."
- return
- if(z_co == ZLEVEL_CENTCOM || z_co < 1 || z_co > ZLEVEL_SPACEMAX)
- telefail()
- temp_msg = "ERROR! Sector is outside known time and space!"
- return
- if(teles_left > 0)
- doteleport(user)
- else
- telefail()
- temp_msg = "ERROR!
Calibration required."
- return
- return
-
-/obj/machinery/computer/telescience/proc/eject()
- for(var/obj/item/I in crystals)
- I.loc = src.loc
- crystals -= I
- power = 0
-
-/obj/machinery/computer/telescience/Topic(href, href_list)
- if(..())
- return
- if(!telepad)
- updateDialog()
- return
- if(telepad.panel_open)
- temp_msg = "Telepad undergoing physical maintenance operations."
-
- if(href_list["setrotation"])
- var/new_rot = input("Please input desired bearing in degrees.", name, rotation) as num
- if(..()) // Check after we input a value, as they could've moved after they entered something
- return
- rotation = Clamp(new_rot, -900, 900)
- rotation = round(rotation, 0.01)
-
- if(href_list["setangle"])
- var/new_angle = input("Please input desired elevation in degrees.", name, angle) as num
- if(..())
- return
- angle = Clamp(round(new_angle, 0.1), 1, 9999)
-
- if(href_list["setpower"])
- var/index = href_list["setpower"]
- index = text2num(index)
- if(index != null && power_options[index])
- if(crystals.len + telepad.efficiency >= index)
- power = power_options[index]
-
- if(href_list["setz"])
- var/new_z = input("Please input desired sector.", name, z_co) as num
- if(..())
- return
- z_co = Clamp(round(new_z), 1, 10)
-
- if(href_list["ejectGPS"])
- if(inserted_gps)
- inserted_gps.loc = loc
- inserted_gps = null
-
- if(href_list["setMemory"])
- if(last_target && inserted_gps)
- inserted_gps.locked_location = last_target
- temp_msg = "Location saved."
- else
- temp_msg = "ERROR!
No data was stored."
-
- if(href_list["send"])
- sending = 1
- teleport(usr)
-
- if(href_list["receive"])
- sending = 0
- teleport(usr)
-
- if(href_list["recal"])
- recalibrate()
- sparks()
- temp_msg = "NOTICE:
Calibration successful."
-
- if(href_list["eject"])
- eject()
- temp_msg = "NOTICE:
Bluespace crystals ejected."
-
- updateDialog()
-
-/obj/machinery/computer/telescience/proc/recalibrate()
- teles_left = rand(30, 40)
- //angle_off = rand(-25, 25)
- power_off = rand(-4, 0)
- rotation_off = rand(-10, 10)
diff --git a/code/world.dm b/code/world.dm
index 42326f6ba69..353d8198183 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -59,6 +59,7 @@
load_mode()
load_motd()
load_admins()
+ load_menu()
if(config.usewhitelist)
load_whitelist()
LoadBans()
@@ -341,5 +342,6 @@
status = s
+
/world/proc/has_round_started()
return SSticker.HasRoundStarted()
diff --git a/config/admins.txt b/config/admins.txt
index d90c33bcda7..b4485c08411 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -127,4 +127,5 @@ Sweaterkittens = Game Master
Feemjmeem = Game Master
JStheguy = Game Master
excessiveuseofcobby = Game Master
-Plizzard = Game Master
\ No newline at end of file
+Plizzard = Game Master
+octareenroon91 = Game Master
diff --git a/html/changelog.html b/html/changelog.html
index 222dbcc4afd..0b7aa971681 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,124 @@
-->
+
08 May 2017
+
Dorsisdwarf updated:
+
+ - Fixed being unable to hit museum cases in melee
+
+
+
07 May 2017
+
Anonmare updated:
+
+ - Removes organic check from mediborg storage container
+
+
Joan updated:
+
+ - Cultists of Nar-sie have their own language. The language's key is ",n".
+ - Sigils of Transgression are slightly brighter.
+
+
Moonlighting Mac updated:
+
+ - Due to budget cuts and oil synthesis replacing expensive processes of digging up haunted primeval ashwalker burial grounds, Nanotransen has taught chemists how to make plastic from chemicals in the hopes that new plastic products can reduce expenditure on metal and glass.
+ - you can now make plastic sheets from chemistry out of heated up crude oil, ash & sodium chloride
+
+
MrStonedOne updated:
+
+ - fixed bug that caused an infinite connection loop when connecting on a new computer or computer with recently changed hardware.
+ - Moved to a new system to make top menu items easier to edit.
+ - Moved icon size stuff to a sub menu
+ - Added option to change icon scaling mode.
+ - Byond added fancy shader supported scaling(Point Sampling), this sucks because it's blurry, the default for /tg/station has changed back to the old nearest neighbor scaling.
+
+
Penguaro updated:
+
+ - Adjusted the Examine description of the right-most tiles of the Space Station 13 sign to be consistent with the rest of the tiles.
+ - Anywhere there was lava below a tile on the station is now space.
+
+
Robustin updated:
+
+ - c4 planting is now 40% faster
+
+
coiax updated:
+
+ - Smartfridges no longer magically gain medicines if deconstructed and rebuilt.
+ - Ash walkers now know and speak Draconic by default, but still know Galactic Common. Remember, Galcom's language key is ",0" and you can review your known languages with the Language Menu.
+
+
octareenroon91 updated:
+
+ - Showers and sinks added to gulag and mining station for hygiene and fire safety.
+ - Watertanks added to mining station for convenient fire extinguisher refill.
+
+
+
06 May 2017
+
4dplanner updated:
+
+ - Internal Affairs Agents now obtain the kill objectives of their targets when they die.
+ - Internal Affairs Agents now have an integrated nanotrasen pinpointer that tracks their target at distances further than ten squares.
+ - Internal Affairs Agents will now lose any restrictions on collateral damage and gain a "Die a glorious death" objective upon becoming the last man standing, and revert if any of their targets are cloned.
+
+
BeeSting12 updated:
+
+ - Pubbystation no longer has two airlocks stacked on top of each other leading into xenobiology's kill room.
+ - Deltastation's chemistry now has a screwdriver.
+ - Deltastation's morgue no longer has a blue tile.
+ - Deltastation's chemistry smart fridge is no longer blocked by a disposal unit.
+
+
Cyberboss updated:
+
+ - Teslas now give off light
+
+
Joan updated:
+
+ - Sigils of Transgression are slightly more visible and glow very faintly.
+
+
LanCartwright updated:
+
+ - Reduction to nutrition when consuming Miner's salve.
+ - Stun/weaken that bypasses bugged chemical protection when consuming Miner's salve.
+
+
Lzimann updated:
+
+ - Telescience is no more.
+
+
PKPenguin321 updated:
+
+ - Undid the gang gamemode removal.
+
+
QualityVan updated:
+
+ - Cargo can order restocking units for NanoMed vending machines
+ - NanoMed vending machines can be build and unbuilt
+
+
Robustin updated:
+
+ - Blood Cultists can now attempt to claim the position of Cult Master with the approval of a majority of their brethren.
+ - The Cult Master has access to unique blood magic that will aid them in leading the cult to victory:
+ - The Cult Master can mark targets, allowing the entire cult to track them down.
+ - The Cult Master has single-use, noisy, and overt channeled spell that will summon the entire cult to their location.
+ - All cultists gain a HUD alert that will assist them in completing their objectives.
+ - Constructs created by soul shards will now be able to track their master.
+ - Cultists created outside of cult mode will now get a working sacrifice and summon objective and the summon rune will no longer fail outside of cult mode.
+ - Gang Dominator max time is now 8 minutes down from 15m
+ - Gang Tagging now reduces the timer by 9 seconds per territory, down from 12 seconds.
+
+
coiax updated:
+
+ - Adamantine golems have special vocal cords that allow them to send one-way messages to all golems, due to fragments of resonating adamantine in their heads. Both of these are organs, and can be removed and put in other species.
+ - You can use adamantine vocal cords by prefixing your message with ":x".
+ - Xenobiology is no longer capable of making golem runes with plasma. Instead, inject plasma into the adamantine slime core to get bars of adamantine which you can then craft into an incomplete golem shell. Add 10 sheets of suitable material to finish the shell.
+ - The metal adamantine is also quite valuable when sold via cargo.
+ - If you know more than the usual number of languages, you'll now remember them after you get cloned.
+ - Humans turning into monkeys will not suddenly be able to speak the monkey language, and will continue to understand and speak human.
+ - Ghosts can now modify their own understood languages with the language menu.
+ - Any mob can also open their language menu with the IC->Open Language Menu verb.
+ - Silicons can now understand Draconic as part of their internal databases.
+ - Golems no longer have underwear, undershorts or socks.
+ - The lavaland Seed Vault ruin can spawn only once.
+ - It is now possible to make plastic golems, who are made of a material flexible enough to crawl through vents (while not carrying equipment). They also can pass through plastic flaps.
+ - Fixed adamantine vocal cord (F) links not working for observers.
+
+
05 May 2017
Incoming updated:
@@ -1266,79 +1384,6 @@
- Wannabe ninjas have been found carrying an experimental chameleon belt. The Spider clan has disavowed any involvement.
-
- 06 March 2017
- Cyberboss updated:
-
- - Map rotation has been made smoother
-
- Gun Hog updated:
-
- - The Aux Base Construction Console now directs to the correct Base Management Console.
- - The missing Science Department access has been added to the Auxiliary Base Management Console.
-
- Hyena updated:
-
- - Space bar is out of bussiness
-
- MrStonedOne updated:
-
- - patched a hacky workaround for /vg/lights memory leaking crashing the server
-
- Penguaro updated:
-
- - Changed DIR of Gas Filter for O2 in Waste Loop from 1 to 4
-
- Sligneris updated:
-
- - 'xeno queen' AI hologram now actually uses the xeno queen sprite as a reference
-
- Tofa01 updated:
-
- - [Omega] Fixes missing walls and wires new dock to the powergrid
-
- XDTM updated:
-
- - Changelings can now click their fake clothing to remove it, without needing to drop the full disguise.
-
- coiax updated:
-
- - The Bardrone and Barmaid are neutral, even in the face of reality altering elder gods.
-
-
- 04 March 2017
- Cyberboss updated:
-
- - You can build lattice in space again
-
- Hyena updated:
-
- - Detective revolver/ammo now starts in their shoulder holster
-
- Joan updated:
-
- - Weaker cult talismans take less time to imbue.
-
- PJB3005 updated:
-
- - Rebased to /vg/station lighting code.
-
- Supermichael777 updated:
-
- - Grey security uniforms have unique names and descriptions
-
- Tofa01 updated:
-
- - Adds the new Centcomm Raven Battlecruiser to the purchasable shuttle list buy now get one free!
-
- coiax updated:
-
- - CTF players start with their helmet toggled off, better to see the whites of their opponents eyes. Very briefly.
- - Existing CTF barricades are repaired between rounds, and deploy instantly when replaced.
- - Healing non-critical CTF damage is faster. Remember though, if you drop into crit, YOU DIE.
- - Admin ghosts can just click directly on the CTF controller to enable them, in addition to using the Secrets panel.
- - Cyborg radios can no longer have their inaccessible wires pulsed by EMPs.
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 2193515d58f..7ff5e81cff2 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -10906,3 +10906,117 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
cause vomiting of organs.
- tweak: Committing suicide with a gas pump can now shoot out random organs.
- bugfix: Toxic vomit now shows up as intended.
+2017-05-06:
+ 4dplanner:
+ - rscadd: Internal Affairs Agents now obtain the kill objectives of their targets
+ when they die.
+ - rscadd: Internal Affairs Agents now have an integrated nanotrasen pinpointer that
+ tracks their target at distances further than ten squares.
+ - rscadd: Internal Affairs Agents will now lose any restrictions on collateral damage
+ and gain a "Die a glorious death" objective upon becoming the last man standing,
+ and revert if any of their targets are cloned.
+ BeeSting12:
+ - bugfix: Pubbystation no longer has two airlocks stacked on top of each other leading
+ into xenobiology's kill room.
+ - rscadd: Deltastation's chemistry now has a screwdriver.
+ - bugfix: Deltastation's morgue no longer has a blue tile.
+ - bugfix: Deltastation's chemistry smart fridge is no longer blocked by a disposal
+ unit.
+ Cyberboss:
+ - tweak: Teslas now give off light
+ Joan:
+ - balance: Sigils of Transgression are slightly more visible and glow very faintly.
+ LanCartwright:
+ - rscadd: Reduction to nutrition when consuming Miner's salve.
+ - rscdel: Stun/weaken that bypasses bugged chemical protection when consuming Miner's
+ salve.
+ Lzimann:
+ - rscdel: Telescience is no more.
+ PKPenguin321:
+ - rscadd: Undid the gang gamemode removal.
+ QualityVan:
+ - rscadd: Cargo can order restocking units for NanoMed vending machines
+ - rscadd: NanoMed vending machines can be build and unbuilt
+ Robustin:
+ - rscadd: Blood Cultists can now attempt to claim the position of Cult Master with
+ the approval of a majority of their brethren.
+ - rscadd: 'The Cult Master has access to unique blood magic that will aid them in
+ leading the cult to victory:'
+ - rscadd: The Cult Master can mark targets, allowing the entire cult to track them
+ down.
+ - rscadd: The Cult Master has single-use, noisy, and overt channeled spell that
+ will summon the entire cult to their location.
+ - rscadd: All cultists gain a HUD alert that will assist them in completing their
+ objectives.
+ - rscadd: Constructs created by soul shards will now be able to track their master.
+ - rscadd: Cultists created outside of cult mode will now get a working sacrifice
+ and summon objective and the summon rune will no longer fail outside of cult
+ mode.
+ - tweak: Gang Dominator max time is now 8 minutes down from 15m
+ - tweak: Gang Tagging now reduces the timer by 9 seconds per territory, down from
+ 12 seconds.
+ coiax:
+ - rscadd: Adamantine golems have special vocal cords that allow them to send one-way
+ messages to all golems, due to fragments of resonating adamantine in their heads.
+ Both of these are organs, and can be removed and put in other species.
+ - rscadd: You can use adamantine vocal cords by prefixing your message with ":x".
+ - rscdel: Xenobiology is no longer capable of making golem runes with plasma. Instead,
+ inject plasma into the adamantine slime core to get bars of adamantine which
+ you can then craft into an incomplete golem shell. Add 10 sheets of suitable
+ material to finish the shell.
+ - experiment: The metal adamantine is also quite valuable when sold via cargo.
+ - bugfix: If you know more than the usual number of languages, you'll now remember
+ them after you get cloned.
+ - rscdel: Humans turning into monkeys will not suddenly be able to speak the monkey
+ language, and will continue to understand and speak human.
+ - rscadd: Ghosts can now modify their own understood languages with the language
+ menu.
+ - rscadd: Any mob can also open their language menu with the IC->Open Language Menu
+ verb.
+ - rscadd: Silicons can now understand Draconic as part of their internal databases.
+ - bugfix: Golems no longer have underwear, undershorts or socks.
+ - tweak: The lavaland Seed Vault ruin can spawn only once.
+ - rscadd: It is now possible to make plastic golems, who are made of a material
+ flexible enough to crawl through vents (while not carrying equipment). They
+ also can pass through plastic flaps.
+ - bugfix: Fixed adamantine vocal cord (F) links not working for observers.
+2017-05-07:
+ Anonmare:
+ - tweak: Removes organic check from mediborg storage container
+ Joan:
+ - rscadd: Cultists of Nar-sie have their own language. The language's key is ",n".
+ - balance: Sigils of Transgression are slightly brighter.
+ Moonlighting Mac:
+ - experiment: Due to budget cuts and oil synthesis replacing expensive processes
+ of digging up haunted primeval ashwalker burial grounds, Nanotransen has taught
+ chemists how to make plastic from chemicals in the hopes that new plastic products
+ can reduce expenditure on metal and glass.
+ - rscadd: you can now make plastic sheets from chemistry out of heated up crude
+ oil, ash & sodium chloride
+ MrStonedOne:
+ - bugfix: fixed bug that caused an infinite connection loop when connecting on a
+ new computer or computer with recently changed hardware.
+ - rscadd: Moved to a new system to make top menu items easier to edit.
+ - tweak: Moved icon size stuff to a sub menu
+ - rscadd: Added option to change icon scaling mode.
+ - bugfix: Byond added fancy shader supported scaling(Point Sampling), this sucks
+ because it's blurry, the default for /tg/station has changed back to the old
+ nearest neighbor scaling.
+ Penguaro:
+ - bugfix: Adjusted the Examine description of the right-most tiles of the Space
+ Station 13 sign to be consistent with the rest of the tiles.
+ - bugfix: Anywhere there was lava below a tile on the station is now space.
+ Robustin:
+ - tweak: c4 planting is now 40% faster
+ coiax:
+ - bugfix: Smartfridges no longer magically gain medicines if deconstructed and rebuilt.
+ - rscadd: Ash walkers now know and speak Draconic by default, but still know Galactic
+ Common. Remember, Galcom's language key is ",0" and you can review your known
+ languages with the Language Menu.
+ octareenroon91:
+ - rscadd: Showers and sinks added to gulag and mining station for hygiene and fire
+ safety.
+ - rscadd: Watertanks added to mining station for convenient fire extinguisher refill.
+2017-05-08:
+ Dorsisdwarf:
+ - bugfix: Fixed being unable to hit museum cases in melee
diff --git a/html/changelogs/AutoChangeLog-pr-26772.yml b/html/changelogs/AutoChangeLog-pr-26772.yml
deleted file mode 100644
index 608a0902493..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26772.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - rscadd: "Adamantine golems have special vocal cords that allow them to send
-one-way messages to all golems, due to fragments of resonating
-adamantine in their heads. Both of these are organs, and can be removed
-and put in other species."
- - rscadd: "You can use adamantine vocal cords by prefixing your message with
-\":x\"."
- - rscdel: "Xenobiology is no longer capable of making golem runes with plasma.
-Instead, inject plasma into the adamantine slime core to get bars of adamantine
-which you can then craft into an incomplete golem shell. Add 10 sheets of
-suitable material to finish the shell."
- - experiment: "The metal adamantine is also quite valuable when sold via cargo."
diff --git a/html/changelogs/AutoChangeLog-pr-26776.yml b/html/changelogs/AutoChangeLog-pr-26776.yml
deleted file mode 100644
index bf9411c7a16..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26776.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - bugfix: "If you know more than the usual number of languages, you'll now remember them after you get cloned."
- - rscdel: "Humans turning into monkeys will not suddenly be able to speak the monkey language, and will continue to understand and speak human."
- - rscadd: "Ghosts can now modify their own understood languages with the
-language menu."
- - rscadd: "Any mob can also open their language menu with the IC->Open Language Menu verb."
- - rscadd: "Silicons can now understand Draconic as part of their internal databases."
diff --git a/html/changelogs/AutoChangeLog-pr-26854.yml b/html/changelogs/AutoChangeLog-pr-26854.yml
new file mode 100644
index 00000000000..8aeb9ff2957
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-26854.yml
@@ -0,0 +1,8 @@
+author: "Moonlighting Mac says"
+delete-after: True
+changes:
+ - tweak: "After a recent trade fair, employees have took it upon themselves to learn how to craft leather objects out of finished leather sheets, for novices they are pretty good at it! Try it yourself!"
+ - rscadd: "Muzzles to silence people are now craftable out of leather sheets."
+ - rscdel: "You can no longer print off designs from a bio-generator that can now be crafted out of leather sheets."
+ - tweak: "Complete sheets of leather can be printed from the bio-generator for 150 biomass to accommodate for a loss of designs."
+ - experiment: "Specialist objects from the leather & cloth category bio-generator category were not removed as to encourage interdepartmental interaction & balance."
diff --git a/html/changelogs/AutoChangeLog-pr-26872.yml b/html/changelogs/AutoChangeLog-pr-26872.yml
deleted file mode 100644
index 031ec641511..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26872.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BeeSting12"
-delete-after: True
-changes:
- - bugfix: "Pubbystation no longer has two airlocks stacked on top of each other leading into xenobiology's kill room."
diff --git a/html/changelogs/AutoChangeLog-pr-26894.yml b/html/changelogs/AutoChangeLog-pr-26894.yml
deleted file mode 100644
index b9cfd4624f5..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26894.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - bugfix: "Golems no longer have underwear, undershorts or socks."
diff --git a/html/changelogs/AutoChangeLog-pr-26895.yml b/html/changelogs/AutoChangeLog-pr-26895.yml
deleted file mode 100644
index e3777f40640..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26895.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Joan"
-delete-after: True
-changes:
- - balance: "Sigils of Transgression are slightly more visible and glow very faintly."
diff --git a/html/changelogs/AutoChangeLog-pr-26899.yml b/html/changelogs/AutoChangeLog-pr-26899.yml
deleted file mode 100644
index cd4b8f7864f..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26899.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Cyberboss"
-delete-after: True
-changes:
- - tweak: "Teslas now give off light"
diff --git a/html/changelogs/AutoChangeLog-pr-26915.yml b/html/changelogs/AutoChangeLog-pr-26915.yml
deleted file mode 100644
index fa85366e4cc..00000000000
--- a/html/changelogs/AutoChangeLog-pr-26915.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "PKPenguin321"
-delete-after: True
-changes:
- - rscadd: "Undid the gang gamemode removal."
diff --git a/html/changelogs/AutoChangeLog-pr-27014.yml b/html/changelogs/AutoChangeLog-pr-27014.yml
new file mode 100644
index 00000000000..0c1695adbcb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-27014.yml
@@ -0,0 +1,4 @@
+author: "ninjanomnom"
+delete-after: True
+changes:
+ - tweak: "Highlander no longer breaks your speakers"
diff --git a/icons/effects/64x64.dmi b/icons/effects/64x64.dmi
index 347bccc9425..361cfff40c0 100644
Binary files a/icons/effects/64x64.dmi and b/icons/effects/64x64.dmi differ
diff --git a/icons/effects/cult_target.dmi b/icons/effects/cult_target.dmi
new file mode 100644
index 00000000000..650feb33613
Binary files /dev/null and b/icons/effects/cult_target.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index d684794ee85..fe537a8e739 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi
index e961c351912..081bbf1aa3c 100644
Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 988ae8bdc83..58c877d4d95 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 29c527b123d..6d05b890398 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/jungle/arachnid.dmi b/icons/mob/jungle/arachnid.dmi
new file mode 100644
index 00000000000..a1db8e351f0
Binary files /dev/null and b/icons/mob/jungle/arachnid.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index 46666cdd5fc..13f16aae59a 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ
diff --git a/icons/obj/vending_restock.dmi b/icons/obj/vending_restock.dmi
index aa9f2873f02..eac7b8a2668 100644
Binary files a/icons/obj/vending_restock.dmi and b/icons/obj/vending_restock.dmi differ
diff --git a/interface/menu.dm b/interface/menu.dm
new file mode 100644
index 00000000000..4bebd5b2023
--- /dev/null
+++ b/interface/menu.dm
@@ -0,0 +1,203 @@
+/*
+/datum/menu/Example/verb/Example()
+ set name = "" //if this starts with @ the verb is not created and name becomes the command to invoke.
+ set desc = "" //desc is the text given to this entry in the menu
+ //You can not use src in these verbs. It will be the menu at compile time, but the client at runtime.
+*/
+
+GLOBAL_LIST_EMPTY(menulist)
+
+/world/proc/load_menu()
+ for (var/typepath in subtypesof(/datum/menu))
+ new typepath()
+
+/datum/menu
+ var/name
+ var/list/children
+ var/datum/menu/myparent
+ var/list/verblist
+ var/checkbox = CHECKBOX_NONE //checkbox type.
+ var/default //default checked type.
+ //Set to true to append our children to our parent,
+ //Rather then add us as a node (used for having more then one checkgroups in the same menu)
+ var/abstract = FALSE
+
+/datum/menu/New()
+ var/ourentry = GLOB.menulist[type]
+ children = list()
+ verblist = list()
+ if (ourentry)
+ if (islist(ourentry)) //some of our childern already loaded
+ Add_children(ourentry)
+ else
+ stack_trace("Menu item double load: [type]")
+ qdel(src)
+ return
+
+ GLOB.menulist[type] = src
+
+ Load_verbs(type, typesof("[type]/verb"))
+
+ var/datum/menu/parent = GLOB.menulist[parent_type]
+ if (!parent)
+ GLOB.menulist[parent_type] = list(src)
+ else if (islist(parent))
+ parent += src
+ else
+ parent.Add_children(list(src))
+
+/datum/menu/proc/Set_parent(datum/menu/parent)
+ myparent = parent
+ if (abstract)
+ myparent.Add_children(children)
+ var/list/verblistoftypes = list()
+ for(var/thing in verblist)
+ LAZYADD(verblistoftypes[verblist[thing]], thing)
+
+ for(var/verbparenttype in verblistoftypes)
+ myparent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype])
+
+/datum/menu/proc/Add_children(list/kids)
+ if (abstract && myparent)
+ myparent.Add_children(kids)
+ return
+
+ for(var/thing in kids)
+ var/datum/menu/menuitem = thing
+ menuitem.Set_parent(src)
+ if (!menuitem.abstract)
+ children += menuitem
+
+/datum/menu/proc/Load_verbs(verb_parent_type, list/verbs)
+ if (abstract && myparent)
+ myparent.Load_verbs(verb_parent_type, verbs)
+ return
+
+ for (var/verbpath in verbs)
+ verblist[verbpath] = verb_parent_type
+
+/datum/menu/proc/Generate_list(client/C)
+ . = list()
+ if (length(children))
+ for (var/thing in children)
+ var/datum/menu/child = thing
+ var/list/childlist = child.Generate_list(C)
+ if (childlist)
+ var/childname = "[child]"
+ if (childname == "[child.type]")
+ var/list/tree = splittext(childname, "/")
+ childname = tree[tree.len]
+ .[child.type] = "parent=[url_encode(type)];name=[url_encode(childname)]"
+ . += childlist
+
+
+
+ for (var/thing in verblist)
+ var/atom/verb/verbpath = thing
+ if (!verbpath)
+ stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]")
+ var/list/entry = list()
+ entry["parent"] = "[type]"
+ entry["name"] = verbpath.desc
+ if (copytext(verbpath.name,1,2) == "@")
+ entry["command"] = copytext(verbpath.name,2)
+ else
+ entry["command"] = replacetext(verbpath.name, " ", "-")
+ var/datum/menu/verb_true_parent = GLOB.menulist[verblist[verbpath]]
+ var/true_checkbox = verb_true_parent.checkbox
+ if (true_checkbox != CHECKBOX_NONE)
+ var/checkedverb = verb_true_parent.Get_checked(C)
+ if (true_checkbox == CHECKBOX_GROUP)
+ if (verbpath == checkedverb)
+ entry["is-checked"] = TRUE
+ else
+ entry["is-checked"] = FALSE
+ else if (true_checkbox == CHECKBOX_TOGGLE)
+ entry["is-checked"] = checkedverb
+
+ entry["command"] = ".updatemenuchecked \"[verb_true_parent.type]\" \"[verbpath]\"\n[entry["command"]]"
+ entry["can-check"] = TRUE
+ entry["group"] = "[verb_true_parent.type]"
+ .[verbpath] = list2params(entry)
+
+/datum/menu/proc/Get_checked(client/C)
+ return C.prefs.menuoptions[type] || default || FALSE
+
+/datum/menu/proc/Load_checked(client/C) //Loads the checked menu item into a new client. Used by icon menus to invoke the checked item.
+ return
+
+/datum/menu/proc/Set_checked(client/C, verbpath)
+ if (checkbox == CHECKBOX_GROUP)
+ C.prefs.menuoptions[type] = verbpath
+ C.prefs.save_preferences()
+ else if (checkbox == CHECKBOX_TOGGLE)
+ var/checked = Get_checked(C)
+ C.prefs.menuoptions[type] = !checked
+ C.prefs.save_preferences()
+ winset(C, "[verbpath]", "is-checked = [!checked]")
+
+/client/verb/updatemenuchecked(menutype as text, verbpath as text)
+ set name = ".updatemenuchecked"
+ menutype = text2path(menutype)
+ verbpath = text2path(verbpath)
+ if (!menutype || !verbpath)
+ return
+ var/datum/menu/M = GLOB.menulist[menutype]
+ if (!M)
+ return
+ if (!(verbpath in typesof("[menutype]/verb")))
+ return
+ M.Set_checked(src, verbpath)
+
+
+/datum/menu/Icon/Load_checked(client/C) //So we can be lazy, we invoke the "checked" menu item on menu load.
+ var/atom/verb/verbpath = Get_checked(C)
+ if (!verbpath || !(verbpath in typesof("[type]/verb")))
+ return
+ if (copytext(verbpath.name,1,2) == "@")
+ winset(C, null, "command = [copytext(verbpath.name,2)]")
+ else
+ winset(C, null, "command = [replacetext(verbpath.name, " ", "-")]")
+
+/datum/menu/Icon/Size
+ checkbox = CHECKBOX_GROUP
+ default = /datum/menu/Icon/Size/verb/iconstretchtofit
+
+/datum/menu/Icon/Size/verb/iconstretchtofit()
+ set name = "@.winset \"mapwindow.map.icon-size=0\""
+ set desc = "&Auto (stretch-to-fit)"
+
+/datum/menu/Icon/Size/verb/icon96()
+ set name = "@.winset \"mapwindow.map.icon-size=96\""
+ set desc = "&96x96 (3x)"
+
+/datum/menu/Icon/Size/verb/icon64()
+ set name = "@.winset \"mapwindow.map.icon-size=64\""
+ set desc = "&64x64 (2x)"
+
+/datum/menu/Icon/Size/verb/icon48()
+ set name = "@.winset \"mapwindow.map.icon-size=48\""
+ set desc = "&48x48 (1.5x)"
+
+/datum/menu/Icon/Size/verb/icon32()
+ set name = "@.winset \"mapwindow.map.icon-size=32\""
+ set desc = "&32x32 (1x)"
+
+
+/datum/menu/Icon/Scaling
+ checkbox = CHECKBOX_GROUP
+ name = "Scaling Mode"
+ default = /datum/menu/Icon/Scaling/verb/NN
+
+/datum/menu/Icon/Scaling/verb/NN()
+ set name = "@.winset \"mapwindow.map.zoom-mode=distort\""
+ set desc = "Nearest Neighbor"
+
+/datum/menu/Icon/Scaling/verb/PS()
+ set name = "@.winset \"mapwindow.map.zoom-mode=normal\""
+ set desc = "Point Sampling"
+
+/datum/menu/Icon/Scaling/verb/BL()
+ set name = "@.winset \"mapwindow.map.zoom-mode=blur\""
+ set desc = "Bilinear"
+
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 45fce1f4173..20cc91bb0c8 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1038,60 +1038,6 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
- elem
- name = "&Icons"
- command = ""
- category = ""
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
- saved-params = "is-checked"
- elem "auto"
- name = "&Auto (stretch-to-fit)"
- command = ".winset \"mapwindow.map.icon-size=0\""
- category = "&Icons"
- is-checked = true
- can-check = true
- group = "size"
- is-disabled = false
- saved-params = "is-checked"
- elem "icon96"
- name = "&96x96 (3x)"
- command = ".winset \"mapwindow.map.icon-size=96\""
- category = "&Icons"
- is-checked = false
- can-check = true
- group = "size"
- is-disabled = false
- saved-params = "is-checked"
- elem "icon64"
- name = "&64x64 (2x)"
- command = ".winset \"mapwindow.map.icon-size=64\""
- category = "&Icons"
- is-checked = false
- can-check = true
- group = "size"
- is-disabled = false
- saved-params = "is-checked"
- elem "icon48"
- name = "&48x48 (1.5x)"
- command = ".winset \"mapwindow.map.icon-size=48\""
- category = "&Icons"
- is-checked = false
- can-check = true
- group = "size"
- is-disabled = false
- saved-params = "is-checked"
- elem "icon32"
- name = "&32x32"
- command = ".winset \"mapwindow.map.icon-size=32\""
- category = "&Icons"
- is-checked = false
- can-check = true
- group = "size"
- is-disabled = false
- saved-params = "is-checked"
elem
name = "&Help"
command = ""
@@ -1359,6 +1305,7 @@ window "mapwindow"
on-show = ""
on-hide = ""
style = ""
+ zoom-mode = "distort"
window "infowindow"
elem "infowindow"
diff --git a/sound/misc/highlander.ogg b/sound/misc/highlander.ogg
index 2116f8a9724..01148b55dbf 100644
Binary files a/sound/misc/highlander.ogg and b/sound/misc/highlander.ogg differ
diff --git a/sound/misc/highlander_delayed.ogg b/sound/misc/highlander_delayed.ogg
index d1cce707811..26453496628 100644
Binary files a/sound/misc/highlander_delayed.ogg and b/sound/misc/highlander_delayed.ogg differ
diff --git a/sound/misc/highlander_only_one.ogg b/sound/misc/highlander_only_one.ogg
index 3b69d26ade5..6458d10ab65 100644
Binary files a/sound/misc/highlander_only_one.ogg and b/sound/misc/highlander_only_one.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 2462a5985d9..ef14eeafbba 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -45,6 +45,7 @@
#include "code\__DEFINES\maps.dm"
#include "code\__DEFINES\math.dm"
#include "code\__DEFINES\MC.dm"
+#include "code\__DEFINES\menu.dm"
#include "code\__DEFINES\misc.dm"
#include "code\__DEFINES\mobs.dm"
#include "code\__DEFINES\monkeys.dm"
@@ -774,7 +775,6 @@
#include "code\game\objects\items\weapons\defib.dm"
#include "code\game\objects\items\weapons\dice.dm"
#include "code\game\objects\items\weapons\dna_injector.dm"
-#include "code\game\objects\items\weapons\explosives.dm"
#include "code\game\objects\items\weapons\extinguisher.dm"
#include "code\game\objects\items\weapons\flamethrower.dm"
#include "code\game\objects\items\weapons\gift.dm"
@@ -968,6 +968,7 @@
#include "code\modules\admin\admin_investigate.dm"
#include "code\modules\admin\admin_ranks.dm"
#include "code\modules\admin\admin_verbs.dm"
+#include "code\modules\admin\adminmenu.dm"
#include "code\modules\admin\banjob.dm"
#include "code\modules\admin\create_mob.dm"
#include "code\modules\admin\create_object.dm"
@@ -1386,7 +1387,8 @@
#include "code\modules\language\language_menu.dm"
#include "code\modules\language\machine.dm"
#include "code\modules\language\monkey.dm"
-#include "code\modules\language\ratvar.dm"
+#include "code\modules\language\narsian.dm"
+#include "code\modules\language\ratvarian.dm"
#include "code\modules\language\slime.dm"
#include "code\modules\language\swarmer.dm"
#include "code\modules\language\xenocommon.dm"
@@ -1669,6 +1671,7 @@
#include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
#include "code\modules\mob\living\simple_animal\hostile\illusion.dm"
+#include "code\modules\mob\living\simple_animal\hostile\jungle_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\killertomato.dm"
#include "code\modules\mob\living\simple_animal\hostile\mecha_pilot.dm"
#include "code\modules\mob\living\simple_animal\hostile\mimic.dm"
@@ -1962,6 +1965,7 @@
#include "code\modules\shuttle\arrivals.dm"
#include "code\modules\shuttle\assault_pod.dm"
#include "code\modules\shuttle\computer.dm"
+#include "code\modules\shuttle\elevator.dm"
#include "code\modules\shuttle\emergency.dm"
#include "code\modules\shuttle\ferry.dm"
#include "code\modules\shuttle\manipulator.dm"
@@ -2059,8 +2063,6 @@
#include "code\modules\surgery\organs\organ_internal.dm"
#include "code\modules\surgery\organs\tongue.dm"
#include "code\modules\surgery\organs\vocal_cords.dm"
-#include "code\modules\telesci\telepad.dm"
-#include "code\modules\telesci\telesci_computer.dm"
#include "code\modules\tgui\external.dm"
#include "code\modules\tgui\states.dm"
#include "code\modules\tgui\subsystem.dm"
@@ -2096,6 +2098,7 @@
#include "code\modules\zombie\items.dm"
#include "code\modules\zombie\organs.dm"
#include "interface\interface.dm"
+#include "interface\menu.dm"
#include "interface\stylesheet.dm"
#include "interface\skin.dmf"
// END_INCLUDE